From d7075802ff267c4efbad59d91b355475a180e736 Mon Sep 17 00:00:00 2001 From: Guilherme Carreiro Date: Wed, 5 Feb 2025 15:31:28 +0100 Subject: [PATCH] prototype-1 --- example/server/example_servlet.rb | 9 ++ example/server/templates/ico.liquid | 0 example/server/templates/settings.liquid | 121 +++++++++++++++++++++++ lib/liquid/tags.rb | 40 ++++---- lib/liquid/tags/let.rb | 40 ++++++++ 5 files changed, 191 insertions(+), 19 deletions(-) create mode 100644 example/server/templates/ico.liquid create mode 100644 example/server/templates/settings.liquid create mode 100644 lib/liquid/tags/let.rb diff --git a/example/server/example_servlet.rb b/example/server/example_servlet.rb index d2d4fd6a7..e9d024d04 100644 --- a/example/server/example_servlet.rb +++ b/example/server/example_servlet.rb @@ -27,6 +27,15 @@ def products { 'products' => products_list, 'more_products' => more_products_list, 'description' => description, 'section' => 'Snowboards', 'cool_products' => true } end + def settings + { + 'settings' => { + 'text' => 'Liquid', + 'font' => 'Arial' + } + } + end + private def products_list diff --git a/example/server/templates/ico.liquid b/example/server/templates/ico.liquid new file mode 100644 index 000000000..e69de29bb diff --git a/example/server/templates/settings.liquid b/example/server/templates/settings.liquid new file mode 100644 index 000000000..e7c0cd620 --- /dev/null +++ b/example/server/templates/settings.liquid @@ -0,0 +1,121 @@ + + +

let

+ +
+ +
+
+
Liquid source
+
+{%- raw -%}
+{% assign text = "My text" %}
+{{ settings }}
+{{ text }}
+{%- endraw -%}
+    
+
+
+
HTML output
+
+{% assign text = "My text" %}
+{{ settings }}
+{{ text -}}
+    
+
+
+ +
+
+
Liquid source
+
+    {%- raw -%}
+{% let (text, font): settings %}
+  text: {{ text }},
+  font: {{ font }}
+{% endlet %}
+    {%- endraw -%}
+    
+
+
+
HTML output
+
+{%- let (text, font): settings %}
+  text: {{ text }},
+  font: {{ font }}
+{% endlet -%}
+    
+
+
+ +
+
+
Liquid source
+
+    {%- raw -%}
+{% let font: settings.font %}
+  text: {{ text }},
+  font: {{ font }}
+{% endlet %}
+    {%- endraw -%}
+    
+
+
+
HTML output
+
+{%- let font: settings.font %}
+  text: {{ text }},
+  font: {{ font }}
+{% endlet -%}
+    
+
+
+ +
+
+
Liquid source
+
+    {%- raw -%}
+Global is not impacted:
+  - text: {{ text }},
+  - font: {{ font }}
+    {%- endraw -%}
+    
+
+
+
HTML output
+
+Global is not impacted:
+  - text: {{ text }},
+  - font: {{ font }}
+    
+
+
diff --git a/lib/liquid/tags.rb b/lib/liquid/tags.rb index 916a63bd5..f8808813a 100644 --- a/lib/liquid/tags.rb +++ b/lib/liquid/tags.rb @@ -1,24 +1,25 @@ # frozen_string_literal: true -require_relative "tags/table_row" -require_relative "tags/echo" -require_relative "tags/if" -require_relative "tags/break" -require_relative "tags/inline_comment" -require_relative "tags/for" -require_relative "tags/assign" -require_relative "tags/ifchanged" -require_relative "tags/case" -require_relative "tags/include" -require_relative "tags/continue" -require_relative "tags/capture" -require_relative "tags/decrement" -require_relative "tags/unless" -require_relative "tags/increment" -require_relative "tags/comment" -require_relative "tags/raw" -require_relative "tags/render" -require_relative "tags/cycle" +require_relative 'tags/table_row' +require_relative 'tags/echo' +require_relative 'tags/if' +require_relative 'tags/break' +require_relative 'tags/inline_comment' +require_relative 'tags/for' +require_relative 'tags/assign' +require_relative 'tags/ifchanged' +require_relative 'tags/case' +require_relative 'tags/include' +require_relative 'tags/continue' +require_relative 'tags/capture' +require_relative 'tags/decrement' +require_relative 'tags/unless' +require_relative 'tags/increment' +require_relative 'tags/comment' +require_relative 'tags/raw' +require_relative 'tags/render' +require_relative 'tags/cycle' +require_relative 'tags/let' module Liquid module Tags @@ -42,6 +43,7 @@ module Tags 'if' => If, 'echo' => Echo, 'tablerow' => TableRow, + 'let' => Let, }.freeze end end diff --git a/lib/liquid/tags/let.rb b/lib/liquid/tags/let.rb new file mode 100644 index 000000000..26059a534 --- /dev/null +++ b/lib/liquid/tags/let.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +module Liquid + class Let < Liquid::Block + MULTI_ASSIGNMENT = /\A\(\s*(?[^)]+)\s*\):\s*(?[^\s]+)\z/ + VAR_ASSIGNMENTS = /(?[\w-]+)\s*:\s*(?[^\s,]+)/ + + def initialize(tag_name, markup, options) + super(tag_name, markup, options) + @assignments = parse_markup(markup.strip) + end + + def render(context) + subcontext = context.new_isolated_subcontext + + @assignments.each do |var, expression| + subcontext[var] = lookup(context, expression) + end + + super(subcontext) + end + + private + + def parse_markup(markup) + if (m = MULTI_ASSIGNMENT.match(markup)) + variables = m[:vars].split(/\s*,\s*/) + source = m[:source] + variables.map { |v| [v, "#{source}.#{v}"] }.to_h + else + markup.scan(VAR_ASSIGNMENTS).to_h + end + end + + def lookup(context, expression) + variable_lookup = Liquid::VariableLookup.new(expression) + variable_lookup.evaluate(context) + end + end +end