Introduction

Template language is used by designers and developers to build web pages. Web pages can have a combination of both static and dynamic content. The static elements are written in HTML, while the dynamic elements are written in FACE.

Like any programming language, FACE has a syntax, interacts with variables, and includes constructs like output and logic. Due to its readable syntax, FACE constructs are easy to recognize, and can be distinguished from HTML by two sets of delimiters:

  • The double curly brace delimiters {{ }}, denote an output expression.
  • The curly brace percentage delimiters {% %} denote a logical expression.

Face Variables

Dynamic variables can be passed through a face template. These are known as FACE Variables and can be printed using {{ }}

Syntax

{{ variable_name }}

Creating a new variable

New variables can be created by assigning values to the variables. The keyword "assign" is used here to do so. Values can also be assigned using mathematical operators. The variables can be of different types, such as:

  • Number
  • String
  • Object
  • List

Strings are enclosed in quotes, Objects are enclosed in curly braces, and Lists are enclosed in square braces.

Syntax

{% assign variable_name = variable_value %}

Example

// Numerical value
{% assign num = 4 %}

{% assign num1 = 4+4 %}

// String value
{% assign str = "John Dane" %}

Objects

Objects follow JSON notations. The data is represented in key-value pairs and are separated by commas.

Syntax

{% assign Obj={key_1:value_1,...,key_n:value_n} %}

Example

{% assign Obj2={"a":"b","c":"d"} %}

Lists

Lists are a collection of various Objects, which also follow JSON notations. Lists contain Objects separated by commas.

Syntax

{% assign Arr=[{key_1:value_1},..,{key_n:value_n}] %}

Example

{% assign Arr2=[{"a":"b"},{"c":[{"d":"e"}]}] %}

Displaying a variable

Variables can be displayed by using double curly braces {{ }}.

Syntax

{% assign variable_name = variable_value %}
{{ variable_name }}

Example

{% assign firstname = "John" %}
{% assign lastname = "Doe" %}
Hi {{ firstname }} {{ lastname }}

//output:
Hi John Doe

The property of an Object can be accessed using the dot operator.

{% assign name = {"firstname":"John","lastname":"Doe"} %}
Hi {{ name.firstname }} {{ name.lastname }}

//output:
Hi John Doe

The elements of a List can be accessed using the index.

{% assign name = [{"firstname":"John","lastname":"Doe"},{"firstname":"Jane","lastname":"Doe"}] %}
Hi {{ name[0].firstname }} {{ name[0].lastname }}
Hi {{ name[1].firstname }} {{ name[1].lastname }}

//output:
Hi John Doe
Hi Jane Doe

Objects and Lists support nesting.

Logical Operations

Logical operations are required to render Face templates. These operations need to cooperate in accordance to several conditions. Various logical operations are supported in Face.

Logical Operators

There are various logical operators in Face, which can be used in rendering the template. They are:

  • == equal
  • != not equal
  • > greater than
  • < less than
  • >= greater than or equal to
  • <= less than or equal to
  • || logical or
  • && logical and

Multiple logical operations can be combined using '||' (logical or) and '&&' (logical and) operations. For complex cases, brackets '(' and ')' may be used.

Example

{% if site.title == "Website" %}
  This is a Website
{% endif %}

{% if site.type == "Commercial" || site.type == "Entertainment" %}
  This site may be a Commercial or Entertainment website.
{% endif %}

{% if (site.type == "Entertainment" && site.title = "Music") && site.status == "free" %}
    This is a free music site
{% endif %}

Complex chains can be done depending on the usage.

Contains Operator

The Contains operator can be used for these three cases:

  • For Strings
  • To check if there is a substring inside the String.
  • For Objects
  • To check if there is a key inside the Object.
  • For Lists
  • To check if there is a value in the List.

Example

// String value
{% assign str="sairam"%}
{% if str contains "sai" %}
    String contains the word
{% endif %}

//output:
String contains the word

// Object value
{% assign obj={"name":{"first":"sai","last":"ram"}}%}

{% if obj.name contains 'first' %}
    The first name is {{obj.name.first}}
{% endif %}

//output:
The first name is sai

General Tags

Tags determine the logic and control flow when it comes to face templating language. Delimiters {% and %} are used for denoting tags.

Assign

The assign tag is used to appoint a value to a variable.

Syntax

{% assign variable_name = variable_value %}

Example

// Numerical value
{% assign num = 4 %}

{% assign sum = 4+4 %}

// String value
{% assign str = "John Dane" %}

//Assigning Multiple values
{% assign first_name="sai",last_name="ram"%}

Capture

Captures a String inside the opening and closing capture tags and assigns it to the given variable. Variables can't be created using the assign tag. However, they can be created using the capture tag. Any output String inside the tag is captured as a new String.

With capture, complex Strings can be created using other expressions.

Syntax

{% capture my_variable %}
    block
{% endcapture %}

Example

{% assign first_name = "Sai" %}
{% assign last_name = "Ram" %}
{% capture name %}
{{ first_name }} {{ last_name }}
{% endcapture %}
My name is {{name}}

//Output
My name is Sai Ram

Comment

Comments can be defined in between open and closing comment tags. Content enclosed within comment blocks will not be rendered.

Syntax

{% comment %}
    block
{% endcomment %}

Example

How are you {% comment %} This is to be ignored. {% endcomment %}

//output
How are you

Raw

Any content between opening and closing raw tags will be rendered as it is.

Syntax

{% raw %} 
    block
{% endraw %}

Example

{% assign first_name = "sai"%}
{% assign second_name = "ram"%}
{% raw %} {{ first_name }} {% endraw %} will output {{ first_name }}
{% raw %} {{ second_name }} {% endraw %} will output {{ second_name }}

//output
{{ first_name }} will output sai
{{ second_name }} will output ram

Control tags

Control tags are used to check if conditions are true or false. The flow proceeds further based on the result. Control tags can be used as branching statements.

If-else

If-else is a basic control tag, where the flow of code can be decided based on a condition. It can also be used to test if a variable exists. Multiple branching can be achieved using the 'elif' tag.

Syntax

{% if condition_1 %}
    block_1
{% elif condition_2 %}
    block_2
{% else %}
    block_3
{% endif %}

Example

{% assign x=2 %}
{% if x == 1 %}
    one
{% elif x == 2 %}
    two
{% else %}
    more than 2
{% endif %}

//output
two


{% assign obj="" %}
{% if obj %}
    obj exists..!
{% else %}
    obj does not exist..!
{% endif %}

//output
obj does not exist..!

Case

Switch case statement is used to execute a particular block of code when a specific condition is met. Various conditions can be defined in a case statement. Else statements are optional. They are used to provide executable code when none of the conditions are met.

Syntax

{% case switch_variable %}
    {% when String_1 %}
        block_1;
    {% when String_2 %}
        block_2;
    {% else %}
        block_3;
{% endcase %}

Example

{% assign ingredient ="cream" %}
{% case ingredient %}
    {% when "cream" %}
        {{ ingredient }} is good with cake. 
    {% when "milk" %}
        {{ ingredient }} is good with cookies.
    {% else %}
        {{ ingredient }} is good with neither a cake nor a cookie
{% endcase %}

//output
cream is good with cake
Switch variables can only be Strings.

Iteration Tags

Iteration Tags are used to repeatedly run a block of code. Various methods of iterations are available in Face depending on the requirement. There are various loop attributes which can be used for each iteration.

Simple For Loop

For loops allow repeated actions to be performed on each item of a List in sequential order.

Syntax

    {% for variable in list %}
            {{ variable.key_1 }} {{ variable.key_2 }} ... {{ variable.key_3 }}
    {% endfor %}

Example

{% 
contacts = [{
    "f_name": "Sai",
    "m_name": "Ram",
    "l_name": "G"
  }, {"f_name": "Gowri",
    "m_name": "",
    "l_name": "Pradeep"
  },{"f_name": "Suresh",
    "m_name": "Babu",
    "l_name": "MD"
  }]
%}

<ul>
    {% for contact in contacts %}
        <li>
            First Name: {{ contact.first_name }} 
            Middle Name: {{ contact.middle_name }} 
            Last Name: {{ contact.last_name }}
        </li>
    {% endfor %}
</ul>

//Output
<ul>
    <li>
        First Name: Sai 
        Middle Name: Ram 
        Last Name: G
    </li>
    <li>
        First Name: Gowri 
        Middle Name: 
        Last Name: Pradeep
    </li>
    <li>
        First Name: Suresh 
        Middle Name: Babu 
        Last Name: MD
    </li>
<ul>

For else

The for else block is executed when there are no items in the List.

Syntax

    {% for variable in list %}
        block
    {% forelse %}
        block
    {% endfor %}

Example

{% contacts = [] %}
<ul>
    {% for contact in contacts %}
        <li>
            {{contact}}
        </li>
    {% forelse %}
        No contacts to show.
    {% endfor %}
</ul>

//output
No contacts to show.

For range

A For loop with the given range using a start, stop, and step value. The ending range is omitted.

Eg:range(0,4) will return 0 1 2 3

Syntax

{% for variable_name in range( start, stop, step ) %}
    block
{% endfor %}

Example

{% for i in range(1, 20) %}
    {{ i }}
{% endfor %}

// Specifying step of 2
{% for i in range(1, 20, 2) %}
    {{ i }}
{% endfor %}

//output
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
1 3 5 7 9 11 13 15 17 19

Object iteration

The keys and values of an Object can be iterated using a For loop construct.

Syntax

{% for key,value in Object %}
    {{key}}
    {{value}}
    block
{% endfor %}

Example

{% assign food = {"salt":"1 tbsp","ketchup":"5 tbsp","mustard":"1 tbsp","pickle":"2 tbsp"} %}

{% for ingredient, amount in food %}
    Use {{ amount }} of {{ ingredient }}
    <br>
{% endfor %}
//output
Use 1 tbsp of mustard 
Use 1 tbsp of salt 
Use 5 tbsp of ketchup 
Use 2 tbsp of pickle 
Order of Iteration is random.

Slicing

Slicing uses start, stop, and step value to iterate items in a List within the given range. The ending range is omitted.

Syntax

SYNTAX DESCRIPTION
a[start : end] items start through end-1
a[start :] items start through the rest of the list
a[ :end] items from the beginning through end-1
a[ : ] a copy of the whole list
a[start : end : step] items start through end -1 , by step
EXAMPLE DESCRIPTION
contacts[10 : 30] returns values from index 10 to index 29
contacts[10 : ] returns values from index 10 to last
contacts[ : 20] returns values from start of list to index 19
contacts[10 : 30 : 5] returns every 5th value from 10 to 29, i.e: 10, 15, 20, 25

Example

{% for contact in contacts[5:] %}
    {{ contact }}        
{% endfor %}

//Output
Will list all contacts with the index of 5 till the end of List.

Cycle

Cycle allows the flow to loop through a set of Strings and for each iteration. The Strings in turn are cycled in the order in which they are passed. Always use cycles within loop.

Example

{% assign links = [
    {"url":"xyz1","text":"Link 1"},
    {"url":"xyz2","text":"Link 2"},
    {"url":"xyz3","text":"Link 3"},
    {"url":"xyz4","text":"Link 4"},
    {"url":"xyz5","text":"Link 5"}
    ] %}

{% for link in links %}
    <li> {% cycle "odd,even" %} url="/{{ link.url }}" text={{ link.text }} </li>
{% endfor %}

//output
odd url="/xyz1" text=Link 1
even url="/xyz2" text=Link 2
odd url="/xyz3" text=Link 3
even url="/xyz4" text=Link 4
odd url="/xyz5" text=Link 5
Cycle Iteration available for Strings.
Always use cycle within a loop.

Loop variables

Loop Variables change for each iteration of the loop, and denote the properties of the current iteration. It can be accessed inside the loop.

VARIABLE DESCRIPTION
loop.index The current iteration of the loop. (1 indexed)
loop.index0 The current iteration of the loop. (0 indexed)
loop.rindex The current iteration from the end of the loop (1 indexed)
loop.rindex0 The current iteration from the end of the loop (0 indexed)
loop.first True if first iteration
loop.last True if last iteration
loop.length The number of items in the sequence

Example

{% users = [
    { "name":"Sai"},
    { "name":"Gowri"},
    { "name":"Suresh"}
]%}

{% for user in users %}
    {{ loop.index}}. {{ user.name }}
    {% if loop.first %}
        first entry
    {% endif %}
    {% if loop.last %}
        last entry
    {% endif %}
{% endfor %}

//output
1. Sai
    first entry
2. Gowri
3. Suresh
    last entry

Control Structures

Control structures are used to manage the flow of the Face code. Various control structures are used to make the flow of code easier.

Macro

Macro can be compared to functions in regular programming language. The main purpose of using a macro is to follow the DRY (Don't Repeat Yourself) principle. They allow you to define reusable chunks of content. Macro can also be defined and called on any part of the face template.

Syntax

//macro definition
{% macro macro_name(arg1,arg2,..) %}
    macro_block
{% endmacro %}

//macro call
{{ macro_name(arg1,arg2..) }}

Example

{% macro defineField(name, value, type) %}
    <div class="field">
        <input  type="{{ type }}" 
                name="{{ name }}"
                value="{{ value }}" />
    </div>
{% endmacro %}

{{ field("username","sai","text")}}

//output
    <div class="field">
        <input  type="text" 
                name="username"
                value="sai" />
    </div>

Include

The include construct is used to import other template files into the current template. All the contents of a template including macro and variables can be imported.

Syntax

{% include template_name %}

Example

file : user.face
{% assign name = "sai" %}
<h1> User template </h1>

file : main.face
{% include 'user' %}
<h1> Main template</h1>
{{ name }}

//output for main.face
<h1> User template </h1>
<h1> Main template</h1>
sai

Extends

The Extends construct can be used to override a base template with child templates. It follows the concept of inheritance in programming language.

Syntax

{% extends template_name %}
Extends construct can be given only on the first line of a template.

More notes on the Extends construct is given in Template Inheritence section.

Filters

Filters are used to modify or format Objects or Variables. A pipe symbol (|) is used to indicate a Filter operation to an Object. Optional arguments can be given to the filter in parentheses. Multiple filters can be chained together, i.e the output of one filter can be applied to the next and so on. The input parameters to a filter may be a String or another Object.

Example

{% assign name = "SAI" %}
{{ name | lower | capitalize | append(" is my name")}}

//output
Sai is my name

The various face filters are listed given below.

lower

The given String is converted to lower case.

Syntax

{{ variable | lower }}

Example

{{ "SaiRAm" | lower }}

//output
sairam

upper

The given String converted to upper case.

Syntax

{{ variable | upper }}

Example

{{ "saiRAM" | upper }}

//output
SAIRAM

remove

Removes all occurrences of the given search-string from the main String.

Syntax

{{ variable | remove(search_string) }}

Example

{{ "Go0wr0i" | remove("0") }}

//output
Gowri

remove_first

Removes the first occurrence of the given search-string from the main String.

Syntax

{{ variable | remove_first(search_string) }}

Example

{{ "Go0wr0i" | remove_first("0") }}

//output
Gowr0i

replace

Replaces all occurrences of the given search-string with the given substring.

Syntax

{{ variable | replace(search_string,replacement_string) }}

Example

{{ "Suresh qwaqwu" | replace("qw","b") }}

//output
Suresh babu

replace_first

Replaces the first occurrence of the given search-string with the given substring.

Syntax

{{ variable | replace_first(search_string,replacement_string) }}

Example

{{ "Suresh qwaqwu" | replace_first("qw","b") }}

//output
Suresh baqwu

append

Attaches the given sub-string at the end of the main String.

Syntax

{{ variable | append(sub_string) }}

Example

{{ "Suresh" | append(" Babu") }}

//output
Suresh Babu

prepend

Attaches the given sub-string before the beginning of the main String.

Syntax

{{ variable | prepend(String_variable) }}

Example

{% name = "Gowri " %}
{{ "Pradeep" | prepend(name) }}

//output
Gowri Pradeep

trim

Displays a copy of the String with the leading and trailing white spaces removed.

Syntax

{{ variable | trim }}

Example

{{ " ZohoSites     " | trim }}

//output
ZohoSites

truncate

Reduces the number of characters in the String to the given value.

Syntax

{{ variable | truncate(number) }}

Example

{% name ="SaiRam" %}
{{ name | truncate(3) }}

//output
Sai

capitalize

Capitalizes the first letter of the given String.

Syntax

{{ variable | capitalize }}

Example

{{ "zohoSItes ROcks..!" | capitalize }}

//output
Zohosites rocks..!

camelize

Converts the given String to Camel case. The delimiters are space and hyphen.

Syntax

{{ variable | camelize }}

Example

{{ "ConverT to-Camel CASE" | camelize }}

//output
ConvertToCamelCase

strip

Removes the leading and trailing blank spaces in the given String.

Syntax

{{ variable | strip }}

Example

{{ "        Sai      " | strip }}

//output
Sai

lstrip

Removes the leading blank spaces, tabs, and new lines at the beginning of the given String.

Syntax

{{ variable | lstrip }}

Example

{{ " Sai " | lstrip }}

//output
Sai 

rstrip

Removes the trailing blank spaces, tabs, and new lines at the end of the given String.

Syntax

{{ variable | rstrip }}

Example

{{ " Sai " | rstrip }}

//output
 Sai

center

Displays a String, padded with the given parameter.

Syntax

{{ variable | center(width) }}

Example

{{ "Sai" | center(5) }}

//output
     Sai     

plus

Adds the given number to the variable.

Syntax

{{ variable | plus(number) }}

Example

{% assign x=3 %}
{{ 3 | plus(5) }}
{{ x | plus(2.5) }}

//output
8
5.5

minus

Subtracts the given number from the variable.

Syntax

{{ variable | minus(number) }}

Example

{% assign x=3 %}
{{ 3 | minus(5) }}
{{ x | minus(2.5) }}

//output
-2
0.5

multiply

Multiplies the given number with the variable.

Syntax

{{ variable | multiply(number) }}

Example

{% assign x=3 %}
{{ 3 | multiply(5) }}
{{ x | multiply(2.5) }}

//output
15
7.5

divide

Divides the variable by a given number.

Syntax

{{ variable | divide(number) }}

Example

{% assign x=3 %}
{{ 2 | divide(5) }}
{{ x | divide(1.5) }}

//output
0.4
2

modulo

Displays the modulo of the variable and the number.

Syntax

{{ variable | modulo(number) }}

Example

{% assign x=3 %}
{{ 13 | modulo(5) }}
{{ x | modulo(2) }}

//output
3
1

abs

Displays the absolute value of the given number.

Syntax

{{ variable | abs }}

Example

{% assign x=-3 %}
{% assign y=-4.3 %}
{{ x | abs }}
{{ y | abs }}

//output
3
4.3

power

Displays the variable raised to the power of a number.

Syntax

{{ variable | power(number) }}

Example

{% assign x=3 %}
{{ 13 | power(5) }}
{{ x | power(2) }}

//output
371293
9

floor

Displays the smallest whole number that is less than or equal to the given number

Syntax

{{ variable | floor }}

Example

{% assign num =3.234 %}
{{ num | floor }}

//output
3.0

ceil

Displays the smallest whole number that is greater than or equal to the given number

Syntax

{{ variable | ceil }}

Example

{% assign num =3.234 %}
{{ num | ceil }}

//output
4.0

currency

Displays the given data in format with the given currency attributes.

Syntax

Attributes:
  • symbol*
  • format*
  • code
  • symbol_on_left ( true/false )
  • code_on_left ( true/false )

*mandatory

Additional Attributes:
  • with_symbol
  • without_symbol
  • with_code
  • without_code
  • with_decimal_separator
  • without_decimal_separator
  • with_integer_part
  • without_integer_part
  • with_fractional_part
  • without_fractional_part

Example

{% assign currency= {} %} 
{% assign currency.code="USD" %} 
{% assign currency.symbol="$" %} 
{% assign currency.format="##,##,### 0.00" %} 
{% assign currency.symbol_on_left=true %} 
{% assign currency.code_on_left=true %}

{% assign value=123564.56%}

{{ value | currency(currency, "with_symbol", "with_code", "with_decimal_separator", "with_integer_part", "with_fractional_part") }}

//Output
USD $1,23,564.56

fileSizeFormat

Displays the given value as a conversion from bytes to higher size ranges.

Syntax

{{ variable | fileSizeFormat }}

Example

{% assign size = 1000000000 %}
{{ size | fileSizeFormat}}

//output
953.67MB

size

Returns the size of the given String or List.

Syntax

{{ variable | size }}

Example

{% assign str = "hello" %}
{% assign list=[{"a":"1"},{"a":"2"}]%}
{{ str | size}}
{{ list |size }}
//output
5
2

first

Displays the first character of the given String, or the first element if it is a List.

Syntax

{{ variable | first }}

Example

{% assign str = "blue bells" %}
{{ str | first }}

//output
b

last

Displays the last character of the given String, or the last element if it is a List.

Syntax

{{ variable | last }}

Example

{% assign str = "blue bells" %}
{{ str | last}}

//output
s

sort

Displays the given Object, sorted based on attributes provided. Parameters for sort filter are optional.

Syntax

{{ map_variable | sort(attribute, reverse, alphanumberic) }}

Example

Input: {% assign test= { "name_list": [
        { "id": 1, "name": "Sam" },
        { "id": 3, "name": "Jack" },
        { "id": 5, "name": "Mike" },
        { "id": 2, "name": "John" },
        { "id": 30, "name": "Peter" }
        ] } %}

1. Sort in natural order by attribute
{% assign list_sort = test.name_list | sort("id") %}

//output
[
        {"name":"Sam","id":1}, 
        {"name":"John","id":2}, 
        {"name":"Jack","id":3}, 
        {"name":"Peter","id":30}, 
        {"name":"Mike","id":5}
]

2. Sort in natural order by attribute
{% assign list_sort = test.name_list | sort("name") %}
{{ list_sort }}

//output
[
        {"name":"Jack","id":3}, 
        {"name":"John","id":2}, 
        {"name":"Mike","id":5}, 
        {"name":"Peter","id":30}, 
        {"name":"Sam","id":1}
]

3. Sort in reverse order by attribute
{% assign list_sort = test.name_list | sort("id", true, false) %}
{{ list_sort }}

//output
[
        {"name":"Mike","id":5}, 
        {"name":"Peter","id":30}, 
        {"name":"Jack","id":3}, 
        {"name":"John","id":2}, 
        {"name":"Sam","id":1}
]

4. Sort alphanumarically in reverse order by attribute 
{% assign list_sort = test.name_list | sort("id", true, true) %}
{{ list_sort }}

//output
[
        {"name":"Peter","id":30}, 
        {"name":"Mike","id":5}, 
        {"name":"Jack","id":3}, 
        {"name":"John","id":2}, 
        {"name":"Sam","id":1}
]

dictsort

Displays the given Object, in alphabetical order or reversed using the keys of the Object. Parameters for dictsort filter are optional.

Syntax

{{ map_variable | dictsort( reverse, alphanumberic, sortbyvalue) }}

Example

Input: {% assign test= { "bulbs": {
        "Bulb1": "50 Watt",
        "Bulb2": "75 Watt",
        "Bulb3": "100 Watt",
        "Bulb4": "10 Watt",
        "Bulb5": "36 Watt"
} } %}

1. Sort in natural order by keys

{% assign bulbs_sorted = test.bulbs | dictsort(false,false) %}
{{ bulbs_sorted }}

//output
{
        Bulb1=50 Watt, 
        Bulb2=75 Watt, 
        Bulb3=100 Watt, 
        Bulb4=10 Watt, 
        Bulb5=36 Watt
}

2. Sort in natural order by values 
{% assign bulbs_sorted = test.bulbs | dictsort(false,false,true) %}
{{ bulbs_sorted }}

//output
{
        Bulb4=10 Watt, 
        Bulb3=100 Watt, 
        Bulb5=36 Watt, 
        Bulb1=50 Watt, 
        Bulb2=75 Watt
}

3. Sort alphanumerically in natural order by keys
{% assign bulbs_sorted = test.bulbs | dictsort(false,false,false) %}
{{ bulbs_sorted }}

//output
{
        Bulb1=50 Watt, 
        Bulb2=75 Watt, 
        Bulb3=100 Watt, 
        Bulb4=10 Watt, 
        Bulb5=36 Watt
}

4. Sort alphanumerically in natural order by values
{% assign bulbs_sorted = test.bulbs | dictsort(false,true,true) %}
{{ bulbs_sorted }}

//output
{       
        Bulb4=10 Watt, 
        Bulb5=36 Watt, 
        Bulb1=50 Watt, 
        Bulb2=75 Watt, 
        Bulb3=100 Watt
}

5. Sort alphanumerically in reverse order by keys
{% assign bulbs_sorted = test.bulbs | dictsort(true,true,false) %}
{{ bulbs_sorted }}

//output
{
        Bulb5=36 Watt, 
        Bulb4=10 Watt, 
        Bulb3=100 Watt, 
        Bulb2=75 Watt, 
        Bulb1=50 Watt
}

6. Sort alphanumerically in reverse order by values
{% assign bulbs_sorted = test.bulbs | dictsort(true,true,true) %}
{{ bulbs_sorted }}

//output
{
        Bulb3=100 Watt, 
        Bulb2=75 Watt, 
        Bulb1=50 Watt, 
        Bulb5=36 Watt, 
        Bulb4=10 Watt
}


7. Simple dictsort
{% assign animals={"ant":"black","dog":"brown","cat":"yellow"} %}
{{animals | dictsort}}

//output
{ant=black, cat=yellow, dog=brown} 

escHtml

Displays the given String, after converting its HTML characters to their equivalent Strings.

Syntax

{{ variable | escHtml }}

Example

{% assign htmlStr="<hi>how are you" %}
{{ htmlStr | escHtml}}    

//output
<hi>how are you

escQuotes

Displays the given String, after escaping the single and double quotes within the text.

Syntax

{{ variable | escQuotes}}

Example

{% assign htmlStr="Sara's cap" %}
{{ htmlStr | escQuotes}}    

//output
Sara\'s cap

urlize

Displays the given String as an URL. A length parameter can also be given to truncate the URL.

Syntax

{{ URL_string | urlize }}
{{ URL_string | urlize(truncate_int) }}

Example

    {% assign url = "sites.zoho.com" %}
    {{url | urlize}}
    {{url | urlize(5)}}

//output
<a href="http://sites.zoho.com" title="http://sites.zoho.com" rel="nofollow" >sites.zoho.com</a>
<a href="http://sites.zoho.com" title="http://sites.zoho.com" rel="nofollow" >sites...</a>

floatValue

Displays the given value as a decimal.

Syntax

{{ number | floatValue }}

Example

{% assign num=2 %}
{{num | floatValue}}

//output
2.0

hasElement

Displays either true or false based on the existence of the specified element in the given String, Object, or List.

Syntax

{{ varibale | hasElement(search_element) }}

Example

{% assign obj = {"a":"1","b":"2"} %}
{% assign str = "Sai" %}
{{ obj | hasElement("a")}}
{{ str | hasElement("i")}}

//output
true
true

pluralize

Displays the singular or plural form of the given value. The default plural String that will be added is 's'. The List is considered plural if the size of the list is greater than 1.

Syntax

{{ variable | pluralize }}
{{ variable | pluralize(plural_string) }}
{{ variable | pluralize(singular_string,plural_string) }}

Example

{% assign list_1=[{"a":"b"},{"c":"d"}] %}
{% assign list_2=[{"a":"b"}] %}

list_1 has {{list_1 | size }} {{list_1 | pluralize("s") }}
list_1 has {{list_1 | size }} {{list_1 | pluralize("s") }}

//output
list1 has 2 elements
list2 has 1 element

entries

Displays the keys and values of an Object.

Syntax

{{ variable | entries }}

Example

{% assign obj={"a":"b","e":"f","c":"d"}  %}
{{ obj | entries }}

//output
[a=b, c=d, e=f]

batch

Displays a List, filled to a given number. The variable to be batched is given as the second parameter.

Syntax

{{ variable | batch(number_of_items,fill_parameter) }}

Example

{% assign list_var=[{"a":"b"},{"c":"d"},{"e":"f"} %}
{{ list_var | batch(5,"test") }}

//output
[{"a":"b"},{"c":"d"},{"e":"f"},"test","test"] 

map

Displays a Map, after applying various filters to one of its attributes.

Syntax

{{ variable | map(attr="attr_name",prefix="prefix_name",upper/lower) }}

Example

{% assign x=[{"a":"one","b":"two"},{"a":"three","b":"four"},{"a":"five","b":"six"}] %}
{{ x | map(attr="a",prefix="a ",lower) }}

{{ x | map(attr="b",prefix="b ",upper) }}

//output
[a one, a three, a five] 
[B TWO, B FOUR, B SIX]

split

Returns a the splited list of a String variable by a delimiter.

Syntax

{{ variable | split(delimiter) }}

Example

{% assign str="this is an example statement" %}
{{ str | split(" ") }}

//output
[this, is, an, example, statement]

{% assign word = str | split(" ")%}
Give an {{ word[3] }}.

//output
Give an example.

splitFirst

Displays the first split of a String variable by a delimiter.

Syntax

{{ variable | splitFirst(delimiter) }}

Example

{% assign str="test.string" %}
{{ str | splitFirst(".") }}

//output
test

splitLast

Displays the last split of a String variable by a delimiter.

Syntax

{{ variable | splitLast(delimiter) }}

Example

{% assign str="test.string" %}
{{ str | splitLast(".") }}

//output
string

encodeURIComponent

Displays the given URI after encoding (Equivalent to JavaScript encodeURIComponent).

Syntax

{{ uri | encodeURIComponent }}

Example

{% assign uri="sites.zoho.com/index" %}
{{ uri | encodeURIComponent }}

//output
sites.zoho.com/index

decodeURI

Displays the given URI after decoding.

Syntax

{{ uri | decodeURI }}

Example

{% assign uri="sites.zoho.com%2Findex" %}
{{ uri | decodeURI }}

//output
sites.zoho.com/index

defaultValue

Displays the current value if the variable is not empty or false. Otherwise, it displays the default value as a parameter.

Syntax

{{ variable | defaultValue(default_value) }}

Example

{% assign val = "" %}
{{ val | defaultValue("default") }}

//output
default

join

Displays the given List joined by the delmiter value given as a parameter.

Syntax

{{ list | join(delimiter) }}

Example

list = ["a","b","c"] 
{{ list | join(":") }}

//output
a:b:c

json

Displays the given List or Object in json format.

Syntax

{{ variable | json }}

Example

{% assign obj = {"a":"b","c":"d"} %} 
{{ obj | json }}

//output
{a=b,c=d}

toJSONString

Displays the given List or Object in json format.

Syntax

{{ variable | toJSONString }}

Example

{% assign obj = {"a":"b","c":"d"} %} 
{{ obj | json }}

//output
{a=b,c=d}

parseJSON

Parses the JSON from String variable

Syntax

{{ variable | parseJSON }}

Example

// Double quotes inside the string are explicitly escaped as directly assigned.

{% assign string = "{\"a\":\"b\",\"c\":\"d\"}" %} 
{% assign obj = string | parseJSON }}
{{ obj.a }}

//output
b

date

Displays the given unix timestamp in date format. The required output format can be given as a parameter.

Syntax

{{ variable | date }}
{{ variable | date(format_string) }}

Example

{{ 1475144184 | date}}
{{ 1475144184 | date("YY-MM-dd")}}

//output
Thu Sep 29 15:46:24 IST 2016 
16-09-29 

dateFormat

Displays the converted date format. The input and output date formats are given as parameters.

Syntax

{{ variable | dateFormat(inputFormat,outputFormat) }}

Example

{% assign date1="2017-03-14 18:41:31.0" %}
{{ date1 | dateFormat("yyyy-MM-dd HH:mm:ss","M-d-yy")}}

//output
3-14-17

Sample Date Patterns

Input string Pattern
2001.07.04 AD at 12:08:56 PDT yyyy.MM.dd G 'at' HH:mm:ss z
Wed, Jul 4, '01 EEE, MMM d, ''yy
12:08 PM h:mm a
12 o'clock PM, Pacific Daylight Time hh 'o''clock' a, zzzz
0:08 PM, PDT K:mm a, z
02001.July.04 AD 12:08 PM yyyyy.MMMM.dd GGG hh:mm aaa
Wed, 4 Jul 2001 12:08:56 -0700 EEE, d MMM yyyy HH:mm:ss Z
010704120856-0700 yyMMddHHmmssZ
2001-07-04T12:08:56.235-0700 yyyy-MM-dd'T'HH:mm:ss.SSSZ
2001-07-04T12:08:56.235-07:00 yyyy-MM-dd'T'HH:mm:ss.SSSXXX
2001-W27-3 YYYY-'W'ww-u

Template Inheritance

Template inheritance is one of the most powerful features of Face. It facilitates building a base template ,and contains all the common elements of a site like header and footer, which it defines as blocks. Child templates, which inherit the base templates, can then override these blocks. This facilitates efficient management and clean structuring of templates. Template inheritance is achieved in face via Extends and Block tags.

Block tag

Block tags can be defined as placeholders, where the content changes when the template is extended. Every block has a name. When blocks are not overridden in the child template, it can be considered as a default content.

Syntax

{% block block_name %}
    block_content
{% endblock %}

Base Template

The base template can be referred to as a skeleton template. It defines a simple base layout of the page. Adding content between block tags is optional.

Child Template

Child templates fill the blocks in the parent template with content. The parent blocks are overridden in the child template.

Example

An example of Template Inheritence is given below. Here, base.face is the parent template, and index.face is the child template.

//Base template -> base.face
<html>
<head>
    <link rel="stylesheet" href="style.css" />
    <title>{% block title %}ZohoSites{% endblock %}</title>
</head>

<body>
    <div id="header">
        {% block header %}
        {% endblock %}
    </div>
    <div id="menu bar">
        {% block menu%}
        <ul>
            <li><a href="/">Home</a></li>
            <li><a href="/blog/">Blog</a></li>
        </ul>
        {% endblock %}
    </div>
    <div id="content">
        {% block content %}{% endblock %}
    </div>
    <div id="footer">
        {% block footer %} 
            <h2>Default footer</h2>
        {% endblock %}
    </div>
</body>
</html>

In the base template above, the {% block %} tags enclose five different blocks that child templates can inherit. The child template may override the content of these block tags in the template.

//Child Template -> index.face
{% extends "base" %}
{% block title %}Index{% endblock %}
This is ignored..!
{% block content %}
    <h1>Index Page</h1>
    <p>
        This is the Index Page
    </p>
{% endblock %}

Here, the {% extends %} tag indicate that the current template is an extension of another template. The extends tag should be included in the beginning of a template. When there is an 'extends' tag, the parent template is fetched before the child template is rendered. The blocks of a parent template are overridden by the child template, then the template gets rendered.

//output -> child.face
<html>
<head>
    <link rel="stylesheet" href="style.css" />
    <title>Index</title>
</head>

<body>
    <div id="header">
    </div>
    <div id="menu bar">
        <ul>
            <li><a href="/">Home</a></li>
            <li><a href="/blog/">Blog</a></li>
        </ul>
    </div>
    <div id="content">
    <h1>Index Page</h1>
    <p>
        This is the Index Page
    </p>
    </div>
    <div id="footer">
        <h2>Default footer</h2>
    </div>
</body>
</html>

Template Inheritence behaviour

  • Blocks can be empty.
  • Blocks defined in the parent template do not have to be defined in the sub template.
  • When a Block defined in parent template is not overridden in child template, the content in the block is considered as the default content.
  • Content defined in blocks outside a child template are ignored.