No commit activity in last 3 years
No release in over 3 years
Apply HTML escaping to all variables in a Liquid block
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 2.0
~> 12.0
~> 3.0
~> 0.52
~> 0.9.11

Runtime

>= 2.3
 Project Readme

Liquid Autoescape

Build Status

This adds an {% autoescape %} block tag to Liquid that causes all variables referenced within it to be escaped for display in an HTML context. It also adds the ability to enable global auto-escaping of all variables by default, and provides a set of tools for not escaping variables that are known to be safe.

Requirements

  • Ruby >= 2.2
  • Liquid >= 2.3

Basic Usage

To enable the {% autoescape %} tag in your Liquid templates, load the tag's files in any Ruby file that will be executed before rendering templates using the following line:

require "liquid/autoescape"

With the tag loaded, you can escape all variables in a Liquid template by wrapping them in an {% autoescape %} tag.

{% autoescape %}
  {{ variable_one }}
  {{ variable_two }}
{% endautoescape %}

To prevent a variable contained in an {% autoescape %} block from being escaped, use the skip_escape filter.

{% autoescape %}
  Escaped: {{ untrusted_content }}
  Not Escaped: {{ trusted_content | skip_escape }}
{% endautoescape %}

Advanced Usage

Autoescaping can be customized to work better with your environment via a Ruby-level configuration object. To configure auto-escaping, use the config object exposed by Liquid::Autoescape.configure in any Ruby file loaded before templates are rendered.

require "liquid/autoescape"

Liquid::Autoescape.configure do |config|
  ...
end

The auto-escape options that can be configured are detailed below.

Trusted Filters

If you are using custom Liquid filters that always generate trusted HTML, you can add them to the list of trusted filters. Any variables that are passed through a trusted filter will not be escaped.

Liquid::Autoescape.configure do |config|
  config.trusted_filters << :generate_markup
end
{% autoescape %}
  Escaped: {{ variable | downcase }}
  Not Escaped: {{ variable | generate_markup }}
{% endautoescape %}

Custom Exemptions

If there are complex conditions under which a variable should not be escaped, you can describe these conditions by creating custom exemptions. Exemptions are functions that receive an instance of Liquid::Autoescape::TemplateVariable that represents a Liquid variable as used in a template and return a boolean value indicating whether the variable is exempt from escaping.

Adding Individual Exemptions

To quickly add a single exemption, use code similar to the following:

Liquid::Autoescape.configure do |config|
  config.exemptions.add do |variable|
    ...
  end
end

Importing Exemption Functions

If you prefer to define exemptions as instance methods on a module, you can import those methods using code similar to the following:

module MyExemptions

  def exemption_one(variable)
    ...
  end

  def exemption_two(variable)
    ...
  end

end

Liquid::Autoescape.configure do |config|
  config.exemptions.import(MyExemptions)
end

The names of the module methods have no bearing on determining exemptions, so they can be whatever you want them to be.

Exemption Conditions

As mentioned above, each exemption function is passed an object that describes a Liquid variable as used in a template. This object exposes the variable's name, as well as a list of any filters that it uses. These values can be used by each exemption function to determine whether a variable should be exempt from auto-escaping, as shown by the code below:

Liquid::Autoescape.configure do |config|
  config.exemptions.add do |variable|
    variable.name == "var_one" && variable.filters.include?(:downcase)
  end
end
{% autoescape %}
  Escaped: {{ var_one }}
  Escaped: {{ var_two | downcase }}
  Not Escaped: {{ var_one | downcase }}
{% endautoescape %}

Global Mode

Autoescaping can be globally enabled, which will cause all variables in all Liquid templates to be escaped, removing the need to use the {% autoescape %} tag. Trusted filters and custom exemptions still apply in global mode, so there is always the ability to mark a variable as exempt from escaping.

Liquid::Autoescape.configure do |config|
  config.global = true
end
Escaped: {{ variable }}
Not Escaped: {{ variable | skip_escape }}

Additionally, auto-escaping can be selectively disabled within a block when running in global mode:

{% assign value = "&" %}

<!-- Renders "&amp;" -->
{{ value }}

<!-- Renders "&&" -->
{% autoescape false %}{{ value }}{{ value }}{% endautoescape %}