Creating layouts using the Sempare Template Engine for Delphi

Sempare Limited - Oct 16 - - Dev Community

The Sempare Template Engine (available at https://github.com/sempare/sempare-delphi-template-engine and GetIt) is a versatile templating system designed specifically for Delphi developers to streamline the creation and management of dynamic HTML, text, or any other text-based output formats. Whether you are building web applications, reports, or email templates, the Sempare Template Engine offers a powerful yet straightforward solution that integrates with minimal boilerplate into Delphi projects. The template engine has been around since 2019 and has many features for you to explore.

In this tutorial, we will explore how layouts can be created using the Sempare Template Engine.

This can be done in different ways, depending on the requirements:

  • use 'include' statements
  • use 'extends' and 'block' statements

In the examples below, we will assume we are working on server side rendering of HTML pages.

Using include statements

Using include statements can be used for layouts, but doesn't scale very well. We will investigate the include statement in another tutorial as it has some super powers. For now, lets say we have an index page. We know there is a header, body and footer. A simple approach is as follows:

header.tpl

<html>
   <header>
   </header>
   <body>
Enter fullscreen mode Exit fullscreen mode

footer.tpl

   </body>
</html>
Enter fullscreen mode Exit fullscreen mode

index.tpl

<% include 'header' %>
   This is my index page
<% include 'footer' %>
Enter fullscreen mode Exit fullscreen mode

In the above, you will note that it may be more complex to manage the layout consistently. We will consider an improved approach in the next section.

Creating a layout

Considering you may be doing server side rendering, we can create a layout.tpl:

<html>
   <header>
      <style>
         <% block 'style'; end %>
      </style>
      <% block 'header'; end %>
   </header>
   <body>
      <% block 'body' %>Default Content<% end %>
   </body>
</html>
Enter fullscreen mode Exit fullscreen mode

The nice thing about the above approach is that we get a good sense of the template above compared to the 'include' approach. Placeholders named style, header and body are defined. The body placeholder block has default content, where the others are empty.

Now we could have an index.tpl:

<% extends 'layout' %>
   <% block 'header %>
       <title>Index</title>
   <% end %>
   <% block 'body' %>
      This is the index page.
   <% end %>
<% end %>
Enter fullscreen mode Exit fullscreen mode

So the above will reference the layout template and replace the header and body placeholder blocks with the content in this template.

Managing state and layout from your code

Now lets say you have two different layouts, one for being an anonymous user, and another for being a signed in user.

Our template could reference the layout via a variable such as:

<% extends layoutTpl %>
   <% block 'header %>
       <title>Index</title>
   <% end %>
   <% block 'body' %>
      This is the index page.
   <% end %>
<% end %>
Enter fullscreen mode Exit fullscreen mode

We may have Delphi/Object Pascal that uses a structure such as:

type
  TIndexData = record
     LayoutTpl : string;
  end;

function GetIndexData() : TIndexData;
begin
   if SignedIn then
     result.LayoutTpl := 'layout_authenticaetd.tpl'
   else
     result.LayoutTpl := 'layout_guest.tpl';
end;
Enter fullscreen mode Exit fullscreen mode

Controlling the layout can be done in the same way we return data to the template engine.

Conclusion

The Sempare Template Engine offers flexibility in the way layouts can be managed, allowing you to maintain your output according to your needs.

Sponsorship Required

Please help us maintain the project by supporting Sempare via GitHub sponsors (https://github.com/sponsors/sempare) or via our payment link (https://buy.stripe.com/aEU7t61N88pffQIdQQ). Sponsors can obtain access to our integrated IDE wizard for RAD Studio.

. . . . . . . . . . .