Skip to content

Twig Overview

Total CMS uses Twig as its templating engine, providing a powerful, secure, and designer-friendly way to create dynamic templates. This guide covers how Twig is integrated into Total CMS and how to use it effectively.

Twig is a modern template engine for PHP that offers:

  • Clean syntax - Easy to read and write
  • Secure - Automatic output escaping
  • Fast - Compiled templates with caching
  • Flexible - Extensible with custom functions and filters
  • Designer-friendly - No PHP knowledge required

Display variables using double curly braces:

{{ variable }}
{{ user.name }}
{{ product['price'] }}
{{ items[0] }}
{# This is a comment and won't appear in the output #}

Control structures use curly braces with percent signs:

{% if cms.userLoggedIn %}
Welcome, {{ cms.userData.name }}!
{% endif %}
{% for item in items %}
<li>{{ item.title }}</li>
{% endfor %}

The most important Twig variable in Total CMS is cms, which fetches content from the CMS:

{# Get all items from a collection #}
{% set posts = cms.collection.objects('blog') %}
{# Get a specific item by ID #}
{% set coolguy = cms.collection.object('users', 'joeworkman') %}

For more information, check out the Total CMS Content with Twig docs.

{% set posts = cms.collection.objects('blog') %}
<div class="blog-posts">
{% for post in posts %}
<article>
<h2>{{ post.title }}</h2>
<time>{{ post.date | date('F j, Y') }}</time>
<div class="content">
{{ post.content | markdown }}
</div>
{% if post.tags %}
<div class="tags">
{% for tag in post.tags %}
<span class="tag">{{ tag }}</span>
{% endfor %}
</div>
{% endif %}
</article>
{% endfor %}
</div>
{% set gallery = cms.render.gallery('portfolio') %}
<div class="gallery">
<h2>{{ gallery.title }}</h2>
<div class="grid">
{% for image in gallery.images %}
<figure>
<img src="{{ image.url | resize(400, 300) }}"
alt="{{ image.alt }}"
loading="lazy">
<figcaption>{{ image.caption }}</figcaption>
</figure>
{% endfor %}
</div>
</div>
{% set feature = api('toggle', 'show-newsletter') %}
{% if cms.toggle('feature') %}
<div class="newsletter">
{% include 'partials/newsletter-signup.twig' %}
</div>
{% endif %}

Total CMS adds many custom filters to Twig:

{{ text | markdown }} {# Convert markdown to HTML #}
{{ text | nl2br }} {# Convert newlines to <br> #}
{{ text | truncate(100) }} {# Truncate to 100 characters #}
{{ text | title }} {# Title Case Text #}
{{ text | slug }} {# convert-to-slug #}
{{ post.date | date('F j, Y') }} {# January 15, 2024 #}
{{ post.date | date('Y-m-d') }} {# 2024-01-15 #}
{{ post.date | time_ago }} {# 2 hours ago #}
{{ post.date | date_modify('+1 day') }} {# Add one day #}
{{ items | first }} {# Get first item #}
{{ items | last }} {# Get last item #}
{{ items | random }} {# Get random item #}
{{ items | slice(0, 3) }} {# Get first 3 items #}
{{ items | filter(v => v.active) }} {# Filter active items #}
{{ items | map(v => v.name) }} {# Extract names #}
{{ random(1, 100) }} {# Random number #}
{{ "now" | date('Y') }} {# Current year #}
{{ dump(variable) }} {# Debug variable #}

Total CMS automatically caches compiled templates. Clear cache when making large changes.

Go to Cache Manager

Twig will automatically render HTML. If you want to display the raw HTML stored in the CMS you can.

{{ html_content | e }}

Access global variables in all templates:

{{ cms.api }}
{{ cms.dashboard }}
{{ cms.logout }}
{{ cms.domain }}

Enable debug mode to use the dump() function:

{{ dump() }} {# Dump all variables #}
{{ dump(user) }} {# Dump specific variable #}
{% if post is defined %}
{{ post.title }}
{% endif %}
{# Or use default filter #}
{{ post.title | default('Untitled') }}
{% try %}
{{ risky_operation() }}
{% catch %}
<p>An error occurred</p>
{% endtry %}
<script>
window.appData = {
user: {{ user | json_encode }},
apiUrl: "{{ api_url }}",
csrfToken: "{{ csrf_token() }}"
};
</script>
<script>
const items = [
{% for item in items %}
{
id: {{ item.id }},
name: "{{ item.name | e('js') }}"
}{% if not loop.last %},{% endif %}
{% endfor %}
];
</script>

Remember: Twig makes your templates more maintainable, secure, and easier to work with. Take advantage of its features to create clean, efficient templates!