triplet 0.1.2 → 0.2.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/.github/workflows/ruby.yml +23 -0
- data/Gemfile.lock +1 -1
- data/README.md +36 -32
- data/lib/triplet.rb +1 -1
- data/lib/triplet/dsl.rb +35 -42
- data/lib/triplet/rails_compatibility.rb +36 -0
- data/lib/triplet/template.rb +3 -1
- data/lib/triplet/version.rb +1 -1
- data/lib/triplet/view_component.rb +5 -3
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ec92ece8a32167845522f68fc13eb3626fc8050a50c2d9d2a3ec584a6484352
|
4
|
+
data.tar.gz: 776de546e4d65f5e86a918a6b6df82e0d6943865d45bfa141c68fa9392a5b065
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c1136f57bb9c8f01e6ea6bae45fae3d86ec41257f748ffdcc379d8872cf67c516013eac3d06b2184f2d0ba8ff15beb09e3cffcb9b568cf6de2d65380e2fe2ccf
|
7
|
+
data.tar.gz: 42e305e5979eee1de486473a7bcc38d0172e1f7da5df5fed4ab0960562ccca9a38b24c5fe245322cc76ae10ec2556dcb9994a0a1e1941e3021685b2a6ef1e236
|
@@ -0,0 +1,23 @@
|
|
1
|
+
name: Ruby
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ main ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ main ]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
test:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
strategy:
|
13
|
+
matrix:
|
14
|
+
ruby: [ '2.5', '2.6', '2.7' ]
|
15
|
+
steps:
|
16
|
+
- uses: actions/checkout@v2
|
17
|
+
- uses: ruby/setup-ruby@v1
|
18
|
+
with:
|
19
|
+
ruby-version: ${{ matrix.ruby }}
|
20
|
+
- name: Install dependencies
|
21
|
+
run: bundle install
|
22
|
+
- name: Run tests
|
23
|
+
run: bundle exec rake
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -3,6 +3,14 @@
|
|
3
3
|
A simple Ruby DSL for defining templates. (Maybe) useful for defining single file [view
|
4
4
|
components](https://github.com/github/view_component).
|
5
5
|
|
6
|
+
Features:
|
7
|
+
|
8
|
+
* Easy to use "AST" for defining HTML tags. `[:a, { href: "/" }, "Home"]`
|
9
|
+
* DSL methods to make defining triplets easier. `a(href: "/") { "Home" }`
|
10
|
+
* Supports Rails helper methods. e.g. `form_for`, `text_field_tag`, `link_to`,
|
11
|
+
etc.
|
12
|
+
* View Component support via `include Triplet::ViewComponent`
|
13
|
+
|
6
14
|
## Installation
|
7
15
|
|
8
16
|
Add this line to your application's Gemfile:
|
@@ -18,22 +26,18 @@ And then execute: `bundle install` in your shell.
|
|
18
26
|
```ruby
|
19
27
|
nav_items = { "home": "/", "Sign Up": "/sign-up" }
|
20
28
|
|
21
|
-
Triplet.template
|
22
|
-
nav
|
23
|
-
h1(class: "font-3xl") { "My App" }
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
li class: "bold font-xl" do
|
28
|
-
a href: link.html_safe { name }
|
29
|
-
end
|
29
|
+
Triplet.template {[
|
30
|
+
nav(class: "max-w-3xl mx-auto flex") {[
|
31
|
+
h1(class: "font-3xl") { "My App" },
|
32
|
+
ul(class: "") {[
|
33
|
+
nav_items.map do |name, link|
|
34
|
+
li(class: "bold font-xl") {[ a(href: link.html_safe) { name } ]}
|
30
35
|
end
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
36
|
+
]}
|
37
|
+
]},
|
38
|
+
"Hello",
|
39
|
+
span(class: "bold") { "world" },
|
40
|
+
]}
|
37
41
|
```
|
38
42
|
|
39
43
|
Will output the equivalent HTML:
|
@@ -42,26 +46,25 @@ Will output the equivalent HTML:
|
|
42
46
|
<nav class="max-w-3xl mx-auto flex">
|
43
47
|
<h1 class="font-3xl">My App</h1>
|
44
48
|
<ul class="">
|
45
|
-
<li class="bold font-xl"><a href="/"
|
46
|
-
<li class="bold font-xl"><a href="/sign-up"
|
49
|
+
<li class="bold font-xl"><a href="/">home</a></li>
|
50
|
+
<li class="bold font-xl"><a href="/sign-up">Sign Up</a></li>
|
47
51
|
</ul>
|
48
52
|
</nav>
|
49
53
|
Hello<span class="bold">world</span>
|
50
54
|
```
|
51
55
|
|
52
|
-
|
56
|
+
The tag methods (e.g. `nav`, `h1`, `p`) are helpers that turn Ruby code into
|
57
|
+
triples, or 3 element arrays.
|
53
58
|
|
54
|
-
|
55
|
-
tag("my-tag", "custom-attribute" => "value") { "body content" }
|
56
|
-
# <my-tag custom-attribute="value">body content</my-tag>
|
57
|
-
```
|
59
|
+
e.g. `p(class: "font-xl") { "hello world!" }` becomes `[:p, { class: "font-xl" }, "hello world!"]`
|
58
60
|
|
59
|
-
|
61
|
+
The two formats can be used interchangeably in templates.
|
62
|
+
|
63
|
+
If you need a custom tag, you can return a triplet directly:
|
60
64
|
|
61
65
|
```ruby
|
62
|
-
|
63
|
-
|
64
|
-
# hello <b>world</b>
|
66
|
+
[:"my-tag", { "custom-attribute" => "value" }, ["body content"]]
|
67
|
+
# <my-tag custom-attribute="value">body content</my-tag>
|
65
68
|
```
|
66
69
|
|
67
70
|
### View Component Support
|
@@ -70,14 +73,15 @@ To use in view components, include the `Triplet::ViewComponent` module and
|
|
70
73
|
define a `call` method. The module will handle the rest.
|
71
74
|
|
72
75
|
```ruby
|
73
|
-
class NavComponent <
|
76
|
+
class NavComponent < ViewComponent::Base
|
74
77
|
include Triplet::ViewComponent
|
75
78
|
|
76
|
-
def
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
79
|
+
def template
|
80
|
+
[
|
81
|
+
h1 { "hello world" },
|
82
|
+
render NavItemComponent.new(title: "Home", path: "/"),
|
83
|
+
render NavItemComponent.new(title: "Pricing", path: "/pricing")
|
84
|
+
]
|
81
85
|
end
|
82
86
|
end
|
83
87
|
```
|
data/lib/triplet.rb
CHANGED
data/lib/triplet/dsl.rb
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
|
3
3
|
module Triplet
|
4
4
|
module DSL
|
5
|
+
include ActionView::Helpers::CaptureHelper
|
6
|
+
include ActionView::Helpers::TagHelper
|
7
|
+
|
5
8
|
TAGS = [
|
6
9
|
:a, :abbr, :address, :area, :article, :aside, :audio,
|
7
10
|
:b, :base, :bdi, :bdo, :blockquote, :body, :br, :button,
|
@@ -30,61 +33,51 @@ module Triplet
|
|
30
33
|
# TODO handle VOID_TAGS specially
|
31
34
|
TAGS.each do |tag|
|
32
35
|
define_method tag do |attrs = {}, &block|
|
33
|
-
|
36
|
+
[
|
37
|
+
tag,
|
38
|
+
attrs,
|
39
|
+
block&.call,
|
40
|
+
]
|
34
41
|
end
|
35
42
|
end
|
36
43
|
|
37
|
-
def
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
@output_buffer.safe_concat ">"
|
46
|
-
|
47
|
-
if block
|
48
|
-
value = nil
|
49
|
-
result = capture do
|
50
|
-
value = block.call
|
51
|
-
end
|
44
|
+
def render_triplet(triplet)
|
45
|
+
if triplet.is_a?(String)
|
46
|
+
triplet
|
47
|
+
elsif triplet.is_a?(Array)
|
48
|
+
# If the array size is 3 and the first object is a
|
49
|
+
# symbol, it's likely a renderable triplet
|
50
|
+
if triplet.length == 3 && triplet[0].is_a?(Symbol)
|
51
|
+
tag, attrs, children = triplet
|
52
52
|
|
53
|
-
|
54
|
-
|
55
|
-
|
53
|
+
content_tag(tag, attrs) do
|
54
|
+
if children.is_a?(Array)
|
55
|
+
safe_join(children.map { |c| render_triplet(c) }, "")
|
56
|
+
else
|
57
|
+
render_triplet(children)
|
58
|
+
end
|
59
|
+
end
|
56
60
|
else
|
57
|
-
|
61
|
+
safe_join(triplet.map { |c| render_triplet(c) }, "")
|
58
62
|
end
|
63
|
+
else
|
64
|
+
triplet.to_s
|
59
65
|
end
|
60
|
-
|
61
|
-
@output_buffer.safe_concat "</#{tag}>"
|
62
66
|
end
|
63
67
|
|
64
68
|
private
|
65
69
|
|
66
|
-
|
67
|
-
attrs.each_with_index do |(k,v), i|
|
68
|
-
@output_buffer << k.to_s
|
69
|
-
@output_buffer.safe_concat '="'
|
70
|
-
@output_buffer << v.to_s
|
71
|
-
@output_buffer.safe_concat '"'
|
72
|
-
@output_buffer.safe_concat ' ' if i != attrs.length - 1
|
73
|
-
end
|
74
|
-
end
|
70
|
+
attr_accessor :output_buffer
|
75
71
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
@output_buffer = original_output_buffer
|
72
|
+
# Override capture to support triplets
|
73
|
+
def capture(*args)
|
74
|
+
value = nil
|
75
|
+
buffer = with_output_buffer { value = yield(*args) }
|
76
|
+
if (string = buffer.presence || value) && string.is_a?(String)
|
77
|
+
ERB::Util.html_escape string
|
78
|
+
elsif value.is_a?(Array) # This is the only change, adds triplet support
|
79
|
+
render_triplet(value)
|
85
80
|
end
|
86
81
|
end
|
87
82
|
end
|
88
83
|
end
|
89
|
-
|
90
|
-
Triplet::Template.include(Triplet::DSL)
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
require "view_component"
|
4
|
+
|
5
|
+
module Triplet
|
6
|
+
module RailsCompatibility
|
7
|
+
VALID_SUFFIXES = ["_field", "_button", "text_area"].freeze
|
8
|
+
VALID_METHODS = [
|
9
|
+
"form_for",
|
10
|
+
"form_with",
|
11
|
+
"label",
|
12
|
+
"fields_for",
|
13
|
+
"fields",
|
14
|
+
].freeze
|
15
|
+
include ActionView::Helpers::FormTagHelper
|
16
|
+
include ActionView::Helpers::FormHelper
|
17
|
+
|
18
|
+
# Override helpers to modify @output_buffer directly
|
19
|
+
(
|
20
|
+
ActionView::Helpers::FormTagHelper.public_instance_methods +
|
21
|
+
ActionView::Helpers::FormHelper.public_instance_methods
|
22
|
+
).each do |method|
|
23
|
+
alias_method :"original_#{method}", method
|
24
|
+
define_method method do |*args, **kwargs, &block|
|
25
|
+
puts "calling #{method}"
|
26
|
+
result = public_send(:"original_#{method}", *args, **kwargs, &block)
|
27
|
+
|
28
|
+
if result.class < String
|
29
|
+
@output_buffer << result
|
30
|
+
end
|
31
|
+
|
32
|
+
nil # Necessary to prevent double renders
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/triplet/template.rb
CHANGED
@@ -2,10 +2,12 @@
|
|
2
2
|
|
3
3
|
module Triplet
|
4
4
|
class Template
|
5
|
+
include Triplet::DSL
|
6
|
+
|
5
7
|
def initialize(output_buffer = ActionView::OutputBuffer.new, &block)
|
6
8
|
@output_buffer = output_buffer
|
7
9
|
|
8
|
-
instance_eval(&block)
|
10
|
+
@output_buffer << render_triplet(instance_eval(&block))
|
9
11
|
end
|
10
12
|
|
11
13
|
def to_s
|
data/lib/triplet/version.rb
CHANGED
@@ -5,10 +5,12 @@ require "view_component"
|
|
5
5
|
module Triplet
|
6
6
|
module ViewComponent
|
7
7
|
include Triplet::DSL
|
8
|
+
alias_method :template_tag, :template
|
8
9
|
|
9
|
-
def
|
10
|
-
|
11
|
-
|
10
|
+
def self.included(klass)
|
11
|
+
klass.define_method(:call) do
|
12
|
+
render_triplet(template)
|
13
|
+
end
|
12
14
|
end
|
13
15
|
end
|
14
16
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: triplet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Blake Williams
|
@@ -107,6 +107,7 @@ executables: []
|
|
107
107
|
extensions: []
|
108
108
|
extra_rdoc_files: []
|
109
109
|
files:
|
110
|
+
- ".github/workflows/ruby.yml"
|
110
111
|
- ".gitignore"
|
111
112
|
- ".travis.yml"
|
112
113
|
- Gemfile
|
@@ -118,6 +119,7 @@ files:
|
|
118
119
|
- bin/setup
|
119
120
|
- lib/triplet.rb
|
120
121
|
- lib/triplet/dsl.rb
|
122
|
+
- lib/triplet/rails_compatibility.rb
|
121
123
|
- lib/triplet/template.rb
|
122
124
|
- lib/triplet/version.rb
|
123
125
|
- lib/triplet/view_component.rb
|