6

I'm building a custom markup for a block but the SVG part is not rendered. Everything else is rendered correctly.

class HomeSocial extends BlockBase
{

    /**
     * {@inheritdoc}
     */
    public function build()
    {
        $markup = '<div id="container">';
        $markup .= '<svg width="26.383960" height="21.428597" viewBox="0.736608 -42.857194 26.383960 21.428597"
xmlns="http://www.w3.org/2000/svg">
<path d="M27.120568 -40.312548C26.149585 -39.894021 25.094896 -39.592681 24.006725 -39.475493C25.128378 -40.145137 25.982174 -41.199826 26.383960 -42.455408C25.346012 -41.835987 24.174136 -41.383978 22.952036 -41.149603C21.964312 -42.204291 20.558060 -42.857194 19.001139 -42.857194C16.004483 -42.857194 13.593766 -40.429736 13.593766 -37.449821C13.593766 -37.031294 13.643989 -36.612767 13.727695 -36.210981C9.241082 -36.445356 5.239962 -38.588216 2.578128 -41.869470C2.109378 -41.065897 1.841520 -40.145137 1.841520 -39.140672C1.841520 -37.265669 2.795762 -35.608301 4.252237 -34.637318C3.364959 -34.670800 2.527905 -34.921917 1.808038 -35.323703C1.808038 -35.306962 1.808038 -35.273480 1.808038 -35.256738C1.808038 -32.628387 3.666299 -30.452045 6.143981 -29.949812C5.691971 -29.832625 5.206479 -29.765660 4.720988 -29.765660C4.369425 -29.765660 4.034603 -29.799143 3.699781 -29.849366C4.386166 -27.706506 6.378356 -26.149585 8.755591 -26.099361C6.897330 -24.642887 4.570318 -23.789091 2.042413 -23.789091C1.590404 -23.789091 1.171876 -23.805832 0.736608 -23.856055C3.130584 -22.315875 5.976570 -21.428597 9.040189 -21.428597C18.984398 -21.428597 24.425252 -29.665214 24.425252 -36.813660C24.425252 -37.048035 24.425252 -37.282411 24.408511 -37.516786C25.463200 -38.286876 26.383960 -39.241118 27.120568 -40.312548ZM27.120568 -40.312548"></path></svg>';
        $markup .= '</div>';

        return array(
            '#markup' => $markup,
            '#cache' => array(
                'max-age' => 3600,
            ),
        );
    }

Do I neet to allow SVG tag somewhere in the configuration?

  • Use inline_template instead of markup, or better a theme function. – user21641 Jan 6 '16 at 19:14
4

Drupal 8 has moved away from using #markup like in your example. While you still can use it there are some limitations. Certain attributes can't be set and certain tags can't be used.

Generally if you want to follow best practice, you should make theme functions and template file, in your example it's pretty simple.

PHP code in module

/**
 * Implements hook_theme().
 */
function hook_theme() {
  return array(
    'svg' => array(
      'variables' => array('svg_attibutes' => [], 'path_attributes' => []),
    ),
  );
}

Add the svg.html.twig template file in the templates folder:

<div id="container">;
  <svg {{ svg_attributes }}>
    <path {{ path_attributes }}></path>
  </svg>
</div>

Doing the above, your render array would become

$render = [
  '#theme' => 'svg',
  '#svg_attributes' => [...],
  '#path_attributes' => [...],
];

Doing it this way also has the advantage that you can in theme debug can see where markup is coming from, you can make theme suggestions or invoke them directly fx using

$render = [
  '#theme' => 'svg__awesome',
  ...

While the initial work is a bit more, it gives a lot of readability and help you working in good way, where markup and logic is separated.

4

Use inline_template instead of markup, or a theme function (as suggested by Ivan Jaros in a comment also).

Refer to class InlineTemplate for way more details. Here is a partial quote of it:

Provides a render element where the user supplies an in-line Twig template.

Properties:

  • #template: The inline Twig template used to render the element.
  • #context: (array) The variables to substitute into the Twig template. Each variable may be a string or a render array.

Usage example:

$build['hello']  = [
  '#type' => 'inline_template',
  '#template' => "{% trans %} Hello {% endtrans %} <strong>{{name}}</strong>",
  '#context' => [
    'name' => $name,
  ]
];
  • 1
    Yes. This should be accepted as correct answer. I am having issues adding a block code to a comment. But context is not required. You can just have the svg tag in the template value. – Daniel Tome Aug 9 '17 at 2:17

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.