Saturday, December 2, 2006

Default Gravatar Image; A Greasemonkey Script

So you may have noticed that Gravatar has been going through some growing pains and isn’t working right now.

Until it’s back, pages that use gravatars aren’t loading quickly, or taking forever to load with broken images… Which is a little annoying. So I wrote a quick Greasemonkey user script to replace the image’s source with the site’s default gravatar image.

  Gravatar Default Image « Click to install

Note: This will only work on sites that use an img tag to show avatars. If a site uses a gravatar url as a css background-image, well, you’re SOL. However, with a little hacking, I’m sure you could tweak this script to do that too, if it was important to you. ;-)

I tested this with Greasemonkey on Firefox 2 and Creammonkey on Safari 2. It’ll probably work on Turnabout for Internet Exploder, but I didn’t test it.

Tuesday, October 31, 2006

Lil Monstas!!!

Lil Monstas is live! Woot! We actually made our Halloween deadline too—barely. There was about five minutes left!

Check it out today and every Monday for new installments. I hope you enjoy it!

Update: now has an RSS feed!

Thursday, September 21, 2006

Table Tag; The HTML Pariah

Here’s a piece of news: The table tag isn’t deprecated in XHTML!

OK, “that’s not news” you say. True. It’s not. But it seems to be for some. In fact, it’s amazing the lengths people will go to avoid using tables. You know what I’m talking about.

But, “It’s not semantic”, “It’s not separating content from layout properly”, “It’s soOOoo Web 1.0” or many of the other “reasons” to shun tables are mostly, well, crap.

There’s no way I’ll believe that it’s better to use a dozen div’s and a hundred lines of CSS to accomplish the same as a table. Talk about re-inventing the wheel!

Just because you can do something, doesn’t mean you should.

Listen, if you have tabular data, or need to use some sort of grid, just use tables. Be reasonable, be pragmatic. If you need a hammer, use a hammer, don’t use your forehead instead. Sure, they’ll both drive nails… Probably.

Let me re-emphasize the ‘be reasonable’ part. Remember, it cuts both ways. Too many tables can be a bad thing, and they can be a crutch. The point of this rant is that you shouldn’t avoid using tables, or some other shunned-but-non-deprecated tag, just because it’s popular to.

- end of rant -

Wednesday, September 20, 2006

Comatose 'Compatibility Mode'

OK, so after mentioning it in my last post, I’ve decided to go ahead and implement it. Comatose version 0.7.1 adds a DEFER_COMATOSE_LOAD flag that you can use to, well, defer comatose’s loading. You will have to manually tell it to load in your environment.rb using Comatose.load.

See this devblog post for more.

Normally, I’d only post this on the Comatose development blog, but I wanted to make sure anybody who’s having problems using Comatose with other plugins/applications knows about this. If you have problems or questions, leave a comment here. Thanks!

Tuesday, September 19, 2006

Comatose Version 0.7

This release finally adds support for versioning. It also adds an auto-loader for any comatose customizations you put in a RAILS_ROOT/lib/comatose folder.

See the devblog post for more.

Comatose has been having a few problems co-existing with some kinds of plugins lately. The problems seem to be caused, at least in part, because the comatose controllers extend ApplicationController and therefore requires the application.rb before the rest of the plugins load.

Plus, some plugins seem to take issue with any previous plugins defining an Active Record model before they’re loaded—very picky stuff.

To combat this, I’m thinking of adding a DEFER_LOADING flag in comatose/init.rb. When the plugin initializes, if that flag is true it won’t load the controllers or the models. You’ll then need to add a call to Comatose::Load in your environment.rb that would then load the controllers and models—after the rest of your app had loaded. By default, the flag will be set to false so that it remains backward compatible.

Look for that in the next release.

Tuesday, August 29, 2006

Retrograde: Part One

Working Area:

I designed it to have some nifty UI stuff like an expandable tree view of pages, drag-n-drop reordering of pages, page previews using AJAX. You know, the standard web 2.0ish stuff.

  • How to handle Drag-n-drop
    • Look further up the track
    • Make the link smart, point to the HTML version of the page and have the onclick handler return false
  • How to handle expandable trees when there’s no AJAX
    • Show all the entries, don’t show the ‘twisties’
  • How to handle AJAX page previews
    • Look for features you can disable
    • Remove button if JS isn’t available


Disabling JavaScript via the web developer extension in Firefox

Does your application work if JavaScript is disabled? It should.

Pardon The Dust

I’ve updated the website, moving away from WordPress (for various reasons). So there may be a few broken links floating about.

The RSS feeds may be a bit fragile too… I updated the .htaccess file to redirect the feeds correctly—I hope. If you’re having a problem with the feeds, broken links, or something else regarding the site, please let me know.

Sunday, July 23, 2006

Comatose v0.6

Comatose 0.6 is out! Here’s a quick summary of the new stuff:

  • ComatoseController has been split into ComatoseController and ComatoseAdminController
  • Both controllers extend your ApplicationController
  • The views, stylesheets, and javascripts have been updated and renamed to reflect the controller change
  • Configuration via Comatose::Options class
  • Liquid is the default text processor
  • Support for named routes
  • A Getting Started Guide
  • Pages now have a created_on field
  • Bug-fixes

For more, see the CHANGELOG.

Turns out I spoke too soon in my earlier post, there is a schema change. So if you're upgrading you'll need to run:

$ ./script/generate comatose_migration --upgrade --from=0.5

If you have questions/problems/feedback, drop by the Comatose project site and post in the forum or report a bug.

Saturday, July 22, 2006

Comatose Development Site

Rubyforge has been kind enough to create a project site for Comatose. I’ve enabled the following project tools for it:

Rubyforge also provides a project-specific wiki. I haven’t enabled it, at this point — If you think it’d be useful, lemme know and I can.

So from here on, if you have problems with Comatose you can add a bug ticket. Or better yet, fix it and submit a patch. ;-) If you need help with something, feel free to post on the mailing list or the help forum.

If you’ve used Comatose, I’d like to encourage you to drop by the open-discussion forum and leave a note. If you’ve done anything special with it, I’d love to hear it!

Wednesday, July 19, 2006

Comatose and PostgreSQL

Apparently, there’s an issue in Comatose that causes an error when migrating the first time when using PostgreSQL. Here’s the fix, courtesy of Lyle Troxell.

Changing comatose_page.rb’s line

acts_as_list :scope=>'parent_id'


acts_as_list :scope=>:parent_id

Fixes the problem.

This fix will be put in the next version...

Thanks Lyle!

Tuesday, July 18, 2006

Comatose, TNG

The response I’ve gotten on Comatose is somewhat overwhelming. I’m glad so many of you have found it useful!

Hopefully I won’t annoy you guys too much with the next release… It has quite a lot of updates, and changes. Enough to warrant this post on it as a kind of ‘heads up’.

If you’ve made customizations to the admin, and if you have used an svn:external to keep up to date with Comatose — you may want to remove the external and commit the current version (0.5) into your plugin directory… Otherwise you will need to tweak some things when I commit the next version.

In the next release, what is now the ComatoseController is going to be broken down into two separate controllers. There will still be a ComatoseController, it’s purpose will be rendering and caching pages. A new ComatoseAdminController will be the home for all of the administration tools. They will each have a before_filter that calls #authorize for authentication purposes.

The way layouts are handled internally has changed too. The controllers will now extend your ApplicationController, so you should be able to use partials and application helpers in your content layouts.

The biggest change, however, is in the page processing. Liquid will be the new default text processor. Don’t panic — ERB will still be available as a configuration option. But I really want a safer way to support content processing. To go along with that, I’m adding a simple method for adding custom functions to the processors that’ll work for both Liquid and ERB. Also, Liquid will be packaged with the plugin, so you won’t have to worry about having it as a dependency.

There are, at this point, no schema changes — so there won’t be a need for new migrations. There’s quite a few more changes I could talk about, but these are the main things that are some-what breaking changes.

I’ll be releasing the new version later this week.

Wednesday, July 12, 2006

Monstas of the Lil' Variety


As some of you may know, I have been collaborating on a webcomic project called Lil Monstas for… Well, a little while now. OK, it’s been so long that some of you may be thinking that it’s never going to see the light of day.

Well, I’m here to tell you that Lil Monstas is alive! It’s aliiivve! Not only that, but we’ve decided on a release schedule.

So, I invite you all to visit on All Hallow’s Eve — October 31, 2006 for our inaugural episode! It should be a lot of fun, I hope to see you all there.

Tuesday, July 11, 2006

Comatose v0.5

Can you guess what time it is? That’s right! It’s time for another Comatose update!

So, what’s new? Here are the main things:

  • Page reordering
  • Updated administration UI
  • Parameterized inline rendering
  • Fragment caching, and a pre-caching hook if you want more control of such things
  • Better importing/exporting of pages
  • Misc. bug-fixes



It's as simple as ever:

$ ./script/plugin source
$ ./script/plugin install comatose
$ ./script/generate comatose_migration
$ rake migrate

Or, for you (OK, us) early adopters:

$ rapt discover --no-prompt
$ rapt install comatose
$ ./script/generate comatose_migration
$ rake migrate

Then, in your routes.rb:

map.comatose_root ''


For those of you upgrading from version 0.4, there aren’t any new db fields — so you won’t need to worry about migrations. However, there are changes to the CSS, JavaScript, and Views. So you might want to diff those with your customized versions (if you’re customizing the Admin).

Oh, and I’ve also bit the bullet and added a few images to spice it up. For new installations, it’ll automatically copy them into RAILS_ROOT/public/images/comatose/.

For existing installations, you’ll want to run:

$ rake comatose:copy_images

That should pretty much do it. Don’t forget to glance over the 400+ line README file.

From the ChangeLog:

[version 0.5]
* Added support for parameterized inline rendering of comatose pages. Use
like a partial: render :comatose=>'path', :locals=>{:username=>'stuff'}
the locals hash will be sent to the ERB context for use when rendering
the page.
* Support for a Hash ERB context exists all the way down to the TextFilters.
* Initial support for fragment caching for inline rendering. It's turned off
by default. Send :use_cache=>true in the render :comatose=>'' tag to use it.
Caching will also not be used if you are sending the page parameters via the
* Return reloadable? false for the ComatoseController by default... This
should prevent the development mode hassles people have been having.
* Updated data migration tasks to better support nested pages.
- comatose:data:export FROM=page_path TO_FILE=file_path
- comatose:data:import TO=page_path FROM_FILE=file_path
- FROM_FILE and TO_FILE default to 'db/comatose-pages.yml'
- FROM and TO default to '', the page tree root
* Fixed 'Clear Page Cache' bug -- it didn't handle the page root being an
array like it should have.
* Removed :page_title and :page_keywords from session
* Updated the rails_version in the about.yml to 1.1+ -- just because I
haven't tested it on anything less than that. If you have, and it works,
let me know!
* Adds the utf8 header to all output (text/html; charset=utf-8). Use
ComatoseController.force_utf8 = false to disable.
* Initial support for page reordering (via AJAX)
* Updated the administration look-n-feel.

Enjoy! As always, if you have any questions/problems feel free to give me a shout.

Thursday, July 6, 2006

Comatose v0.4

I’ve just checked in a big update for Comatose.

Here’s a list of the major changes from the CHANGELOG:

[version 0.4]
* Added keywords field
* Abstracted text filters into a micro plugin structure, default
support for
- Textile
- Markdown
- RDoc
* It will only show the filters as a choice in the admin if you have
the necessary libraries for the filters to function.
* Added ComatoseController.hidden_meta_info = [] as a way of showing/hiding
the meta fields
* The comatose_migration generator now accepts an --upgrade flag which
will create a micro migration that only has the new fields in it
* get_root_page will now support returning an array of root pages to show
in the admin page list
* Created some initial tests... (Can you tell I'm not a test _first_ guy?)
* Inline rendering now handles :silent flag -- it will just return and
empty string if :silent=>true
* Modified all the internal references to ComatoseController to self.class.
The views reference controller.class. Redirects redirect to :controller=>
self.controller_name or controller.controller_name (action and view
respectively). This show allow you to sub-class the ComatoseController.

As always, I’ve tried to keep the README up to date with the changes.

Upgrading from the previous version...

I’ve added a couple of fields to the comatose page model… If you have already installed the comatose plugin, and have the add_comatose_support migration applied, you can get a migration of just the new fields by running:

$ ./script/generate comatose_migration --upgrade

There’s only one other feature that I know I’m going to add in the near future—The ability to re-order the pages. It won’t be a big deal when I release that one though, I already have the field I need in there.


As always, check it out, kick the tires, etc. Let me know if you have any issues/questions/suggestions…. darthapo at gmail dot com

Sunday, July 2, 2006

Comatose Screenshots

I've had some requests for screenshots of the administration ui... So, without further ado, here they are.

Page ListPage DeletePage EditPage Edit - MorePage Edit - ReparentingPage Edit - Preview

Hmmm... After looking at the screenshots myself, I think I'm going to re-label "Expire Page Cache" to "Clear Page Cache". But still, you get the idea. That's the default administration ui that comes out of the box. It's straight CSS -- no images.

You can, however, completely customize it to look like your application by running:

$ rake comatose:customize

That will copy all the necessary files to your application folders for customization. The README talks more about that.

From Version 0.5

Update! The following screen shots are from version 0.5:


Technorati Tags: , ,

Comatose Update

There’s a new version of Comatose, the micro CMS plugin, out there.

I wanted to give you guys a quick heads up. This new version has a couple of breaking changes… After this release, if there are any data model changes, I’ll add a generator to the plugin that will create an ‘upgrade’ migration so you can update smoothly. But I’m hoping since it’s only been a few hours since the initial release, not too many people will have to revert anything!

If you’re not sure what Comatose is, you can read my last post on it for the background.

New Features

  • Hierarchal pages
  • Updated administration styles
  • Page previews
  • ERB pre-processing


$ ./script/plugin source
$ ./script/plugin install comatose
$ ./script/generate comatose_migration
$ rake migrate

Add to the bottom of your config/routes.rb file:

map.comatose_root ''

That’s it—you’re good to go.

There’s a lot more info, and an FAQ example, in the README.

Saturday, July 1, 2006

Comatose, a Micro CMS Plugin


  • Easy to install—It’s a Rails plugin
  • Light-weight—It only adds one table to your schema (and has a generator to create the migration for you)
  • Runs entirely from the plugin folder by default
  • Intelligent page caching
  • Easy to leverage throughout your application
  • Full administration UI that can be re-skinned
  • Supports Textile filtering
  • Simple ‘mounting’ of the cms root path in your routes.rb file
  • Easy to wrap content in a Rails layout
  • It’s not meant to be a feature-complete CMS system. If this bugs you… Well, you should look into something like Radiant
  • No versioning support
  • No page status, all pages are ‘live’

Lately, I’ve had a recurring issue arise on my projects: They generally require a few content pages. Nothing fancy. Just a privacy policy, terms & conditions, an FAQ, that kind of thing.

I don’t really want to make these static HTML pages. They are likely to change at some point, especially the FAQ. Plus, I’d like to have them leverage Rails’ layout support. At the very least, I’d like to have them easy to re-skin.

That said, I don’t want to spend the time integrating an actual CMS system into the application. And really, for just a few pages, it’s too much.

I wanted an easier way. Something that was tiny, simple, and lightweight. Something I could drop into existing applications. In short; a micro CMS plugin.

They say necessity is the mother of invention, although I’ve often thought laziness is… But that’s a different post altogether. The point is, I wound up building something to suit my needs—perhaps it’ll suit yours as well.

I call it Comatose.

Comatose? What a Horrible Name!

Yeah, probably so. I just wanted something unique with the letters CMS in it. Comatose is the first one I thought of.


  • Easy to install—It’s a Rails plugin
  • Light-weight—It only adds one table to your schema (and has a generator to create the migration for you)
  • Runs entirely from the plugin folder by default
  • Intelligent page caching
  • Easy to leverage throughout your application
  • Full administration UI that can be re-skinned
  • Supports Textile filtering
  • Simple ‘mounting’ of the cms root path in your routes.rb file
  • Easy to wrap content in a Rails layout
  • It’s not meant to be a feature-complete CMS system. If this bugs you… Well, you should look into something like Radiant
  • No versioning support
  • No page status, all pages are ‘live’


Quite simple. Just run the following in your console, at your application’s root folder:

./script/plugin source
./script/plugin install comatose
./script/generate comatose_migration
rake migrate

Comatose is now installed and setup.


To enable it in to your application, just add a line to your config/routes.rb file:

map.comatose_root '/pages'

That’s it! Now, whenever you visit http://your-app-url/pages it will render your cms pages.

Have a look at the README for more.


Feel free to use Comatose. I’ve released it, at this point, under the MIT license. Which basically means you can use it however you want.

If you like it, hate it, or have some ideas for new features, let me know! ( darthapo at gmail dot com )

Thursday, May 4, 2006

Radiant's Radiance

I’ve been playing with John W. Long’sRadiant CMS for the last few days and I have to say… I really like it. It walks the line between complexity and simplicity very well. And we all know how slippery a slope that is.

So what’s it all about? Why should you take the time to get familiar with it? Radiant is simple to use, simple to extend, and from my experience, simple to setup. Yet it enables the creation of complex websites. And it’s only an alpha version!

Tell you what, I’ll give you an overview of Radiant and you can make your own conclusion.

Hierarchical Pages

Ultimately, all CMS tools boil down to the fact that you are building web pages. And instead of obfuscating that by creating some abstracted terminology. Radiant calls it like it is. You create pages. You create site hierarchy by adding child pages. That simple.

Pages Admin


Behaviors are very powerful. You can think of them as plugins. Or as page enhancements. Or even as page types. Basically, they add functionality to a page. So instead of just being content, your pages can be more active—they have something to do! And we all need something to do.

Closeup: Behaviors

What they do depends on the behavior selected. For example, the Archive behavior changes the URLs of it’s child pages to mimic a blog-type URL scheme.

The real power of Radiant, I think, is in behaviors. Radiant includes a generator that creates the boilerplate code for new behaviors (and their unit tests) for you. So creating your own behaviors is really rather trivial. I’ve already created a few custom behaviors, and they are surprisingly compact.

In future posts I’ll make some of the behaviors I’ve developed publicly available, talk about how behaviors are developed, and what kind of things they are well suited for.

One of the ways that behaviors make a page more ‘active’ is by providing custom tags to the page they are applied to. Which leads us to…


For a in-depth understanding of the tag-system you should look at Radius. The short, short version: the tag syntax looks like namespaced XML tags. They aren’t, but look like it:

... content here ...

The interesting thing to me is how the tag output is based on context. For example, consider this snippet which loops through a page’s children and outputs a list of their titles:

h1. <r:title/>'s Children

* <r:title/>

(Yes, it’s generating Textile—More on that in just a bit…)

Notice that the tag <r:title/> is used twice, but with different output. That’s because of the context. When it’s called the first time (in the h1) it’s in the page context, so it shows the page’s title. When it’s called in the <r:children:each> tag, it’s context is the child page, so it shows the title of the child page.

Radiant comes with a lot of default tags that are very useful. I’ve only shown you a couple here. See the development wiki for more…

Text Filters

I will admit it. I am a Textile addict. I would, and mostly do, use it everywhere. So you can understand my delight to find it supported in Radiant.

Closeup: Filters

Text filters are pretty much what they sound like. They allow your content to be preprocessed before it’s rendered. It comes bundled with filters for my beloved Textile, and Markdown if you’re into that kind of thing. Of course, if you are just entering straight HTML you can choose to have no filter at all.

If you aren’t a Textile or Markdown person, you can always build your own filter. Radiant comes with a built-in generator to write all the boilerplate code for you!

Page Parts

I know what your thinking. Your thinking: C’mon M@, behaviors and tags do sound neat and all, but you know that pages can be complex things. They can be comprised of any number of different things, or parts.

Why yes, I do know that. Thank you. So does Radiant. You can create multiple content fragments, called page parts, for any given page. In fact, the main content of a page is just a page part, named “body”, that gets created automatically.

Page parts are one of those things that are simple, but that really allow you to build complex websites. They are shown as tabs in the admin UI.

Closeup: Page parts

Oh, I nearly forgot to mention that each page part can have a different text filter. Oh, and the filters are run after the tags, so you can have tags generate textile (or markdown, or your own custom filter format)... *whew*


Layouts are where your site design flexibility comes from. In practice, they work very much like Rails’ layouts.


Each page can be rendered with a different layout, or inherit it’s layout from the parent page. Multiple layouts are handy if you have different designs for different sections of the site, or different languages, etc.

Closeup: Layout selector


Snippets are site-wide content fragments. You can include them on any page, or layout. I wind up using them for headers, footers, inline css, global sidebars, and main navigation.


And More

There’s a lot of stuff I haven’t even touched on. For example customized 404 pages, multiple language support, page caching, publishing workflow, and lots more.

Be sure and check it out. I think you’ll be glad you did.

Sunday, April 9, 2006

Rails Theme Support Plugin v 1.4

I've just checked in version 1.4 of the theme_support plugin. It contains quite a few bugfixes and updates. This version also integrates a couple of patches from akg and D.J. Vogel. Thanks guys!

Version 1.4 adds:

  • Bugfixes, of course
  • Better Rails 1.1 support
  • ActionMailer theme support (experimental)
  • Updates to the themeitem liquid tag
  • Support for theme sub-directories
  • Fleshed out the Theme object to make is easy to list all of the installed Themes

As a little background, the plugin is based on the theme system developed by the Typo guys and adds support for:

  • Multiple concurrent themes
  • A rails generator for creating a theme folder structure
  • Rake tasks for pre-caching all of the themes for increased security and performance
  • Overriding views with theme-specific rhtml or liquid templates (based on early Typo code)
  • Forcing theme views to only allow liquid templates
  • Made supporting themes as easy as using layouts

To install the plugin, go to your rails application root folder and run:

  ./script/plugin install

or, for you Windows folks:

  ruby script\\plugin install

Look at the README in $/vendor/plugins/theme_support for more on implementing themes in your application.

Wednesday, April 5, 2006

More Zebras

Update: OK, you got me. You should really use the built-in Rails helper, cycle.

<table class="Grid">
 <% for user in @users %>
  <tr class="<%= cycle('Even', 'Odd') %>">
      ... Stuff Here
 <% end %>
Here's the helper I've been using lately for zebra striping table rows:
def zebra_stripe( index, even_class="Even", odd_class="Odd" )
  index % 2 == 0 ? even_class : odd_class
In the view, you use the rubyesque .each_with_index like this:
<table class="Grid">
<% @users.each_with_index do |user, i| %>
  <tr class="<%= zebra_stripe(i) %>">
      ... Stuff Here
<% end %>
Simple as that!

Saturday, March 18, 2006

RubyConf '06

RubyConf '06 -- I know some of the presenters, and have never been to Chicago -- should be loads of fun! I'll see you there!

Tuesday, February 28, 2006

Who Stole December -- and, uh, January (and February)?

Wow, I haven't posted in quite a while! Sorry about that. Things have just been kinda crazy.

Well then, lemme catch you up on a few things... I finished up a stint with Site5. I was helping them out on their new offering: Flashback -- Be sure and check 'em out, they're a good bunch of guys 'n gals that really care about web-hosting. [/plug]

There are a couple of patches to the theme_engine that I need to integrate and publish -- look for that in the near future.

In the next few weeks I'm planning on releasing version 0.6 of TaskTHIS. It will fix some issues with Rails 1.0 (probably 1.1 at that point) and have better database support. Also, it'll have some examples of AJAX failure handling (which I'll talk more about in the next few days).

Activity on the Zoo Dot Com front! I'm writing several storylines now so that I can keep well ahead of schedule. And there's something else, very exciting, in the works for ZDC -- I can't tell you about it now, though. Hopefully soon. Very soon.

I guess that's pretty much it -- Oh yeah, I moved too. Heh, a little time consuming that is. Anyway, I will now return to my more regular posting self -- Stay tuned. Same M@ channel, same M@ time. (Did I just say that? Oh jeez...)