Skip to content

Commit

Permalink
Support for Array and Set attribute values (phlex-ruby#546)
Browse files Browse the repository at this point in the history
This adds support for Array or Set attribute values like this:

```ruby
div(class: ["bg-red-500", "rounded"])
# or
div(class: Set["bg-red-500", "rounded"])
```

Array or Set attribute values will be treated like a token list, and its
members will be joined with a space. This works as long as all elements
are either strings or symbols.

Additionally, this change removes the implicit conversion of attribute
values to a string by calling `to_s` on anything that is not recognized.
Now attribute values that are not either a String, a Symbol, an Array, a
Set, or a Hash with values of one of these types, will raise an
ArgumentError.
  • Loading branch information
willcosgrove authored Mar 29, 2023
1 parent 504da6a commit 5e0ca1f
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 1 deletion.
6 changes: 5 additions & 1 deletion lib/phlex/sgml.rb
Original file line number Diff line number Diff line change
Expand Up @@ -406,8 +406,12 @@ def __build_attributes__(attributes, buffer:)
end
}, buffer: buffer
)
when Array
buffer << " " << name << '="' << ERB::Escape.html_escape(v.compact.join(" ")) << '"'
when Set
buffer << " " << name << '="' << ERB::Escape.html_escape(v.to_a.compact.join(" ")) << '"'
else
buffer << " " << name << '="' << ERB::Escape.html_escape(v.to_s) << '"'
raise ArgumentError, "Element attributes must be either a Boolean, a String, a Symbol, an Array of Strings or Symbols, or a Hash with values of one of these types"
end
end

Expand Down
60 changes: 60 additions & 0 deletions test/phlex/view/attributes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,66 @@ def template
end
end

with "an array of string attributes" do
view do
def template
div(class: %w(bg-red-500 rounded))
end
end

it "joins the array with a space" do
expect(output).to be == %(<div class="bg-red-500 rounded"></div>)
end
end

with "an array of symbol attributes" do
view do
def template
div(class: %i(bg-red-500 rounded))
end
end

it "joins the array with a space" do
expect(output).to be == %(<div class="bg-red-500 rounded"></div>)
end
end

with "an array of symbol and string attributes" do
view do
def template
div(class: ["bg-red-500", :rounded])
end
end

it "joins the array with a space" do
expect(output).to be == %(<div class="bg-red-500 rounded"></div>)
end
end

with "a set of string attributes" do
view do
def template
div(class: Set["bg-red-500", "rounded"])
end
end

it "joins the array with a space" do
expect(output).to be == %(<div class="bg-red-500 rounded"></div>)
end
end

with "an object that is not a boolean, String, Symbol, Array, or Hash" do
view do
def template
div(class: Object.new)
end
end

it "raises a Phlex::ArgumentError" do
expect { output }.to raise_exception(Phlex::ArgumentError)
end
end

if RUBY_ENGINE == "ruby"
with "unique tag attributes" do
view do
Expand Down

0 comments on commit 5e0ca1f

Please sign in to comment.