triplet 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b40b0b70887646a31162a22cabddccae123dbccda5d43dc80fd7242b5aa94f81
4
- data.tar.gz: 48bfda56958ed0fe61cb24706217b7f64488cd5154ef6f35385cb090abc956f0
3
+ metadata.gz: 6ec92ece8a32167845522f68fc13eb3626fc8050a50c2d9d2a3ec584a6484352
4
+ data.tar.gz: 776de546e4d65f5e86a918a6b6df82e0d6943865d45bfa141c68fa9392a5b065
5
5
  SHA512:
6
- metadata.gz: a41c7887916837e1f588fd5ebb224d5de2995abba38f2724d1dbb02aa7c9bea51d59b340851d98cc0fe362aa805f2f226870e745af06bf3224c6bc83fd69dfbe
7
- data.tar.gz: a6dd49020e45e0feeb3e0ee616f3c04832956c4a6c0c7d133b8435874092f2d7c7a15861f9b815f5c2025811af62733060ffae0a22acd83ff11e2b3e3a36412c
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
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- triplet (0.1.2)
4
+ triplet (0.2.0)
5
5
  actionview (>= 5.0.0, < 7.0)
6
6
 
7
7
  GEM
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 do
22
- nav class: "max-w-3xl mx-auto flex" do
23
- h1(class: "font-3xl") { "My App" }
24
-
25
- ul class: "" do
26
- nav_items.each do |name, link|
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
- end
32
- end
33
-
34
- text "Hello"
35
- span(class: "bold") { "world" }
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="/"></a></li>
46
- <li class="bold font-xl"><a href="/sign-up"></a></li>
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
- If you need a custom tag, you can use the `tag` helper method:
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
- ```ruby
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
- To output strings with no wrapping tag, use the `text` helper:
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
- text "hello "
63
- b { "world" }
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 < ::ViewComponent::Base
76
+ class NavComponent < ViewComponent::Base
74
77
  include Triplet::ViewComponent
75
78
 
76
- def call
77
- h1 { "hello world" }
78
-
79
- render NavItemComponent.new(title: "Home", path: "/")
80
- render NavItemComponent.new(title: "Pricing", path: "/pricing")
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
  ```
@@ -3,8 +3,8 @@
3
3
  require "action_view" # Necessary for output buffer
4
4
 
5
5
  require "triplet/version"
6
- require "triplet/template"
7
6
  require "triplet/dsl"
7
+ require "triplet/template"
8
8
 
9
9
  module Triplet
10
10
  class Error < StandardError; end
@@ -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
- tag(tag, attrs, &block)
36
+ [
37
+ tag,
38
+ attrs,
39
+ block&.call,
40
+ ]
34
41
  end
35
42
  end
36
43
 
37
- def text(text)
38
- @output_buffer << text
39
- end
40
-
41
- def tag(tag, attrs = {}, &block)
42
- @output_buffer.safe_concat "<#{tag}"
43
- @output_buffer.safe_concat " " unless attrs.empty?
44
- _write_attributes(attrs)
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
- # Supports returning a string directlycfrom blocks
54
- if result.length == 0 && value
55
- @output_buffer << value
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
- @output_buffer << result
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
- def _write_attributes(attrs)
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
- def capture
77
- original_output_buffer = @output_buffer
78
-
79
- begin
80
- @output_buffer = ActionView::OutputBuffer.new
81
- yield
82
- @output_buffer
83
- ensure
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
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Triplet
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -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 render_in(view_context, &block)
10
- @output_buffer ||= ActionView::OutputBuffer.new
11
- super(view_context, &block)
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.1.2
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