fvsch / kirby-twig

Twig templating support for Kirby CMS 2. For Kirby 3, use https://github.com/amteich/kirby-twig
MIT License
70 stars 8 forks source link

Work with Kirby Patterns plugin #13

Closed jvgreenaway closed 7 years ago

jvgreenaway commented 7 years ago

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

fvsch commented 7 years ago

It depends on what kind of "working" you're looking for. :)

The easy part: Using patterns from your Twig page templates

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.)

The hard part: Twig templates for patterns

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.

Twig templates in the site/patterns/mypattern directory

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} %}
jvgreenaway commented 7 years ago

@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.

eQRoeil commented 7 years ago

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 ;)

fvsch commented 7 years ago

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']);
eQRoeil commented 7 years ago

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)

fvsch commented 7 years ago

I’m reopening this issue with the following target:

fvsch commented 7 years ago

@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.)

eQRoeil commented 7 years ago

@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.

fvsch commented 7 years ago

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).