Skip to content

Instantly share code, notes, and snippets.

@bangpound
Created May 6, 2015 02:38
Show Gist options
  • Save bangpound/853f893959cb8d2666fe to your computer and use it in GitHub Desktop.
Save bangpound/853f893959cb8d2666fe to your computer and use it in GitHub Desktop.
{
"autoload": {
"psr-0": {
"": "lib/"
}
}
}
name = Twig Filter
core = 7.x
dependencies[] = pimple
<?php
/**
* Implements hook_filter_info().
*/
function twigfilter_filter_info() {
$filters['twig'] = array(
'title' => t('Twig'),
'process callback' => 'twig_filter_process',
);
return $filters;
}
/**
* Implements hook_filter_process().
*/
function twig_filter_process($text, $filter, $format, $langcode, $cache, $cache_id) {
try {
return twig_render($text);
} catch (\Twig_Error_Syntax $e) {
drupal_set_message($e->getMessage(), 'error');
return $text;
}
}
/**
* Helper function to actually render templates.
*/
function twig_render($template, array $context = array()) {
$c = pimple_get_container();
/** @var \Twig_Environment $twig */
$twig = $c['twig_filter'];
/** @var \Twig_Extension_Sandbox $sandbox */
if ($twig->hasExtension('sandbox')) {
$sandbox = $twig->getExtension('sandbox');
if (!$alreadySandboxed = $sandbox->isSandboxed()) {
$sandbox->enableSandbox();
}
$output = $twig->render($template, $context);
if (!$alreadySandboxed) {
$sandbox->disableSandbox();
}
return $output;
}
return $twig->render($template, $context);
}
<?php
/**
* Implements hook_pimple_info_alter().
*
* @return array
*/
function twigfilter_pimple_info_alter(&$info) {
foreach ($info as &$definition) {
$definition['providers'][] = array(
'class' => 'TwigFormatServiceProvider',
'values' => array(
'twig.sandbox.allowed_tags' => array('entity_view'),
'twig.sandbox.allowed_functions' => array('entity_load','entity_view','drupal_render'),
),
);
}
}
<?php
class TwigFormatServiceProvider implements \Pimple\ServiceProviderInterface
{
public function register(\Pimple\Container $pimple)
{
$pimple['twig.sandbox.allowed_tags'] = array();
$pimple['twig.sandbox.allowed_filters'] = array();
$pimple['twig.sandbox.allowed_methods'] = array();
$pimple['twig.sandbox.allowed_properties'] = array();
$pimple['twig.sandbox.allowed_functions'] = array();
$pimple['twig_filter'] = function (\Pimple\Container $c) {
/** @var \Twig_Environment $twig */
$twig = new \Twig_Environment($c['twig.loader.string'], array_merge($c['twig.options'], array(
'optimizations' => 0,
'cache' => false,
)));
$twig->addExtension($c['twig.extension.sandbox']);
$twig->addTokenParser($c['twig.token_parser.entity_view']);
$twig->registerUndefinedFunctionCallback(function ($name) {
if (in_array($name, array('entity_load', 'entity_view', 'drupal_render')) && function_exists($name)) {
return new Twig_SimpleFunction($name, $name);
}
return false;
});
return $twig;
};
$pimple['twig.token_parser.entity_view'] = function () {
return new \Drufony\Bridge\Twig\TokenParser\EntityViewTokenParser();
};
$pimple['twig.extension.sandbox'] = function (\Pimple\Container $c) {
return new Twig_Extension_Sandbox($c['twig.sandbox.security_policy']);
};
$pimple['twig.sandbox.security_policy'] = function (\Pimple\Container $c) {
return new Twig_Sandbox_SecurityPolicy(
$c['twig.sandbox.allowed_tags'],
$c['twig.sandbox.allowed_filters'],
$c['twig.sandbox.allowed_methods'],
$c['twig.sandbox.allowed_properties'],
$c['twig.sandbox.allowed_functions']
);
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment