philiprehberger-html_builder 0.7.0 → 0.9.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 +4 -4
- data/CHANGELOG.md +14 -0
- data/README.md +29 -1
- data/lib/philiprehberger/html_builder/builder.rb +41 -0
- data/lib/philiprehberger/html_builder/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 56b6f4a4c8e09045d724f5f67b3f8cec1e87fc2daddd397e04604cf13bcd33d8
|
|
4
|
+
data.tar.gz: 1b820c958ea1cafe11fa4aa415fb76b17aebef39aa611b6f100dedcdf01f2411
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '0398ad1acd04f45d1e28dc890a8436e01d42b9ed4e9bab2f0ee6d8e278d505016f74bee609c8743a0f8e3d69c111b3e03c83e9e2779bcb7437a51f7167183e1a'
|
|
7
|
+
data.tar.gz: 693dbcc9294f41267f54e66ef5c9a082f24c1a222d4db7d3c648623a392cf8ca6e6a80ac7fea0c944eb080c87ef598fba5b1292829ac4cc6825495bbbe54f1c3
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.9.0] - 2026-05-30
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- `HtmlBuilder.data(**attrs)` helper to build `data-*` attribute hashes, mirroring the existing `aria` helper
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- Bug report issue template now includes a required `gem-version` field and marks `ruby-version` as required, matching the standard template
|
|
17
|
+
|
|
18
|
+
## [0.8.0] - 2026-05-20
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
- `Builder#capture { ... }` — render a block in an isolated scope and return the HTML as a string without appending to the current document. Inherits previously defined components, so component reuse works inside captured fragments. Pairs naturally with `Builder#raw` for inserting the captured HTML into the document.
|
|
22
|
+
- Card image reference in the README for registry-side rendering
|
|
23
|
+
|
|
10
24
|
## [0.7.0] - 2026-04-26
|
|
11
25
|
|
|
12
26
|
### Added
|
data/README.md
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
[](https://rubygems.org/gems/philiprehberger-html_builder)
|
|
5
5
|
[](https://github.com/philiprehberger/rb-html-builder/commits/main)
|
|
6
6
|
|
|
7
|
+

|
|
8
|
+
|
|
7
9
|
Programmatic HTML builder with tag DSL, auto-escaping, form helpers, components, and output formatting
|
|
8
10
|
|
|
9
11
|
## Requirements
|
|
@@ -181,9 +183,14 @@ Philiprehberger::HtmlBuilder.build do
|
|
|
181
183
|
aria(label: 'Save', expanded: false, describedby: nil)
|
|
182
184
|
end
|
|
183
185
|
# => { 'aria-label' => 'Save', 'aria-expanded' => 'false' }
|
|
186
|
+
|
|
187
|
+
Philiprehberger::HtmlBuilder.build do
|
|
188
|
+
data(controller: 'menu', modal_target: 'dialog', open: true)
|
|
189
|
+
end
|
|
190
|
+
# => { 'data-controller' => 'menu', 'data-modal-target' => 'dialog', 'data-open' => 'true' }
|
|
184
191
|
```
|
|
185
192
|
|
|
186
|
-
`merge_attrs` joins `:class` values with a single space and `:style` values with `'; '`. Other keys follow last-write-wins, and input hashes are not mutated. `aria` converts snake_case keys to `aria-kebab-case` string keys, stringifies values, and omits keys whose value is `nil`.
|
|
193
|
+
`merge_attrs` joins `:class` values with a single space and `:style` values with `'; '`. Other keys follow last-write-wins, and input hashes are not mutated. `aria` converts snake_case keys to `aria-kebab-case` string keys, stringifies values, and omits keys whose value is `nil`. `data` mirrors `aria` for the `data-*` attribute namespace.
|
|
187
194
|
|
|
188
195
|
### CSS Class Helpers
|
|
189
196
|
|
|
@@ -198,6 +205,25 @@ end
|
|
|
198
205
|
# => <div class="btn btn-lg active">Click me</div>
|
|
199
206
|
```
|
|
200
207
|
|
|
208
|
+
### Capturing Fragments
|
|
209
|
+
|
|
210
|
+
Render a block in a separate scope and capture the HTML as a string instead of appending it to the document. Useful when the same fragment is needed in more than one place or as a value:
|
|
211
|
+
|
|
212
|
+
```ruby
|
|
213
|
+
Philiprehberger::HtmlBuilder.build do
|
|
214
|
+
badge = capture { strong 'NEW', class: 'badge' }
|
|
215
|
+
article do
|
|
216
|
+
h2 'Headline'
|
|
217
|
+
raw badge
|
|
218
|
+
p 'Body text'
|
|
219
|
+
raw badge
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
# => <article><h2>Headline</h2><strong class="badge">NEW</strong><p>Body text</p><strong class="badge">NEW</strong></article>
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
`capture` inherits any components defined on the parent builder, so component reuse works inside captured fragments.
|
|
226
|
+
|
|
201
227
|
### Fragment Caching
|
|
202
228
|
|
|
203
229
|
Cache rendered block results by key. On subsequent calls with the same key, the cached HTML is returned without re-executing the block:
|
|
@@ -348,7 +374,9 @@ Philiprehberger::HtmlBuilder.merge(header, body, footer)
|
|
|
348
374
|
| `Builder#class_names(*args)` | Build a conditional CSS class string from strings and hashes |
|
|
349
375
|
| `Builder#merge_attrs(*hashes)` | Merge attribute hashes, concatenating `:class` (space) and `:style` (`'; '`) values |
|
|
350
376
|
| `Builder#aria(**pairs)` | Build an ARIA attribute hash from snake_case keys (rendered as `aria-kebab-case`); omits nil values |
|
|
377
|
+
| `Builder#data(**attrs)` | Build a `data-*` attribute hash from snake_case keys (rendered as `data-kebab-case`); omits nil values |
|
|
351
378
|
| `Builder#cache(key) { ... }` | Cache rendered block output by key; return cached HTML on repeat calls |
|
|
379
|
+
| `Builder#capture { ... }` | Render the block in an isolated scope and return its HTML string (no append) |
|
|
352
380
|
| `Escape.html(value)` | Escape HTML special characters in a string |
|
|
353
381
|
|
|
354
382
|
## Development
|
|
@@ -308,6 +308,47 @@ module Philiprehberger
|
|
|
308
308
|
result
|
|
309
309
|
end
|
|
310
310
|
|
|
311
|
+
# Build a `data-*` attribute hash from keyword pairs
|
|
312
|
+
#
|
|
313
|
+
# snake_case keys are converted to `data-kebab-case` string keys. Values are
|
|
314
|
+
# converted to strings. Keys whose value is `nil` are omitted from the result.
|
|
315
|
+
# String keys are passed through with a `data-` prefix and underscores
|
|
316
|
+
# converted to dashes (e.g. `"modal-target"` becomes `"data-modal-target"`).
|
|
317
|
+
#
|
|
318
|
+
# @param attrs [Hash] keyword pairs to convert into `data-*` attributes
|
|
319
|
+
# @return [Hash<String, String>] hash with `"data-*"` string keys and string values
|
|
320
|
+
def data(**attrs)
|
|
321
|
+
result = {}
|
|
322
|
+
attrs.each do |key, value|
|
|
323
|
+
next if value.nil?
|
|
324
|
+
|
|
325
|
+
result["data-#{key.to_s.tr('_', '-')}"] = value.to_s
|
|
326
|
+
end
|
|
327
|
+
result
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
# Render a block in an isolated builder scope and return the HTML string
|
|
331
|
+
# without appending anything to the current document.
|
|
332
|
+
#
|
|
333
|
+
# Useful for template helpers that need to compute a fragment once and
|
|
334
|
+
# then insert it in multiple places (e.g. via {#raw}) or pass it as a
|
|
335
|
+
# string attribute (e.g. ``title:`` containing a small piece of escaped
|
|
336
|
+
# markup) — none of which can be expressed with the regular tag DSL
|
|
337
|
+
# because every tag method side-effects into the current scope.
|
|
338
|
+
#
|
|
339
|
+
# @yield block evaluated against a fresh builder; the same DSL methods
|
|
340
|
+
# (tags, `text`, `raw`, components, etc.) are available
|
|
341
|
+
# @return [String] the captured HTML (minified)
|
|
342
|
+
# @raise [Error] if no block is given
|
|
343
|
+
def capture(&block)
|
|
344
|
+
raise Error, 'a block is required for capture' unless block
|
|
345
|
+
|
|
346
|
+
nested = Builder.new
|
|
347
|
+
@components.each { |name, b| nested.instance_variable_get(:@components)[name] = b }
|
|
348
|
+
nested.instance_eval(&block)
|
|
349
|
+
nested.to_html
|
|
350
|
+
end
|
|
351
|
+
|
|
311
352
|
# Cache a rendered block result by key
|
|
312
353
|
#
|
|
313
354
|
# On the first call with a given key, the block is executed, its rendered
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: philiprehberger-html_builder
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.9.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Philip Rehberger
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-05-31 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: Build HTML programmatically using a clean tag DSL with nested blocks,
|
|
14
14
|
automatic content escaping, void element support, and attribute hashes.
|