Skip to content

Instantly share code, notes, and snippets.

@inoas
Created May 25, 2017 20:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save inoas/649a921179fbd160d80c4fc2bfd70876 to your computer and use it in GitHub Desktop.
Save inoas/649a921179fbd160d80c4fc2bfd70876 to your computer and use it in GitHub Desktop.
<?php
namespace FlexiCms\View;
use App\View\AppView;
use Cake\Core\Configure;
use Cake\Event\EventManager;
use Cake\Http\Response;
use Cake\Http\ServerRequest;
use \Exception;
/**
* Class SimpleTwigView
* @package FlexiCms\View\TwigView
*/
class SimpleTwigView extends AppView
{
/**
* Twig instance.
*
* @var \Twig_Environment
*/
protected $twig;
/**
* Helpers.
*
* @var array
*/
protected $helperList = [];
/**
* Constructor
*
* @param \Cake\Http\ServerRequest|null $request Request instance.
* @param \Cake\Http\Response|null $response Response instance.
* @param \Cake\Event\EventManager|null $eventManager Event manager instance.
* @param array $options View options.
*/
public function __construct(
ServerRequest $request = null,
Response $response = null,
EventManager $eventManager = null,
array $options = []
) {
parent::__construct($request, $response, $eventManager, $options);
$twigFallackPath = ROOT . '/plugins/' . $this->plugin . '/src/Template/Frontend/Twig/';
$twigPath = ROOT . '/tmp/twig/';
$twigCachePath = ROOT . '/tmp/twig/cache/';
$twigLookupPathList = [
$twigPath,
$twigFallackPath,
];
$twigEnvOptions = [
'charset' => strtolower(Configure::read('App.encoding')),
'auto_reload' => Configure::readOrFail('debug'),
'debug' => Configure::readOrFail('debug'),
'cache' => $twigCachePath,
];
$loader = new \Twig_Loader_Filesystem($twigLookupPathList);
$twig = new \Twig_Environment($loader, $twigEnvOptions);
$twig->addExtension(new \WyriHaximus\TwigView\Lib\Twig\Extension\View($this));
$twig->addExtension(new \WyriHaximus\TwigView\Lib\Twig\Extension\Arrays);
$twig->addExtension(new \WyriHaximus\TwigView\Lib\Twig\Extension\Basic);
$twig->addExtension(new \WyriHaximus\TwigView\Lib\Twig\Extension\I18n);
$twig->addExtension(new \WyriHaximus\TwigView\Lib\Twig\Extension\Inflector);
$twig->addExtension(new \WyriHaximus\TwigView\Lib\Twig\Extension\Number);
$twig->addExtension(new \WyriHaximus\TwigView\Lib\Twig\Extension\Strings);
$twig->addExtension(new \WyriHaximus\TwigView\Lib\Twig\Extension\Time);
$twig->addExtension(new \WyriHaximus\TwigView\Lib\Twig\Extension\Utils);
if (Configure::readOrFail('debug') === true) {
$profile = new \Twig_Profiler_Profile();
$twig->addExtension(new \WyriHaximus\TwigView\Lib\Twig\Extension\Profiler($profile));
}
$twig->addTokenParser(new \WyriHaximus\TwigView\Lib\Twig\TokenParser\Cell);
$twig->addTokenParser(new \WyriHaximus\TwigView\Lib\Twig\TokenParser\Element);
$this->twig = $twig;
$registry = $this->helpers();
$helpersList = array_merge($this->helpers, $registry->loaded());
$helpers = $registry->normalizeArray($helpersList);
foreach ($helpers as $properties) {
list(, $class) = pluginSplit($properties['class']);
$this->helperList[$class] = $this->{$class};
}
}
/**
* Renders view for given template file.
*
* Render triggers helper callbacks, which are fired before and after the template are rendered,
* as well as before and after the layout. The helper callbacks are called:
*
* - `beforeRender`
* - `afterRender`
*
* @param string|false|null $view Name of view file to use
* @param string|null $layout Layout to use.
* @return string|null Rendered content or null if content already rendered and returned earlier.
* @throws \Exception If there is an error in the view.
* @triggers View.beforeRender $this, [$viewFileName]
* @triggers View.afterRender $this, [$viewFileName]
*/
public function render($view = null, $layout = null)
{
if ($this->hasRendered) {
return null;
}
$this->dispatchEvent('View.beforeRender', [$this->template]);
$out = $this->renderTwigTemplate($this->template);
$this->dispatchEvent('View.afterRender', [$this->template]);
$this->hasRendered = true;
$out .= '<!-- Served via ' . $this->viewVars['meta_generator'] . ' -->';
return $out;
}
/**
* Render the template.
*
* @param string $viewTemplate Template file.
* @param array $data Data that can be used by the template.
*
* @throws \Exception
* @return string
*/
public function renderTwigTemplate($renderFile, $data = []) {
if (empty($data)) {
$data = $this->viewVars;
}
$data = array_merge($data, $this->helperList, ['_view' => $this]);
try {
return $this->twig->loadTemplate($renderFile)->render($data);
} catch (Exception $e) {
$previous = $e->getPrevious();
if ($previous !== null && $previous instanceof Exception) {
throw $previous;
}
throw $e;
}
}
}
@inoas
Copy link
Author

inoas commented May 25, 2017

Load like this from CmsDocumentsController::display()

        // TODO Switch Around Engine TWIG|PHP
        $this->viewBuilder()
            ->setLayout(false)
            ->setClassname('FlexiCms.SimpleTwig')
            ->setTemplate('default_document.twig');

        // Build template file cache from entity if template given but not cached.
        if ($cmsDocument->has('cms_template') === true) {
            $twigSavePath = ROOT . '/tmp/twig/';
            $twigTemplateName = $cmsDocument->cms_template->id . '_' . $cmsDocument->cms_template->id;
            $twigTemplateName = $this->plugin . '_document_' . str_replace('-', '_', $twigTemplateName) . '.twig';
            if (file_exists($twigSavePath . '/' . $twigTemplateName) === false) {
                file_put_contents($twigSavePath . '/' . $twigTemplateName, $cmsDocument->cms_template->body,  LOCK_EX);
            }
            $this->viewBuilder()
                ->setTemplate($twigTemplateName);
        }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment