Archive for January, 2008

Sandstone Preview: Features

Saturday, January 5th, 2008

OK, so I’ve explained a bit about what Sandstone is, and how it integrates with an existing Rails application (and how that results in better customizability and upgradeability). What exactly does it offer, though?

Starting with the basics, Sandstone is built around pages. Pages can be nested (using acts_as_tree), and have the standard attributes (path, content, title, and various bits of metadata). Sandstone enforces a simple workflow, where editors can create or edit pages that managers can then publish; editing a published page creates a new draft, to prevent changes from going live immediately. It also uses acts_as_versioned to handle the various drafts that are created. We have one Sandstone install using a WYSIWYG for the content, but the trunk version still uses straight HTML.

By default, pages use an included (customizable, of course) layout. Managers can create new layouts, however, that are then made available to editors for use on their pages. These page templates work just like a standard Rails layout - in fact, they are ERb templates, so you can use any embedded Ruby you like in them.

Both pages and page templates are cached to the filesystem (in app/views/pages/generated and app/views/layouts/generated, respectively) when they’re saved - and the cached versions of pages can actually be edited and saved to the filesystem independently of the web UI. This was intended to allow our designers (who are perfectly comfortable working with views of this sort) to make changes in their editor of choice, save them in the appropriate directory (and in source control), and have those changes picked up and saved to the database by Sandstone.

The plugin also gives you a sitemap by default - any pages created through Sandstone will automatically be added. Furthermore, if you specify a path that corresponds to a route already recognized in the system (like /categories, if you have a map.resources :categories in your routes file), Sandstone will recognize that and add an entry to the sitemap, but it won’t override your dynamic page.

Currently, the only roles in the system are editor and manager. As mentioned above, editors can create and edit pages. Managers can also work with pages directly, but they can also publish pages, manage page templates, and manage the user accounts that Sandstone recognizes.

So that’s what Sandstone currently does. Since it’s still under primary development, though, what might be more interesting is what’s on the roadmap - so that’s what I’ll talk about next time.

Sandstone Preview: Integration

Wednesday, January 2nd, 2008

Wow, who knew the holidays would be so counter-productive to finishing this post? Sorry about that!

Anyways, last time I gave a quick overview of the Sandstone plugin, and promised to explain the twin miracles of its customizability and upgradeability. Both of these stem from the way in which Sandstone integrates into an existing Rails application. When you install it, you get a generator - run that, and several controllers, models, and views are created in your app folder. If you open up one of the models, though, you’ll see something odd:

class Page < ActiveRecord::Base
include Sandstone::Models::Page
end

Similarly, the controllers seem… slim:

class PagesController < ApplicationController
include Sandstone::Controllers::Pages
layout 'sandstone'
before_filter :require_sandstone_editor,
:except => [:show, :destroy]
before_filter :require_sandstone_manager,
:only => [:destroy]
around_filter :authorize_sandstone_editor,
:only => [:edit, :update]
end

With both the controllers and models created by the generator, the bulk of the functionality is hidden away in modules defined within the plugin. This is the key to the whole approach - you have files in app/ that you can modify to your heart’s content - adding or overriding actions on the controllers and methods on the models as you need to, tweaking the filters and layouts used by the controllers, etc. - but the basic capabilities are preserved in vendor/plugins/sandstone. When you upgrade, then, all you have to do is install the new plugin over the old one, updating all of the Sandstone-provided functionality. Anything you’ve done in the app/ folder, however, will remain untouched (unless you rerun the generator, of course).

Obviously, this isn’t a foolproof approach. In particular, it falls down when you try to upgrade to a major release that significantly adds or changes its structure. To combat this, we’re not heavily promoting Sandstone until we get it to a point we consider stable (that’ll be Sandstone 1.0), after which we’ll keep such breaking changes to a minimum.

There is one other aspect of the integration that I’d like to talk about… Sandstone (as you can see from the controller above) has the concept of a user with a role (editor and manager, currently). Many, if not all, applications that might make use of the plugin will already have a User model of some sort, though. To deal with that, Sandstone avoids defining any sort of User model directly. Instead, it expects you to already have some sort of authentication already in place (restful_authentication or something similar, currently). The Editor model in Sandstone hooks into that preexisting model via a foreign key relationship. This allows for even easier integration into your existing system.