there is a project called TheForeman (v3.3.0) for which I want to override some ERB templates with spree/deface (v1.5.3), for example _managed.html.erb, and add something at the end of it.
# in app/overrides/nic/manageds/_managed/add_my_partial.html.erb.deface
<!-- insert_after "erb[loud]:contains('nic/provider_specific_form')" -->
<%= render 'my/partial', :f => f %>
Works great! Now, there are 5 more templates of the same kind, where the same approach works. But then I have to supply the identical .deface
for each template. It would be more sensible and maintainable if I were to put my partial at the end of the other partial, which is rendered in each template (my current deface select target), right? Sadly, I failed to achieve that with deface, which brought me here.
What I've tried so far...
insert_after
cannot use closing_selector
and it looks like it doesn't recognize which ERB elements start and end Ruby blocks
erb[silent]:contains('if')
inserts as second line in the fileerb[silent]:contains('end')
inserts three times, once after each <% end %>
:root
or :last
as CSS selectors yield very strange results I cannot explain. Both select more than the root and final elements, which makes no sense.last-of-type
seems to be completely ignored and therefor erb[silent]:last-of-type
selects every silent ERB elementnth-child
seems to be processed, but...
erb[silent]:contains('end'):nth-child(3)
hits nothingerb[silent]:nth-child(5)
hits the second <% end %>
erb[silent]:nth-child(6)
hits nothingerb[silent]:nth-last-child(1)
after each <% end %>
:root>erb[silent]:contains('end')
inserts after the second <% end %>
cut
action, I wouldn't know how to paste whatever was cut back for other ludicrous tests like...
Maybe, if there was a way to let deface show me the concrete pseudo HTML markup of an ERB file, I could experiment with CSS selectors against that. At this point I cannot extrapolate that in my imagination far enough.
I welcome any hints!
Thank you for your time, Xavier.
if there was a way to let deface show me the concrete pseudo HTML markup of an ERB file (...)
That, in fact, wasn't so difficult:
require 'deface'
raw_erb = File.open(path_to_erb_template).read
puts Deface::Parser.erb_markup!(raw_erb)
Which produces...
<erb silent> if provider_partial_exist?(@host.compute_resource, &#39;network&#39;) </erb>
<erb silent> hidden = f.object.virtual? ? &quot;hidden&quot; : &quot;&quot; </erb>
<fieldset data-erb-class="compute_attributes <%= hidden %>">
<h3 class="col-md-offset-1">
<erb loud> @host.compute_resource.provider_friendly_name </erb>
<erb silent> if f.object.compute_attributes[&quot;from_profile&quot;] </erb>
<span class="profile">( <erb loud> _(&quot;from profile %s&quot;) % f.object.compute_attributes[&quot;from_profile&quot;] </erb> )</span>
<erb silent> end </erb>
</h3>
<erb silent> new_vm = @vm ? @vm.persisted? : new_vm?(@host) </erb>
<erb loud> f.fields_for &#39;compute_attributes&#39;, OpenStruct.new(f.object.compute_attributes) do |f| </erb>
<erb loud> render provider_partial(@host.compute_resource, &#39;network&#39;), :f =&gt; f, :disabled =&gt; f.object.persisted?, :compute_resource =&gt; @host.compute_resource, :new_host =&gt; new_vm, :new_vm =&gt; new_vm </erb>
<erb silent> end </erb>
</fieldset>
<erb silent> end </erb>
On www.videlibri.de I could interactively test CSS selectors against that. The solution then was found quickly and is rather simple: :root:last-child
[foreman@host ~]# foreman-rake deface:get_result[nic/_provider_specific_form]
---------------- Before ----------------
<% if provider_partial_exist?(@host.compute_resource, 'network') %>
<% hidden = f.object.virtual? ? "hidden" : "" %>
<fieldset class="compute_attributes <%= hidden %>">
<h3 class="col-md-offset-1">
<%= @host.compute_resource.provider_friendly_name %>
<% if f.object.compute_attributes["from_profile"] %>
<span class="profile">( <%= _("from profile %s") % f.object.compute_attributes["from_profile"] %> )</span>
<% end %>
</h3>
<% new_vm = @vm ? @vm.persisted? : new_vm?(@host) %>
<%= f.fields_for 'compute_attributes', OpenStruct.new(f.object.compute_attributes) do |f| %>
<%= render provider_partial(@host.compute_resource, 'network'), :f => f, :disabled => f.object.persisted?, :compute_resource => @host.compute_resource, :new_host => new_vm, :new_vm => new_vm %>
<% end %>
</fieldset>
<% end %>
---------------- Overrides (1)--------
- 'add_my_partial' will be applied.
---------------- After ----------------
<% if provider_partial_exist?(@host.compute_resource, 'network') %>
<% hidden = f.object.virtual? ? "hidden" : "" %>
<fieldset class="compute_attributes <%= hidden %>">
<h3 class="col-md-offset-1">
<%= @host.compute_resource.provider_friendly_name %>
<% if f.object.compute_attributes["from_profile"] %>
<span class="profile">( <%= _("from profile %s") % f.object.compute_attributes["from_profile"] %> )</span>
<% end %>
</h3>
<% new_vm = @vm ? @vm.persisted? : new_vm?(@host) %>
<%= f.fields_for 'compute_attributes', OpenStruct.new(f.object.compute_attributes) do |f| %>
<%= render provider_partial(@host.compute_resource, 'network'), :f => f, :disabled => f.object.persisted?, :compute_resource => @host.compute_resource, :new_host => new_vm, :new_vm => new_vm %>
<% end %>
</fieldset>
<% end %>
<%= render 'foreman_cnames/hosts/host_aliases', :f => f %>
---------------- Diff -----------------
<% if provider_partial_exist?(@host.compute_resource, 'network') %>
<% hidden = f.object.virtual? ? "hidden" : "" %>
<fieldset class="compute_attributes <%= hidden %>">
<h3 class="col-md-offset-1">
<%= @host.compute_resource.provider_friendly_name %>
<% if f.object.compute_attributes["from_profile"] %>
<span class="profile">( <%= _("from profile %s") % f.object.compute_attributes["from_profile"] %> )</span>
<% end %>
</h3>
<% new_vm = @vm ? @vm.persisted? : new_vm?(@host) %>
<%= f.fields_for 'compute_attributes', OpenStruct.new(f.object.compute_attributes) do |f| %>
<%= render provider_partial(@host.compute_resource, 'network'), :f => f, :disabled => f.object.persisted?, :compute_resource => @host.compute_resource, :new_host => new_vm, :new_vm => new_vm %>
<% end %>
</fieldset>
<% end %>
+<%= render 'my/partial', :f => f %>
+