"Best practices: When to use raw vs |e('html') filter for titles and content?"

Hello Grav community,

I’m trying to establish clear guidelines for when to use the raw filter versus the |e('html') filter in Twig templates, and would appreciate your expertise.

From my understanding:

  • The raw filter is used for trusted HTML content (like page.content)

  • The |e('html') filter is commonly applied to site.title and sometimes page.title in default themes

My questions:

  1. Trusted content clarification: If site and page titles are managed by authenticated users with admin permissions, shouldn’t they be considered “trusted” and safe to output without HTML escaping? Why do templates typically escape them?

  2. Consistency requirement: If HTML escaping is recommended for titles, should this be applied consistently across all contexts where these titles appear (meta tags, aria-labels, alt attributes, etc.)?

  3. Are there specific security concerns with title fields that I might be overlooking?

I want to ensure I’m following both security best practices and Grav’s intended patterns. Thank you for your guidance!

1 Like

I don’t have anything to contribute on security here, though it’s a valid question.

  1. Some authenticated users better fit the description of “editors” and escaping protects them from unintentionally breaking HTML parsing. So it’s a knowledge issue more than a trust one in this case.
  2. Yes, and many of these less common applications are more likely to fly under the radar.
  3. I can’t say.

Thanks @hughbris

For now, I’m applying the escape filter to titles and the |markdown(false) filter to fields with more specific content, since the markdown filter already applies escaping.

But it would be nice if theme and plugin developers had some kind of “quick guide” to securing them. At least in my case, I’m not an expert in anything, much less security. I try to do what I do as best as possible.

Thank you very much @Maria1 for your contribution.

I’ve been refactoring the code for the Editorial and Mundana themes, basically following what you’re suggesting. I escape titles with |e (it’s the simplified way to use |e('html') ), and |raw for content and summaries. However, I’ve used specific escapes for attributes within HTML tags.

For example,

  • |e('url'): when the content is within part of a URL. Example: <a class="" href="{{ new_base_url }}/category{{ config.system.param_sep }}{{ category|e('url') }}">
  • e|('html_attr'): when the content to be escaped is within a tag attribute. For example, title, aria-label, etc.

I hope this is the correct way to implement escaping, I want to refactor all my themes to be safe and efficient, following this strategy.

Your examples are more about the links and attributes actually functioning correctly though. I use those too and I’ve also used |e('js') once or twice.

I’m going to do a scan too. Thanks for the tips, @Maria1.

1 Like