Partial Template
We have two files: a.html.erb
and b.html.erb
, with similar contents.
a.html.erb
1<div class="container mx-auto"> 2 <h1> a.html.erb </h1> 3 4 <ul role="list"> 5 <li>Ruby</li> 6 <li>Rails</li> 7 <li>C++</li> 8 <li>C</li> 9 <li>Python</li> 10 <li>JavaScript</li> 11 ... 12 ... 13 <!-- many more --> 14 </ul> 15</div>
b.html.erb
1<div class="container mx-auto"> 2 <h1> b.html.erb </h1> 3 4 <ul role="list"> 5 <li>Ruby</li> 6 <li>Rails</li> 7 <li>C++</li> 8 <li>C</li> 9 <li>Python</li> 10 <li>JavaScript</li> 11 ... 12 ... 13 <!-- many more --> 14 </ul> 15</div>
Contents of both files are identical except <h1>
tag. I'm going to follow the DRY (Don't Repeat Yourself) principle and remove those duplicates using a partial template.
Creating a partial
The name of the partial template or a partial starts with an underscore(_
).
Here's my partial _langList.html.erb
:
1<ul role="list"> 2 <li>Ruby</li> 3 <li>Rails</li> 4 <li>C++</li> 5 <li>C</li> 6 <li>Python</li> 7 <li>JavaScript</li> 8 ... 9 ... 10 <!-- many more --> 11</ul>
Now we can replace these codes in a.html.erb
and b.html.erb
with the partial we just created.
Calling a partial
a.html.erb
1<div class="container mx-auto"> 2 <h1> a.html.erb </h1> 3 4 <%= render partial: 'langList' %> 5</div>
b.html.erb
1<div class="container mx-auto"> 2 <h1> b.html.erb </h1> 3 4 <%= render partial: 'langList' %> 5</div>
Note that I didn't use '_langList'
. You don't need to include the underscore when passing the name. In fact, you shouldn't include it otherwise rails wont be able to locate partials.
Sometimes you might need to specify the partial in a specific view directory. Let say you have a _langList.html.erb
inside the home
view.
1<%= render partial: 'home/langList' %>
Passing local variables
We can further reduce those codes in a.html.erb
and b.html.erb
by passing in contents inside the <h1>
tag with a variable to the partial.
a.html.erb
1<div class="container mx-auto"> 2 <%= render partial: 'langList', :locals => {:title => "a.html.erb"} %> 3</div>
b.html.erb
1<div class="container mx-auto"> 2 <%= render partial: 'langList', :locals => {:title => "b.html.erb"} %> 3</div>
Using :locals
, we can pass in variables to the partial. Here, :title
is the key I named, and I can access its value with title
(without the colon) in partial.
_langList.html.erb
1<h1> <%= title %> </h1> 2 3<ul role="list"> 4 <li>Ruby</li> 5 <li>Rails</li> 6 <li>C++</li> 7 <li>C</li> 8 <li>Python</li> 9 <li>JavaScript</li> 10 ... 11 ... 12 <!-- many more --> 13</ul>
If you want, you can even include those <div>
tags inside the partial and reduce the code even further more.
_langList.html.erb
1<div class="container mx-auto"> 2 <h1> <%= title %> </h1> 3 4 <ul role="list"> 5 <li>Ruby</li> 6 <li>Rails</li> 7 <li>C++</li> 8 <li>C</li> 9 <li>Python</li> 10 <li>JavaScript</li> 11 ... 12 ... 13 <!-- many more --> 14 </ul> 15</div>
a.html.erb
1<%= render partial: 'langList', :locals => {:title => "a.html.erb"} %>
b.html.erb
1<%= render partial: 'langList', :locals => {:title => "b.html.erb"} %>