For the administration system, Cliqon makes great use of templates. We anticipate that developers will wish to use the Cliqon templating system for their front end web sites as well.


Cliqon uses a slightly modified version of the Razr template engine developed by the Pagekit team, some years ago. This is in turn, a port of the Microsoft Razor parsing engine which can be found on Github under the Antaris badge.


Razr templates and the arsing engine are extremely straightforward and simple to understand and use. The parser using Regular Expressions to convert the contents of any file with included instructions into a HTML string. Templates are in effect PHP scripts but the regular PHP open and closer commands - <php? Echo $action/$variable ?> are replaced with a combination of the @ symbol plus instructions and brackets ().

Language

As a simple example, we might write:


<h1>@( $title )</h1>

@( 23 * 42 )

@( "<Data> is escaped by default." )


Or use the @raw() directive to output any PHP data without escaping.


@raw("This will <strong>not</strong> be escaped.")


You can access single variables and nested variables in arrays/objects using the following dot . notation.


array(

   'title' => 'I am the walrus',

   'artist' => array(

       'name' => 'The Beatles',

       'homepage' => 'http://www.thebeatles.com',

   )

)


Example


<h1>@( $title )</h1>

<p>by @( $artist.name ), @( $artist.homepage )</p>

Conditional control structures

Use @if, @elseif, @else for conditional control structures. Use any boolean PHP expression.


Example


@set($expression = false)

@if( $expression )

   One.

@elseif ( !$expression )

   Two.

@else

   Three.

@endif

Loops

You can use loop statements like foreach and while.


@foreach($values as $key => $value)

   <p>@( $key ) - @( $value )</p>

@endforeach


@foreach([1,2,3] as $number)

   <p>@( $number )</p>

@endforeach


@while(true)

   <p>Infinite loop.</p>

@endwhile

Include

Extract reusable pieces of markup to an external file using partials and the @include directive. You can pass an array of arguments as a second parameter.


<section>@include('partial.tpl', ['param' => 'parameter'])</section>


and in partial.tpl:


<p>Partial with @( $param )<p>


Output


<section><p>Partial with parameter<p><section>

Extending templates with blocks

Use the @block directive to define blocks inside a template. Other template files can extend those files and define their own content for the defined blocks without changing the rest of the markup.


Example


@include('child.tpl', ['param' => 'parameter'])


In parent.tpl:


<h1>Parent template</h1>


@block('contentblock')

   <p>Parent content.</p>

@endblock


<p>Parent content outside of the block.</p>


And in child.tpl:


@extend('parent.tpl')


@block('contentblock')

   <p>You can extend themes and overwrite content inside blocks. Paremeters are available as well: @( $param ).</p>

@endblock


Note: To use an @ symbol in your text, such as info@domain.com, enter the symbol twice – info@@domain.com.

How Cliqon uses Razr templating

The sections above were taken from the Pagekit/Razr Readme. In practice Razr templating is significantly more powerful than this Readme suggests. The most important thing to understand is that fundamentally, Razr generates HTML with embedded PHP scripts. Razr provides only a few keywords for use attached to the @ symbol but virtually any PHP activity that can be written or configured on one line can exist within the brackets. Also snippets of ordinary PHP can be included in the template and these will be just passed through the engine “as is” and without any conversion.


As a general rule, this version of Cliqon only executes the template engine from a Controller. Let us look at a summarised version of the PageController which can be found in /controllers.


class PageController

{

       private $cfg;

       private $idiom;

       private $page;

       private $rq = [];


       function get($idiom, $page)

       {


               global $clq;

               $this->cfg = $clq->get('cfg');

               $clq->set('idiom', $idiom);

               $this->page = $page;

               $cms = $clq->resolve('Cms');

               method_exists($cms, $page) ? $method = $page : $method = "page";


               // Load Template Engine

               $tpl = new Engine(new FilesystemLoader($clq->get('basedir')."views"),

                 $clq->get('basedir')."cache");                

               $template = $this->page.'.tpl';

               $vars = [

                       'rootpath' => $clq->get('rootpath'),

                       'viewpath' => $clq->get('rootpath').'views/',

                       'includepath' => $clq->get('rootpath').'includes/',

                       'page' => $this->page,

                       'cmscontent' => $cms->$method($idiom, $_REQUEST),

                       'cfg' => $this->cfg,

                       'idiom' => $this->idiom,

                       'scripts' => $clq->get('js'),

                       'rq' => $_REQUEST

               ];        

               

               echo $tpl->render($template, $vars);

       }

}


In the next section we will describe Cliqon Routing. At this point please accept that a URL has been generated along the lines of http://domain.com/page/en/news/?a=24. Routing loads the PageController and the two important arguments are the language and page name, plus the $_REQUEST.


Cliqon makes the following arbitrary decisions about the configuration of the Template system and most of these decisions are represented by values in the site Configuration. Also we have chosen to demonstrate the front-end page controller. Thus it is relatively straightfoward. In comparison, the AdmninController is more complicated as it contains more programming related to Access Control.


We recommend that all PHP scripting and programming related to the main website is contained in the Class entitled Cms. You will probably want to create a Method for each Page. However we must stress that Cliqon is designed to be so flexible that it can accommodate virtually any way of working. Our recommendations for the front-end are based on the way we write the Administration system and the hundreds of web sites that we have written for customers.


The Controller identifies that there is a Method in CMS that has the same name as the page.


We now create an instance of the Template engine, giving as arguments to the Constructor the ability to load a template file from filesystem and the subdirectory where the generated HTML will be cached. We have chosen that our instance of the Template Engine shall be known as $tpl. We now define the name of our page template, which we call the same name as the page.


Our template called $page.tpl contains variables. We need to provide values for these variables. We create an array called $vars. In the $vars array we write key/value pairs. The value of a pair can be anything – a string of characters, the result of a Method call or a sub array.


One of the variables is special. It contains the dynamic javascript that will be consumed by a special @raw($scripts) block within the Document.Ready block on the Template.


Thus, as a Developer, you could elect to have no PHP template variable substitution within the template itself and do everything at Javascript level using Vue templates as an example.


So in $vars, we have defined a few useful variables, for example, the paths to the views, images, includes and public subdirectories. We have populated a main Content block with dynamic HTML content retrieved from the CMS Page Method. In the Page Method, we also generated the appropriate Javascripting which the Page Method “sets” and the Controller “gets”. You will understand that this is a Convenience mechanism. You can write your Controllers, Classes and Methods anyway you want.


Finally we can Echo the “Render”. Where the Template Render method receives two arguments, the name of the template and the arguments for the template. You can also replace Render with Publish. We just prefer Echo Render because it reminds us which aspect of our programming is producing the result on the screen.

Configuration and arbitrary decisions

Cliqon has a very flexible and expandable administration system. We choose to configure the “views” directory (the place where templates are stored) as a sub-directory called admin. We cannot visualise why you would want to change this.


We choose to give our templates the extension .tpl. We choose to make the subdirectory from which the website templates are retrieved, a subdirectory called /views.


In the administration system, we keep child templates for the main “admindesktop” template in /admin/partials. We choose to keep component templates that are used by the administration Class and Methods in the /admin/components subdirectory.


If we wanted to create several different access routes to the data – for example, pages for desktop, pages for mobiles and a completely different system for user interaction with the data, all of these can be accommodated by a Cliqon system.

Front-end templates

A few words about configuring templates for a Cliqon front end. We provide two versions of the Cliqon Framework that you can download - a demonstration version and a production version. The demonstration version is a modified instance of the Cliqon website. The production version has a single page as a template.  It is this version we shall refer to as an example.


Displayed below is a summarized version of index.tpl.


@include('partials/header.tpl')

@include('partials/cookieconsent.tpl')

</head>

<body class="landing-page">


   @include('partials/nav.tpl')


   <div class="wrapper">

       <div class="page-header page-header-small">

           <div class="page-header-image" data-parallax="true" style="background-image: url('@($viewpath)img/bg6.jpg');">

           </div>

           <div class="container">

               <div class="content-center">

                   <h2 class="title"><img class="img-fluid col-sm-5" src="@($viewpath)/img/logo.png" title="This is Cliqon" alt="@($viewpath)/img/logo.png" style="margin-top: 40px;" /></h2>

                   <div class="text-center">

                       <a href="#pablo" class="btn btn-primary btn-icon  btn-icon-mini">

                           <i class="fa fa-facebook-square"></i>

                       </a>

                       …………….

                   </div>

               </div>

           </div>

       </div>

       <div class="section section-about-us">

           <div class="container">

               <div class="row">

                   <div class="col-md-8 offset-md-2 text-center">

                       <h2 class="title">@(Q::uStr('2:What is Cliqon?'))</h2>

                       <h5 class="description">@(Q::uStr('3:Cliqon is a web app ....'))</h5>

                   </div>

               </div>

               …………………..

                </div>

           </div>

       </div>

       @include('partials/footer.tpl')


   </div>


@include('partials/script.tpl')


<!-- End of Page -->

@include('partials/end.tpl')


We can draw your attention to a few important things in the code. The first is how we include “partials” to help us normalise the template codebase. As a second point, you can see how we include important variables such path information. As explained previously the Pagekit readme does not do justice to the power of the template engine. Not only can we include variables, but we can include static and instantiated methods to retrieve language content.


Created with the Personal Edition of HelpNDoc: Write eBooks for the Kindle