Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 230 lines (180 sloc) 16.205 kB
273483c @lsegal Fix various template_paths issues
authored
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2 <html>
3 <head>
4 <title>Tater Tots</title>
5 </head>
6 <body>
7 <div id='page'>
8 <div id='title'>
b1b2ff0 @lsegal Templates
authored
9 <h1>Tadpole: Revolutionizing Templates in Ruby</h1>
8235b7f @lsegal Author
authored
10
a2d89aa @lsegal link updates
authored
11 <p><em>Created by <a href="http://www.gnuu.org">Loren Segal</a> in 2008</em></p>
273483c @lsegal Fix various template_paths issues
authored
12 </div>
13 <div id='content'>
14 <ol>
1b071be @lsegal Templates
authored
15 <li id='#&lt;Tadpole::SectionProviders::TemplateProvider:0x5bb828&gt;'>
53dc5ba @lsegal Templates
authored
16 <h2>Quick How-To's</h2>
17
18 <h3>Create a Template</h3>
19
c10f09a @lsegal Templates
authored
20 <p>Creating a template is literally as easy as 1-2-3:</p>
21
53dc5ba @lsegal Templates
authored
22 <ol>
90f9836 @lsegal Templates
authored
23 <li><p>Create your templates in a directory. All directories are templates and all templates
24 are directories. The directory name will be the (or part of) the name of your template.
25 Example for template <code>mytemplate</code>:</p>
53dc5ba @lsegal Templates
authored
26
c10f09a @lsegal Templates
authored
27 <pre><code>templates/&#x000A; mytemplate/&#x000A; setup.rb&#x000A; section1.erb&#x000A; section2.haml&#x000A; copyright.html&#x000A;</code></pre></li>
53dc5ba @lsegal Templates
authored
28 <li><p>Setup the "<em>table of contents</em>" of your sections in the <code>setup.rb</code>:</p>
29
c10f09a @lsegal Templates
authored
30 <pre><code>def init&#x000A; super&#x000A; sections 'section1', 'section2', 'copyright'&#x000A;end&#x000A;</code></pre>
53dc5ba @lsegal Templates
authored
31
90f9836 @lsegal Templates
authored
32 <p>Your sections can include another template (directory). This will call whatever
33 sections were part of that other template.</p>
34
53dc5ba @lsegal Templates
authored
35 <p>A directory does not <em>require</em> a <code>section.rb</code>. If it is not supplied, it will inherit
36 the setup file from its parent (including its sections).</p></li>
37 <li><p>Register the <code>templates</code> path as your root template directory and run the template:</p>
38
1b071be @lsegal Templates
authored
39 <pre><code>require 'tadpole'&#x000A;Tadpole.register_template_path 'path/to/templates'&#x000A;Tadpole('mytemplate').run&#x000A;</code></pre></li>
53dc5ba @lsegal Templates
authored
40 </ol>
c10f09a @lsegal Templates
authored
41
1b071be @lsegal Templates
authored
42 <h3>Override a Template</h3>
43
c10f09a @lsegal Templates
authored
44 <p>You can override templates by simply registering another template_path and creating
45 a template of the same name in the new path. Using the <code>mytemplate</code> example from above
46 we can now make a directory:</p>
47
48 <pre><code>custom_templates/&#x000A; mytemplate/&#x000A; setup.rb&#x000A; header.erb&#x000A;</code></pre>
49
50 <p>This template will <em>inherit</em> from the template above. Our <code>setup.rb</code> will therefore
51 contain:</p>
52
53 <pre><code>def init&#x000A; super&#x000A; sections.unshift 'header'&#x000A;end&#x000A;</code></pre>
54
55 <p>And to run this file all we need to do is:</p>
56
1b071be @lsegal Templates
authored
57 <pre><code>require 'tadpole'&#x000A;Tadpole.register_template_path 'path/to/templates' # Register base template path&#x000A;Tadpole.register_template_path 'path/to/custom_templates' # Register overridden template path&#x000A;&#x000A;# Running our template will now add our 'header' file to the output&#x000A;Tadpole('mytemplate').run&#x000A;</code></pre>
58
59 <h3>Heirarchical Sections</h3>
90f9836 @lsegal Templates
authored
60
61 <p>Sometimes you may need to encapsulate the output of some sections inside another one. An HTML
62 template, for example, will usually contain the page body inside the body tag of a more general
63 "header" template. To set this up, you use the following <code>sections</code> call:</p>
64
65 <pre><code>sections 'header', ['section1', 'section2', 'copyright']&#x000A;</code></pre>
66
67 <p>You can then call these from your <code>header.erb</code> file as simple yields. Each yield renders
68 one section in the sub-list:</p>
69
75cc116 @lsegal Templates
authored
70 <pre><code>&lt;html&gt;&#x000A; &lt;body&gt;&#x000A; &lt;h1&gt;Section 1&lt;/h1&gt;&#x000A; &lt;%= yield %&gt;&#x000A;&#x000A; &lt;h1&gt;Section 2&lt;/h1&gt;&#x000A; &lt;%= yield %&gt;&#x000A;&#x000A; &lt;h1&gt;Copyright&lt;/h1&gt;&#x000A; &lt;%= yield %&gt;&#x000A; &lt;/body&gt;&#x000A;&lt;/html&gt;&#x000A;</code></pre>
90f9836 @lsegal Templates
authored
71
72 <p>Alternatively you can yield all sub-sections with the convenience call <code>all_sections</code>
75cc116 @lsegal Templates
authored
73 (in the following <a href="http://haml.hamptoncatlin.com">Haml</a> example, yield param 's'
74 contains the section name which would serve as the li's id attribute):</p>
90f9836 @lsegal Templates
authored
75
75cc116 @lsegal Templates
authored
76 <pre><code>%html&#x000A; %body&#x000A; %ol&#x000A; - all_sections do |s|&#x000A; %li{:id =&gt; s}= yield&#x000A;</code></pre>
53dc5ba @lsegal Templates
authored
77 </li>
1b071be @lsegal Templates
authored
78 <li id='#&lt;Tadpole::SectionProviders::FileProvider:0x5a7cd8&gt;'>
709f4c0 @lsegal Update templates
authored
79 <h2>What is Tadpole?</h2>
80
81 <p><strong>Tadpole</strong> is a small templating engine that attempts to solve a problem that
82 no other templating engine does: <em>extensibility</em>. When dealing with templates,
83 most engines focus on the formatting of the output content while forgetting about
84 the important task a developer faces of hooking all these 'views' together. While
85 it may seem trivial and worth ignoring, in reality, many templates become plagued
86 with complexity and coupling due to the lack of support beyond the mere presentation
87 of a single file.</p>
88
89 <p><strong>Tadpole</strong> deals not with the formatting or translation or markup, but rather
90 with the organization of the data as it is outputted. In fact, <strong>Tadpole</strong> is not
91 markup at all, nor does it care what markup you use, having out of the box support
030a16f @lsegal Templates
authored
92 for the obvious template languages in Ruby (ERB, <a href="http://www.haml.hamptoncatlin.com">Haml</a>,
93 <a href="http://code.whytheluckystiff.net/markaby">Markaby</a>, <a href="http://builder.rubyforge.org">Builder</a>)
94 and the ability to add more. <strong>Tadpole is all about information organization, not formatting</strong>.</p>
709f4c0 @lsegal Update templates
authored
95
030a16f @lsegal Templates
authored
96 <p>If you need a good visualization of what <strong>Tadpole</strong> is, think of it as <em>the table of</em>
97 <em>contents for your views</em>. Just as it is important to designing each view and partial of
709f4c0 @lsegal Update templates
authored
98 your template, it is important to decide in what order these views will ultimately be
99 organized. <strong>Tadpole</strong>'s job is to store nothing but your table of contents, and then
100 spit it out when you're ready to show it to the world. This technique becomes very
b89a21e @lsegal Templates
authored
101 powerful in some potentially familiar scenarios. (<em>See the "Real World Examples"</em>)</p>
273483c @lsegal Fix various template_paths issues
authored
102 </li>
1b071be @lsegal Templates
authored
103 <li id='#&lt;Tadpole::SectionProviders::FileProvider:0x5a747c&gt;'>
709f4c0 @lsegal Update templates
authored
104 <h2>Why Tadpole?</h2>
105
106 <p>Sufficed to say, you might be wondering what the <em>big deal</em> is. I mean, you're
107 probably getting along just fine without this new concept of tables of contents
108 ...<em>or so you think</em>. The truth is that there are a lot of real-world scenarios
109 where the old-style template production simply doesn't cut it. I can say this
110 because <strong>Tadpole</strong> was <a href="http://www.github.com/lsegal/yard">born from one of them</a>.</p>
111
112 <p>I'll be honest, <strong>Tadpole</strong> does not meet every use-case scenario, and it probably
113 never will. But if you're writing a <em>blog app</em>, <em>CMS</em>, customizable <em>forum software</em> or
114 anything that will eventually support <em>customizable templates</em> or <em>theming</em>,
115 <em><strong>Tadpole</strong> was made for you</em>. Even if you're just dealing with a lot of <em>template</em>
116 <em>coupling</em> or <em>internationalization code</em>, there's a good chance you're looking at the
117 right tool as well.</p>
118
119 <h3>Good With Customizable Themes, You Say?</h3>
120
121 <p>Anyone who writes customizable software knows that it requires a lot of de-coupled code.
122 While templates are sometimes considered support files rather than actual software, the
123 same law holds true for them. Coupled templates are bad for theming because your users
124 can't get at the data they want.</p>
125
126 <p>The standard solution to this problem is to split your templates up into many 'partials'.
127 That way, any user can just go into the right partial and easily edit what they need
128 without copying <em>all</em> of the template data, right? <strong>Wrong</strong>. The problem starts when a
129 user wants to start adding or removing partials altogether. In fact, it's actually the
130 smallest changes that cause the biggest problems. Everytime they add one line to every
131 new partial, they pull in another entire file. Once <em>you</em> update that file, the changes
132 no longer sync to the user. Fixed a typo in your template? Your user may never get the
133 memo if he pulled in the file you touched. However, because <strong>Tadpole</strong> never actually
134 deals with template <em>data</em>, the same setup in <strong>Tadpole</strong> would not be problematic.
135 Using <strong>Tadpole</strong>, the user would never even have to touch your templates given a good
136 set of insertion points.</p>
137
138 <p>The lesson is, when it comes to customization, there is no partial that is partial enough.
139 <strong>Tadpole</strong> inevitably suffers from this problem as well. However, once you start thinking
140 in terms of template organization you'll find that it's much harder to decide what part
141 of a view deserves a 'partial' than it is to simply split your template up into a series
142 of cohesive "<em>sections</em>".</p>
143 </li>
1b071be @lsegal Templates
authored
144 <li id='#&lt;Tadpole::SectionProviders::FileProvider:0x5a6e50&gt;'>
b89a21e @lsegal Templates
authored
145 <h2>Some <em>Theoretically</em>-Real-World Examples of Tadpole in Action</h2>
709f4c0 @lsegal Update templates
authored
146
147 <ol>
148 <li><p><em>Bob</em> made a Blogging application called <em>"Boblog"</em> and distributed it under the
149 MIT license over the internet. <em>Janet</em> found this application and decided to
150 use it to power her upcoming "100 Carrot Recipes" blog. She was mostly happy with
151 the provided themes but wanted to customize the look of the sidebar by adding a
152 "Favourite Recipes" links section and writing a tidbit about herself. Now "Boblog"
153 was a simplistic blog tool and did not support a multitude of plugins, but did use
154 <strong>Tadpole</strong> for theming. Janet read about the way customization was done using "Boblog"
155 and got to work making her changes. Janet went into her custom templates directory and
156 created her own new template <code>janet</code> because she had a bad feeling about directly playing
157 with the existing template files (<em>and "Boblog" docs said she didn't need to</em>). Inside
158 that directory she created her new files <code>fav_recipes.html</code> and <code>about.html</code> where she
159 inserted her links to various world renowned Carrot Chefs and a story about her dreams
160 of one day meeting them. Now, she wanted her about section to go at the top of the sidebar,
161 but she wanted her own links section to go beneath the regular links section (already
162 provided by "Boblog"). So, as per the docs, she continued to add a <code>setup.rb</code> file which
163 would connect her new files together with the template. In this file, she simply wrote:</p>
164
165 <pre><code>inherits 'default_theme'&#x000A;&#x000A;&#x000A;def init&#x000A; super&#x000A; sections.unshift 'about'&#x000A; sections.place('fav_recipes').before('links')&#x000A;end&#x000A;</code></pre>
166
167 <p>She then went into "Boblog"'s administration interface and selected the new <code>janet</code>
168 theme. Voila, her dream of tasty success would finally come true.</p>
169
b89a21e @lsegal Templates
authored
170 <p>Three days later, <em>Bob</em> got word from an anonymous tipster of a nasty bug in his software
171 that could potentially lead to harmful attacks if left unfixed. Guess what, that bug was
172 in the sidebar template that Janet was using! He quickly patched the bug and released a
173 fix, notifying all of his users of the changes (Janet was on his mailing list). Because
174 Janet never edited any of the files belonging to "Boblog", all she had to do was download
175 the patch and restart the application without ever having to remake all of her ever-so-
176 important theming changes to her blog.</p></li>
177 <li><p>Midget Inc. is working on a colourful new site redesign for their mobile widget business.
178 They sell mobile widgets to customers all across the globe and have very strict legal
179 procedures they need to follow when advertising their mobile widgets. In one specific
180 region, they are required by law to show a disclaimer above any advertising images they
181 display. Rather than place region specific logic inside a partial view, they decide to
182 use <strong>Tadpole</strong> to handle their templating system. They decide to use a folder structure
183 of the following to display their advertising page:</p>
184
185 <pre><code>advertising/&#x000A; setup.rb&#x000A; content.erb&#x000A; images.erb&#x000A; fr/&#x000A; setup.rb&#x000A; disclaimer.erb&#x000A;</code></pre>
186
187 <p><code>advertising/setup.rb</code> contains the following:</p>
188
189 <pre><code>def init; super; sections 'content', 'images' end&#x000A;</code></pre>
190
191 <p>The <code>fr/</code> subdirectory contains the specific content they need for the law-requiring region
192 and the logic to render this template only in that region is controlled by the controller.
193 Because the <code>fr/</code> template automatically inherits its sections from its parent, all they need
194 to do to set up this new logic is put the following in the <code>fr/setup.rb</code>:</p>
195
196 <pre><code>def init&#x000A; super&#x000A; sections.place('disclaimer').before('images')&#x000A;end&#x000A;</code></pre>
197
198 <p>And the templates can be rendered with:</p>
199
200 <pre><code>Tadpole('advertising').run&#x000A;Tadpole('advertising/fr').run&#x000A;</code></pre>
201
202 <p>Respectively.</p></li>
709f4c0 @lsegal Update templates
authored
203 </ol>
273483c @lsegal Fix various template_paths issues
authored
204 </li>
1b071be @lsegal Templates
authored
205 <li id='#&lt;Tadpole::SectionProviders::FileProvider:0x5a6860&gt;'>
206 <h2>You Should Also Know</h2>
207
208 <p>That this <code>README</code> was generated by <strong>Tadpole</strong>. Try it:</p>
209
210 <pre><code>ruby examples/example2/run.rb markdown/readme&#x000A;</code></pre>
211 </li>
212 <li id='#&lt;Tadpole::SectionProviders::FileProvider:0x5a6860&gt;'>
273483c @lsegal Fix various template_paths issues
authored
213 <h2>You Should Also Know</h2>
214
fea221a @lsegal Update readmes
authored
215 <p>That this <code>README</code> was generated by <strong>Tadpole</strong>. Try it:</p>
273483c @lsegal Fix various template_paths issues
authored
216
8064c8d @lsegal Stuff
authored
217 <pre><code>ruby examples/example2/run.rb markdown/readme&#x000A;</code></pre>
273483c @lsegal Fix various template_paths issues
authored
218 </li>
219 </ol>
220 </div>
221 <div id='copyright'>
26e28de @lsegal Update copyright info section
authored
222 <h2>Copyright &amp; Licensing Information</h2>
223
273483c @lsegal Fix various template_paths issues
authored
224 <p><em>Copyright 2008 Loren Segal.</em>
225 <em>All code licensed under the MIT License.</em></p>
226 </div>
227 </div>
228 </body>
229 </html>
Something went wrong with that request. Please try again.