Shopify / liquid

Liquid markup language. Safe, customer facing template language for flexible web apps.
https://shopify.github.io/liquid/
MIT License
11.13k stars 1.39k forks source link

Add concept of `Liquid::Environment` #1815

Closed ianks closed 3 months ago

ianks commented 4 months ago

Currently, Liquid relies heavily on global state which makes it pretty inflexible. It's common to see code unsafely mutating global tags with Liquid::Template.register_tag. This PR offers a way to configure multiple sandboxed Liquid rendering environments.

Liquid::Environment

In Liquid, an "Environment" is a scoped environment that encapsulates custom tags, filters, and other configurations. This allows you to define and isolate different sets of functionality for different contexts, avoiding global overrides that can lead to conflicts and unexpected behavior.

By using Worlds, you can:

  1. Encapsulate Logic: Keep the logic for different parts of your application separate.
  2. Avoid Conflicts: Prevent custom tags and filters from clashing with each other.
  3. Improve Maintainability: Make it easier to manage and understand the scope of customizations.
  4. Enhance Security: Limit the availability of certain tags and filters to specific contexts.

Here's an example of how you can define and use Worlds in Liquid:

user_env = Liquid::Environment.build do |env|
  env.register_tag("renderobj", RenderObjTag)
end

Liquid::Template.parse(<<~LIQUID, environment: user_env)
  {% renderobj src: "path/to/model.obj" %}
LIQUID

In this example, RenderObjTag is a custom tag that is only available within the user_world.

Similarly, you can define another world for a different context, such as email templates:

email_env = Liquid::Environment.build do |env|
  env.register_tag("unsubscribe_footer", UnsubscribeFooter)
end

Liquid::Template.parse(<<~LIQUID, world: email_env)
  {% unsubscribe_footer %}
LIQUID
tobi commented 4 months ago

World isn't the right title here, It's more like Session or Environment. But the concept is sound

ianks commented 4 months ago

World isn't the right title here, It's more like Session or Environment. But the concept is sound

Agree, renamed to Environment in https://github.com/Shopify/liquid/pull/1815/commits/58cef46eb8903dd5a06d1659ed8718ec8c3ac272