Closed jvgreenaway closed 7 years ago
It depends on what kind of "working" you're looking for. :)
So let’s say you have both the patterns plugin and kirby-twig installed and enabled, and your patterns use PHP templates, but your pages use Twig templates. From your page templates, I suspect you want to use the pattern()
function, which is not available by default.
You can fix this like this:
<?php // site/config/config.php
c::set('twig.env.functions', ['pattern']);
(Alternatively, update kirby-twig to the latest version, I just pushed a fix to make this function available to templates by default, no configuration needed.)
Not much I can do in kirby-twig for that. The patterns plugin calls a PHP file directly:
class Pattern {
// …
public function template() {
return tpl::load($this->file('html.php'), $this->data());
}
// …
}
Kirby provides a Kirby\Component\Template
class for loading page templates, but there is no such component for loading template fragments, such as snippets or patterns. So both snippets and patterns use Tpl::load
, which loads a PHP file with the data.
So you would need the next Kirby version (2.5) to add an abstracted component for loading template fragments (Kirby\Component\TemplateFragment
maybe), and changes in Kirby core + Patterns to make use of that, and changes in kirby-twig to add Twig support for it.
I don’t think you’re going to do that if you’re using the Patterns plugin to, well, make a visual list of patterns, but I’ll just add that if you have a Twig template in one of your patterns directory it should be easy to include it from a page.
First I’d recommend that you set up a @patterns
namespace like this:
<?php // site/config/config.php
c::set('twig.namespace.pattenrs', kirby()->roots()->site().'/patterns');
Then from your page templates you should be able to do:
{% include '@patterns/mypattern/mypattern.twig' with {some:data, to:inject} %}
@fvsch Thank you for such a thorough explanation – you've really helped me understand the integration potential.
Would be amazing for Kirby core to add Template abstraction.
Going to try and write some Twig template patterns without integrating with the Pattern plugin.
Hello @fvsch ,
I've added an option to your TwigRenderer class
public function __construct( $patternsDir = null )
to set the $templateDir
if defined
then in my pattern folder, I create a pattern.html.php :
$r = new Kirby\Plugin\Twig\TwigRenderer(__DIR__);
echo $r->render('pattern.html.twig', ['text' => 'hello from twig']);
I've not yet fully tested this solution but it seems to do what I need : writing patterns in twig, using them in twig
(then, I'll try to find a way to see the .twig templates code)
Merci pour ce plugin ;)
I think you can do something similar without changing the plugin’s code.
// site/config/config.php
c::set('twig.namespace.patterns', kirby()->roots()->site().'/patterns');
// site/patterns/mypattern/mypattern.html.php
$r = new Kirby\Plugin\Twig\TwigRenderer();
echo $r->render('@patterns/mypattern/mypattern.html.twig', ['text' => 'hello from twig']);
Now, maybe I’m mistaken, but your pattern template will get executed every time you use this pattern in a page. If you loop on 100 objects which use the same pattern, that means you will end up creating a new Twig_Environment
every time, and I expect that it’s not cheap (in CPU/time and memory).
One solution would be to change Kirby\Plugin\Twig\TwigRenderer
to use a singleton pattern. And I could maybe make a utility function that calls Kirby\Plugin\Twig\TwigRenderer::render
, so it's possible to just write:
// site/config/config.php
c::set('twig.namespace.patterns', kirby()->roots()->site().'/patterns');
// site/patterns/mypattern/mypattern.html.php
echo twig('@patterns/mypattern/mypattern.html.twig', ['text' => 'hello from twig']);
Thanks @fvsch
I may have find a way to create the singleton pattern
I've added
private static $_instance = null;
[...]
public static function getInstance() {
if(is_null(self::$_instance)) {
self::$_instance = new TwigRenderer();
}
return self::$_instance;
}
made the constructor private
and replaced $twig = new TwigRenderer();
by $twig = TwigRenderer::getInstance();
in TwigTemplate.php
and used it like this in pattern folder :
$r = Kirby\Plugin\Twig\TwigRenderer::getInstance();
echo $r->render('@patterns/slider/slider.html.twig', ['structure' => $structure, 'contentURL' => $contentURL]);
seems fine... (and thanks for the namespace tip)
happy (to try) to make a PR if you want (and if it was the right think to do of course)
I’m reopening this issue with the following target:
@eQRoeil Can you test the patterns-support branch? This should work:
// site/config/config.php
c::set('twig.namespace.patterns', kirby()->roots()->site().'/patterns');
// site/patterns/mypattern/mypattern.html.php
echo twig('@patterns/mypattern/mypattern.html.twig', ['text' => 'hello from twig']);
I’ve prepared some documentation: https://github.com/fvsch/kirby-twig/blob/patterns-support/doc/plugins.md#modules-and-patterns-plugins (In particular: see the part about passing the context's variables to the twig template.)
@fvsch tested and worked
i'm going to use patterns with twig for a project starting next week,i'll tell you how it goes.
Thanks a lot for your answers and your time.
I pushed a substantial refactor + improvements to error reporting to the https://github.com/fvsch/kirby-twig/tree/patterns-support branch. I’m planning to make it the next major release (kirby-twig 3.0), once I’ve updated the documentation accordingly, and possibly added full Composer support (see #7).
Would it be possible to get this plugin working with the Kirby Pattern plugin?
Wondering if anyone has any experience of this. I imagine the Pattern plugin would need to add Twig support rather than this plugin making twig patterns work. 🤔
https://github.com/getkirby-plugins/patterns-plugin