Site icon Embarcadero RAD Studio, Delphi, & C++Builder Blogs

RAD Studio Web Development Reimagined with the WebStencils Template Engine

06 rad studio web development reimagined with the webstencils 1600 x 900

RAD Studio 12.2 introduces WebStencils, a server-side script-based integration and processing of HTML files, often called a template engine. This and its component can be used in WebBroker and RAD Server, but also for DataSnap and even in non-Web applications to produce HTML, JSON, YAML, comma delimited files, or any other file in which you need to merge specific data. The application code can be written in Delphi or in C++.

WebStencils main goal is to significantly extend the existing web technologies in RAD Studio (WebBroker, DataSnap, RAD Server) by providing server-side scripting and turning RAD Server from a Web Service engine into a Web Site and Web Service tool. This means the ability to create HTML pages with standard tools and adopt any CSS and JavaScript libraries, while retaining the ability to add data from the generated pages coming from the application, like the result of a database query or any other complex data processing. 

In other words the main goal is to help with navigational and interactive websites: A blog, an online catalog, an online ordering system, a reference like a dictionary, and a wiki. These are all examples of navigational websites. In addition, WebStencils can be a good foundation for HTMX as a solution for web development. The two technologies go nicely together. HTMX pages can benefit from server-side code generation and hook into REST servers regarding content updates. Delphi web technologies can offer page generation and REST APIs at a very high-quality level.

From PageProducer to WebStencilsProcessor

Historically, the WebBroker and DataSnap libraries used the PageProducer component and derived ones to customize the HTML returned by a web server application. The processing was very limited and there was no simple way to have a shared template for the website pages. Also, the tag-based notation (<#custom attrib=”value”>) wasn’t very easy to use. WebStencils offers a different notation (the previous tag will become @custom.value) that’s easier to write and maintain into a complex HTML page, adds conditional and looping statements, and introduces a template and include mechanisms.

At the same time, the new WebStencilsProcessor components is a drop-in replacement for a PageProducer, as it implements the same interface and can be used in a WebBroker or DataSnap WebAction. You can add this component to a WebModule (the design-time data modules used by RAD Studio web applications), hook it to an action, and you’ll be good to get started with it. Before I get to a demo, though, let’s go over the syntax and a few other key elements of WebStencils.

This is an example of the WebStencilsProcessor component connected to an action in WebBroker:

The WebStencils Syntax

The WebStencils scripting language in RAD Studio has a rather simple syntax based on two elements:

Accessing an Object Value

The general value access is based on a dot notation as @myobject.value. What does this stand for?

The name of the object (myobject) is a symbolic local name. It can be define in multiple ways:

The name of the specific element of the object (value) can be mapped to:

Accessing Values with the Dot Notation

Suppose you have an HTML WebStencils snippet with this code:
[crayon-673ef0cfa5420121321710/]
You can provide the data using a component with this event handler (the OnValue event):
[crayon-673ef0cfa542b809271334/]
In this simple case, the code checks only the object name (the first part of the symbol before the dot), but in general, you’d also want to check the FieldName, the symbol after the dot).

The alternative approach is to provide the values using an object. In this case, we must configure and associate the object with the action’s producer.
This is a complete example, assuming a TMyObject class with a Name string property :
[crayon-673ef0cfa542e040511988/]
The code defined the HTML template, using a Delphi multiline string, creates an object registering it as a script variable (calling AddVar), registered with the name ‘world’, and executes the script by accessing to its Content property. The result is “Value obtained from data: Hello hello.

Using a DataSet

The alternative option is to use the current record of a dataset rather than an object. In this case (given a ClientDataSet), your initialization code might look like this:

This code registers a ClientDataSet with the name dataset. The matching HTML can have references to the object and some of the fields of each of the records, by using a foreach loop and the @loop WebStencils keywords to refer to the current element of the loop (that is, the current record):

This results in an output like the following output:

Templates: Layout and Body

A must-have feature of a template engine is the ability to merge a shared HTML template with the actual content of a page. This is accomplished using:

Here is an example of the use of @LayoutPage and @RenderBody in a specific page and a sample template. As you can see the page refers to the specific template, while the template has a general placeholder indicating where to merge in the page content. Notice that this is a reduce version of the HTML code used to generate the page shown above.

Test.html
[crayon-673ef0cfa5430993684210/]
BaseTemplate.html
[crayon-673ef0cfa5432958516048/]

The Two WebStencils Components

To end this quick introduction to WebStencils (full coverage will easily take a small book!) I want to mention the two different components provided by the new WebStencils package:

Here is a WebModule with both components:

I know this isn’t terribly obvious at first sight, but overall the WebStencilsProcessor is used to process a single URL (and you can have many in an app) while the WebStencilsEngine can define it’s own mapping of URLs to actual files to process, offering also a mechanism to execute specific server side code for each… but that would require another blog post.

Introducing WebStencilsEngine

Up to now in this blog post we have seen simple demos using the Processors component associated directly or indirectly to an action in WebBroker. This is nice, but won’t scale to a Web server with dozens or hundreds of different URLs. That’s why there is also an Engine component. But how does it work? How to you map URLs to files to process and how do you associate specific code to be executed on the server? The WebStencilsEngine component has a PathTemplates collection property you can use to associate a URL path to a specific file. This is an example in a RAD Server package:

The PathTemplates collection property serves also a different purpose, which explains why there are value listed with not mapping (like company): You can associate to each item in the collection an event handle with initialization code to be executed when the URL matches, similarly to the code in the OnAction event handlers earlier. For example, the following code for the company URL checks if there is an ID parameter passed in the URL and saved in the script variables and uses it to locate a specific record in the dataset to display on the web page:

There is Way More

The WebStencils engine is fairly complex. There are more WebStencils keywords and I’ve covered here and dozens of properties, methods, and events in the two components. Here is the main Embarcadero DocWiki link for WebStencils, but we are working on extensive documentation and we know that one independent experts is working on a book. I might blog more, as well.

Exit mobile version