+ Rollin Your Own URLs

why the lucky stiff why at hobix.com
Mon Sep 13 13:10:45 EDT 2004


=== Hi, Hi, Daily Tip: Rollin Your Own URLs ===

I am totally sympathetic to those of you who hate Hobix's default 
setup.  You have a right to your own lifestyle and I hope you lash out 
and destroy all the customs that I've put in place.

The default URLs in Hobix take the form of:

  http://example.org/category/entry.html

Basically, this amounts to:

  File.join( weblog.link, entry.id + "." + ext )

I'm not really into long URLs.  This URLs is appealing to me because 
it's nice and readable.  I hate seeing the date in the URL.  In 
addition, I leave room for category indices at: 
http://example.org/category/.

=== The skel_entry method ===

In Hobix::Weblog, you can create the handlers for the various 
templates.  In the default setup, any template with an 'entry' prefix 
outputs individual entry archives.

So if you have skel/entry.html.quick, you'll get the default Quick 
template to build HTML for each entry.

Here's the current code for the `skel_entry' method:

    # Handler for templates with `entry' prefix.  These templates will
    # receive one entry for each entry in the weblog.  The handler requests
    # entry pages to be output as `/shortName.ext'.
    def skel_entry( path_storage )
        all_entries = [path_storage.find]
        all_entries += sections_ignored.collect { |ign| 
path_storage.find( :all => true, :inpath => ign ) }
        all_entries.each do |entry_set|
            entry_set.extend Hobix::Enumerable
            entry_set.each_with_neighbors do |nexte, entry, prev|
                page = Page.new( "/#{ entry[0] }" )
                page.prev = prev[0] if prev
                page.next = nexte[0] if nexte
                page.timestamp = entry[1]
                page.updated = path_storage.modified( entry[0] )
                yield :page => page, :entry => entry[0]
            end
        end
    end

The above method does a bit of fanciness.  Notice that it groups entries 
by sections_ignored as well.  This ensures that the `prev' and `next' 
links for each page stay within its category.  We'll talk about `prev' 
and `next' links in the coming days.

The important part is this line:

                page = Page.new( "/#{ entry[0] }" )

When looping through entries in skel methods, you won't be dealing with 
Entry objects yet.  The `find' methods don't actually load entries.  
They just load information from the entry index.  Instead, we get an 
Array of [entry_id, creation_time].  This at least allows us to order 
the entries and make some basic decisions.

You can also retrieve the modification time for an entry with: 
path_storage.modified( entry[0] ).  This incurs no performance hit.

=== Future-proofing URLs ===

If you need canonical URLs which are future-proofed to the degree 
outlined by Már Örlygsson 
<http://mar.anomy.net/entry/2003/06/22/17.15.00/>, you can make a new 
skel method to accomplish this.  I wouldn't override skel_entry, leave 
it the default.  Maybe you'll want to use it in other sections of your 
blog (i.e. about pages and such).

We'll archive as suggested by Mark Pilgrim 
<http://diveintomark.org/archives/2003/08/15/slugs>:

    * Individual archive: |http://diveintomark.org/archives/2003/08/04/xp|||

We'll call our new method `skel_entryfull':

    # Handler for templates with `entryfull' prefix.  These templates will
    # receive one entry for each entry in the weblog.  The handler requests
    # entry pages to be output as `/archives/yyyy/mm/dd/shortName'.
    def skel_entry( path_storage )
        all_entries = [path_storage.find]
        all_entries += sections_ignored.collect { |ign| 
path_storage.find( :all => true, :inpath => ign ) }
        all_entries.each do |entry_set|
            entry_set.extend Hobix::Enumerable
            entry_set.each_with_neighbors do |nexte, entry, prev|
                page = Page.new( "/archives/#{ entry[1].strftime( 
"%Y/%m/%d" ) }/#{ entry[0] }" )
                page.prev = prev[0] if prev
                page.next = nexte[0] if nexte
                page.timestamp = entry[1]
                page.updated = path_storage.modified( entry[0] )
                yield :page => page, :entry => entry[0]
            end
        end
    end

If you don't use the `prev' and `next' links, this can be shortened to:

    def skel_entry( path_storage )
        path_storage.all.each do |entry|
            page = Page.new( "/archives/#{ entry[1].strftime( "%Y/%m/%d" 
) }/#{ entry[0] }" )
            page.timestamp = entry[1]
            page.updated = path_storage.modified( entry[0] )
            yield :page => page, :entry => entry[0]
        end
    end

You'll probably also want to make sure that your entries use this link 
as their canonical URL (their entry.link).

   class Hobix::Entry
      def link
          "/archives/#{ created.strftime( "%Y/%m/%d" ) }/#{ id }.html"
      end
   end

Now, just:

   touch skel/entryfull.html.quick

And:

  hobix upgen blogName

_why

**



More information about the Hobix-is-the-way mailing list