Static pages for the enterprise

''

HasManyThroughJoshSusser writes about how to handle simple static pages.

This is a fairly simple problem that many sites face. You want to keep use of your layout (and any conditionals in it - like a login/logout area, for example), but it feels like overkill to build a bunch of empty actions just to render static content. Not to mention that it’s a disgusting violation of RESTful action naming (which, personally speaking, would keep me up at night).

In Josh’s example, he already has a home_controller with an index action for his homepage - and he takes advantage of that existing controller by adding a #show action to it, and adding a route which will send his static content page requests to that action:

map.home ':page', :controller => 'home', :action => 'show', :page => /about|contact/

This works well, but I don’t really like the overloading of the home_controller #show action there. You’re not showing a home … unless it’s a real estate app and all your static pages are actually For Sale listings … !!!

Here’s an enterprisey static page solution I recently used.

In your routes…

map.site 'site/:name', :controller => 'page', :action => 'show'

And in PageController…

class PageController < ApplicationController

  verify :params => :name, :only => :show, :redirect_to => :root_url
  before_filter :ensure_valid, :only => :show

  def show
    render :template => "pages/#{current_page}"
  end

  protected

  def current_page
    params[:name].to_s.downcase
  end

  def ensure_valid
    unless %w(about copyright guidelines help privacy terms).include? current_page
      render :nothing => true, :status => 404 and return false
    end
  end

end

In this approach, I do a few things to help myself sleep at night:

  • I’m staying RESTful with action naming - that’s maybe one hour each night
  • I’m keeping the logic about what’s a valid page or not in the controller (which is the next best spot to the filesystem) - although I like Josh’s suggestion to use a PAGES constant in the controller as well.
  • I’m avoiding the implicit action behavior that rails gives you when you have files on disk which match requested paths. I’ve never liked this, so I don’t want to reward bad behavior by taking advantage of it.

We’ve also done the create an empty SiteController and throw static content in app/views/site/* approach - and we’ve also tried using Comatose - with mixed results.

What does everyone else do?

Pair with one of our expert developers to level up your skills with Coaching by thoughtbot. Save time learning best practices and techniques for reducing technical debt in Ember, Ruby, Haskell, and Go in 1-on-1 sessions tailored to your goals.