101

Web Template Engines and Agile UI – Romans Malinovskis – Medium

 6 years ago
source link: https://medium.com/@romaninsh/web-template-engines-and-agile-ui-82f911c0242c
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Web Template Engines and Agile UI

This is article from the series where I explain ideology and motivation for my frameworks (see also https://medium.com/@romaninsh/the-out-of-the-box-framework-part2-b289bdcd4056) and today I’d like to talk why Agile UI uses it’s own template engine, how this engine different to other popular template engines such as Twig, Smarty and raw PHP. I will also discuss approach to “separation of concern” and how Agile UI Views are different to MVC views.

Active and Passive Template Engines

Template engine is a software library that can read template files, which will typically contain HTML and render them into full HTML body, which is sent by your application to the browser. Not all template engines are the same and I usually distinguish template engines between “passive” and “active”

Active Template Engines

Twig, Smarty and even PHP itself are template engines that permit use of logic that may influence flow of your application. A main characteristic of such template is presence of loops, includes, conditional blocks as well as modifiers.

Here is an example Twig template:

{% for user in users %}
* {{ user.name }}
{% else %}
No users have been found.
{% endfor %}

Typically active template engines would compile template into PHP code and store them in a temporary folder.

Passive Template Engine

Template engine that has no logic. A most popular passive template engine is Mustache however Agile Toolkit have used a passive template engine based around the concept designed in 1999.

The concept defines that only 2 elements may be present inside template: Tag and Region:

{greetings}Hello, {$name}!!{/greetings}

The above example illustrates full capabilities of Template engine in Agile UI. Moustache has slightly different syntax, but same principle.

The goal of passive template engine is to offer quick parsing capabilities and absolute lack of logic inside template.

Next I’ll look into concern separation in a framework and how that works with different template engine types.

Concern Separation and MVC/MVP/.. patterns

Authors of frameworks come up with “patterns” in order to educate new developers on how to properly distribute logic. Most old-school PHP developers would put everything into one file — markup, database queries and logic. A general principle of “concern separation” dictates logic should be split up and implemented in different places.

For instance a classic MVC framework may define model as a structure/object, then define controller as a logical piece which would retrieve model data and wrap it into View, which is then implemented as a template. As theory goes — model-related logic should be contained inside the model just like presentation logic (HTML) must only reside inside View (template).

Here I present a typical controller implementation:

public function show($id)
{
return view('user.profile', ['user' => User::findOrFail($id)]);
}

You can see that controller here acts as a glue and extracts $id from request, selects which model to use and also provides name of the template.

Controller does not, however, contain any fine-tuned logic on how user.profile should present the data, which restricts your choice of template engine to Active Templates.

Why I think this pattern has a flaw

In practical applications, quite often you’ll end up adding more and more logic inside your View template which not only requires very intimate knowledge of your “user.profile” schema, but also may embed links and scripts.

How Agile UI handles concern separation

The biggest difference in Agile UI handling of “View” is that it separates this concern into 2 areas: Template and View class. A similar controller code when using with Agile UI would look like this:

$view = new CRUD();
$view->init();
$view->setModel((new User($db)->ref('profile_id'));
return $view->render();

As you might have guessed, Agile UI removal of logic from Templates works perfectly with a dedicated View class. Here is a good example on how “Table” class manipulates it’s passive template table.html based around logic.

There is a big difference between Table implementation in Agile UI to how you would implement table in any other PHP framework. Because “Table” view is so much smarter, it can now read concents of the Model (field types) properly convert it’s type, escape and present value for the columns of your choice.

A result is that in Agile UI you would almost never have need to provide custom table template or redefine Table view yourself. It has no hard bindings to a specific Model fields.

The same can be said about all the other Views in Agile UI — all of them are compatible with any data structure and any database persistence.

How Agile UI handles page layouts

Traditionally, HTML layouts are responsibility of the developer. Agile UI comes with full-screen layouts which you can use out of the box.

$app->initLayout('Centered');
$app->add('CRUD')->setModel(new User($db));

When you do so, a combination of “View” and “Template” is created like this:

  • HTML boilerplate (containing Layout)
  • Layout (containing menu or frame and CRUD)
  • CRUD (containing Table, which you don’t add explicitly)

And here you can observe another unique quality of “Views” in Agile UI. They can be hierarchical. Most PHP frameworks would use templates with includes and some custom logic, but in Agile UI it’s the objects that regulate containment of the templates.

Layout template also defines various Tags where you can Root your views, for example:

$app->layout->add('Button', 'UserMenu');

This specifies template Tag {$UserMenu} where button will be rendered. Another note is that complex Views such as CRUD will rely on other Views such as Table which comes with it’s own Passive Template.

Conclusion

Template engines are created to suit it’s environments and are either equipped to contain a logic or require pairing with external logic that would manipulate the template. Agile UI is unique as it is entirely built on passive generic templates complimented by a well designed View class hierarchy.

As a result, Agile UI:

  • Can be used to build apps without use of custom templates;
  • Has Views that are generic and can be used with any data;
  • Allows recursive hierarchical use of templates;
  • Separates View logic from the presentation/linking code;
  • Most importantly — let you built entire app without any custom HTML.

You may love this approach or hate it, but for the goals that I have set for Agile UI it works wonders. I invite you to explore more about Views and Templates in Agile UI documentation. Further reading:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK