The tool of thought for software solutions
Minchens Court, Minchens Lane
tel: +44 1256 830030
fax: +44 1256 830031
Dyalog is a trademark of Dyalog
Copyright Ó 1982-2018
Dyalog is a trademark of Dyalog Limited
Copyright ã 1982 – 2018 by Dyalog Limited.
All rights reserved.
Dyalog Version 17.0
No part of this publication may be reproduced in any form by any means without the prior written permission of Dyalog Limited, Minchens Court, Minchens Lane, Bramley, Hampshire, RG26 5BH, United Kingdom.
Dyalog Limited makes no representations or warranties with respect to the contents hereof and specifically disclaims any implied warranties of merchantability or fitness for any particular purpose. Dyalog Limited reserves the right to revise this publication without notification.
UNIX is a registered trademark of The
All other trademarks and copyrights are acknowledged.
The Dyalog webinar “Something Old, Something New & Something Experimental” includes a discussion and demonstration of the HTMLRenderer; it can be viewed at .
Code samples can be copied-and-pasted from an HTML version of this document at .
Introduced with Dyalog 16.0, HTMLRenderer is an object which provides a cross-platform mechanism for producing Graphical User Interfaces (GUI), based on HyperText Markup Language (HTML). Currently HTMLRenderer is available under Microsoft Windows and Apple macOS. Our plan is to make HTMLRenderer available under Linux as well – including the Raspberry Pi. Using HTMLRenderer, your application can use the same user interface code and work in the same way across platforms.
NOTE: With the release of Dyalog 17.0, HTMLRenderer has a new property, InterceptedURLs, which is used to indicate which URL patterns should trigger an HTTPRequest event for handling by your application. InterceptedURLs is a 2-column matrix where each row contains a URL pattern to match and a Boolean indicating whether the URL triggers an HTTPRequest event and is signalled back to your application. InterceptedURLs MUST be defined and have at least one row containing a 1 in the 2nd column, in order for your callback function to be used.
This is a breaking change from earlier versions of HTMLRenderer. To achieve the same behaviour as earlier versions set:
InterceptedURLs ← 1 2⍴'*' 1
Additionally, the event message included with the HTTPRequest event now includes an 11th element, which contains the HTTP Method that was invoked. Application code should not assume a specific length of this, or any other event messages.
A minimal example of using an HTML renderer would be the following: The first line of code below creates an HTML header which includes a title tag – this will set the caption for the form that contains the HTML renderer. The second line defines the HTML body, and uses simple HTML tags to mark text up as bold, italic and underlined. Finally, an HTMLRenderer is created, using the header and body as the HTML and setting the size property as well:
body←'<body><b>APL</b> + </i>HTML</i> = <u>TRUE</u></body>'
'hr' ⎕WC 'HTMLRenderer' (head,body) ('Size' (10 20))
Under Microsoft Windows, the result will be:
And under macOS:
On all platforms, the creation of an HTMLRenderer object causes APL to open a new window and run a copy of the Chromium Embedded Framework (CEF), passing the HTML to the CEF for rendering.
If the HTML contains references to other documents, the CEF will retrieve each one by making an HTTP request. Requests with URLs that match a triggering pattern in InterceptedURLs will generate an HTTPRequest event on the instance of HTMLRenderer, which can be directed to a callback function in APL. Requests with URLs that do not match a pattern in InterceptedURLs or that match a pattern with a 0 in the second column will cause the CEF to push the request out to the network and see whether an external server is able to service it. InterceptedURLs allows an APL application to decide how which content it wants to provide, and to what extent it wants to act as a portal for other services that will provide the rest of the data.
The following code illustrates how HTMLRenderer objects can be used as children of normal ⎕WC forms under Microsoft Windows. By setting the AsChild property of an HTMLRenderer object to 1, we request that the window be embedded as a sub-form of another window.
'f1'⎕WC'Form' 'Important Stuff' ('Coord'
'ScaledPixel')('Size' 820 1100)
)copy dfns pco
'f1.label1' ⎕WC 'Label' 'Primes < 100' (10 40)
'f1.primes' ⎕WC 'Grid' ('*' @ (0∘pco) 10 10⍴⍳100) ('Posn' 40 40)
f1.primes.(TitleHeight TitleWidth CellWidths Size)←0 0 25 (200 255)
'f1.label2' ⎕WC 'Label' 'Has the Large Hadron Collider destroyed the world yet?' (360 40)
'f1.areWeStillHere' ⎕WC 'HTMLRenderer' ('ASChild' 1) ('Posn' 390 40)('Size' 400 500)
twitter←'<a class="twittertimeline" href="https://twitter.com/dyalogapl">'
twitter,←'Tweets by dyalogapl</a>'
twitter,←'<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>'
'f1.twitter' ⎕WC 'HTMLRenderer' ('AsChild' 1) ('Posn' 40 570)('Size' 750 500)
The result can be seen below; a form that contains a Windows grid showing prime numbers between 1 and 100 as well as provides live feeds from two external sites. Note that no callbacks have been assigned and no URLs are indicated to be intercepted; in this case the HTMLRenderer always goes to the network to satisfy requests for data.
'HR' ⎕WC 'HTMLRenderer'
The function on the next page creates a very simple application with 2 pages: A home page called main and another page called clicked which is displayed if the user follows a link. Initialise the application by calling myapp with an empty right argument; this will cause it to create a namespace containing all the resources, and then create an HTMLRenderer and set the URL property so that it navigates to the first page – and itself as the callback function.
If called with a non-empty argument, the function handles callbacks. It verifies whether the request is for a page within its own domain and that a variable by that name exists; if all is well it returns the value of that variable as the response to the request.
∇ r←myapp args;event;obj;operation;intercept;scode;stext;mime
;url;header;postdata;approot;page;requested;method  ⍝ Serve up a small application   approot←'http://myapp/'   :If 0=≢args⍝ Setup  #.MyApp←⎕NS''  #.MyApp.main←'Hello APLers<br/>Click <a href="clicked">here</a>!'  #.MyApp.clicked←'Thank You!<br/>Click <a href="main">to go back...</a>!'  event←'Event' 'HTTPRequest' 'myapp'  intercept←1 2⍴(approot,'*')1 ⍝ intercept all URLs beginning with our approot  'hr'⎕WC'HTMLrenderer'('Size' 150 300)('Coord' 'ScaledPixel')
('InterceptedURLs'intercept)event  hr.URL←approot,'main' ⍝ Off we go!  :Return  :EndIf   (obj event operation intercept scode stext mime url header postdata method)←11↑args  requested←url ⍝ remember this   :If intercept←approot≡(≢approot)↑url ⍝ Validate domain (not really needed in v17.0)  page←(≢approot)↓url   :If 2=MyApp.⎕NC page ⍝ Do we have a variable with the name of the requested page?  (scode stext mime)←200 'OK' 'text/html' ⍝ Yes  postdata←MyApp⍎page ⍝ Return the value of the variable as output   :Else  (scode stext)←404 'Page not found' ⍝ Aww shucks  postdata←'Page not found'  :EndIf   url←'' ⍝ Not doing anything clever  header←'Cache-control: no-cache' ⍝ Always refresh these pages  r←(obj event operation intercept scode stext mime url header postdata)  :EndIf   ⎕←((1+intercept)⊃'[pass]'(6↑⍕scode)),' ',requested
Define a callback function:
 ⍝ Our first HTTPRequest callback function
 (obj event operation intercept scode stext mime url header postdata method)←11↑args
 intercept←1 ⍝ Intercept this call
 (scode stext mime)←200 'OK' 'text/html' ⍝ HTTP success code
 url←header←'' ⍝ Nothing clever at all
 postdata←'Thank you!' ⍝ Data
 r←(obj event operation intercept scode stext mime url header postdata)
Now, define a form and set up the callback:
'hr' ⎕WC 'HTMLRenderer'
hr.(Coord Size Posn)←'Pixel'(300 300)(20 20)
hr.HTML,←'<form action="#"><button>Click Me!</button></form>'
hr.InterceptedURLs←1 2⍴'*' 1 ⍝ intercept all requests
The form should look like this:
If you click on the button, the content should be replaced:
HttpUtils is a utility namespace provided with Dyalog APL v16.0 and later. It contains classes and functions for processing and formatting HTTP request and response messages. HttpUtils is designed to work with HTMLRenderer and with Conga 'HTTP' mode.
HttpUtils is distributed in the /Library/Conga/ folder in your Dyalog
installation and can be loaded using the SALT Load command. Both of the
following statements will load HttpUtils, though the latter is suitable for
running under program control.
HttpUtils is maintained in the library-conga Dyalog GitHub repository found
. There you can see the revision history and you may participate in the development community by reporting issues and by posting questions and suggestions.
The following example shows a simple HTML form with 2 input fields and a submit button. The callback is processed using the HttpRequest and HttpResponse classes found in HttpUtils.
:If 0∊⍴args ⍝
evt←'Event' 'HTTPRequest' 'SimpleForm' 
'hr'⎕WC'HTMLRenderer'('HTML'html)('Coord' 'ScaledPixel')('Size' 400
:Else ⍝ handle the
req←⎕NEW #.HttpUtils.HttpRequest args ⍝ create a request
from the callback
resp←⎕NEW #.HttpUtils.HttpResponse args ⍝ create a response
based on the request 
who←req.(FormData∘Get)¨'first' 'last' ⍝ req.FormData has
the data from the
resp.Content←'<h2>Welcome',who,'!</h2>' ⍝ set the
content for the response
r←resp.ToHtmlRenderer ⍝ and send it
Running SimpleForm '' displays the form. After filling in the form and clicking the button, SimpleForm is called again as the callback function for the HTTPRequest event, but this time args is non-empty and the callback portion lines [12-17] are executed.
#.HttpUtils.HttpRequest args ⍝ create a request from the callback data
The HttpRequest constructor accepts an argument of HTMLRenderer callback data and will parse and extract the various bits of the HTTP message into a more useful and accessible format.
#.HttpUtils.HttpResponse args ⍝ create a response based on the request
We create a response object to send back to HTMLRenderer. Like HttpRequest, the HttpResponse constructor also accepts an argument of the HTMLRenderer callback data.
'last' ⍝ req.FormData
has the data from the form
The HttpRequest class has extracted the HTML form field values into FormData. The values are retrievable by their field names in the HTML form, in this case 'first' and 'last'. Refer to lines [3-4] in SimpleForm to see where the field names were originally assigned.
 who←∊' ',¨who
 resp.Content←'<h2>Welcome',who,'!</h2>' ⍝ set the content for the response page
We now set Content in the response to be our new content for the page. The default content type is 'text/html', but other content types can be specified as appropriate for your application.
 r←resp.ToHtmlRenderer ⍝ and send it back
Finally, the response's ToHtmlRenderer method formats and populates a result appropriate for the callback and our friendly message is displayed.
To use the HTMLRenderer, you either need to be able to produce HTML and associated documents, or allow HTTP requests to pass through, as demonstrated in the example in chapter 1.
Dyalog provides a number of tools to help you generate HTML.
The SVG data produced by the RenderSVG method can be assigned directly to the HTML property of an HTMLRenderer object. The CEF accepts SVG in place of HTML and is able to render it without further intervention. You can also use the various Save… functions in SharpPlot to save graphs in SVG or other formats, and link to them using an HTML img tag.
WC2 – HTML Creation Library
page.Add _.title 'Hello World!'
page.Add _.Style 'body' ('font-family' 'Verdana')
page.Add _.h3 'Hello World!'
'fn' form.Add _.Input 'text' 'Drake' 'First Name: '
'ln' form.Add _.Input 'text' 'Mallard' ' :Last Name' 'right'
p1←'p1' form.Add _.p ''
b1←'b1' form.Add _.Button 'Press Me'
We will make announcements when WC2 is available; contact Dyalog if you would like to participate in the design and testing of these components.
The HTML Renderer is implemented using the Chromium Embedded Framework (CEF); for more information on CEF visit .
As HTMLRenderer is an object in the Dyalog GUI framework, it has many of the expected properties for a ⎕WC GUI control. The properties for HTMLRenderer are found in table 1, with properties specific to HTMLRenderer highlighted in red.
Table 1. HTMLRenderer properties
Note that unlike many other ⎕WC GUI controls, HTMLRenderer does not have a Caption property to set the caption in the title bar. The title bar caption is set by including a <title> element within the <head> element in the HTML for the page. For example:
The HTML property is a character vector of the content rendered in the object. The interpreter does not perform any pre-processing of the text. As such, it must be properly formed HTML using single-byte (⎕DR 80) character data, including any necessary escaping and encoding.
NOTE: Typically, you will need to UTF-8 encode any text outside the Unicode range 0-127.
The URL property is a character vector representing the "root" URL of the object. If not specified, 'dyalog_root' is the default value of URL. If subsequent requests for resources are received via the HTTPRequest event, the URL element of the event's arguments can be examined to see if it begins with the "root". If so, the content is intended to be provided locally by your application, otherwise, it should be retrieved from the URL element of the argument.
This property only has an effect on Microsoft Windows platforms.
The AsChild property is a Boolean indicating how the HTMLRenderer object should be treated. Possible values are:
· 1 – the HTMLRenderer object should be treated as a child of its parent object.
· 0 – the HTMLRenderer object should be treated as a top level object similar to how a Form object is treated.
The default is 0.
The InterceptedURLs property is a 2-column matrix that specifies whether HTMLRenderer will trigger an HTTPRequest event for the requested URL. The first column is a wild-carded character scalar or vector containing a pattern to match. The second column is a Boolean indicating whether HTMLRenderer should trigger an HTTPRequest event for a URL matching the corresponding pattern. InterceptedURLs may contain any number of rows.
The default is 0 2⍴'' meaning that no URLs will trigger an HTTPRequest event.
The following will trigger an
HTTPRequest event for all requested URLs
InterceptedURLs ← 1 2⍴'*' 1
The following will attempt to retrieve from the net URLs containing '.dyalog.com' and trigger an HTTPRequest event for all other requested URLS
InterceptedURLs ← 2 2⍴'*.dyalog.com*' 0 '*' 1
The events for HTMLRenderer are found in table 2, with events specific to HTMLRenderer highlighted in red.
Table 2. HTMLRenderer events
The event message reported as the result of ⎕DQ, or supplied as the right argument to your callback function, is a 11 element vector as described in table 3.
NOTE: the event message only had 10 elements in version 16.0. Application code should not assume a specific length for this, or indeed any other event messages.
Table 3. Explanation of the 11-element vector HTTPRequest event message
HTMLRenderer object name or reference
Event name 'HTTPRequest'
HTTP Request Headers
HTTP Request Body
HTTP Method (new in version 17.0): Typically 'GET' or 'POST', but other methods may occur.
When preparing a response, elements of the event message need to be updated. Specifically:
 : set to 1 if you will handle the request by updating other elements of the
In a typical scenario, you will check whether the requested URL in  begins with the "root" URL:
o If it does, then your application will supply the content of the response. In this situation, update the appropriate elements of the event message, setting element  to 1 and return.
o If it does not, then the request is for some external resource. Return without changing any elements of the event message and HTMLRenderer will attempt to retrieve the requested resource.
·  : set to the HTTP status code for the response. Success is indicated by code 200.
·  : set to the HTTP status message for the response. Success is indicated by the message 'OK'.
·  : set to the MIME type of the response. For sending HTML, the MIME type is 'text/html'.
·  : set to any HTTP message headers necessary for the response.
·  : set to the body of the response. Typically this will be HTML.
Chromium's developer tools can be used to inspect and debug the rendered HTML content.
To use Chromium's developer tools
Start the Dyalog interpreter with a command line
where xxxxx is the port number to use to connect to HTMLRenderer.
2. Start the HTMLRenderer application.
Open a Google Chrome browser and navigate to
where xxxxx is the port number you specified in step 1.
To run HTMLRenderer under a Windows runtime interpreter (dyalogrt.exe) you should:
1. Create your runtime environment as described in the Dyalog for Microsoft Windows Installation and Configuration Guide
2. Copy the following files from the Dyalog installation folder into the same folder as the dyalogrt.exe.
 Conga is the Dyalog TCP/IP utility library – HTTP mode was introduced in Conga version 3.0