<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Taming Hobo with Tyler Lesmann</title>
    <link>http://hobo.tylerlesmann.com/</link>
    <description>Newest entries</description>
    <language>en-us</language>
    <item>
      <title>Headers and Footers in Hobo</title>
      <description>&lt;p&gt;It&amp;#8217;s really easy to override the header and footer in hobo. There are two ways to do this. I use both in &lt;a href="http://github.com/auranet/aura-site/"&gt;aura-site&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;First, look at the pages definition in &lt;a href="http://github.com/tablatom/hobo/blob/767f10665aea70b8fa2f7542c363e809ad255736/hobo/taglibs/rapid_pages.dryml#L14-52"&gt;rapid_pages.dryml&lt;/a&gt;. Everything with a param attribute can be redefined.&lt;/p&gt;

&lt;p&gt;Note the &lt;a href="http://github.com/tablatom/hobo/blob/767f10665aea70b8fa2f7542c363e809ad255736/hobo/taglibs/rapid_pages.dryml#L4"&gt;main-nav&lt;/a&gt; element. By default, Hobo will magically generate a menu for you, based on your project. On aura-site, we override this in &lt;a href="http://github.com/auranet/aura-site/blob/525e8d7c7582b3b4cfe30116b6b6349a17101273/app/views/taglibs/application.dryml#L17-52"&gt;application.dryml&lt;/a&gt; to build our menus the way the admin wants.&lt;/p&gt;

&lt;p&gt;Now you can also redefine the page as a whole. We do this in the &lt;a href="http://github.com/auranet/aura-site/blob/525e8d7c7582b3b4cfe3/app/views/taglibs/themes/aura/aura.dryml#L1-23"&gt;aura theme&lt;/a&gt; to add a bit of css and javascript to the head of the html.&lt;/p&gt;

&lt;p&gt;The easiest way to make a header or footer is to use this second method. Just use a &lt;code&gt;&amp;lt;header:&amp;gt;&lt;/code&gt; to replace the header or &lt;code&gt;&amp;lt;append-header:&amp;gt;&lt;/code&gt; to add to the end of it. Same deal with footer, just use the &lt;code&gt;&amp;lt;footer:&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;append-footer:&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;prepend-footer:&amp;gt;&lt;/code&gt;.&lt;/p&gt;</description>
      <author>Tyler Lesmann</author>
      <link>http://hobo.tylerlesmann.com/entries/8</link>
      <guid>http://hobo.tylerlesmann.com/entries/8</guid>
    </item>
    <item>
      <title>Make a Blog with Hobo:  Theming</title>
      <description>&lt;p&gt;It took me awhile to figure out how Hobo&amp;#8217;s theming engine works. It&amp;#8217;s not hard to create and use a new theme if you know the caveats.&lt;/p&gt;

&lt;p&gt;We&amp;#8217;ll start by using hobo&amp;#8217;s default theme, clean, as a template. Go into &lt;em&gt;RAILS_ROOT/app/views/taglibs/themes&lt;/em&gt;. You will see a directory called &lt;em&gt;clean&lt;/em&gt;. Inside this directory is a single file called &lt;em&gt;clean.dryml&lt;/em&gt;. You&amp;#8217;ll want to pick a name for your theme. For this example, my new theme will be called &lt;em&gt;red&lt;/em&gt;. Create a new directory called &lt;em&gt;red&lt;/em&gt; and copy &lt;em&gt;clean/clean.dryml&lt;/em&gt; to &lt;em&gt;red/red.dryml&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;We do not need to make changes to &lt;em&gt;red.dryml&lt;/em&gt; for it to work properly. This file is where you will define &lt;em&gt;tags&lt;/em&gt;, &lt;em&gt;cards&lt;/em&gt;, and &lt;em&gt;forms&lt;/em&gt; specific to your theme. If you need to pull in some more &lt;a href="http://github.com/auranet/aura-site/blob/c82c32bee7a2957199368eb0705a2c786684f52a/app/views/taglibs/themes/aura/aura.dryml"&gt;javascript and css&lt;/a&gt;, this would be the place to do it.&lt;/p&gt;

&lt;p&gt;Next, we need go to &lt;em&gt;RAILS_ROOT/public/hobothemes&lt;/em&gt;. Again you will see a &lt;em&gt;clean&lt;/em&gt; directory. Copy this directory to a new one, &lt;em&gt;red&lt;/em&gt;. Go to &lt;em&gt;stylesheets&lt;/em&gt; within the &lt;em&gt;red&lt;/em&gt; directory. Rename &lt;em&gt;clean.css&lt;/em&gt; to &lt;em&gt;red.css&lt;/em&gt;. Now we have the media assets for our new theme all set up. So how do we use this new theme?&lt;/p&gt;

&lt;p&gt;Open &lt;em&gt;RAILS_ROOT/app/views/taglibs/application.dryml&lt;/em&gt;. You&amp;#8217;ll see a tag early on called &lt;em&gt;set-theme&lt;/em&gt;. Just change that to point to &lt;em&gt;red&lt;/em&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code class="xml"&gt;&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;set-theme&lt;/span&gt; &lt;span class="attribute"&gt;name&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;red&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;/&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you are running your server, then restart now. Hobo will not load the new theme correctly otherwise. Now your blog its own theme!&lt;/p&gt;</description>
      <author>Tyler Lesmann</author>
      <link>http://hobo.tylerlesmann.com/entries/7</link>
      <guid>http://hobo.tylerlesmann.com/entries/7</guid>
    </item>
    <item>
      <title>Make a Blog with Hobo: Lifecycles</title>
      <description>&lt;p&gt;Sometimes we may want to not publish our blog entries to the world. They might need a little work, which we plan on doing later. So our entries need two states: &lt;em&gt;published&lt;/em&gt; and &lt;em&gt;drafted&lt;/em&gt;. Hobo&amp;#8217;s lifecycles make this not too much of a chore.&lt;/p&gt;

&lt;p&gt;First, let&amp;#8217;s open &lt;em&gt;app/models/entry.rb&lt;/em&gt; and define our lifecycle. These lines can go right after where we&amp;#8217;ve defined our relations.&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="ident"&gt;lifecycle&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
  &lt;span class="ident"&gt;state&lt;/span&gt; &lt;span class="symbol"&gt;:drafted&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:default&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;
  &lt;span class="ident"&gt;state&lt;/span&gt; &lt;span class="symbol"&gt;:published&lt;/span&gt;

  &lt;span class="ident"&gt;transition&lt;/span&gt; &lt;span class="symbol"&gt;:publish&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt;&lt;span class="symbol"&gt;:drafted&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="symbol"&gt;:published&lt;/span&gt;&lt;span class="punct"&gt;},&lt;/span&gt; &lt;span class="symbol"&gt;:available_to&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="symbol"&gt;:user&lt;/span&gt;
  &lt;span class="ident"&gt;transition&lt;/span&gt; &lt;span class="symbol"&gt;:unpublish&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt;&lt;span class="symbol"&gt;:published&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="symbol"&gt;:drafted&lt;/span&gt;&lt;span class="punct"&gt;},&lt;/span&gt; &lt;span class="symbol"&gt;:available_to&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="symbol"&gt;:user&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We&amp;#8217;ve defined our two states. Our entries will default to the &lt;em&gt;drafted&lt;/em&gt; state. There are also two transitions. Transitions define how our entry can change states. A entry can become &lt;em&gt;drafted&lt;/em&gt; only when it is in the &lt;em&gt;published&lt;/em&gt; state. The opposite is also true. Only the user, or author in this case, can change states. Now let&amp;#8217;s migrate!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ script/generate hobo_migration&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;States are now engaged, but we cannot change between them. We need to add some buttons. Hobo provides the extremely helpful &lt;em&gt;&lt;code&gt;&amp;lt;transition-buttons/&amp;gt;&lt;/code&gt;&lt;/em&gt; tag to accomplish this. Open &lt;em&gt;app/views/taglibs/application.dryml&lt;/em&gt; and add this tag to our &lt;em&gt;entry-info&lt;/em&gt; tag like so.&lt;/p&gt;

&lt;pre&gt;&lt;code class="xml"&gt;&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;def&lt;/span&gt; &lt;span class="attribute"&gt;tag&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;entry-info&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;div&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
    Posted on &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="namespace"&gt;view&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;&lt;span class="tag"&gt;created-at&lt;/span&gt;&lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;div&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;div&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
    Tags: &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="namespace"&gt;view&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;&lt;span class="tag"&gt;tags&lt;/span&gt;&lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;div&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;transition-buttons&lt;/span&gt;&lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;def&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You now have Publish and Unpublish buttons. The assortment of buttons depends on the transitions available to your current user. So we have our states and we can change between them. Now we just need to do something with those states. Let&amp;#8217;s change the view permissions in &lt;em&gt;app/models/entry.rb&lt;/em&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;view_permitted?&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;field&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="ident"&gt;acting_user&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;administrator?&lt;/span&gt; &lt;span class="keyword"&gt;or&lt;/span&gt; &lt;span class="ident"&gt;state&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="punct"&gt;&amp;#39;&lt;/span&gt;&lt;span class="string"&gt;published&lt;/span&gt;&lt;span class="punct"&gt;&amp;#39;&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now an entry is viewable if the user is an adminstrator or if the entry is in a &lt;em&gt;published&lt;/em&gt; state.&lt;/p&gt;</description>
      <author>Tyler Lesmann</author>
      <link>http://hobo.tylerlesmann.com/entries/6</link>
      <guid>http://hobo.tylerlesmann.com/entries/6</guid>
    </item>
    <item>
      <title>Make a Blog with Hobo:  Commenting</title>
      <description>&lt;p&gt;It would be nice to allow our readers to leave a little feedback, so in this edition we&amp;#8217;ll do just that. This should give you insight into how Hobo can present one-to-many relationships. Create a very simple model with the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ script/generate hobo_model_resource comment body:text&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Nothing you haven&amp;#8217;t seen. Open &lt;em&gt;app/models/comment.rb&lt;/em&gt; and alter it to be like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Comment&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ActiveRecord&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Base&lt;/span&gt;

  &lt;span class="ident"&gt;hobo_model&lt;/span&gt; &lt;span class="comment"&gt;# Don&amp;#39;t put anything above this&lt;/span&gt;

  &lt;span class="ident"&gt;fields&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
    &lt;span class="ident"&gt;body&lt;/span&gt; &lt;span class="symbol"&gt;:text&lt;/span&gt;
    &lt;span class="ident"&gt;timestamps&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="ident"&gt;belongs_to&lt;/span&gt; &lt;span class="symbol"&gt;:user&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:creator&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;
  &lt;span class="ident"&gt;belongs_to&lt;/span&gt; &lt;span class="symbol"&gt;:entry&lt;/span&gt;

  &lt;span class="comment"&gt;# --- Permissions --- #&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;create_permitted?&lt;/span&gt;
    &lt;span class="ident"&gt;acting_user&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;signed_up?&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;update_permitted?&lt;/span&gt;
    &lt;span class="ident"&gt;acting_user&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;administrator?&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;destroy_permitted?&lt;/span&gt;
    &lt;span class="ident"&gt;acting_user&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;administrator?&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;view_permitted?&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;field&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="constant"&gt;true&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A few changes to note here. We&amp;#8217;ve added two relations, one to the &lt;em&gt;User&lt;/em&gt; model and another to the &lt;em&gt;Entry&lt;/em&gt; model. The &lt;em&gt;:creator&lt;/em&gt; flag automatically sets the user if one is not given. You should also note the change to the permissions. Any user that has signed up will be able to create new comments. Let&amp;#8217;s add the relations to the &lt;em&gt;Entry&lt;/em&gt; model. Put these lines after the fields in &lt;em&gt;app/models/entry.rb&lt;/em&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="ident"&gt;belongs_to&lt;/span&gt; &lt;span class="symbol"&gt;:user&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:creator&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;
&lt;span class="ident"&gt;has_many&lt;/span&gt; &lt;span class="symbol"&gt;:comments&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:dependent&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="symbol"&gt;:destroy&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The relation to comments has been made and now each entry will have an author. Now for the User model. Add these lines to &lt;em&gt;app/models/user.rb&lt;/em&gt; after the fields:&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="ident"&gt;has_many&lt;/span&gt; &lt;span class="symbol"&gt;:entries&lt;/span&gt;
&lt;span class="ident"&gt;has_many&lt;/span&gt; &lt;span class="symbol"&gt;:comments&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Go ahead and run a &lt;em&gt;hobo_migration&lt;/em&gt; to apply the changes to the database.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ script/generate hobo_migration&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you take a look at the blog now, you&amp;#8217;ll find a very awkward setup. Comments can only be created from the Comments tab. Comments aren&amp;#8217;t connected to entries in an obvious way. Let&amp;#8217;s change that. First, open up &lt;em&gt;app/viewhints/entry_hints.rb&lt;/em&gt; and add this before the final &lt;em&gt;end&lt;/em&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="ident"&gt;children&lt;/span&gt; &lt;span class="symbol"&gt;:comments&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Comments related to an entry are now shown on the entry&amp;#8217;s show page. Let&amp;#8217;s make it so users can add comments from there as well. Open &lt;em&gt;app/controllers/comments_controller.rb&lt;/em&gt; and change it to be like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;CommentsController&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ApplicationController&lt;/span&gt;

  &lt;span class="ident"&gt;hobo_model_controller&lt;/span&gt;

  &lt;span class="ident"&gt;auto_actions&lt;/span&gt; &lt;span class="symbol"&gt;:destroy&lt;/span&gt;
  &lt;span class="ident"&gt;auto_actions_for&lt;/span&gt; &lt;span class="symbol"&gt;:entry&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:create&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;

&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;em&gt;auto_actions&lt;/em&gt; are now limited to destroy, which will allow the administrators to easily remove comments. The &lt;em&gt;auto_actions_for&lt;/em&gt; is very convenient. That one line allows users to make comments from the show page of an entry. Take a look. One problem you should notice is that the user relation is accessible. Users would be able to leave comments as anyone on the site. That&amp;#8217;s no good. Open &lt;em&gt;app/views/taglibs/application.dryml&lt;/em&gt; and append this to the end of it:&lt;/p&gt;

&lt;pre&gt;&lt;code class="xml"&gt;&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;extend&lt;/span&gt; &lt;span class="attribute"&gt;tag&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;card&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;for&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Comment&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;old-card&lt;/span&gt; &lt;span class="attribute"&gt;merge&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;body:&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;div&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
        On &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="namespace"&gt;view&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;&lt;span class="tag"&gt;created_at&lt;/span&gt;&lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;, &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="namespace"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;&lt;span class="tag"&gt;user&lt;/span&gt;&lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt; said:
      &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;div&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="namespace"&gt;view&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;&lt;span class="tag"&gt;body&lt;/span&gt;&lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;body:&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;old-card&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;extend&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;extend&lt;/span&gt; &lt;span class="attribute"&gt;tag&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;form&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;for&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Comment&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;old-form&lt;/span&gt; &lt;span class="attribute"&gt;merge&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;field-list:&lt;/span&gt; &lt;span class="attribute"&gt;fields&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;body&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;without-body-label&lt;/span&gt;&lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;old-form&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;extend&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We&amp;#8217;ve made a prettier card for comments and the form has been trimmed to only display a field for body. Of course, that&amp;#8217;s not enough to stop users from spoofing comments. Open &lt;em&gt;app/controllers/comments_controller.rb&lt;/em&gt; and add this before the final &lt;em&gt;end&lt;/em&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;create_for_entry&lt;/span&gt;
  &lt;span class="comment"&gt;# Remove user spoofing&lt;/span&gt;
  &lt;span class="comment"&gt;# Hobo should make this easier&lt;/span&gt;
  &lt;span class="ident"&gt;params&lt;/span&gt;&lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;comment&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;].&lt;/span&gt;&lt;span class="ident"&gt;delete&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;user_id&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt;
  &lt;span class="ident"&gt;hobo_create&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Yep. Hobo allows you customize how controllers on related pages work. All that we&amp;#8217;ve done is removed &lt;em&gt;user_id&lt;/em&gt; from the &lt;em&gt;params&lt;/em&gt;. Hobo will instead relate the comment to the creator as we defined earlier. You might consider doing something similar to this for entries as well. Since comments are related to users and entries are now related to users, let&amp;#8217;s make the user show page more interesting. Create a new file at &lt;em&gt;app/viewhints/user_hints.rb&lt;/em&gt; and add this content:&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;UserHints&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;Hobo&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;ViewHints&lt;/span&gt;
  &lt;span class="ident"&gt;children&lt;/span&gt; &lt;span class="symbol"&gt;:entries&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:comments&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The user show page now features entries and comments authored by the user. Your extra credit on this lesson is to make the card for Entry more presentable.&lt;/p&gt;</description>
      <author>Tyler Lesmann</author>
      <link>http://hobo.tylerlesmann.com/entries/5</link>
      <guid>http://hobo.tylerlesmann.com/entries/5</guid>
    </item>
    <item>
      <title>Make a Blog with Hobo: Tagging</title>
      <description>&lt;p&gt;In this episode, we&amp;#8217;ll add tagging support to our blog. Features of this lesson will be applicable to any many-to-many relationship in Hobo. Before I go any further, at the time of this writing, Hobo does not support &lt;em&gt;has_and_belongs_to_many :models&lt;/em&gt;. A many-to-many relationship will only be blessed with the Hobo magic when implemented using &lt;em&gt;has_many :models, :through =&amp;gt; :join_model&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;We need two tables, one for tags and a join table. We create these with the following commands:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ script/generate hobo_model_resource tag name:string
$ script/generate hobo_model tag_assignment&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Only thing you haven&amp;#8217;t seen before is the &lt;em&gt;hobo_model&lt;/em&gt;. It&amp;#8217;s like &lt;em&gt;hobo_model_resource&lt;/em&gt; less the controllers, which a join table doesn&amp;#8217;t need. Let&amp;#8217;s add the relationship code to the models. Add these lines to their indicated files before the &lt;em&gt;# &amp;#8212; Permissions &amp;#8212; #&lt;/em&gt; line.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;app/models/entry.rb&lt;/em&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="ident"&gt;has_many&lt;/span&gt; &lt;span class="symbol"&gt;:tags&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:through&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="symbol"&gt;:tag_assignments&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:accessible&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;
&lt;span class="ident"&gt;has_many&lt;/span&gt; &lt;span class="symbol"&gt;:tag_assignments&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:dependent&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="symbol"&gt;:destroy&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;app/models/tag.rb&lt;/em&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="comment"&gt;# Let&amp;#39;s change the ordering while we&amp;#39;re in here.  It defaults to created_at.&lt;/span&gt;
&lt;span class="comment"&gt;# This will affect how cards are ordered as well as when tags are viewed as&lt;/span&gt;
&lt;span class="comment"&gt;# a whole.&lt;/span&gt;
&lt;span class="ident"&gt;set_default_order&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;name&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; 

&lt;span class="ident"&gt;has_many&lt;/span&gt; &lt;span class="symbol"&gt;:entries&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:through&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="symbol"&gt;:tag_assignments&lt;/span&gt;
&lt;span class="ident"&gt;has_many&lt;/span&gt; &lt;span class="symbol"&gt;:tag_assignments&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:dependent&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="symbol"&gt;:destroy&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;app/models/tag_assignment.rb&lt;/em&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="ident"&gt;belongs_to&lt;/span&gt; &lt;span class="symbol"&gt;:entry&lt;/span&gt;
&lt;span class="ident"&gt;belongs_to&lt;/span&gt; &lt;span class="symbol"&gt;:tag&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Most of this is pure rails, except for the &lt;em&gt;:accessible&lt;/em&gt;. This tells Hobo to build tag assignment into the form for Entry. Whenever a user accesses a tag&amp;#8217;s show page, Hobo will display any child objects the coder describes. To describe children, we edit the viewhints, which in this case is &lt;em&gt;app/viewhints/tag_hints.rb&lt;/em&gt;. Add this line:&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="ident"&gt;children&lt;/span&gt; &lt;span class="symbol"&gt;:entries&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Time to apply the changes to the database!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ script/generate hobo_migration&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that if you&amp;#8217;ve been following along to this tutorial, you will need to add &lt;em&gt;tags&lt;/em&gt; to the &lt;em&gt;fields&lt;/em&gt; of &lt;em&gt;field-list&lt;/em&gt; for the Entry form, if you want to see how regular many-to-many relationships work in Hobo. You&amp;#8217;ll remember that the form is described in &lt;em&gt;app/views/taglibs/application.dryml&lt;/em&gt;. The way Hobo does these relationships is clumsy as you&amp;#8217;ll see, for tagging anyway. It would be better for the blogger to just enter a bunch of words and phrases separated by commas. Let&amp;#8217;s make it work that way. Add the following line to the list of fields in &lt;em&gt;app/models/entry.rb&lt;/em&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="ident"&gt;tagstring&lt;/span&gt;     &lt;span class="symbol"&gt;:string&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will hold the input string for the user. Now there are a few ways to handle the actual assignment of the tags to the blog entry. We could implement it like we did markdown formatting for posts earlier. Since I haven&amp;#8217;t shown how to go outside the box in controllers yet, we&amp;#8217;ll do it that way. Open &lt;em&gt;app/controllers/entries_controller.rb&lt;/em&gt; and add the following lines before the last &lt;em&gt;end&lt;/em&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;assign_tags&lt;/span&gt;
  &lt;span class="ident"&gt;params&lt;/span&gt;&lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;entry&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;][&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;tags&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;]&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;params&lt;/span&gt;&lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;entry&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;][&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;tagstring&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;].&lt;/span&gt;&lt;span class="ident"&gt;split&lt;/span&gt;&lt;span class="punct"&gt;(&amp;#39;&lt;/span&gt;&lt;span class="string"&gt;,&lt;/span&gt;&lt;span class="punct"&gt;&amp;#39;).&lt;/span&gt;&lt;span class="ident"&gt;collect&lt;/span&gt;&lt;span class="punct"&gt;{&lt;/span&gt;
    &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;tag&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;#39;&lt;/span&gt;&lt;span class="string"&gt;@&lt;/span&gt;&lt;span class="punct"&gt;&amp;#39;&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="constant"&gt;Tag&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;find_or_create_by_name&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;tag&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;strip&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_s&lt;/span&gt;
  &lt;span class="punct"&gt;}&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;create&lt;/span&gt;
  &lt;span class="ident"&gt;assign_tags&lt;/span&gt;
  &lt;span class="ident"&gt;hobo_create&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;update&lt;/span&gt;
  &lt;span class="ident"&gt;assign_tags&lt;/span&gt;
  &lt;span class="ident"&gt;hobo_update&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The meat of the changes is in the &lt;em&gt;assign_tags&lt;/em&gt; method. Here we take the &lt;em&gt;tagstring&lt;/em&gt; field and split it by commas. Then, we create or get a Tag instance for each tag, pull the id, and add &lt;em&gt;@&lt;/em&gt; to the front of the id. All of these ids are put into the &lt;em&gt;tags&lt;/em&gt; param where Hobo will look at them later. We add two other methods: &lt;em&gt;create&lt;/em&gt; and &lt;em&gt;update&lt;/em&gt;. These will override the default Hobo/rails actions. We first call &lt;em&gt;assign_tags&lt;/em&gt; to parse the tags. After this we use &lt;em&gt;hobo_create&lt;/em&gt; or &lt;em&gt;hobo_update&lt;/em&gt;, which invokes the usual Hobo handling.&lt;/p&gt;

&lt;p&gt;Make sure you have the &lt;em&gt;tagstring&lt;/em&gt; in the &lt;em&gt;fields&lt;/em&gt; of the Entry form and apply the changes to the database.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ script/generate hobo_migration&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Look at that! Easy tagging! One last thing. Let&amp;#8217;s make the tags a bit more visible by having them appear on the show page and card for Entry. Since we will need the same code in both places, we will make a new DRYML tag. In &lt;em&gt;app/views/taglibs/application.dryml&lt;/em&gt;, remove the existing &lt;em&gt;&lt;code&gt;&amp;lt;extend tag=&amp;quot;card&amp;quot; for=&amp;quot;Entry&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/em&gt; and add this:&lt;/p&gt;

&lt;pre&gt;&lt;code class="xml"&gt;&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;extend&lt;/span&gt; &lt;span class="attribute"&gt;tag&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;card&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;for&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Entry&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;old-card&lt;/span&gt; &lt;span class="attribute"&gt;merge&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;prepend-body:&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;entry-info&lt;/span&gt;&lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;prepend-body:&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;old-card&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;extend&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;def&lt;/span&gt; &lt;span class="attribute"&gt;tag&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;entry-info&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;div&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
    Posted on &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="namespace"&gt;view&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;&lt;span class="tag"&gt;created-at&lt;/span&gt;&lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;div&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;div&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
    Tags: &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="namespace"&gt;view&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;&lt;span class="tag"&gt;tags&lt;/span&gt;&lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;div&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;def&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Alter &lt;em&gt;app/views/entries/show.dryml&lt;/em&gt; to be like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class="xml"&gt;&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;show-page&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;append-content-header:&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;entry-info&lt;/span&gt;&lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;append-content-header:&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;field-list:&lt;/span&gt; &lt;span class="attribute"&gt;replace&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="namespace"&gt;view&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;&lt;span class="tag"&gt;body_html&lt;/span&gt;&lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;field-list:&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;show-page&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In DRYML, tags are includes with a bit of extra magic. For instance, in this &lt;em&gt;entry-info&lt;/em&gt; tag, we are using &lt;em&gt;&lt;code&gt;&amp;lt;view:created-at/&amp;gt;&lt;/code&gt;&lt;/em&gt; and &lt;em&gt;&lt;code&gt;&amp;lt;view:tags/&amp;gt;&lt;/code&gt;&lt;/em&gt;. Hobo knows how to handle these depending on the context. If used out of context, Hobo gracefully outputs &lt;em&gt;Not Available&lt;/em&gt;. To use a tag, we simply use it by name, like &lt;em&gt;&lt;code&gt;&amp;lt;entry-info/&amp;gt;&lt;/code&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Take a look at the results. Hobo made the entry&amp;#8217;s tags each link to the tag&amp;#8217;s show page. The tags are more visible and users can easily navigate to similarly tagged blog posts.&lt;/p&gt;</description>
      <author>Tyler Lesmann</author>
      <link>http://hobo.tylerlesmann.com/entries/4</link>
      <guid>http://hobo.tylerlesmann.com/entries/4</guid>
    </item>
    <item>
      <title>Make a Blog with Hobo: Customizing Cards, Forms, and Pages</title>
      <description>&lt;p&gt;In this part of the tutorial, we&amp;#8217;ll make it so the interface and presentation of the blog are not so clumsy.&lt;/p&gt;

&lt;p&gt;First thing to do is remove the &lt;em&gt;body_html&lt;/em&gt; field from the Entry form. Open &lt;em&gt;app/views/taglibs/application.dryml&lt;/em&gt; and add the following:&lt;/p&gt;

&lt;pre&gt;&lt;code class="xml"&gt;&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;extend&lt;/span&gt; &lt;span class="attribute"&gt;tag&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;form&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;for&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Entry&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;old-form&lt;/span&gt; &lt;span class="attribute"&gt;merge&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;field-list:&lt;/span&gt; &lt;span class="attribute"&gt;fields&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;name, body_markdown&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;/&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;old-form&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;extend&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;DRYML is powerful, but very complex. It takes a bit of time to understand it. The part that makes the changes is the &lt;em&gt;&lt;code&gt;&amp;lt;field-list: fields=&amp;quot;name, body_markdown&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/em&gt;. The &lt;em&gt;&lt;code&gt;&amp;lt;old-form merge&amp;gt;&lt;/code&gt;&lt;/em&gt; tells Hobo to only merge the changes I describe into the existing form. So how do I know what the existing form looks like? It took me a while to figure this out because it isn&amp;#8217;t in Hobo&amp;#8217;s documentation at the time of this post. If you look near the top of &lt;em&gt;app/views/taglibs/application.dryml&lt;/em&gt;, you&amp;#8217;ll see these lines:&lt;/p&gt;

&lt;pre&gt;&lt;code class="xml"&gt;&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;include&lt;/span&gt; &lt;span class="attribute"&gt;src&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;taglibs/auto/rapid/cards&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;/&amp;gt;&lt;/span&gt;
&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;include&lt;/span&gt; &lt;span class="attribute"&gt;src&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;taglibs/auto/rapid/pages&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;/&amp;gt;&lt;/span&gt;
&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;include&lt;/span&gt; &lt;span class="attribute"&gt;src&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;taglibs/auto/rapid/forms&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;/&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Every time the server is booted, Hobo automatically creates three files for us, based on our model and controller. These are located in &lt;em&gt;app/views/taglibs/auto/rapid/&lt;/em&gt;. If you open up the &lt;em&gt;forms.dryml&lt;/em&gt; in this directory, then you&amp;#8217;ll see the form automatically created for Entry. It looks something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class="xml"&gt;&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;def&lt;/span&gt; &lt;span class="attribute"&gt;tag&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;form&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;for&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Entry&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;form&lt;/span&gt; &lt;span class="attribute"&gt;merge&lt;/span&gt; &lt;span class="attribute"&gt;param&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;default&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&amp;gt;&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;error-messages&lt;/span&gt; &lt;span class="attribute"&gt;param&lt;/span&gt;&lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;field-list&lt;/span&gt; &lt;span class="attribute"&gt;fields&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;name, body_markdown, body_html&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;param&lt;/span&gt;&lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;div&lt;/span&gt; &lt;span class="attribute"&gt;param&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;actions&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;submit&lt;/span&gt; &lt;span class="attribute"&gt;label&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;#{ht &amp;#39;entries.actions.save&amp;#39;, :default=&amp;gt;[&amp;#39;Save&amp;#39;]}&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;param&lt;/span&gt;&lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;or-cancel&lt;/span&gt; &lt;span class="attribute"&gt;param&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;cancel&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;/&amp;gt;&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;div&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;form&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;def&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Notice the &lt;em&gt;&lt;code&gt;&amp;lt;field-list&amp;gt;&lt;/code&gt;&lt;/em&gt;? Any element with a &lt;em&gt;param&lt;/em&gt; attribute can be accessed later by appending a colon to the tag name, like we did with &lt;em&gt;field-list:&lt;/em&gt;. Pretty slick, right? Let&amp;#8217;s add some helpful text to the form for those who don&amp;#8217;t know markdown by heart. Let&amp;#8217;s also change the label of the &lt;em&gt;name&lt;/em&gt; field to be &lt;em&gt;Title&lt;/em&gt; and &lt;em&gt;body_markdown&lt;/em&gt; to be &lt;em&gt;Body&lt;/em&gt;. We do this in a file called &lt;em&gt;app/viewhints/entry_hints.rb&lt;/em&gt;. Make the file resemble this:&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;EntryHints&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;Hobo&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;ViewHints&lt;/span&gt;
  &lt;span class="ident"&gt;field_names&lt;/span&gt; &lt;span class="symbol"&gt;:name&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Title&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:body_markdown&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Body&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="ident"&gt;field_help&lt;/span&gt;  &lt;span class="symbol"&gt;:body_markdown&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;#39;&lt;/span&gt;&lt;span class="string"&gt;
    Supports markdown formatting&amp;lt;br/&amp;gt;
    *emphasized* = &amp;lt;em&amp;gt;emphasized&amp;lt;/em&amp;gt;&amp;lt;br /&amp;gt;
    **strong** = &amp;lt;strong&amp;gt;strong&amp;lt;/strong&amp;gt;&amp;lt;br /&amp;gt;
    [Developer&lt;span class="escape"&gt;\&amp;#39;&lt;/span&gt;s Blog](http://hobo.tylerlesmann.com/) =
    &amp;lt;a href=&amp;quot;http://hobo.tylerlesmann.com/&amp;quot;&amp;gt;Developer&lt;span class="escape"&gt;\&amp;#39;&lt;/span&gt;s Blog&amp;lt;/a&amp;gt;&amp;lt;br /&amp;gt;
    Go &amp;lt;a href=&amp;quot;http://daringfireball.net/projects/markdown/syntax&amp;quot;&amp;gt;here&amp;lt;/a&amp;gt;
    for more information.&lt;/span&gt;&lt;span class="punct"&gt;&amp;#39;&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Pretty easy when you know where to put it. Let&amp;#8217;s alter how our posts are displayed in a list. The abbreviated version of any model instance, like an Entry, is known as a &lt;em&gt;card&lt;/em&gt; in Hobo. Let&amp;#8217;s have the card for Entry display the &lt;em&gt;created_at&lt;/em&gt; date. Open up &lt;em&gt;app/views/taglibs/application.dryml&lt;/em&gt; again and append this content:&lt;/p&gt;

&lt;pre&gt;&lt;code class="xml"&gt;&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;extend&lt;/span&gt; &lt;span class="attribute"&gt;tag&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;card&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;for&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Entry&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;old-card&lt;/span&gt; &lt;span class="attribute"&gt;merge&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;body:&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
      Posted on &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="namespace"&gt;view&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;&lt;span class="tag"&gt;created-at&lt;/span&gt;&lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;body:&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;old-card&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;extend&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Looks a bit similar to the form we changed earlier. Here we are replacing the body of the card. The &lt;em&gt;&lt;code&gt;&amp;lt;view:created-at/&amp;gt;&lt;/code&gt;&lt;/em&gt; element will do a few things for us. Depending on the field type, the content will be escaped. It also will format the field for us, like here with the &lt;em&gt;created_at&lt;/em&gt; datetime field. Also, make note that all underscores in fields become hyphens in DRYML. You might notice a lot of content in ending up in this &lt;em&gt;application.dryml&lt;/em&gt;. You should consider using includes to organize it, like those used by the automatically generated tags, cards, and forms. One last thing to do. Let&amp;#8217;s change the way the Entry is viewed. Readers don&amp;#8217;t need to see the &lt;em&gt;body_markdown&lt;/em&gt; field or the field labels. They only need the HTML version of the post. Create a new file at &lt;em&gt;app/views/entries/show.dryml&lt;/em&gt; with the following content:&lt;/p&gt;

&lt;pre&gt;&lt;code class="xml"&gt;&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;show-page&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;append-content-header:&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
    Posted on &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="namespace"&gt;view&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;&lt;span class="tag"&gt;created-at&lt;/span&gt;&lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;append-content-header:&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;field-list:&lt;/span&gt; &lt;span class="attribute"&gt;replace&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="namespace"&gt;view&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;&lt;span class="tag"&gt;body_html&lt;/span&gt;&lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;field-list:&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;show-page&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Getting an idea of how DRYML works? Since &lt;em&gt;body_html&lt;/em&gt; is an html field, it will not be escaped. See the &lt;em&gt;&lt;code&gt;&amp;lt;append-content-header:&amp;gt;&lt;/code&gt;&lt;/em&gt;? Hobo, like Rails and Ruby, has loads of magic. By slapping &lt;em&gt;append-&lt;/em&gt; or &lt;em&gt;prepend-&lt;/em&gt; in front of the tag, we can add content within that element. You can replace a tag and its content by adding the &lt;em&gt;replace&lt;/em&gt; attribute, like here with the &lt;em&gt;&lt;code&gt;&amp;lt;field-list: replace&amp;gt;&lt;/code&gt;&lt;/em&gt;. It&amp;#8217;s starting to come together.&lt;/p&gt;

&lt;p&gt;Next up is &lt;a href="/entries/4-make-a-blog-with-hobo-tagging"&gt;tagging support&lt;/a&gt;.&lt;/p&gt;</description>
      <author>Tyler Lesmann</author>
      <link>http://hobo.tylerlesmann.com/entries/3</link>
      <guid>http://hobo.tylerlesmann.com/entries/3</guid>
    </item>
    <item>
      <title>Making a Blog with Hobo: Posting</title>
      <description>&lt;p&gt;Welcome to the first part of the tutorial. We will start a new hobo project, set up a model to hold blog entries, and add markdown formatting.&lt;/p&gt;

&lt;p&gt;To create our new hobo project, we use this command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ hobo blog&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You will see a load of output. This is the scripts of hobo and rails setting up everything we need to get started. We will now create a model to hold our posts with this command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ cd blog
$ script/generate hobo_model_resource entry name:string body_markdown:text body_html:html&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You&amp;#8217;ll be presented with more output. Hobo&amp;#8217;s scripts have created several things for us. The most important at the moment is a new model, &lt;em&gt;entry&lt;/em&gt;, which has three fields: A string field called &lt;em&gt;name&lt;/em&gt;, a text field called &lt;em&gt;body_markdown&lt;/em&gt;, and a html field called &lt;em&gt;body_html&lt;/em&gt;. What&amp;#8217;s the difference between text and html fields? Text fields are escaped when viewed. They are the same otherwise. Let&amp;#8217;s make it so our posts are can be written in markdown. This is our first bit of coding! Open a new file in the project directory called &lt;em&gt;app/models/markdown_wrapper.rb&lt;/em&gt; and insert the following ruby:&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;&amp;#39;&lt;/span&gt;&lt;span class="string"&gt;rubygems&lt;/span&gt;&lt;span class="punct"&gt;&amp;#39;&lt;/span&gt;
&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;&amp;#39;&lt;/span&gt;&lt;span class="string"&gt;maruku&lt;/span&gt;&lt;span class="punct"&gt;&amp;#39;&lt;/span&gt;

&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;MarkdownWrapper&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;before_save&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;record&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;record&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;body_html&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Maruku&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;record&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;body_markdown&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;to_html&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What this little piece of code does is every time our model is about to be saved, the text in &lt;em&gt;body_text&lt;/em&gt; will be compiled into HTML by maruku and placed in &lt;em&gt;body_html&lt;/em&gt;. There is one more thing to do to start to use it. Open &lt;em&gt;app/models/entry.rb&lt;/em&gt; and add a line of &lt;em&gt;before_save MarkdownWrapper.new&lt;/em&gt; after the line that reads &lt;em&gt;hobo_model&lt;/em&gt;. Your code should look something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Entry&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ActiveRecord&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Base&lt;/span&gt;

  &lt;span class="ident"&gt;hobo_model&lt;/span&gt; &lt;span class="comment"&gt;# Don&amp;#39;t put anything above this&lt;/span&gt;

  &lt;span class="ident"&gt;before_save&lt;/span&gt; &lt;span class="constant"&gt;MarkdownWrapper&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;

  &lt;span class="ident"&gt;fields&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
    &lt;span class="ident"&gt;name&lt;/span&gt;          &lt;span class="symbol"&gt;:string&lt;/span&gt;
    &lt;span class="ident"&gt;body_markdown&lt;/span&gt; &lt;span class="symbol"&gt;:text&lt;/span&gt;
    &lt;span class="ident"&gt;body_html&lt;/span&gt;     &lt;span class="symbol"&gt;:html&lt;/span&gt;
    &lt;span class="ident"&gt;timestamps&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;


  &lt;span class="comment"&gt;# --- Permissions --- #&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;create_permitted?&lt;/span&gt;
    &lt;span class="ident"&gt;acting_user&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;administrator?&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;update_permitted?&lt;/span&gt;
    &lt;span class="ident"&gt;acting_user&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;administrator?&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;destroy_permitted?&lt;/span&gt;
    &lt;span class="ident"&gt;acting_user&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;administrator?&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;view_permitted?&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;field&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="constant"&gt;true&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;See our fields in the &lt;em&gt;fields do&lt;/em&gt; block? The &lt;em&gt;timestamps&lt;/em&gt; are &lt;em&gt;created_at&lt;/em&gt; and &lt;em&gt;updated_at&lt;/em&gt; datetime fields, which are added by hobo. Now all we have to do is apply the changes to the database. We do that with this command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ script/generate hobo_migration&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Hobo will generate the database migration for us. You will see that it is creating a &lt;em&gt;users&lt;/em&gt; table in addition to our &lt;em&gt;entries&lt;/em&gt; table. Enter &lt;em&gt;m&lt;/em&gt; to save the migration and apply it to our database. It will ask you to name the migration. This can be whatever you want. I like to use &lt;em&gt;initial&lt;/em&gt; on the first one. Let&amp;#8217;s fire up the development server and take a look!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ script/server&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Navigate to &lt;a href="http://localhost:3000/"&gt;http://localhost:3000/&lt;/a&gt; and you&amp;#8217;ll see the new hobo app! It will have you create a new administrator user. Then, you can create your blog posts! A lot of functionality has been accomplished with a few lines, but the interface is awkward. We will fix this in the &lt;a href="/entries/3-make-a-blog-with-hobo-customizing"&gt;next portion&lt;/a&gt; of the tutorial.&lt;/p&gt;</description>
      <author>Tyler Lesmann</author>
      <link>http://hobo.tylerlesmann.com/entries/2</link>
      <guid>http://hobo.tylerlesmann.com/entries/2</guid>
    </item>
    <item>
      <title>Make a Blog with Hobo</title>
      <description>&lt;p&gt;If you follow this tutorial, you will end up with a fully functional blog, with markdown formatting, tagging, commenting. You will also get a walkthrough of the many of hobos features. If you just want the code for this blog, then you can get it from &lt;a href="http://code.google.com/p/emmett-blog/"&gt;Google Code&lt;/a&gt;. This tutorial only assumes one thing, which is that you have ruby and the &lt;a href="http://www.hobocentral.net/"&gt;hobo&lt;/a&gt;, &lt;a href="http://maruku.rubyforge.org/"&gt;maruku&lt;/a&gt;, and &lt;a href="http://syntax.rubyforge.org/"&gt;syntax&lt;/a&gt; gems installed.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="/entries/2-making-a-blog-with-hobo-posting"&gt;Posting&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href="/entries/3-make-a-blog-with-hobo-customizing"&gt;Customizing Cards, Forms, and Pages&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href="/entries/4-make-a-blog-with-hobo-tagging"&gt;Tagging&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href="/entries/5-make-a-blog-with-hobo-commenting"&gt;Commenting&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href="/entries/6-make-a-blog-with-hobo-lifecycles"&gt;Lifecycles&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href="/entries/7-make-a-blog-with-hobo-theming"&gt;Theming&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</description>
      <author>Tyler Lesmann</author>
      <link>http://hobo.tylerlesmann.com/entries/1</link>
      <guid>http://hobo.tylerlesmann.com/entries/1</guid>
    </item>
  </channel>
</rss>

