<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Posts about Haml</title>
    <link>http://wiki.futuretoby.com/tag/haml</link>
    <language>en-us</language>
    <item>
      <title>Turbogears and ReML</title>
      <description>I followed the Turbogears 20 minute tutorial &lt;a href="http://docs.turbogears.org/1.0/Wiki20/Page1" mce_href="http://docs.turbogears.org/1.0/Wiki20/Page1"&gt;here&lt;/a&gt;. The first impressions of Turbogears are:&lt;br&gt;&lt;ol&gt;&lt;li&gt;It's a bit more verbose than rails: there's more plumbing - you have to explicitly define which view you want to use for each action, as supposed to doing everything based on convention.&lt;br&gt;&lt;/li&gt;&lt;li&gt;you explicitly pass the local variables to the view as a hash, as supposed to using class or global variables&lt;/li&gt;&lt;li&gt;Turbogears uses a template engine called kid by default, which is very different from rails' erb in philosophy, there's more emphesis on designer friendliness and higher level support for template inheritence&lt;/li&gt;&lt;li&gt;Python/Turbogears in general is safer than ruby/rails - &lt;a href="http://wiki.futuretoby.com/Ruby:%20Extremely%20Unsafe" mce_href="http://wiki.futuretoby.com/Ruby:%20Extremely%20Unsafe"&gt;see my last post&lt;/a&gt;, in that you usually get more informative errors, such as &lt;font color="#808080" face="courier new,courier"&gt;NameError: global name 'pag' is not defined&lt;/font&gt; rather than &lt;font color="#808080" face="courier new,courier"&gt;nil when you didn't expect it&lt;/font&gt;&lt;/li&gt;&lt;li&gt;The development feedback is not &lt;i&gt;quite &lt;/i&gt;as good as rails. Turbogears requires a restart everytime you make a change. The restart is automatically triggered everytime you save a file in the project, and it is very fast, but it still takes about 5 seconds to rails' 0(ruby has this luxury because of its open classes)&lt;br style=""&gt;&lt;/li&gt;&lt;/ol&gt;I am hip to Haml so I had to see if I could get it working with Turbogears. I found a couple of implementations: &lt;a href="http://reml.wikidot.com/documentation" mce_href="http://reml.wikidot.com/documentation"&gt;ReML&lt;/a&gt; and &lt;a href="http://lucumr.pocoo.org/cogitations/2008/02/15/ghrml-haml-for-genshi/" mce_href="http://lucumr.pocoo.org/cogitations/2008/02/15/ghrml-haml-for-genshi/"&gt;GHRML&lt;/a&gt;. Tried them both, ReML was simpler and more approachable, so I wrote a &lt;a href="http://docs.turbogears.org/1.0/TemplatePlugins" mce_href="http://docs.turbogears.org/1.0/TemplatePlugins"&gt;Turbogears plugin&lt;/a&gt; for it. The important bit of the plugin code is here:&lt;br&gt;&lt;br&gt;&lt;font color="#808080" face="courier new,courier"&gt;from reml import TemplateLoader&lt;/font&gt;&lt;font color="#808080"&gt;&lt;br&gt;&lt;br&gt;&lt;/font&gt;&lt;font color="#808080" face="courier new,courier"&gt;class RemlTg(object):&lt;br&gt;&amp;nbsp; &lt;br&gt;&amp;nbsp; def __init__(self, extra_vars_func=None, options=None):&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; pass&lt;br&gt;&lt;br&gt;&amp;nbsp; def load_template(self, templatename):&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Find a template specified in python 'dot' notation."&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; parts = templatename.split('.')&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return TemplateLoader('/'.join(parts[0:len(parts)-1])).load(parts[len(parts)-1] + '.reml')&lt;br&gt;&lt;br&gt;&amp;nbsp; def render(self, info, format="html", fragment=False, template=None):&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Renders the template to a string using the provided info."&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return self.load_template(template).render(info)&lt;/font&gt;&lt;br&gt;&lt;br&gt;After that, I converted the views in the tutorial into ReML. Let me do a wc on them for comparison, wait just a minute...&lt;br&gt;&lt;br&gt;&lt;font color="#808080" face="courier new,courier"&gt;$ wc wiki20/templates/*.kid&lt;br&gt;&amp;nbsp; 25&amp;nbsp;&amp;nbsp; 76 1068 wiki20/templates/edit.kid&lt;br&gt;&amp;nbsp; 71&amp;nbsp; 173 2802 wiki20/templates/master.kid&lt;br&gt;&amp;nbsp; 21&amp;nbsp;&amp;nbsp; 56&amp;nbsp; 773 wiki20/templates/page.kid&lt;br&gt;&amp;nbsp; 21&amp;nbsp;&amp;nbsp; 50&amp;nbsp; 705 wiki20/templates/pagelist.kid&lt;br&gt;&amp;nbsp;138&amp;nbsp; 355 5348 total&lt;br&gt;airport@wedding-singer ~/documents/play/turbogears/Wiki-20&lt;br&gt;$ wc wiki20/templates/*.reml&lt;br&gt;&amp;nbsp; 16&amp;nbsp;&amp;nbsp; 41&amp;nbsp; 492 wiki20/templates/edit.reml&lt;br&gt;&amp;nbsp; 38&amp;nbsp;&amp;nbsp; 86 1338 wiki20/templates/master.reml&lt;br&gt;&amp;nbsp; 12&amp;nbsp;&amp;nbsp; 30&amp;nbsp; 327 wiki20/templates/page.reml&lt;br&gt;&amp;nbsp;&amp;nbsp; 8&amp;nbsp;&amp;nbsp; 24&amp;nbsp; 190 wiki20/templates/pagelist.reml&lt;br&gt;&amp;nbsp; 74&amp;nbsp; 181 2347 total&lt;/font&gt;&lt;br&gt;&lt;br&gt;So that's about a 50% code reduction, not bad. Here's a Sample for comparison:&lt;br&gt;&lt;br&gt;&lt;b&gt;page.kid:&lt;/b&gt;&lt;br&gt;&lt;font color="#808080" face="courier new,courier"&gt;&amp;lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&amp;gt;&lt;br&gt;&amp;lt;html xmlns="http://www.w3.org/1999/xhtml"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; xmlns:py="http://purl.org/kid/ns#"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; py:extends="'master.kid'"&amp;gt;&lt;br&gt;&amp;lt;head&amp;gt;&lt;br&gt;&amp;lt;title&amp;gt; ${page.pagename} - 20 Minute Wiki &amp;lt;/title&amp;gt;&lt;br&gt;&amp;lt;/head&amp;gt;&lt;br&gt;&amp;lt;body&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;div class="main_content"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;div style="float:right; width: 10em"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Viewing &amp;lt;span py:replace="page.pagename"&amp;gt;Page Name Goes Here&amp;lt;/span&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;br/&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; You can return to the &amp;lt;a href="/"&amp;gt;FrontPage&amp;lt;/a&amp;gt;.&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/div&amp;gt;&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;div py:replace="XML(data)"&amp;gt;Page text goes here.&amp;lt;/div&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;p&amp;gt;&amp;lt;a href="${tg.url('/edit', pagename=page.pagename)}"&amp;gt;Edit this page&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/div&amp;gt;&lt;br&gt;&amp;lt;/body&amp;gt;&lt;br&gt;&amp;lt;/html&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;page.reml&lt;/b&gt;&lt;br&gt;&lt;font face="courier new,courier"&gt;&lt;font color="#808080"&gt;- append('master.reml')&lt;br&gt;- def title():&lt;br&gt;&amp;nbsp; =page.pagename&lt;br&gt;- def content():&lt;br&gt;&amp;nbsp; %div: 'style':'float:right; width: 10em'&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Viewing&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; %span=page.pagename&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; You can return to the&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; %a: 'href':tg.url('/')&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Frontpage&lt;br&gt;&amp;nbsp; %div=unescaped(data)&lt;br&gt;&amp;nbsp; %a: 'href':tg.url('/edit', pagename=page.pagename)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Edit this page&lt;br&gt;&lt;br&gt;&lt;/font&gt;&lt;br&gt;&lt;/font&gt;</description>
      <pubDate>Thu, 20 Mar 2008 10:10:00 -0500</pubDate>
      <guid>http://wiki.futuretoby.com/Turbogears_and_ReML</guid>
      <author>toby ho</author>
      <link>http://wiki.futuretoby.com/Turbogears_and_ReML</link>
    </item>
  </channel>
</rss>

