Skip to content

Instantly share code, notes, and snippets.

@glendmaatita
Created November 16, 2013 16:54
Show Gist options
  • Save glendmaatita/7502431 to your computer and use it in GitHub Desktop.
Save glendmaatita/7502431 to your computer and use it in GitHub Desktop.
draft Artikel Emagz PHPI : Twig Template Engine
[Twig](http://twig.sensiolabs.org/) adalah template engine untuk PHP, dibuat oleh Fabien Potencier sebagai bagian dari project Symfony, dan saat ini sudah menjadi default template engine untuk Symfony. Twig secara syntax 100% sama dengan [Jinja](http://jinja.pocoo.org/), template engine untuk web application di Python.
Adapun banyaknya template engine ini, terutama di PHP, dipicu oleh semakin concern-nya para programmer untuk menulis kode yang bersih, rapi, dan paling utama adalah memisahkan kode untuk business process dan view (tampilan). Template engine berguna untuk memfasilitasi programmer untuk membuat view yang fleksibel dan benar-benar memisahkan kode view dari kode untuk business process dan logika.
Template engine untuk PHP sendiri sangat beragam karena pada dasarnya, kode PHP dapat digunakan untuk templating juga. Jika anda pernah memakai framework semisal CodeIgniter atau Kohana, mereka menggunakan kode PHP langsung untuk templating. Dengan kata lain, jika anda membuka file views anda, anda akan mendapati view anda penuh dengan kode PHP. Setidaknya ada beberapa alasan kenapa saya menyarankan anda untuk mencoba Twig sebagai template engine untuk aplikasi web anda, yaitu
+ **Bagian dari project Symfony**. Saya pribadi yakin pada kualitas kode dan kehandalan komponen-komponen Symfony. Jadi jika saya mencari komponen untuk aplikasi PHP, prefer saya yang utama adalah komponen Symfony, baru ke Zend Framework dll.
+ **Sudah merupakan Composer Package**. Ini juga salah satu alasan utama. Kita dapat dengan sangat mudah mengintegrasikan suatu library jika library tersebut sudah support composer. Bagaimana jika belum support Composer? Ada dua pilihan. Pertama, fork library tersebut dan buat versi Composer-support nya. Kedua, cari library lain. Karena saat ini, support terhadap Composer sudah sangat essensial
+ **Template Engine**. Loh kok disebutkan lagi? Yap, ini untuk mempertegas saja, bahwa Twig adalah benar-benar sebuah template engine. Bukan sekedar HTML Abstraction seperti [Jade](http://jade-lang.com/). Dalam artian kita akan mendapat berbagai fitur seperti operator, filter, functions, dll. Tambahan lagi, Twig tidak menggunakan kode PHP sama sekali untuk membuat file View, sehingga kita tidak akan melihat sebaris kode PHP pun di Views kita jika menggunakan Twig. Kode kita menjadi lebih clean
+ **Fleksibel**. Meskipun sudah menyediakan beragam function dan filter, kita tetap dapat membuat filter dan function buatan kita sendiri. Ini artinya kita dapat meng-extend fungsionalitas dari Twig
+ **Cepat**. Twig sangat cepat dalam me-render template kita menjadi HTML. Tidak ada penalti performa yang signifikan meskipun kita menggunakan banyak function dan filter di view kita
+ Dan banyak kelebihan lain yang dapat anda baca di [official website nya](http://twig.sensiolabs.org/)
**Instalasi**
Menginstall Twig paling mudah tentu saja dengan menggunakan Composer. Buat sebuah folder project bernama misalnya *twig-project* dan letakkan sebuah file bernama *composer.json* didalamnya yang isinya
{
"require": {
"twig/twig": "v1.13.2"
}
}
lalu install
~$ composer install
**Penggunaan Dasar**
Pada dasarnya, penggunaan Twig dapat dirangkum oleh beberapa baris kode berikut ini
require 'path/to/autoload.php';
$loader = new \Twig_Loader_Filesystem('/path/to/templates');
$twig = new \Twig_Environment($loader);
echo $twig->render('index.html');
Pada *baris pertama*, kita load dulu class-class pada Twig dengan memanggil file **autoload.php** dari Composer. Kemudian pada *baris kedua*, kita menentukan lokasi folder dimana templates kita diletakkan. *Baris ketiga*, kita membuat object dari instance class **Twig_Environment**. Object tersebut kita gunakan untuk merender template pada baris terakhir.
Sebelum kita membuat contoh project dengan menggunakan Twig, kita pelajari dahulu bagaimana bentuk template pada Twig
**Templating, Filter, dan Function**
Sebuah file template pada dasarnya hanyalah sebuah file text biasa. Kita bisa menggunakan sembarang extensi untuk file template kita. Saya sendiri kadang menggunakan ekstensi *.twig* atau *.tpl*. Namun anda dapat mengganti dengan ekstensi lain, tidak masalah. File-file ini nantinya akan digenerate menjadi HTML oleh Twig. Perhatikan contoh sederhana dari isi template menggunakan Twig
<!DOCTYPE html>
<html>
<head>
<title>My Users</title>
</head>
<body>
{# navigation here #}
<ul id="navigation">
{% for user in users %}
<li><a href="{{ user.twitter }}">{{ user.name }}</a></li>
{% endfor %}
</ul>
</body>
</html>
Yang menarik perhatian dari awal adalah 3 macam tipe bracket yang ada di Twig. Pertama adalah **{% %}**. Bracket ini digunakan untuk tempat melakukan operasi atau assign value suatu variable. Kedua lainnya yaitu **{{ }}** digunakan untuk mencetak (echo atau print) suatu value/variable. Dan yang terakhir adalah **{# #}** digunakan untuk comment
Template umumnya akan banyak berisi operasi variable. Variable adalah apa yang ingin kita tampilkan di template kita ketika template tersebut dirender menjadi HTML. Misalnya, isinya adalah value yang berasal dari hasil pemrosesan program di controller atau model, dan ingin kita tampilkan di view kita. Selain itu, Variable ini dapat diproses lebih lanjut dengan menggunakan **filter** atau dapat digenerate dengan menggunakan **function** seprerti contoh diatas.
***Filter*** adalah suatu fungsi, entah itu built-in Twig atau tidak yang dapat kita gunakan untuk memanipulasi Variable. Filter ini diletakkan di sebelah kanan Variable dengan pemisah berupa tanda ( **|** ). Contoh kita ingin agar value dari suatu Variable dirender dengan gaya capitalize, maka potongan contoh template diatas dapat kita ubah sebagai berikut
<li><a href="{{ user.twitter }}">{{ user.name | capitalize }}</a></li>

Contoh beberapa filter yang akan sering kita gunakan adalah
+ **raw** : me-render isi dari variable tanpa di-escape terlebih dahulu. jadi jika kita misalnya mempunyai variable yang berisi kode HTML, kode HTML itu akan di-render apa adanya, tanpa melalui proses escaping (default)
+ **capitalize** : sudah kita contohkan diatas. Value dari variable akan dirender dengan style capitalize, yaitu huruf pertama adalah huruf balok
+ **trim** : sudah tahu pastinya fungsi dari trim, yaitu untuk menghilangkan space kanan dan kiri
+ **upper** : merender isi dari variable dengan huruf balok
+ dll ( simak di [http://twig.sensiolabs.org/documentation](http://twig.sensiolabs.org/documentation) ) section filter
Sedangkan ***Functions*** adalah fungsionalitas built-in dari Twig yang dapat kita gunakan untuk menggenerate content dari template kita. Contoh dari function ini misalnya adalah **date** untuk menggenerate tanggal sekarang
{% if date(user.created_at) < date() %}
{# do something #}
{% endif %}
**date()** akan menggenerate tanggal saat ini. List function lainnya dapat dilihat di [http://twig.sensiolabs.org/documentation](http://twig.sensiolabs.org/documentation) section *filter*
**Tags, Tests, Operators**
[Tags](http://twig.sensiolabs.org/doc/tags/index.html) dapat dikatakan adalah fungsi khusus dari Twig untuk melakukan operasi yang spesifik. Susah dijelaskan hehe, tapi kita akan paham karena contoh2 kedepannya nanti kita pasti akan banyak menggunakan tags ini. Contoh Tags yg paling umum adalah *Control Structure*. Twig menyediakan tags control structure **if-else** dan **for** untuk loops. Kita bisa pakai ini untuk menggantikan control structure dari PHP
Contoh misalnya kita punya variable *users* yang berisi list daftar user yang kita query dari database kita, dan kita ingin me-render-nya di view
{% if users|length > 0 %}
<ul>
{% for user in users %}
<li>{{ user.username }}</li>
{% endfor %}
</ul>
{% endif %}
Pada contoh diatas, kita menggabungkan tags *if* dengan filter *length* . Kita dapat juga menggabungkan tags dengan apa yang disebut **Operators** dan **Tests**
{% if users is defined %}
<ul>
{% for user in users %}
<li>{{ user.username }}</li>
{% endfor %}
</ul>
{% endif %}
Perhatikan khususnya kode berikut ini
{% if users is defined %}
**is** adalah contoh *operators*. Operators ini ada beberapa macam yaitu
- Math Operator
Terdiri dari berbagai macam operasi mathematics seperti ( + - / % * **)
{% i = i + 1 * 2/3 %}
- Comparison
Operator pembanding. Sudah beberapa kali kita gunakan tadi
{% if users|length > 0 %}
{# do something #}
{% endif %}
- Logic
Operator logika seperti ( and, or, not )
{% if (users|length < 5) and (visitors|length < 4) or (visitors|length > 1) %}
{# do something #}
{% endif %}
- Operator **in** mengetest apakah suatu haystack mengandung value tertentu
{% if 1 is in [1, 2, 3] %}
- Operator **is** adalah operator untuk melakukan mengetest value dari suatu variable. Dapat dilihat di contoh diatas (operator in)
**Test** sendiri di Twig digunakan berpasangan dengan operator **is** untuk mengetest value dari suatu variabel. Beberapa macam *test* misalnya *defined, null, empty, odd, dll*
{% if foo is defined %} --> mengetest apakah variable foo telah didefinisikan
{% if foo is null %} --> mengetest apakah nilai foo adalah null
**Let's having fun with Twig**
Kita akan coba membuat tampilan sederhana dengan memanfaat fitur-fitur di Twig. Kita telah mempunyai sebuah project dengan Twig yang sudah terinstall di dalamnya melalui Composer. Kita akan buat folder kita seperti berikut ini
+ twig-project
- composer.json
+ app
+ views
- app.php
+ vendor
- index.php
Kita akan meletakkan template dan views kita di folder views. Sedangkan **app.php** adalah file utama untuk program kita.
**index.php**
*index.php* cuma digunakan sebagai front controller, proses selanjutnya diserahkan ke *app.php*
<?php
include __DIR__ . '/app/app.php';
**app.php**
*app.php* akan berisi logika dari aplikasi sederhana ini, untuk menunjukkan cara kerja Twig. Pertama, tentunya kita harus me-load dahulu class-class Twig yang sudah kita install via Composer
<?php
require_once __DIR__.'/../vendor/autoload.php';
Lalu kita membuat loader dengan parameter lokasi folder template-template kita yaitu di folder *app/views*
$loader = new \Twig_Loader_Filesystem(__DIR__ . '/views');
Lalu kita render template bernama *index.twig* yang berada di folder *views*
$twig = new \Twig_Environment($loader);
echo $twig->render('index.twig');
*index.twig* hanya berisi kode sederhana dibawah ini, hanya untuk mengetest bawah konfigurasi dan struktur folder yang kita buat sudah benar
<!DOCTYPE html>
<html>
<head>
<title>My Page</title>
</head>
<body>
<div class="header">
<ul id="navigation">
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</div>
<div class="content">
Hello Glend!!
</div>
<div class="footer">
Copyright 2013
</div>
</body>
</html>
Yap, langsung arahkan browser anda ke *http://localhost/twig-project* dan lihat hasilnya!
**Extends & Include Template**
View atau tampilan suatu website umumnya terdiri dari beberapa bagian, contoh misalnya *layout* dan *content*. *Layout* umumnya selalu sama untuk semua halaman. Yang bersifat dinamis (berubah-ubah) adalah *content*. Adapun *layout* sendiri biasanya terdiri dari beberapa bagian misalnya *header, sidebar, ataupun footer*. Pemisahan view menjadi layout dan content ini dimaksudkan agar kita sebagai developer mudah dalam memantain view kita sendiri. Kita tidak perlu repot mengedit semua file view ketika terjadi perubahan di header atau footer misalnya. Twig, sebagai template engine pun menfasilitasi mekanisme ini. Kita lihat bagaiman Twig melakukan hal ini.
Pertama, kita pisahkan dulu *index.twig* diatas menjadi layout (yang sifatnya statis), dan content yang sifatnya dinamis. Layout kita akan bagi menjadi beberapa bagian, yaitu *header* dan *footer*. Header ini akan kita tempatkan ke file tersendiri yang bernama *header.twig*
{# views/header.twig #}
<ul id="navigation">
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
Sedangkan footer akan kita tempatkan di file *footer.twig*
{# footer.twig #}
Copyright 2013
Sedangkan isi dari file *layout.twig* kita adalah **sama dengan** file *index.twig* setelah kode HTML nya dikurangi *header.twig* dan *footer.twig*. Sebagai gantinya, kita gunakan tags **include**. Gunanya untuk menginclude-kan kode dari file views lain
<!DOCTYPE html>
<html>
<head>
<title>My Page</title>
</head>
<body>
<div class="header">
{% include 'header.twig' %}
</div>
<div class="content">
{% block content %}{% endblock%}
</div>
<div class="footer">
{% include 'footer.twig' %}
</div>
</body>
</html>
Selanjutnya, adalah isi dari file *index.twig* itu sendiri. terlihat pada file *layout.twig* diatas, kode untuk konten kita telah diganti dengan
{% block content %}{% endblock %}
Itu artinya isi dari konten sudah terpisah dari file layout, dan berada di dalam tags **block** yang bernama content. Kita bisa mengganti nama block sesuka kita
{% block content %}
Hello Glend!
{% endblock %}
Terakhir, adalah kita harus memberitahu Twig bahwa kita menggunakan Layout file yang bernama *layout.twig* untuk *index.twig* kita. Kita gunakan tags **extends**
{# views/index.twig #}
{% extends 'layout.twig' %}
{% block content %}
Hello Glend!
{% endblock %}
Di Twig kita dapat menggunakan *extends* agar view kita (index.twig) mendapat semua properti dan value dari *layout.twig* (ingat konsep extends - inheritence). Kemudian kita meng-override block content di layout, yang kosong dan tidak berisi, dengan block content di index.twig yang berisi kode view. Hasilnya, adalah view yang dengan konten yang dinamis dan clean.
Struktur project kita akan menjadi seperti dibawah ini
+ twig-project
- composer.json
+ app
+ views
- layout.twig
- header.twig
- footer.twig
- index.twig
- app.php
+ vendor
- index.php
Agar views kita lebih dinamis, kita bisa me-pass value ke views. Misalnya hasil pemrosesan data di model atau controller akan kita pass ke view. KIta melakukannya dengan cara menambah parameter ke method render dalam bentuk array
// app/app.php
echo $twig->render('index.twig', array('name' => 'Glend', 'greet' => 'Hello'));
// views/index.twig
{% extends 'layout.twig' %}
{% block content %}
{{ greet }}, {{ name }}!
{% endblock %}
Sekian, intro Twig dari saya. Semoga bermanfaat
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment