I've run into a wall trying to render a svg image markup code into html from a plain text field.

I'm looking to render the svg code from a plain text field without overriding the plain text field rendering everywhere else.

plain text format currently converts all html tags and <> to &lt; &gt;.

I created a field template and tried both outputting the field content as

{{ item.content.context.value }}

and

{{ item.content|raw }}

both render the value as string wrapping every line with "quotation marks" and converting line-breaks into <br/> tags.

I previously had the field type formatted text, but that also wrapped everything in <pre> tags, even when all tags were allowed. I'd really like to get it working with plain text.

Example of the svg-code the field has to hold in text form:

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
         viewBox="0 0 290 290" enable-background="new 0 0 290 290" xml:space="preserve">
    <g>
        <path fill="none" stroke="#78C681" stroke-width="3" stroke-miterlimit="10" d="M261.1,273.1H28.9c-6.6,0-12-5.4-12-12V28.9
            c0-6.6,5.4-12,12-12h232.1c6.6,0,12,5.4,12,12v232.1C273.1,267.7,267.7,273.1,261.1,273.1z"/>
        <circle fill="none" stroke="#1B435D" stroke-width="2" stroke-miterlimit="10" cx="145.2" cy="166.9" r="62.7"/>
        <line fill="none" stroke="#78C681" stroke-width="3" stroke-miterlimit="10" x1="16.9" y1="60.8" x2="273.1" y2="60.8"/>
        <circle fill="none" stroke="#1B435D" stroke-width="2" stroke-miterlimit="10" cx="178.3" cy="152.3" r="6.8"/>
        <path fill="none" stroke="#1B435D" stroke-width="2" stroke-linecap="round" stroke-miterlimit="10" d="M115.1,167.9
            c8.8,0,22.3,3.2,28.4,4.7"/>
        <path fill="none" stroke="#1B435D" stroke-width="2" stroke-linecap="round" stroke-miterlimit="10" d="M151.9,216.9
            c0,0,17.2-1.5,29.6-14.8"/>
    </g>
</svg>

Hope someone can help.

Best,

Alari

  • Out of the box plain text has a filter that escapes markup. |raw doesn't unescape already escaped markup. The escaping is happening earlier than Twig's auto escape. – Cottser Dec 27 '15 at 17:36
up vote 14 down vote accepted

A solution by iworkyon from the Drupal community:

field--node--[field name].html.twig:

{% if svg %}
  <div class="my-svg">
    {{ svg|raw }}
  </div>
{% endif %}

THEME.info:

/**
* Implements hook_preprocess_field().
*/
function MYTHEME_preprocess_field(&$variables, $hook) {
    switch ($variables['element']['#field_name']) {
      case 'field_svg_test':
        $variables['svg'] = $variables['items'][0]['content']['#context']['value'];
        break;
    }
}
  • Hehe, looks like my "I'm at work" IRC nickname snuck in here :D Fun discovery while googling! – ividyon Mar 15 '17 at 16:10
  • Hope you don't mind :) It helped me, so I thought I'd share. – Alari Truuts Mar 28 '17 at 8:20

Did you try to apply the raw filter on the value?

{{ item.content.context.value|raw }}

But this is not secure. To output files, you can use a file field. This has the correct field formatters to generate the link. If you are not able to configure the link in the ui to your needs, you can modify the twig or preprocess for this specific field.

  • raw is being/has been removed: drupal.org/node/2603074 – Clive Dec 17 '15 at 11:14
  • 4k4: The field is a plain text field and not a file. The field value will be the copied markup of an svg image. I tried your solution, but nothing is different, still get the quotation marks wrapping and linebreaks issue. Also now I'm worried about using |raw after what Clive said and am even further from reaching a solution. – Alari Truuts Dec 17 '15 at 11:47
  • You are even further from reaching a solution, because you try to trick the auto escaping und drupal tries everything to discourage you from doing this. Better use the mechanism that are there to provide file links as described in my answer. And then use the appropriate twig templates down the line to change the rendering. – 4k4 Dec 17 '15 at 12:04
  • 4k4: I'm a bit confused now, as the content the field has to hold is not a file. it's in the form of text/svg-code. I updated the question with an example. – Alari Truuts Dec 17 '15 at 12:18
  • Plain text will not be able to output this svg code. Did you try the text format "Full Html", if this can process the svg-code? If not, you better put the svg in its own svg-file. – 4k4 Dec 17 '15 at 12:26

This worked for me:

{{ item.content['#context'].value|raw }}

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.