Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save IceShack/cdee4c02753455e9a3c9 to your computer and use it in GitHub Desktop.
Save IceShack/cdee4c02753455e9a3c9 to your computer and use it in GitHub Desktop.
MacroTwigExtension - Autoloading macro in templates for symfony 2.3+
{# app/Resources/views/Bundle/Controller/action.html.twig #}
{{ macro_list_ol(['un', 'deux', 'trois']) }}
{% set hash = { 'one': 'un, 'two': 2, 'posts': posts } %}
{{ macro_list_ul(hash) }}
{% macro article(art) %}
<article>
<h3>{{ art.title }}</h3>
<p>{{ art.content }}</p>
<div class="comments>{{ macro_list_ol(art.comments) }}</div> {# autoloaded from macro %}
<article>
{% endmacro %}
{% import _self as macro %}
{{ macro.article(post) }} {# needs to be imported as current "_self" is not in autoloaded library #}
{# app/Resources/views/_includes/macros/list.twig #}
{% macro ol(array) %}
{% if array is iterable %}
<ol>
{% for item in array %}
<li>
{% if item is iterable %}
{% for sub_item in item %}{{ macro_list_ul(sub_item) }}{% endfor %}
{% else %}{{ item }}{% endif %}
</li>
{% endfor %}
</ol>
{% else %}
<ol><li>{{ array }}</li></ol>
{% endif %}
{% endmacro %}
{% macro ul(array) %}
{% if array is iterable %}
<ul>
{% for key, item in array %}
<li>{{ key }}:
{% if item is iterable %}
{% for sub_item in item %}{{ macro_list_ol(item) }}{% endfor %}
{% else %}
{{ item }}
{% endif %}
</li>
{% endfor %}
</ul>
{% else %}
<ul><li>{{ array }}</li></ul>
{% endif %}
{% endmacro %}
<?php
// src/AppBundle/Twig/MacroTwigExtension.php
namespace AppBundle\Twig;
class MacroAutoloadTwigExtension extends \Twig_Extension
{
public function getFunctions()
{
return array(
// "*"" is used to get "template_macro" as $macro as third argument
new \Twig_SimpleFunction('macro_*', array($this, 'twigRenderMacro'), array(
'needs_environment' => true, // $env first argument will render the macro
'is_safe' => array('html'), // function returns escaped html
'is_variadic' => true, // and takes any number of arguments
))
);
}
public function twigRenderMacro(\Twig_Environment $env, $macro, array $vars = array())
{
list($name, $func) = explode('_', $macro);
$template = $env->loadTemplate(sprintf('_includes/macros/%s.twig', $name));
return call_user_func_array([$template, 'get' . $func], $vars);
}
public function getName()
{
return 'macro_autoload_extension';
}
}
# app/config/sevices.yml
services:
app.macro_autoload_extension:
class: AppBundle\Twig\MacroAutoloadExtension
public: false
tags:
- { name: twig.extension }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment