File tree Expand file tree Collapse file tree 3 files changed +54
-4
lines changed Expand file tree Collapse file tree 3 files changed +54
-4
lines changed Original file line number Diff line number Diff line change @@ -46,6 +46,34 @@ is equivalent to:
4646> [ !TIP]
4747> Computed attributes work with partials as well as standard HTML tags.
4848
49+ #### Short form
50+
51+ If value of a dynamic attribute is the same as its name, you can omit the value.
52+
53+ For example
54+ ``` html
55+ <div style% >Text</div >
56+ ```
57+ is equivalent to:
58+ ``` erb
59+ <div style%="style">Text</div>
60+ ```
61+ which in turn is equivalent to:
62+ ``` erb
63+ <div style="<%= style %>">Text</div>
64+ ```
65+
66+ Since ` class ` is a Ruby keyword, it's treated specially:
67+ ``` html
68+ <div class% >Text</div >
69+ ```
70+ is equivalent to:
71+ ``` erb
72+ <div class="<%= binding.local_variable_get('class') %>">Text</div>
73+ ```
74+
75+ > [ !TIP]
76+ > Short form is especially useful when you want to apply a ` class ` and ` style ` attribute to a partial root.
4977
5078### Partials
5179
Original file line number Diff line number Diff line change 11module Theo
22 module Rails
3- ATTRIBUTE_NAME = /[ \w \- :@]+ /
3+ ATTRIBUTE_NAME = /(?<name>[a-z][ \w \- :@]*) /
44 ATTRIBUTE_VALUE = /(?:(?:"(?<value>[^"]*)")|(?:'(?<value>[^']*)'))/
5- ATTRIBUTE = /(?:(?:(?<name>#{ ATTRIBUTE_NAME . source } )\s *=\s *#{ ATTRIBUTE_VALUE . source } )|(?<name>#{ ATTRIBUTE_NAME . source } ))/
6- DYNAMIC_ATTRIBUTE = /(?:(?<name>#{ ATTRIBUTE_NAME . source } )\s *%=\s *#{ ATTRIBUTE_VALUE . source } )/
5+ ATTRIBUTE = /(?:(?:#{ ATTRIBUTE_NAME . source } \s *=\s *#{ ATTRIBUTE_VALUE . source } )|#{ ATTRIBUTE_NAME . source } )/
6+ DYNAMIC_ATTRIBUTE = /(?:(?:#{ ATTRIBUTE_NAME . source } \s *%=\s *#{ ATTRIBUTE_VALUE . source } )|(?:#{ ATTRIBUTE_NAME . source } %))/
7+ RESERVED_ATTRIBUTE_NAME = %w[ alias and begin break case class def do else elsif end ensure false for if in module next nil not or redo rescue retry return self super then true undef unless until when while yield ] . to_set
78 ATTRIBUTES = /(?<attrs>(?:\s +#{ ATTRIBUTE . source } )*)/
89 LITERAL_ATTRIBUTES = %i[ path as yields collection ] . freeze
910 PARTIAL_TAG = /(?<partial>_\w +)/
@@ -16,7 +17,16 @@ module Rails
1617 class Theo
1718 def process ( source )
1819 # Attributes
19- source = source . gsub ( DYNAMIC_ATTRIBUTE , '\k<name>="<%= \k<value> %>"' )
20+ source = source . gsub ( DYNAMIC_ATTRIBUTE ) do |_ |
21+ match = Regexp . last_match
22+
23+ name = match [ :name ]
24+
25+ # See https://island94.org/2024/06/rails-strict-locals-local_assigns-and-reserved-keywords for more info
26+ value = match [ :value ] || ( RESERVED_ATTRIBUTE_NAME . include? ( name ) ? "binding.local_variable_get('#{ name } ')" : name )
27+
28+ "#{ name } =\" <%= #{ value } %>\" "
29+ end
2030
2131 # Partials
2232 source . gsub ( TEMPLATE ) do |_ |
Original file line number Diff line number Diff line change 1717 include_examples 'theo to erb' , 'evaluates dynamic attribute' ,
1818 %(<a href%="2 % 2 == 0 ? '/even' : '/odd'">Link</a>) ,
1919 %(<a href="<%= 2 % 2 == 0 ? '/even' : '/odd' %>">Link</a>)
20+
21+ include_examples 'theo to erb' , 'evaluates shortened dynamic attribute' ,
22+ %(<a href%>Link</a>) ,
23+ %(<a href="<%= href %>">Link</a>)
24+
25+ include_examples 'theo to erb' , 'evaluates shortened reserved dynamic attribute' ,
26+ %(<div class%>Content</div>) ,
27+ %(<div class="<%= binding.local_variable_get('class') %>">Content</div>)
28+
29+ include_examples 'theo to erb' , 'ignores trim symbols' ,
30+ %(<%- variable -%>) ,
31+ %(<%- variable -%>)
2032 end
2133
2234 context 'partial' do
You can’t perform that action at this time.
0 commit comments