3

I have some list items in drupal 8 which created by item_list template.I am sending some <a> tagged data to the item_list template. My idea was to get the output as <a href="/this-is-new.html">This is new page</a>.

But it returns the output as <li>&lt;a href="/this-is-new.html"&gt;This is new page&lt;/a&gt;</li>.

I need to print this in a twig template. But with the output I had it renders as a string in the template not as a html anchor tag. I needed to view a link to another page in template. But all I am getting is a string with the <a href="/this-is-new.html">This is new page</a>. What should I do?

1

Try using convert_encoding('UTF-8', 'HTML-ENTITIES') twig filter. For example {{ item|convert_encoding('UTF-8', 'HTML-ENTITIES')}}.

  • This don't work for me :( – i am batman Jan 25 '18 at 6:11
1

NOTE: this should be avoided as it is considered bad practice as mentioned in the comments, leaving here as a to be avoided example

Inside your twig template try this

  {{ var|raw }}

where var is the variable being printed.

For more information here

  • Using the |raw filter should be avoided for security reasons. For a better method to get the raw value see How do I get the raw field value in a template? – No Sssweat Jan 25 '18 at 5:42
  • Sorry for the down vote, but I consider using the |raw filter bad practice. You event mentioned it in your comment {# var won't be escaped #}. But I don't want you to delete this answer, It's good for others to learn about avoiding this security pitfall. – No Sssweat Jan 25 '18 at 5:54
  • @NoSssweat This won't work for me because it only escapes the outer element. As an example with my code it will only escape <li> tag but not the string inside. I need to convert the string inside. This output is coming from item_list by auto generating the lists from Drupal. Because of that I can't grab the inside string in the <li> tag. – i am batman Jan 25 '18 at 6:15
  • @NoSssweat twig documentation does not mention anywhere that its not secure. – GiorgosK Jan 25 '18 at 7:11
  • 1
    @NoSssweat yes I understand the reasoning behind escaping but I did not know the inner working of you solution and that it was actually being escaped (thought it was raw) ... thanks for the link very informative – GiorgosK Jan 27 '18 at 15:01
1

To send html markup to a template use a #markup render element

$variables['link'] = [
  '#markup' => '<a href="/this-is-new.html">This is new page</a>',
];

so that the html tags are not escaped when you output the variable in twig:

{{ link }}

The link here is only an example. There are better ways to build links, see How do I create a link?

0

You can make use Markup class which defines an object that passes safe strings through the render system.

1.) You first need to create a TwigExtension.php class inside a module and define a function which will actually return a formatted string.

2.) Use that function inside any of your twig files to render formatted strings.

3.) Do Rebuild the cache, using Drush cr.

-> Create a module_name.services.yml file under modules/module_name:

services:
  module_name.twig.TwigExtension:
    class: Drupal\module_name\TwigExtension
    tags:
      - {name: twig.extension}

-> Create a TwigExtension.php under modules/module_name/src/TwigExtension.php :

<?php

namespace Drupal\module_name;

use Drupal\Core\Render\Markup;

/**
 * Class DefaultService.
 *
 * @package Drupal\module_name
 */
class TwigExtension extends \Twig_Extension {

  /**
   * {@inheritdoc}
   * This function must return the name of the extension. It must be unique.
   */
  public function getName() {
    return 'block_display';
  }

  /**
   * In this function we can declare the extension function
   */
  public function getFunctions() {
    return array(
      new \Twig_SimpleFunction('render_string', array($this, 'render_string'), array('is_safe' => array('html'))),
    );
  }

  /**
   * Function to decode html special chars
   */
  public function render_string($string) {
    $render_string = Markup::create($string);
    return $render_string;
  }

-> **Insert twig function inside your twig file: **

{% set str = render_string('<a href="/this-is-new.html">This is new page</a>') %}
....
....
{{ str }}

Hope, this will help you.

0

But it returns the output as <li>&lt;a href="/this-is-new.html"&gt;This is new page&lt;/a&gt;</li>.

The reason for this, is because Twig is auto escaping your HTML. List only allows list related HTML tags, like <li>.

I have some list items in drupal 8

My idea was to get the output as <a href="/this-is-new.html">This is new page</a>

Don't use List as your field type, instead use Link and set it to unlimited.

enter image description here


Now when you add a new node:

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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