M@'s Musings

Pontificus Maximus

M@ McCray

I'm the creator of the webcomic ZooDotCom, and a web developer.

This is where I post random thoughts/images.

Enjoy!

Search my Posterous

 

Comatose, TaskTHIS, and Theme Support. Oh My!

Well, I’ve been a little remiss in my open-source development of late. Many apologies, things have been a bit hectic. You know the feeling, I’m sure.

But that’s not why I’m posting. I thought I’d outline my ideas for the future of these projects and get your feedback and/or ideas.

Comatose, The Micro CMS Plugin

The things that are definitely coming…

Edge Rails – Since Rails 1.2 is now official, it’s time to finally support ‘edge rails’. :-D

Actually, I have a version that runs on Rails 1.2 now, but I’m debating about Rails 1.1 backward compatibility. The new version changes quite a bit. The DEFER_COMATOSE_LOAD stuff goes away, replaced by better configuration support and a Dispatch::to_prepare block. Plus you no longer override the ComatoseAdminController for authentication, instead in the configuration you specify modules to include in the class. Oh yeah, and the controllers no longer extend ApplicationController.

Test Harness – The tests in the plugin itself are very spartan, at best. I have a horribly ugly test harness I use for the actual unit testing that I’m going to clean up and release.

Some possibilities

Liquid Only – I really think I’m going to drop ERb support. How many of you use ERb over Liquid for page processing?

RESTful Pages – Perhaps using the new RESTfully CRUDDY support would be useful. The idea of having an API for pages is interesting.

Mount Behaviors – I haven’t thought this through yet, it just popped into my head: map.comatose_root 'devblog', :index=>'blog', :behavior=>'blog'

This example would add ‘blog-like’ support such as all children being paged entries (showing last 10, next page, last page, etc.), automatic hAtom microformat support, and maybe some sort of archives… I don’t know. I still haven’t thought about this too much.

The behavior support would be pluggable, much like text-filters and drops… Can you think of any other behavior that would make sense?

Maybe :behavior=>'syndicated' to create RSS/ATOM feeds of the child pages? Perhaps they’d be mixable by saying :behavior=>'blog syndicated' or :behavior=>'blog,syndicated'.

The probably nots

Media Management – It just feels like too much. I have a hacked up version of Comatose that supports page attachments. But you wind up having to deal with upload directories, and file permissions and… It just feels too heavy. And too heavy != micro.

Perhaps it could be a separate plugin?

TaskTHIS

TaskTHIS is getting a bit long in the tooth. It was written right about the time some of my AJAX patches were being added to Rails. Which was pre 1.0. So, yeah. It needs some love.

It was created as a show-and-tell for the then-new-and-nifty AJAX support. Which, of course, is now old hat.

In keeping with the tradition of show-and-tell, I thought TaskTHIS would be an excellent application to show how to use the new CRUD/REST/Resources stuff in Rails 1.2.

I have a few ideas outlined here. The biggest ones are:

API – This is fairly straight-forward, we’ll get most if it from Rails. We’ll just add the appropriate authentication for the XML requests.

OpenID – I was thinking replacing the existing login system with OpenID authentication. I like the idea of just typing in my domain to login… Who needs passwords? Seriously though, this may be a bit controversial — please weigh in.

Oh, I forgot to mention, TaskTHIS.com is working again.

Theme Support Plugin

Basically, just add any outstanding patches and ensure it works on Rails 1.2. I imagine the routing stuff will need to be tweaked.

Whadda Ya Think?

What would/wouldn’t you like to see in any of these projects?

Posted
 

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 http://mattmccray.com/svn/rails/plugins/theme_support

or, for you Windows folks:

ruby script\\plugin install http://mattmccray.com/svn/rails/plugins/theme_support

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

Posted
 

Rails Theme Support Plugin



Update: I changed the svn URL to point to it's new home!


Currently, to add support for themes into your rails application, you have to install the theme_generator. The generator will then create the folder structure for themes, and it also creates the plugin files for theme support in rails.


The more I've thought about it, the less I like this approach. I'd rather have a fully encapsulated plugin that would add support for themes into rails and define a simple generator that would merely create the boilerplate theme structure.


To that end, I present the Rail Theme Support plugin. To install the plugin execute the following in the root of your application (requires rails 0.14.3+):

./script/plugin install http://mattmccray.com/svn/rails/plugins/theme_support


In the next couple of days I'll have a trac installation up and running for it too.


You can, of course, still get the theme_generator from RubyForge. But I think the plugin will be the approach I will recommend moving forward.


Try it out and let me know what you think!

Posted
 

Theme Generator Shapes Up


I've released theme_generator version 1.3.0. It's shaping up rather nicely, if I say so myself.


The theme support is now completely encapsulated in a plugin -- it was split across a plugin and a component.


Like Typo, it fully supports custom application views, of course. (It is based on the Typo theme system, after all.)


It also supports using liquid templates (if you have the liquid plugin installed). You can also lock down the themes to only allow the rendering of liquid templates.


And it's dead simple to use. Once you have the theme_generator installed, here are the steps to make your application support themes...


Step One: Generate a theme named 'default'


In your command terminal, cd into your Rails (0.14.3+) application folder and execute:

./script/generate theme default


It spits out the folder structure for a theme named 'default' (it doesn't actually have to be called 'default', call it what you like).


Since it's the first time we've used it for this application, it'll also create the theme_support plugin files for us.


Step Two: Update your ApplicationController


Now we update the ApplicationController (application.rb) to tell Rails to use our new theme.


[code lang="ruby"]
class ApplicationController < ActionController::Base

layout 'default' # You may need to modify this, the generator will
# create a layout named 'default' by, uh, default

theme 'default' # Tell Rails to use the theme named default

end
[/code]


Step Three: There is no step three


Your app is now ready to support themes! You can create whatever theme-specific stylesheets, images, javascripts, layouts, and application views you'd like and Rails will pick them up.


Note: To reference theme-specific content you'll want to use the theme_* helper tags. See the docs for more.


Credit where credit is due...


Of course, this generator and plugin wouldn't be as remotely robust if it wasn't for the excellent work of Tobias, Scott, and the rest of the Typo guys.


Installation


Want it? Just gem it:

sudo gem install theme_generator


Or, if you already have it:

sudo gem update theme_generator


If you are on Windows, you can leave out the sudo part.


In the near future I'll be posting a tutorial explaining how to implement user and/or application level themes... In the meantime, if you have any suggestions or questions, feel free to send 'em my way.

Posted
 

Full Theme Support in Rails, Revisited


OK, so after a short discussion and some experiments, I've realized that the Typo approach to themes has a lot more merit than I initially thought... For general use it still has some trouble areas, but that's nothing that can't be fixed.


I've created a new theme_generator that takes their general approach and makes it easy to leverage in any application. Even an existing one.


How to use it...


Usage is extremely easy. First, use the generator to create a default theme.

./script/generate theme default


(It doesn't have to be called 'default', it can be whatever you'd like)


This will create the main themes folder structure, the initial theme files for the theme ('default' in this case), and it creates the plugins/components needed to support themes.


Now you can use themes as easily as you do layouts. The following will use a layout named 'main' in the 'default' theme.


[code lang="ruby"]
class ApplicationController < ActionController::Base
layout 'main'
theme 'default'
end
[/code]


Here's an example of per-user themes:


[code lang="ruby"]
class ApplicationController < ActionController::Base
layout 'default'
theme :get_user_theme

def get_user_theme
# This assumes, of course, your User has a 'theme' field
return @session[:user].nil? ? 'default' : @session[:user].theme
end
end
[/code]


Differences from Typo themes...


I did take the liberty of tweaking of couple of things (beyond setting the theme in your controller). The main difference is that I changed the cached theme structure.


Before:

/public/images/theme/stylesheets/theme/javascript/theme


After:

/public/themes/[THEME_NAME]/images/stylesheets/javascript


What does this mean? For one thing, it's a lot easier to remove cached theme files... Just delete the public/themes folder.


Also, you should be using relative paths to images in your CSS. For example:


[code lang="css"]
BODY {
background: #FFF url(../images/page-bg.jpg) top left;
}
[/code]


Requirements...



Update: theme_generator is now hosted on RubyForge.




The theme_generator requires Rails >= 0.14. The easiest way to install the theme_generator is by running:

sudo gem install theme_generator


It's that simple. Feel free to install it and let me know what you think.

Posted
 

Supporting Themes In Your Rails Application


Update:
There's an updated version of the theme_generator. See the blog post or download it.


I was pretty impressed after looking at the theme support in Typo 2.5. However, I don’t think it’s a system that you should replicate if you want your application to support simple themes.


Before I get too far along let me make it clear that it’s not my intention to cast aspersions on Typo, it’s an excellent tool. In fact, I plan on switching to it from WordPress in the near future.


My issue with Typo’s theme scheme (heh) is that it doesn’t leverage the web-server as it should. Rails is impressive, and it’s caching is quite good. But web-servers like Apache have been around for many years. They are really good at what they do, so let them do it! Rails can’t compete with the server’s ability to deliver static content like CSS and graphics.


Following is how I’ve been implementing themes in Rails applications. In addition to relying on the web-server to provide static files, it also leverages existing Rails infrastructure wherever possible. Bear in mind, I’m not suggesting the following to be an end-all solution. Nor is it a drop-in replacement for Typo’s theme support. Merely think of it as a good starting point.


I’ve been using this approach enough that I’ve created a generator for it.


theme_generator


Usage


After you’ve installed the generator, just call it with the name of the theme you’d like to create.


./script/generate theme blue-bird

It will then add theme_engine.rb to your lib/ folder and create the required file structure.


Note: On Windows, it looks more like:


ruby script\\generate theme blue-bird

File Structure


Let’s start by having a look at the file structure it creates. Here’s an example for a theme named ‘blue-bird’.


app/views/layouts/themes/blue-bird/public/themes/blue-bird/images/javascripts/theme.css

Just from looking at that, you can probably get a good idea where I’m going.


Static Files


All of the static files, CSS, Images, and JavaScripts are under the app/public/themes directory, as they should be. Apache (or lighttpd, or whatever) will happily serve these up for us.


To reference theme-specific images from the CSS it’s as simple as:


[code lang="css"]
BODY {
background: url( images/my-bg.png );
}
[/code]

Be sure to use a relative path to the image. CSS will look for images relative to the CSS file, not the page, remember?


Layouts


You’ll notice under the app/views/layouts folder, I’ve added a theme structure similar to the one under app/public/. As an example, app/views/layouts/themes/default/main.rhtml is the main layout for the ‘default’ theme.


In your controller, you’ll tell Rails that you want a themed layout like this:


[code lang="ruby"]
class MyController << ApplicationController
layout :themed_layout
end
[/code]

Current Theme


The only thing that’s left to your controller is indicating which theme is currently active. It’s as simple as overriding the current_theme method.


[code lang="ruby"]
class MyController << ApplicationController
layout :themed_layout

def current_theme
'blue-bird'
end

end
[/code]

To set the theme for the entire application, you can add that to your ApplicationController instead (in app/controllers/application.rb).


Tag Helpers


To aid in retrieving themed media, helper methods have been added to the ActionView::Helpers::AssetTagHelper module.



  • theme_image_path

  • theme_stylesheet_path

  • theme_javascript_path

  • theme_stylesheet_link_tag

  • [More to come…]


Usage is generally quite simple. In your view, if you want to reference a themed image:


[code lang="xml"]

[/code]

Last, But Not Least


This needs to be included at the bottom of your environments.rb:


[code lang="ruby"]require_dependency 'theme_engine'[/code]

That’s it really—pretty straight forward. If you look at the theme_engine.rb you’ll see it’s a less-is-more type solution.


In the next few days I’ll polish the theme_engine some more, based on the feedback y’all provide, and refactor it into a plugin.

Posted
Theme by Cory Watilo.
More great Posterous themes at themes.posterous.com.