0

Is it possible to apply a specific text filter (not a whole text format) to a string in Twig?
(Or at least in template preprocess, if not possible in Twig)

Use case:

I've a special block for hand-picked, trusted editors that allows them to inject unfiltered HTML (for social widgets like Facebook posts, TripAdvisor reviews, etc) into the homepage. Basically it is just a custom content block with a text field, and printed using |raw to avoid style and script tags being from filtered:

{{ content.body.0['#text']|raw }}

This does already work as expected.

Now I've got the additional requirement to apply the text filter from the LinkIt module on this field. The editors want to provide a link to a node, and the link to the node should be printed using the correct language prefix and the SEO-friendly URL alias. E.g. I've got a text field containing something like

<script src="https://external.com/social_widget.js" async defer>
<div id="#placeholder_social_widget"><!-- External widget does it's magic in here</div>
<script>/* some scripts from us */</script>
<a data-entity-substitution="canonical" data-entity-type="node" data-entity-uuid="whatever-123-abc-def">Link with correct language prefix and SEO-friendly URL-alias</a>

and I want to run the LinkIt replacement on that field and then output it, but without filtering or escaping any of the JS or CSS.

2
  • This seems risky to be honest.
    – Kevin
    Commented May 2, 2018 at 17:14
  • Giving someone the keys to your house is not a matter of security, it is a matter of trust. Leaving the door open for everyone would be a security issue.
    – Hudri
    Commented May 2, 2018 at 22:52

2 Answers 2

0

If those HTML are mostly or all static, you could consider implementing your own tokens via hook_token_info() and hook_tokens() in your custom module.

This way, you would avoid any potential risks, and accidentally malformed markup... and would have to full control on the replaced and returned markup.

Your authors would add a token like this in the content: [custom:facebookpost:12345]

... and your token could return an embedded Facebook post markup in return.

In my experience this method works much better than any other alternatives, mostly because:

  1. those embed widgets usually have custom tags and/or tag attributes which may not be compatible with CKEditor settings, text formats, etc.
  2. embedding those widgets directly, would make maintaining content much harder on the long run.
  3. provider(s) may change the embed markup. (Consider updating 100s or thousands of content entries via find & replace vs. updating the embed markup in token definition only)
  4. and it's not a hack.
0

My issue was a misunderstanding of how the filter "Display any HTML as plain text" works: I thought enabling it would allow me to enter all HTML code, but in fact it does the exact opposite, it does not allow any HTML code.

After disabling the "Display any HTML as plain text" filter, the LinkIt filter worked as expected, I could use a normal text format printed with {{ content.body }} without any post-processing like |raw or similar.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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