Templates with Twig

Easier Than You Think

with Margaret Staples

Hello, Nice to Meet You

I'm Margaret

Hello, Nice to Meet You

I'm Margaret

I have been working with Twig

mostly as part of the Symfony2 framework

for about 3 years

Hello, Nice to Meet You

I'm Margaret

I'm developing a Social Strategy City-Builder RPG game of awesomeness.

brunegame.com

Twig Templates

Overview

  1. Create a New Project
  2. Install Twig
  3. Create a Twig Layout
  4. Initial Twig Template
  5. Using Variables
  6. Conditionals and Loops
  7. Including Templates
  8. Additional Information

Create a New Project

Local Webserver

Linux + Apache + MySQL + PHP

Create a New Project

New Project Structure

*/NewProject

*/NewProject/src

*/NewProject/views

*/NewProject/index.php

 

 

 

*/path/to/web/directory

Install Twig

Composer

Dependency Manager for PHP

getcomposer.org

Install Twig

Install Twig

*/NewProject/composer.json

{
    "autoload": {
        "psr-4": {
            "NewProject\\Classes\\": "src/"
        }
    },
    "require": {
        "twig/twig": "~1.0"
    }
}

> php composer.phar install

Install Twig

Install Twig (Alternative)

> php composer.phar init

Search for a package: Twig

Enter package # to add ...: 0

...
    "autoload": {
        "psr-4": {
            "NewProject\\Classes\\": "src/"
        }
    }
...

Install Twig

*/NewProject/index.php

<?php

require_once 'vendor/autoload.php';
require_once 'vendor/twig/twig/lib/Twig/Autoloader.php';

Twig_Autoloader::register();

$loader = new Twig_Loader_Filesystem('views');

$twig = new Twig_Environment($loader, [
    'cache' => 'cache',
]);

Add to index.php

Create a Twig Layout

*/NewProject/views/layout.html

<!DOCTYPE html>
<html>
    <head>
        <style>
            h1 {
                color: blue;
            }
        </style>
    </head>
    <body>
    </body>
</html>

Create layout.html

Create a Twig Layout

Add Blocks to the Layout

Create layout.html

...
    <body>
        {% block content %}
        {% endblock %}

        {% block footer %}
            © Copyright 2015 by MyCompany.
        {% endblock %}
    </body>
...

Blocks designate areas that may be replaced by child templates.

Block content in the layout will be the default.

Initial Twig Template

*/NewProject/views/index.html

{% extends 'layout.html' %}

{% block content %}
 
    <h1>Hello World!</h1>

{% endblock %}

Create index.html

Initial Twig Template

*/NewProject/src/Page.php

<?php

namespace NewProject\Classes;

class Page
{
    public function index()
    {
        return [ 
            'salute' => 'goodnight',
            'target' => 'moon'
         ];

Create Page.php

Initial Twig Template

*/NewProject/index.php

<?php

...

use NewProject\Classes\Page;

...

$page = new Page();

echo $twig->render('index.html', $page->index());

Use Page.php and index.html

Initial Twig Template

localhost/NewProject/index.php

View Initial Twig Template

Hello World!

Let's Review!

What is the purpose of views/layout.html?

Provide HTML, CSS, and Javascript that is the same for multiple templates

Let's Review!

What is the purpose of Page.php's index() function?

To prepare data for the index.html template.

Let's Review!

To identify where in layout.html to place the template content.

What is the purpose of the

{% content block %} {% endblock %} tags?

Using Variables

Use variables from Page.php index()

*/NewProject/src/Page.php

return [ 
    'salute' => 'goodnight',
    'target' => 'moon'
 ];

*/NewProject/index.php

echo $twig->render('index.html', $page->index());

Using Variables

*/NewProject/views/index.html

{% extends 'layout.html' %}

{% block content %}
 
    <h1>{{ salute }} {{ target }}!</h1>

{% endblock %}

Use variables from Page.php index()

Using Variables

View Your Page

localhost/NewProject/index.php

goodnight moon!

Using Variables

Modify Your Variables

*/NewProject/views/index.html

{% extends 'layout.html' %}

{% block content %}
 
    <h1>{{ salute|title }} {{ target|title }}!</h1>

{% endblock %}

Goodnight Moon!

Using Variables

{{ salute|capitalize }} = Goodnight

{{ salute|lower }} = goodnight

{{ salute|upper }} = GOODNIGHT

{{ salute }} moon = goodnight moon

{{ salute ~ ' ' ~ target }} = goodnight moon

{{ "goodnight ${target}" }} = goodnight moon

{{ "hi moon"|replace({ 'hi': 'goodnight' }) }} = goodnight moon

Strings

twig.sensiolabs.org

Using Variables

{{ -1234.567|round }} = -1235

{{ -1234.567|abs }} = 1234.567

{{ "1 + 2 = ${1 + 2}" }} = 1 + 2 = 3

{{ -1234.567|number_format(2) }} = -1,234.56

{{ 5 // 2 }} = 2

{{ 2 ** 3 }} = 8

Numbers

twig.sensiolabs.org

Using Variables

Setting Variables

twig.sensiolabs.org

{% set my_var = "I am a new value!" %}

{{ my_var }}

I am a new value!

Using Variables

More Filters

twig.sensiolabs.org/doc/filters/index.html

trim
upper
url_encodereplace
reverse
round
nl2br
number_format
convert_encoding
date
abs
batch
capitalize
date_modify
default
escape
first
formatjoin
json_encode
keys
last
length
lower
merge
rawslice
sort
split
striptags

Using Variables

Custom Filters, Functions, and Tags

twig.sensiolabs.org/doc/advanced.html#creating-an-extension

Implement the Twig_ExtensionInterface Interface

Register using the addExtension() method

Override the getFilters() method

Register functions using the getFunctions() method

Override the getTokenParsers() method

Let's Review!

How do we print the value of a variable in Twig?

Surround the variable name with double curly brackets:

{{ foo }}

Let's Review!

How do we apply a Twig filter to a value?

Follow the value with a pipe and the name of the filter:

{{ foo|title }}

Let's Review!

What signifies an action tag as opposed to a display tag?

Surround the action with curly-bracket percent-sign pairs:

{% set foo = bar %}

Conditionals and Loops

Logic

{{ "goodnight" starts with "g" }} = true

{{ "moon" ends with "p" }} = false

{{ "night" in "goodnight" }} = true

{{ 1 in [ 1, 2, 3 ] }} = true

{{ 1 is even }} = false

{{ 4 not in [ 1, 2, 3 ] }} = true

{{ "moon"|length < 3 }} = false

twig.sensiolabs.org

Conditionals and Loops

Conditionals

*/NewProject/views/index.html

{% if target|lower == 'sun' %}
    {% set title_color = 'red' %}
{% else %}
    {% set title_color = 'purple' %}
{% endif %}

<h1 style="color:{{ title_color }}">
    {{ salute|title }} {{ target }}!
</h1>

Goodnight Moon!

Conditionals and Loops

Loops

*/NewProject/src/Page.php

public function index()
{        
    return [ 
        'salute' => 'Goodnight',
        'my_set' => [ 
            'red' => 'Sun', 
            'blue' => 'Moon',
            'purple' => 'Stars' 
        ]
     ];
}

Conditionals and Loops

Loops

*/NewProject/views/index.html

{% for key,value in my_set %}

    <h1 style="color: {{ key }}">
        {{ loop.index }}. {{ salute }} {{ value }}!
    </h1>

{% endfor %}

1. Goodnight Sun!

2. Goodnight Moon!

3. Goodnight Stars!

Conditionals and Loops

Loops with Objects

class MyRecord 
{
    protected title;
    protected description;
    protected link;
    protected color;

    ...
}

Conditionals and Loops

Loops with Objects

*/NewProject/views/index.php

{% for record in my_records %}
    <a href="{{ record.link }}">
        <h1 style="color: {{ record.color }}">
            {{ record.title }}
        </h1>
    </a>
    <p>{{ record.description }}</p>
{% endfor %}

Conditionals and Loops

Loops with Nested Arrays

$my_array = [
    1 => [
        'title' => "My Title",
        'description' => "This is a description",
        'link' => "http://twig.sensiolabs.org",
        'color' => "blue"
    ],
    2 => [
        'title' => "Other Title",
        'description' => "Another description",
        'link' => "http://getcomposer.org",
        'color' => "green"
    ]
];

Conditionals and Loops

Loops with Nested Arrays

*/NewProject/views/index.php

{% for record in my_records %}
    <a href="{{ record.link }}">
        <h1 style="color: {{ record.color }}">
            {{ record.title }}
        </h1>
    </a>
    <p>{{ record.description }}</p>
{% endfor %}

Let's Review!

How do we access the keys when looping through an array?

By providing a key name followed by a comma and a value name in the loop declaration:

{% for key,value in array %} 

Let's Review!

How do we access an object's properties?

By using a dot, followed by the property name:

myObject.objectProperty

*Bracket notation also works: myObject['objectProperty']

Let's Review!

How do we access an array value by key?

Just like an object:

myArray.arrayKey

*Bracket notation also works: myArray['arrayKey']

Let's Review!

How can we get the current iteration count in a loop?

loop.index

Including Templates

Create heading.html

*/NewProject/images/fancyheading.png

*/NewProject/views/heading.html

<div class="heading">
    <img src="../images/fancyheading.png">
</div>

Including Templates

Create feature.html

*/NewProject/views/feature.html

<div class="feature">
    <img src="../images/feature.png">
</div>

*/NewProject/images/feature.png

Including Templates

Create feature.html

*/NewProject/views/index.html

{% extends 'layout.html' %}

{% block content %}

    {% include 'heading.html' %}
        
    <h1>{{ salute|title }} {{ my_set.blue }}!</h1>

    {% include 'feature.html' %}

{% endblock %}

Including Templates

localhost/NewProject/index.php

View Your Page

Goodnight Moon!

Twig Templates

Additional Information

http://twig.sensiolabs.org/

Questions?

Margaret Staples

@dead_lugosi on twitter

deadlugosi on freenode

brunegame.com

Twig

By Margaret Staples

Twig

  • 3,684