phlex
phlex copied to clipboard
Inline tags declaration
Hi everyone,
I have a question (more like an advice) about phlex tag registration improvement.
We are doing a migration from another rendering gem (fortitude) to phlex and have a lot of legacy code, which supports both block and inline tags:
div do
'Some content'
end
# returns same result
div 'Some content'
I did patch register_element method here like this:
def #{method_name}(inline_content = nil, **attributes, &block)
#...
elsif inline_content.present? # with inline content
buffer << "<#{tag}" << (Phlex::ATTRIBUTE_CACHE[respond_to?(:process_attributes) ? (attributes.hash + self.class.hash) : attributes.hash] || __attributes__(**attributes)) << ">"
inline_content_block = Proc.new { inline_content }
yield_content(&inline_content_block)
buffer << "</#{tag}>"
else
#...
end
(without attributes part also updated)
to support both approaches and its works pretty good in most of places except some specific cases.
After applying this patch to a Phlex::HTML::StandardElements
Phlex::HTML::StandardElements.module_eval { extend PhlexElementRegisterer }
and re-registering all elements with patched register_element method:
Phlex::HTML::StandardElements.registered_elements.each do |method_name, tag|
Phlex::HTML::StandardElements.register_element(method_name, tag: tag)
end
For example nested tags like tables:
table do
tr do
td 'Content'
end
end
generate expected html:
<table>
<tr>
<td>Content</td>
</tr>
</table>
but if I do something more specific:
table do
tr do
td div { 'Content' }
end
end
it moves div block outside table tag:
<div>Content</div>
<table>
<tr>
<td></td>
</tr>
</table>
When debugging I see that the div tag method was called with &block and after it the td method also called, but without any arguments or even a block.
As a second example it happens not only with table tag:
def link_tag(text)
div do
link_to(text, '#')
end
end
div class: 'first_nested' do
div class: 'second_nested' do
div link_tag('something'), class: 'third_nested'
end
end
Will return:
<div class="first_nested">
<div class="second_nested">
<div><a href="#">something</a></div>
<div class="third_nested"></div>
</div>
</div>
Maybe you will see how this issue can be solved? If solved, will this approach (supporting inline tags) be acceptable, as a future patch, to phlex (after it will be stable and test covered)?
Thanks!