How to include a twig variable in a twig variable ? (on a config yaml file)

Hello,

I wish create some text with variables like :

// config/annonces.yaml
region: "My region"

// config/news.yaml
presentation: My text blablabla <em>lbablaba {{ config.annonces.region }}</em> blabla ...

Is it possible ? Thx

See the docs:

You are also not limited to the user/config/system.yaml or the user/config/site.yaml files as described above. You can create any arbitrary .yaml configuration file in the user/config folder you wish and it will get picked up by Grav automatically.

I do not believe there’s a way to reference other YAML files from within YAML. There are only node anchors. The YAML parser certainly won’t parse the Twig. But I suppose if you inject the Twig early enough in the lifecycle, it will end up being processed when the page is.

I found the following in the Twig docs:

{{ include(template_from_string("Hello {{ name }}")) }}

It seems this is what you are after, but I couldn’t get it to work…

Prerequisite:

The template_from_string function is not available by default. You must add the Twig_Extension_StringLoader extension explicitly when creating your Twig environment

@nicolasG Did some more research and managed to get the suggestion I made above working…

I’m using the Quark theme for convenience, but an inherited theme should be used for production.

These are the steps I took:

  • Created file ‘/user/config/annonces.yaml’ with content:
    region: "My region"
    
  • Created file ‘user/config/news.yaml’ with content:
    presentation: My text blablabla <em>lbablaba {{ config.annonces.region }}</em> blabla ...
    
  • In ‘/user/themes/quark/quark.php’, I replaced the following lines:
    public function onThemeInitialized()
    {
    
    }
    
    with:
    public function onThemeInitialized()
    {
       // Don't proceed if we are in the admin plugin
        if ($this->isAdmin()) {
            return;
        }
        // Enable the main event we are interested in
        $this->enable([
            'onTwigExtensions' => ['onTwigExtensions', 0],
        ]);
    }
    
    public function onTwigExtensions()
    {
        $this->grav['twig']->twig->addExtension(new \Twig_Extension_StringLoader());
    }
    
  • In ‘/user/themes/quark/templates/default.html.twig’, I added the following line to block ‘content’:
    <h1>{{ include(template_from_string(config.news.presentation)) }}</h1>
    
  • Fired up the browser which shows:

    My text blablabla lbablaba My region blabla …

2 Likes

I didn’t know where to put “Twig_Extension_StringLoader”, your answer provides the solution, perfect, thank you very much!

Now, it opens a debate on the solution to be adopted… Let me explain:

Either this solution, or create a twig function that makes a simple “str_replace” of keywords containing in the text as %%city%%%% then in my html view, just do {{ replaceAndShowFunction(config.news.presentation) }}, what do you think?

Which solution would you prefer?

It depends on your decisive selection criteria of the solution. Only then can be decided which solution fits best.

I don’t know yours, but I could think of criteria like:

  • ease of implementation
  • ease of maintenance
  • flexibility/extensibility
  • performance