liquid_response 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +266 -0
- data/Rakefile +8 -0
- data/lib/liquid_response/controller_helper.rb +26 -0
- data/lib/liquid_response/core_ext.rb +29 -0
- data/lib/liquid_response/errors.rb +17 -0
- data/lib/liquid_response/version.rb +5 -0
- data/lib/liquid_response/view_helper.rb +112 -0
- data/lib/liquid_response.rb +15 -0
- data/sig/liquid_response.rbs +4 -0
- metadata +84 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: bf11fe2f34626e9a1de07771d207a6fd41b305358f40251711ca1c0f8c97b7c2
|
|
4
|
+
data.tar.gz: e31a1a2426d569019b198f7b948d513cda3789fec8befe89f663cea2be0d33fb
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: a94e27ac67684b698d91b535e3c4945ac29c729afb772a18aa854f76d2da97fe63d63170df834231cb28defa02426a8f2f5fd23bf1cdea9faf1883c54f64cd85
|
|
7
|
+
data.tar.gz: c19d90983a3f2b216e0fa73a4cd759bce8c67a6baf92ce04ee6617643d1cce34c1660b85fac39f026b42131d9379e04c8b5f54414eeeaeed4d5d44288d7960f0
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Elia Schito
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# LiquidResponse
|
|
2
|
+
|
|
3
|
+
Rails controller and view helpers for rendering [Liquid](https://shopify.github.io/liquid/) templates — designed for [Shopify App Proxy](https://shopify.dev/docs/apps/online-store/app-proxies) and any Rails app that serves Liquid markup to a storefront.
|
|
4
|
+
|
|
5
|
+
## How it works
|
|
6
|
+
|
|
7
|
+
Shopify's App Proxy lets your Rails app respond to storefront requests with Liquid templates, which Shopify then renders in the context of the live theme. `LiquidResponse` handles:
|
|
8
|
+
|
|
9
|
+
- Registering the `liquid` MIME type with Rails
|
|
10
|
+
- Telling Rails to prefer `liquid` over `html` for app proxy requests
|
|
11
|
+
- Stripping `turbo-stream` from the Accept header (Turbo injects it everywhere; the proxy can't use it)
|
|
12
|
+
- View helpers for building valid Liquid `{% render %}`, `{% assign %}`, and `{% capture %}` tags from ERB
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
Add to your Gemfile:
|
|
17
|
+
|
|
18
|
+
```ruby
|
|
19
|
+
gem "liquid_response"
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Setup
|
|
23
|
+
|
|
24
|
+
### 1. Register the MIME type
|
|
25
|
+
|
|
26
|
+
```ruby
|
|
27
|
+
# config/initializers/liquid_response.rb
|
|
28
|
+
require "liquid_response"
|
|
29
|
+
|
|
30
|
+
LiquidResponse.register_liquid_mime_type!
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### 2. Include the controller helper
|
|
34
|
+
|
|
35
|
+
```ruby
|
|
36
|
+
class AppProxyController < ApplicationController
|
|
37
|
+
include LiquidResponse::ControllerHelper
|
|
38
|
+
|
|
39
|
+
allow_liquid_rendering_when_html_is_requested
|
|
40
|
+
end
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`allow_liquid_rendering_when_html_is_requested` installs a `before_action` that:
|
|
44
|
+
- Strips `turbo-stream` from `request.formats`
|
|
45
|
+
- Prepends `Mime[:liquid]` so Rails picks the `.liquid.erb` template
|
|
46
|
+
|
|
47
|
+
### 3. Create `.liquid.erb` views
|
|
48
|
+
|
|
49
|
+
Rails will look for `app/views/posts/show.liquid.erb` when the request format resolves to `liquid`. Write Liquid tags using the view helpers:
|
|
50
|
+
|
|
51
|
+
```erb
|
|
52
|
+
<%# app/views/posts/show.liquid.erb %>
|
|
53
|
+
<%= render_liquid "my-app--post--card", title: @post.title, published: @post.published? %>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
This outputs:
|
|
57
|
+
|
|
58
|
+
```liquid
|
|
59
|
+
{% render "my-app--post--card", title: "Hello World", published: true %}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## View helpers
|
|
63
|
+
|
|
64
|
+
All helpers are available in views once `LiquidResponse::ControllerHelper` is included (it auto-includes `LiquidResponse::ViewHelper` as a helper module).
|
|
65
|
+
|
|
66
|
+
### `render_liquid(snippet_name, **assigns)`
|
|
67
|
+
|
|
68
|
+
Emits a Liquid `{% render %}` tag with the given assigns.
|
|
69
|
+
|
|
70
|
+
```erb
|
|
71
|
+
<%= render_liquid "my-app--product--card",
|
|
72
|
+
title: @product.title,
|
|
73
|
+
price: @product.price,
|
|
74
|
+
available: @product.available? %>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
```liquid
|
|
78
|
+
{% render "my-app--product--card", title: "Widget", price: 9.99, available: true %}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### `assign_liquid(variable_name, value)`
|
|
82
|
+
|
|
83
|
+
Emits a `{% assign %}` tag. Useful for hoisting a value to Liquid scope before passing it to a snippet.
|
|
84
|
+
|
|
85
|
+
```erb
|
|
86
|
+
<%= assign_liquid :greeting, "Welcome" %>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
```liquid
|
|
90
|
+
{% assign greeting = "Welcome" %}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### `liquid_variable(name)`
|
|
94
|
+
|
|
95
|
+
Returns a `LiquidVariable` object — a placeholder that renders as a bare Liquid variable name (no quotes). Pass it as an assign value when the variable already exists in Liquid scope.
|
|
96
|
+
|
|
97
|
+
```erb
|
|
98
|
+
{% assign products = collections.all.products %}
|
|
99
|
+
<%= render_liquid "my-app--product--list", items: liquid_variable(:products) %>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
```liquid
|
|
103
|
+
{% render "my-app--product--list", items: products %}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### `liquid_capture(name, &block)`
|
|
107
|
+
|
|
108
|
+
Wraps the block output in `{% capture %}` / `{% endcapture %}`.
|
|
109
|
+
|
|
110
|
+
```erb
|
|
111
|
+
<%= liquid_capture(:sidebar) do %>
|
|
112
|
+
<p>Some sidebar content</p>
|
|
113
|
+
<% end %>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
```liquid
|
|
117
|
+
{% capture sidebar %}<p>Some sidebar content</p>{% endcapture %}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Passing complex values
|
|
121
|
+
|
|
122
|
+
### Strings, numbers, booleans, nil, dates, times, symbols
|
|
123
|
+
|
|
124
|
+
Converted to their JSON equivalents automatically.
|
|
125
|
+
|
|
126
|
+
```erb
|
|
127
|
+
<%= render_liquid "my-app--order",
|
|
128
|
+
id: 42,
|
|
129
|
+
status: :pending,
|
|
130
|
+
placed_on: Date.today,
|
|
131
|
+
gift: false,
|
|
132
|
+
note: nil %>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
```liquid
|
|
136
|
+
{% render "my-app--order", id: 42, status: "pending", placed_on: "2026-05-26", gift: false, note: null %}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Hashes (nested objects)
|
|
140
|
+
|
|
141
|
+
Each Hash assign is promoted to an intermediate `{% assign %}` variable so Liquid receives it as an object.
|
|
142
|
+
|
|
143
|
+
```erb
|
|
144
|
+
<%= render_liquid "my-app--address--card",
|
|
145
|
+
address: {
|
|
146
|
+
street: @address.line1,
|
|
147
|
+
city: @address.city,
|
|
148
|
+
zip: @address.zip
|
|
149
|
+
} %>
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
```liquid
|
|
153
|
+
{% assign h_address_a1b2c = null | default: street: "Via Roma 1", city: "Roma", zip: "00100" %}
|
|
154
|
+
{% render "my-app--address--card", address: h_address_a1b2c %}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Nesting works recursively:
|
|
158
|
+
|
|
159
|
+
```erb
|
|
160
|
+
<%= render_liquid "my-app--subscription",
|
|
161
|
+
plan: {
|
|
162
|
+
name: "Monthly",
|
|
163
|
+
interval: { unit: "week", count: 4 }
|
|
164
|
+
} %>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
```liquid
|
|
168
|
+
{% assign h_interval_x = null | default: unit: "week", count: 4 %}
|
|
169
|
+
{% assign h_plan_y = null | default: name: "Monthly", interval: h_interval_x %}
|
|
170
|
+
{% render "my-app--subscription", plan: h_plan_y %}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Arrays
|
|
174
|
+
|
|
175
|
+
Arrays are converted to indexed hashes (Liquid has no native array literal):
|
|
176
|
+
|
|
177
|
+
```erb
|
|
178
|
+
<%= render_liquid "my-app--tag--list", tags: ["sale", "new"] %>
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
```liquid
|
|
182
|
+
{% assign h_tags_z = null | default: 0: "sale", 1: "new" %}
|
|
183
|
+
{% render "my-app--tag--list", tags: h_tags_z %}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Custom objects — `as_liquid` protocol
|
|
187
|
+
|
|
188
|
+
Any object that implements `as_liquid` is serialized through it. The method must return a `Hash`, a scalar, or another `as_liquid`-capable object.
|
|
189
|
+
|
|
190
|
+
```ruby
|
|
191
|
+
class Product
|
|
192
|
+
def as_liquid
|
|
193
|
+
{ "title" => title, "price" => price.to_f, "available" => available? }
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
```erb
|
|
199
|
+
<%= render_liquid "my-app--product--card", product: @product %>
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
`LiquidResponse` ships with `as_liquid` on `String`, `Numeric`, `TrueClass`, `FalseClass`, `NilClass`, `Date`, `Time`, `Symbol`, `Array`, `Hash`, and `Data` — all the types you use day-to-day.
|
|
203
|
+
|
|
204
|
+
### ActiveModel / Serializable objects
|
|
205
|
+
|
|
206
|
+
Objects that respond to `serializable_hash` are converted automatically:
|
|
207
|
+
|
|
208
|
+
```erb
|
|
209
|
+
<%= render_liquid "my-app--user--card", user: current_user %>
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Mixing types
|
|
213
|
+
|
|
214
|
+
Everything composes:
|
|
215
|
+
|
|
216
|
+
```erb
|
|
217
|
+
<%= render_liquid "my-app--portal",
|
|
218
|
+
customer_name: @customer.name,
|
|
219
|
+
logged_in: true,
|
|
220
|
+
items: liquid_variable(:cart_items),
|
|
221
|
+
address: {
|
|
222
|
+
city: @shipping_address.city,
|
|
223
|
+
zip: @shipping_address.zip
|
|
224
|
+
} %>
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## `liquid_routes` (app-level, not in the gem)
|
|
228
|
+
|
|
229
|
+
The helper `liquid_routes` — which exposes Rails route helpers as a Liquid-usable hash — is intentionally **not** part of this gem. It depends on your app's routing conventions. Define it yourself in your base controller and expose it via `helper_method`:
|
|
230
|
+
|
|
231
|
+
```ruby
|
|
232
|
+
class AppProxyController < ApplicationController
|
|
233
|
+
include LiquidResponse::ControllerHelper
|
|
234
|
+
allow_liquid_rendering_when_html_is_requested
|
|
235
|
+
|
|
236
|
+
helper_method :liquid_routes
|
|
237
|
+
|
|
238
|
+
private
|
|
239
|
+
|
|
240
|
+
def liquid_routes
|
|
241
|
+
Rails.application.routes.routes
|
|
242
|
+
.filter_map do |route|
|
|
243
|
+
next unless route.name&.start_with?("my_app_proxy_")
|
|
244
|
+
[route.name.sub("my_app_proxy_", "") + "_url", route.path.spec.to_s.sub(/\([^)]*\)/, "")]
|
|
245
|
+
end
|
|
246
|
+
.sort.to_h
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Then in views:
|
|
252
|
+
|
|
253
|
+
```erb
|
|
254
|
+
<%= render_liquid "my-app--nav", routes: liquid_routes %>
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## Development
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
bundle install
|
|
261
|
+
bundle exec rake test
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## License
|
|
265
|
+
|
|
266
|
+
MIT
|
data/Rakefile
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_support/concern"
|
|
4
|
+
require "liquid_response/view_helper"
|
|
5
|
+
|
|
6
|
+
module LiquidResponse
|
|
7
|
+
module ControllerHelper
|
|
8
|
+
extend ActiveSupport::Concern
|
|
9
|
+
|
|
10
|
+
class_methods do
|
|
11
|
+
def allow_liquid_rendering_when_html_is_requested
|
|
12
|
+
before_action do
|
|
13
|
+
# Strip turbo-stream from all positions — Turbo's Accept header lists it first,
|
|
14
|
+
# which causes Rails to select that format and return the wrong content type.
|
|
15
|
+
request.formats.reject! { |f| f.turbo_stream? }
|
|
16
|
+
html_like = request.formats.any? { |f| f.html? || f.all? }
|
|
17
|
+
request.formats.unshift Mime[:liquid] if html_like
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
included do
|
|
23
|
+
helper LiquidResponse::ViewHelper
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "date"
|
|
4
|
+
|
|
5
|
+
[String, Numeric, TrueClass, FalseClass, NilClass, Date, Time, Symbol].each do |klass|
|
|
6
|
+
klass.class_eval do
|
|
7
|
+
def as_liquid
|
|
8
|
+
self
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
Array.class_eval do
|
|
14
|
+
def as_liquid
|
|
15
|
+
map.with_index { |v, i| [i, v] }.to_h.as_liquid
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
Hash.class_eval do
|
|
20
|
+
def as_liquid
|
|
21
|
+
transform_values { it.respond_to?(:as_liquid) ? it.as_liquid : it }
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
Data.class_eval do
|
|
26
|
+
def as_liquid
|
|
27
|
+
to_h.as_liquid
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LiquidResponse
|
|
4
|
+
class UnsupportedValueError < ArgumentError
|
|
5
|
+
attr_accessor :key, :value
|
|
6
|
+
|
|
7
|
+
def initialize(value, key = nil)
|
|
8
|
+
@value = value
|
|
9
|
+
@key = key
|
|
10
|
+
super("Can't convert value #{value.inspect} of type #{value.class} to a liquid-compatible format")
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def message
|
|
14
|
+
key ? "Error converting value for key '#{key}': #{super}" : super
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require "active_support/core_ext/object/blank"
|
|
5
|
+
require "active_support/core_ext/object/json"
|
|
6
|
+
require "liquid_response/errors"
|
|
7
|
+
require "liquid_response/core_ext"
|
|
8
|
+
|
|
9
|
+
module LiquidResponse
|
|
10
|
+
module ViewHelper
|
|
11
|
+
class LiquidBuffer
|
|
12
|
+
class LiquidVariable
|
|
13
|
+
def initialize(name)
|
|
14
|
+
@name = name.to_s
|
|
15
|
+
self.class.validate_name!(@name)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.validate_name!(name)
|
|
19
|
+
unless name.to_s.match?(/\A[a-zA-Z_][a-zA-Z0-9_]*\z/)
|
|
20
|
+
raise ArgumentError, "Invalid Liquid variable name: #{name}"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
attr_reader :name
|
|
25
|
+
|
|
26
|
+
def self.random(prefix = "var")
|
|
27
|
+
prefix = prefix.to_s.gsub(/[^a-zA-Z0-9]+/, "_")
|
|
28
|
+
prefix = "var" if prefix.blank? || prefix.match?(/\A\d/)
|
|
29
|
+
new("#{prefix}_#{SecureRandom.hex(5)}")
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def inspect
|
|
33
|
+
"LiquidVariable(#{name})"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def as_liquid
|
|
37
|
+
self
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def initialize
|
|
42
|
+
@lines = []
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def line(liquid_line)
|
|
46
|
+
@lines << liquid_line
|
|
47
|
+
nil
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def to_s
|
|
51
|
+
@lines.join("\n").html_safe
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def render_liquid(name, **assigns)
|
|
55
|
+
assigns_liquid = ", #{liquid_arguments(assigns)}" unless assigns.blank?
|
|
56
|
+
line "{% render #{name.to_s.to_json}#{assigns_liquid} %}"
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def assign_liquid(variable, value)
|
|
60
|
+
LiquidVariable.validate_name!(variable)
|
|
61
|
+
|
|
62
|
+
if value.is_a?(Hash)
|
|
63
|
+
value = "null | default: #{liquid_arguments(value, variable)}"
|
|
64
|
+
else
|
|
65
|
+
value = liquid_value(value, variable)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
line "{% assign #{variable} = #{value} %}"
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def liquid_arguments(assigns, _base_name = nil)
|
|
72
|
+
assigns.map { |k, v| "#{k}: #{liquid_value(v, k.to_s)}" }.join(", ")
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def liquid_value(value, variable_name = nil)
|
|
76
|
+
if value.respond_to?(:as_liquid)
|
|
77
|
+
value = value.as_liquid
|
|
78
|
+
elsif value.respond_to?(:serializable_hash)
|
|
79
|
+
value = value.serializable_hash
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
value = case value
|
|
83
|
+
when String, Numeric, TrueClass, FalseClass, NilClass, Date, Time, Symbol
|
|
84
|
+
value.to_json
|
|
85
|
+
when LiquidVariable
|
|
86
|
+
value.name
|
|
87
|
+
when Hash
|
|
88
|
+
assign_name = LiquidVariable.random("h_#{variable_name}").name
|
|
89
|
+
assign_liquid(assign_name, value)
|
|
90
|
+
assign_name
|
|
91
|
+
else
|
|
92
|
+
raise UnsupportedValueError.new(value, variable_name)
|
|
93
|
+
end
|
|
94
|
+
value.html_safe
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
%i[render_liquid assign_liquid].each do |method_name|
|
|
99
|
+
define_method method_name do |*args, **kwargs|
|
|
100
|
+
LiquidBuffer.new.tap { _1.send(method_name, *args, **kwargs) }.to_s
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def liquid_capture(name, &block)
|
|
105
|
+
safe_join(["{% capture #{name} %}".html_safe, capture(&block).html_safe, "{% endcapture %}".html_safe])
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def liquid_variable(name)
|
|
109
|
+
LiquidBuffer::LiquidVariable.new(name)
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "liquid_response/version"
|
|
4
|
+
require "liquid_response/errors"
|
|
5
|
+
require "liquid_response/core_ext"
|
|
6
|
+
require "liquid_response/view_helper"
|
|
7
|
+
require "liquid_response/controller_helper"
|
|
8
|
+
|
|
9
|
+
module LiquidResponse
|
|
10
|
+
def self.register_liquid_mime_type!
|
|
11
|
+
return if Mime::Type.lookup_by_extension(:liquid)
|
|
12
|
+
|
|
13
|
+
Mime::Type.register "application/liquid", :liquid
|
|
14
|
+
end
|
|
15
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: liquid_response
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Elia Schito
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: railties
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '7.0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '7.0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: activesupport
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '7.0'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '7.0'
|
|
40
|
+
description: LiquidResponse provides Rails controller and view helpers for rendering
|
|
41
|
+
Liquid templates, designed for use with Shopify App Proxy and similar setups where
|
|
42
|
+
Rails serves Liquid markup to a storefront.
|
|
43
|
+
email:
|
|
44
|
+
- elia@schito.me
|
|
45
|
+
executables: []
|
|
46
|
+
extensions: []
|
|
47
|
+
extra_rdoc_files: []
|
|
48
|
+
files:
|
|
49
|
+
- LICENSE.txt
|
|
50
|
+
- README.md
|
|
51
|
+
- Rakefile
|
|
52
|
+
- lib/liquid_response.rb
|
|
53
|
+
- lib/liquid_response/controller_helper.rb
|
|
54
|
+
- lib/liquid_response/core_ext.rb
|
|
55
|
+
- lib/liquid_response/errors.rb
|
|
56
|
+
- lib/liquid_response/version.rb
|
|
57
|
+
- lib/liquid_response/view_helper.rb
|
|
58
|
+
- sig/liquid_response.rbs
|
|
59
|
+
homepage: https://github.com/elia/liquid_response
|
|
60
|
+
licenses:
|
|
61
|
+
- MIT
|
|
62
|
+
metadata:
|
|
63
|
+
allowed_push_host: https://rubygems.org
|
|
64
|
+
homepage_uri: https://github.com/elia/liquid_response
|
|
65
|
+
source_code_uri: https://github.com/elia/liquid_response
|
|
66
|
+
changelog_uri: https://github.com/nebulab/liquid_response/releases
|
|
67
|
+
rdoc_options: []
|
|
68
|
+
require_paths:
|
|
69
|
+
- lib
|
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: 3.2.0
|
|
75
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
76
|
+
requirements:
|
|
77
|
+
- - ">="
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: '0'
|
|
80
|
+
requirements: []
|
|
81
|
+
rubygems_version: 4.0.10
|
|
82
|
+
specification_version: 4
|
|
83
|
+
summary: Render Liquid templates from Rails controllers and views
|
|
84
|
+
test_files: []
|