Skip to content

Instantly share code, notes, and snippets.

@austintaylor
Created March 15, 2012 15:19
Show Gist options
  • Save austintaylor/2044757 to your computer and use it in GitHub Desktop.
Save austintaylor/2044757 to your computer and use it in GitHub Desktop.
A different approach to HTML templating
<h1><%= _('Profile') %></h1>
<%= form_for @profile, :url => user_profile_path(@profile), :html => {:class => 'profile'} do |f| %>
<%= render 'shared/errors', :model => @profile %>
<dl>
<dt><%= f.label :name, _('Name') %></dt>
<dd><%= f.text_field :name %></dt>
</dl>
<dl>
<dt><%= f.label :email, _('Email') %></dt>
<dd><%= f.text_field :email %></dt>
</dl>
<dl>
<dt><%= f.label :gender, _('Gender') %></dt>
<dd><%= f.select :gender, Profile::GENDERS %></dd>
</dl>
<fieldset class="services">
<% Profile::SERVICE_TYPES.each do |type| %>
<% f.fields_for :services do |ff| %>
<% ff.fields_for type, @profile.services.detect {|s| s.service_type == type } || @profile.services.build(:service_type => type) do |fff| %>
<dl id="<%= type %>_field">
<%= fff.hidden_field :id if fff.object.id %>
<%= fff.hidden_field :service_type %>
<dt><%= fff.label :url, _(type.titleize) %></dt>
<dd><%= fff.text_field :url %></dd>
</dl>
<% end %>
<% end %>
<% end %>
</fieldset>
<dl>
<dt><%= _('Options') %></dt>
<dd><%= f.check_box :public %><%= f.label :public, _('Show public profile') %></dd>
<dd><%= f.check_box :newsletter %><%= f.label :newsletter, _('Receive updates via email') %></dd>
<% if @profile.admin? %>
<dd><%= f.check_box :show_admin_status %><%= f.label :show_admin_status, _('Show admin status on profile') %></dd>
<% end %>
</dl>
<%= link_to _('Cancel'), user_profile_path(@profile) %>
<%= f.submit _('Save') %>
<% end %>
%h1= _('Profile')
= form_for @profile, :url => user_profile_path(@profile), :html => {:class => 'profile'} do |f|
= render 'shared/errors', :model => @profile
%dl
%dt= f.label :name, _('Name')
%dd= f.text_field :name
%dl
%dt= f.label :email, _('Email')
%dd= f.text_field :email
%dl
%dt= f.label :gender, _('Gender')
%dd= f.select :gender, Profile::GENDERS
%fieldset.services
- Profile::SERVICE_TYPES.each do |type|
- f.fields_for :services do |ff|
- ff.fields_for type, @profile.services.detect {|s| s.service_type == type } || @profile.services.build(:service_type => type) do |fff|
%dl{:id => "#{type}_field"}
= fff.hidden_field :id if fff.object.id
= fff.hidden_field :service_type
%dt= fff.label :url, _(type.titleize)
%dd= fff.text_field :url
%dl
%dt= _('Options')
%dd
= f.check_box :public
= f.label :public, _('Show public profile')
%dd
= f.check_box :newsletter
= f.label :newsletter, _('Receive updates via email')
- if @profile.admin?
%dd
= f.check_box :show_admin_status
= f.label :show_admin_status, _('Show admin status on profile')
= link_to _('Cancel'), user_profile_path(@profile)
= f.submit _('Save')
<h1 x-loc>Profile</h1>
<form class="profile" x-action="/user/profiles/{profile}" x-method-for="profile">
<div x-partial="shared/errors" x-yield="profile->model"/>
<dl>
<dt><label x-for x-loc>Name</label></dt>
<dd><input type="text" x-bind="profile.name"/></dt>
</dl>
<dl>
<dt><label x-for x-loc>Email</label></dt>
<dd><input type="text" x-bind="profile.email"/></dt>
</dl>
<dl>
<dt><label x-for x-loc>Gender</label></dt>
<dd><select x-bind="profile.gender" x-options="global.profile.genders"/></dd>
</dl>
<fieldset class="services" x-each="global.profile.service_types->type">
<dl x-id="{type}_field">
<input type="hidden" x-bind="profile.services[service_type=type].id" x-if-exists/>
<input type="hidden" x-bind="profile.services[service_type=type].service_type"/>
<dt><label x-for x-content="type.titleize" x-loc/></dt>
<dd><input type="text" x-bind="profile.services[service_type=type].url"/></dd>
</dl>
</fieldset>
<dl>
<dt x-loc>Options</dt>
<dd><input type="checkbox" x-bind="profile.public" x-boolean/><label x-for x-loc>Show public profile</label></dd>
<dd><input type="checkbox" x-bind="profile.newsletter" x-boolean/><label x-for x-loc>Receive updates via email</label></dd>
<dd x-if="profile.admin?"><input type="checkbox" x-bind="profile.show_admin_status" x-boolean/><label x-for x-loc>Show admin status on profile</label></dd>
</dl>
<a x-href="/user/profiles/{profile}" x-loc>Cancel</a>
<input type="submit" x-loc>Save</input>
</form>
@ravinggenius
Copy link

Have you taken a look at Plates? This looks kind-of similar.

@austintaylor
Copy link
Author

@ravinggenius Cool. Sounds like it has some of the same motivations. It's not really the same idea, though (templating by DOM manipulation rules vs DSL embedded in special attributes). Batman.js is closer.

@aiwilliams
Copy link

I think, for me, it's difficult to have an opinion that is well informed enough without using it for a while in various situations. Also, there are some designers who love to work in the actual application codebase, enjoy a terse language like Slim, and can even be taught enough Ruby avoid being stalled when they need a data structure or helper method. Then there is the fact that some template languages work good in one place and not in another. Sorry I can't give you a more hot/cold response :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment