Search code examples
twigstring-interpolationpatternlab.io

Patternlab / Twig Variable Interpolation doesn't work with string from json


I'm working on a project that's based on the twig patternlab framework. I'm using JSON files for most of my content, especially for pages.

I want to integrate a link (build by an atom) into a text I got from my JSON file that has a placeholder for the link. I'm working with texts from a multilingual cms so putting a placeholder into the text content is the easiest way to keep it flexible.

This is an excerpt from my json file

{
    "legal" : "Mit dem Absenden des Formulars akzeptieren Sie unsere #{ legalLink }.",
    "deeplink" : {
        "label" : "Datenschutzbedingungen",
        "url" : "#AGB_link"
    }
}

and this is in my twig template

{# __ build the link __ #}
{% set legalLink %}
    {% include "atoms-link" with contact.deeplink %}
{% endset %}

{# __ set up the string with interpolation placeholder __ #}
{% set legalText_a = "Mit dem Absenden des Formulars akzeptieren Sie unsere #{ legalLink }." %}
{% set legalText_b = contact.legal %}
{% set legalText_c %}
    {% include contact.legal %}
{% endset %}

{# __ dump to check/debug how it comes out __ #}
{{ dump (legalText_a) }}<hr>
{{ dump (legalText_b) }}<hr>
{{ dump (legalText_c) }}<hr>

{# __ output the result __ #}
<p>A) {{ legalText_a|raw }}</p>
<p>B) {{ legalText_b|raw }}</p>
<p>C) {{ legalText_c|raw }}</p>

This is my result (both dump ant the final html.

string(121) "Mit dem Absenden des Formulars akzeptieren Sie unsere Datenschutzbedingungen ."
string(69) "Mit dem Absenden des Formulars akzeptieren Sie unsere #{ legalLink }."
object(Twig_Markup)#2627 (2) { ["content":protected]=> string(78) " Mit dem Absenden des Formulars akzeptieren Sie unsere #{ legalLink }.   " ["charset":protected]=> string(5) "UTF-8" }

A) Mit dem Absenden des Formulars akzeptieren Sie unsere Datenschutzbedingungen.
B) Mit dem Absenden des Formulars akzeptieren Sie unsere #{ legalLink }.
C) Mit dem Absenden des Formulars akzeptieren Sie unsere #{ legalLink }.

Option A works perfectly, when I use twig set with a string, the interpolation kicks in and everything outputs correctly. But thats with a string in my template code... thats NOT what I want.

Option B was my first attempt with the String from my JSON file but when I use the var with a string for the set, the interpolation doesn't kick in. I tried multiple variations with |raw and not sure what else but the result was always the same.

Option C doesn't work either. Using twig set with the include as a chunk turns it into twig markup code and that can hardly be used for anything from my recent experience. I still thought I'd give it a try.

Is there a way to get the interpolation to work or is there a good alternative with twig/patternlab to get what I'm trying to achieve?


Solution

  • To solve this issue you would first need to enable the extension Twig_Extension_StringLoader. This give you access to the function template_from_string, which give you the ability to "create" templates inside twig and (re)enable the string interpolation you need.

    register extension

    $twig->addExtension(new Twig_Extension_StringLoader());

    use template_from_string to achieve desired effect

    {% set legalLink = 'Datenschutzbedingungen' %}
    {{ include(template_from_string('{{ "'~contact.legal~'" }}')) }}