homura-runtime 0.1.3 → 0.1.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 328d7e98210fb60bb229a46166aa605b2c9e2a85baca8418cac31a0ac3688311
4
- data.tar.gz: 3e3c0562902a031343eddf788a078d1556649c286ec79e44295626a0be2058a3
3
+ metadata.gz: 6e37f705dbc9ddf448634efe039bcc390d577c1683ad1759db58fdb1fbceee02
4
+ data.tar.gz: 9dfa51f60c34241302354b5069f10ba560a61c51d4b70a1799893d785d2ae434
5
5
  SHA512:
6
- metadata.gz: 971c5697869ed0ecc0ba57d6aa5263c6f3b36f5e2bfa0c5e6efc67efe5bb5aade01dd0b522aaa685c4226074924b5a6e8269135fd6a12bdf1f8a6592d3b120cb
7
- data.tar.gz: 0ef026fa796bfedb3960b42c1f2ea6a09a1d382d9883d16fd744767d3967a3649f0ee9cb322e80f1ddff6db752f05f12da94c62b04c238fe8f43aa4143b667d8
6
+ metadata.gz: 0655d2c8e8f889892df7500cfadc663df079be3c7326815523b2fad12cacdce4eb729f859e145bfdc8c26f8ad0bc12bc2d5ee2dfd3acf14e71c82ffafd4057d3
7
+ data.tar.gz: 93c6e9c5607b995d631060f511633bd94b3fa74f9db3c9adee3806b684a1ea7134b136bde12f9c8a3fa7d1da5f3ff76c95929c253251eb7daf3f1f9685bc5342
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.4 (2026-04-23)
4
+
5
+ - Teach the precompiled ERB runtime to support Sinatra-style layout blocks and
6
+ `<%= yield %>` in layout templates.
7
+ - Keep legacy `@content` / `@docs_inner` layouts working as compatibility
8
+ fallbacks while apps migrate to the least-surprise Sinatra style.
9
+
3
10
  ## 0.1.3 (2026-04-23)
4
11
 
5
12
  - Fix binary static asset embedding so image responses preserve exact bytes on
data/exe/compile-erb CHANGED
@@ -43,11 +43,21 @@ USAGE
43
43
  module HomuraERB
44
44
  module_function
45
45
 
46
+ def normalize_fragment(fragment)
47
+ stripped = fragment.strip
48
+ return '__homura_template_yield__' if stripped == 'yield' || stripped == 'yield()'
49
+
50
+ fragment
51
+ end
52
+
46
53
  # Compile an ERB source string to a Ruby method body that assembles
47
54
  # an HTML string in a local variable `_out`. The body references
48
55
  # `@ivars` and method calls directly, so it must be run via
49
56
  # `instance_exec` on the Sinatra instance the route was dispatched
50
- # on. That gives `<%= @name %>` the usual Sinatra semantics.
57
+ # on. That gives `<%= @name %>` the usual Sinatra semantics. Layout
58
+ # templates can also write `<%= yield %>` — we rewrite that specific
59
+ # form to an instance helper because Ruby's `yield` keyword is not
60
+ # valid inside the Proc body we generate here.
51
61
  def compile(source)
52
62
  ruby = +"_out = ''\n"
53
63
  cursor = 0
@@ -75,15 +85,15 @@ module HomuraERB
75
85
  elsif inner.start_with?('==')
76
86
  # `<%== expression %>` — identical to `<%= %>` in this minimal
77
87
  # dialect (no HTML escaping yet; the author is responsible).
78
- expr = inner[2..].strip
88
+ expr = normalize_fragment(inner[2..].strip)
79
89
  ruby << "_out = _out + ((#{expr})).to_s\n"
80
90
  elsif inner.start_with?('=')
81
91
  # `<%= expression %>`
82
- expr = inner[1..].strip
92
+ expr = normalize_fragment(inner[1..].strip)
83
93
  ruby << "_out = _out + ((#{expr})).to_s\n"
84
94
  else
85
95
  # `<% code %>` — Ruby statement(s), emitted verbatim
86
- ruby << inner.strip << "\n"
96
+ ruby << normalize_fragment(inner.strip) << "\n"
87
97
  end
88
98
 
89
99
  cursor = close_idx + 2
@@ -142,10 +152,16 @@ def emit_header(io, namespace)
142
152
  @templates[name.to_sym] = body
143
153
  end
144
154
 
145
- def render(name, instance, locals = {})
155
+ def render(name, instance, locals = {}, &block)
146
156
  body = @templates[name.to_sym]
147
157
  raise "#{namespace}: no template registered for \#{name.inspect}" unless body
148
- instance.instance_exec(locals, &body)
158
+ previous_block = instance.instance_variable_get(:@__homura_template_block__)
159
+ begin
160
+ instance.instance_variable_set(:@__homura_template_block__, block)
161
+ instance.instance_exec(locals, &body)
162
+ ensure
163
+ instance.instance_variable_set(:@__homura_template_block__, previous_block)
164
+ end
149
165
  end
150
166
 
151
167
  def registered?(name)
@@ -187,6 +203,22 @@ def emit_sinatra_patch(io, namespace)
187
203
 
188
204
  module ::Sinatra
189
205
  module Templates
206
+ def __homura_template_yield__
207
+ block = @__homura_template_block__
208
+ raise LocalJumpError, 'no block given' unless block
209
+
210
+ block.call
211
+ end
212
+
213
+ def __homura_default_template_block_for__(template)
214
+ case template.to_sym
215
+ when :layout
216
+ proc { @content } if defined?(@content)
217
+ when :layout_docs
218
+ proc { @docs_inner } if defined?(@docs_inner)
219
+ end
220
+ end
221
+
190
222
  # homura patch: dispatch to precompiled templates when we
191
223
  # have one. Unknown symbols raise a clear message instead of
192
224
  # wandering into upstream Tilt, which would blow up on
@@ -194,7 +226,20 @@ def emit_sinatra_patch(io, namespace)
194
226
  def erb(template, options = {}, locals = {}, &block)
195
227
  if template.is_a?(::Symbol) && ::#{namespace}.registered?(template)
196
228
  locals ||= {}
197
- ::#{namespace}.render(template, self, locals)
229
+ block ||= __homura_default_template_block_for__(template)
230
+ output = ::#{namespace}.render(template, self, locals, &block)
231
+
232
+ layout = options[:layout]
233
+ layout = false if layout.nil? && options.include?(:layout)
234
+ if layout
235
+ layout = :layout if layout == true
236
+ layout = layout.to_sym
237
+ raise "homura: layout \#{layout.inspect} not precompiled; run bin/compile-erb" unless ::#{namespace}.registered?(layout)
238
+
239
+ return ::#{namespace}.render(layout, self, locals) { output }
240
+ end
241
+
242
+ output
198
243
  else
199
244
  raise "homura: erb \#{template.inspect} not precompiled; run bin/compile-erb"
200
245
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CloudflareWorkers
4
- VERSION = '0.1.3'
4
+ VERSION = '0.1.4'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: homura-runtime
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kazuhiro NISHIYAMA