Overview

HTML Template plugins provide a simple way to serve HTML content at a given URI that may represent an entire page or just a part of a page.

File Structure

The following files define the “mycompany.news” HTML template plugin:

mycompany/ – directory for ‘mycompany.*’ plugins
news.html – an HTML template that contains various blocks of content (title, body, etc)
news.cfg (optional) – the plugin configuration file
news.py (optional) – provides the context against which the template is evaluated, as well as optionally handling the HTTP request/response
news (optional) – directory containing resources for the news plugin

Configuration File

The configuration file for an HTML template plugin supports the following standard attributes:

  • UriPatterns (optional) – a comma-separated list of URIs which this plugin will handle. If this is not defined, the plugin will handle a URI based on the plugin name, so mycompany.news would be available at /mycompany/news
  • PagePlugin (optional) – the name of an HTML plugin to use as the master template. Generally this is not needed.

Example:

UriPatterns = /news/list
PagePlugin = mycompany.master

HTML Template File

The template file is a standard HTML templating. It may consist of one or more blocks which can be placed in different areas of the page depending on the master template specified (or the default master template).

Example:

{% block Title %}Recent News{% endblock %}

{% block Body %}

<ul class="newsList">
    {% for entry in this.NewsEntries %}
        <li>
            <h3>{%=entry.Title%} | Posted on {%=entry.Date%}</h3>
            <span>{%=entry.Content%}</span>
        </li>
    {% endfor %}
</ul>

{% endblock %}

Standard Template Blocks

Below are some standard template blocks which should be used regardless of the master template. Other non-standard blocks may also be used when defining a custom master template, however.

“Required”

  • Body – the main HTML content.

“Optional”

  • Title – a user-visible title. This may be displayed in the page body (for example,
    in an <h1> tag), or it may be rendered inside the <title> tag (or both) depending on
    the master template.
  • Header – HTML which will be inserted into the page’s <head> tag. Mostly useful for executing
    scripts which should execute prior to the DOM being loaded, and linking to CSS.
  • Scripts – HTML which is placed after all other elements. Intended for scripts which should execute
    when the DOM is available.

Providing Data for a Template

Defining a Python .py file with the same name as the .html file will allow you to control the data against which the template is evaluated. To do this, define a function named ‘setup’, which takes in 3 arguments: a request object (com.cyclecomputing.apex.rest.plugin.PluginRequest), a response object (com.cyclecomputing.apex.rest.plugin.PluginResponse), and a record.

The record passed into setup() will automatically be placed in the template’s evaluation context as an attribute named “this”. If you want to provide the template with multiple records, simply nest them inside the context record.

Example:

from application import datastore, expressions


def setup(request, response, context):
    '''
    Define a list of hard-coded news entries and add them to the template's
    evaluation context.
    '''
    now = expressions.parse("now()")

    context.setList("NewsEntries", [
        datastore.newAd({
            "Title"   : "First Post!",
            "Date"    : now,
            "Content" : "This is my first news entry!"
        }),
        datastore.newAd({
            "Title"   : "Second Post!",
            "Date"    : now,
            "Content" : "This is my second news entry!"
        })
    ])

You could then get the list in your template:

{% for entry in this.NewsEntries %}
    Title: {%= entry.Title %}
{% endfor %}

Defining a Master Template

If you would like to create a page which does not use the default CycleServer theme, you can define an HTML template plugin which can act as a master template. Other HTML template plugins can use this master template by setting PagePlugin = name.of.master.template. Below is an example of a master template for the news example above:

<!DOCTYPE html>
<html lang="en-us">

<title>{% callblock Title %}</title>

<head>
    {% callblock Header %}
    {% block Header %}{% endblock %}
</head>

<body>
    {% callblock Body %}

    {% callblock Scripts %}
    {% block Scripts %}{% endblock %}
</body>

</html>

Note that in this example, default blocks are provided for “Scripts” and “Header”. This means that plugins that use this master template can provide these blocks, but they are not required. On the other hand, no default blocks are provided for “Title” or “Body”, so child templates must define them.