Skip to content

Commit

Permalink
Support inline tags (#755)
Browse files Browse the repository at this point in the history
Based on [issue](#750)

Adding support of inline tag declaration
Examples:
```
h1 'Hello'
```
will render:
```
<h1>Hello</h1>
```

```
div do
  h1 'Hello', class: 'title'
end
```
will render:
```
<div><h1 class="title">Hello</h1></div>
```
  • Loading branch information
joeldrapper authored Sep 2, 2024
2 parents 3fbc982 + 09cb7ef commit 29eb1e4
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 3 deletions.
1 change: 1 addition & 0 deletions lib/phlex.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ module Phlex
Escape = ERB::Escape
ATTRIBUTE_CACHE = FIFO.new
SUPPORTS_FIBER_STORAGE = RUBY_ENGINE == "ruby"
Null = Object.new.freeze
end

def 💪
Expand Down
22 changes: 19 additions & 3 deletions lib/phlex/elements.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,20 @@ def register_element(method_name, tag: method_name.name.tr("_", "-"))
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
# frozen_string_literal: true
def #{method_name}(**attributes, &block)
def #{method_name}(content = Phlex::Null, **attributes, &block)
context = @_context
buffer = context.buffer
fragment = context.fragments
target_found = false
if content != Phlex::Null && !content.is_a?(String)
raise ArgumentError.new("Only String allowed for inline tags content")
end
if block && content != Phlex::Null
raise ArgumentError.new("Using inline and block syntax at same time is forbidden")
end
if fragment
return if fragment.length == 0 # we found all our fragments already
Expand All @@ -59,15 +67,23 @@ def #{method_name}(**attributes, &block)
buffer << "<#{tag}" << (Phlex::ATTRIBUTE_CACHE[attributes] ||= __attributes__(attributes)) << ">"
yield_content(&block)
buffer << "</#{tag}>"
else # without content block
elsif content != Phlex::Null # with inline content
buffer << "<#{tag}" << (Phlex::ATTRIBUTE_CACHE[attributes] ||= __attributes__(attributes)) << ">"
plain(content)
buffer << "</#{tag}>"
else # without content
buffer << "<#{tag}" << (Phlex::ATTRIBUTE_CACHE[attributes] ||= __attributes__(attributes)) << "></#{tag}>"
end
else # without attributes
if block # with content block
buffer << "<#{tag}>"
yield_content(&block)
buffer << "</#{tag}>"
else # without content block
elsif content != Phlex::Null # with inline content
buffer << "<#{tag}>"
plain(content)
buffer << "</#{tag}>"
else # without content
buffer << "<#{tag}></#{tag}>"
end
end
Expand Down
82 changes: 82 additions & 0 deletions test/phlex/view/renderable/render.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,5 +91,87 @@ def view_template(&block)
end
end
end

with "inline tag method call" do
with "simple inline tag" do
view do
def view_template
h1 "Hello", class: "title"
end
end

it "renders a new instance of that view" do
expect(output).to be == "<h1 class=\"title\">Hello</h1>"
end
end

with "regular nesting" do
view do
def view_template
div class: "first" do
div class: "second" do
div "Hello", class: "third"
end
end
end
end

it "renders a new instance of that view" do
expect(output).to be == "<div class=\"first\"><div class=\"second\"><div class=\"third\">Hello</div></div></div>"
end
end

with "contain block" do
view do
def block_div
proc { div "Hello" }
end

def view_template
div block_div
end
end

it "raise argument error" do
expect { output }.to raise_exception(ArgumentError, message: be == "Only String allowed for inline tags content")
end
end

with "contain nil argument" do
view do
def view_template
h1 div "Hello"
end
end

it "raise argument error" do
expect { output }.to raise_exception(ArgumentError, message: be == "Only String allowed for inline tags content")
end
end

with "both block and inline arguments" do
view do
def view_template
h1("Hello") { "Hello" }
end
end

it "raise argument error" do
expect { output }.to raise_exception(ArgumentError, message: be == "Using inline and block syntax at same time is forbidden")
end
end

with "non string content" do
view do
def view_template
div :hello, class: "first"
end
end

it "raises argument error" do
expect { output }.to raise_exception(ArgumentError, message: be == "Only String allowed for inline tags content")
end
end
end
end
end

0 comments on commit 29eb1e4

Please sign in to comment.