Skip to content

Instantly share code, notes, and snippets.

@nruth
Last active December 12, 2015 03:19
Show Gist options
  • Save nruth/4706439 to your computer and use it in GitHub Desktop.
Save nruth/4706439 to your computer and use it in GitHub Desktop.
simple rails static page renderer
# last entry:
#static page routes
get '/home' => redirect('/')
root :to => 'static_pages#home'
get '*page', :to => 'static_pages#show', :constraints => {:page => %r{[\w\-\/]+}}
# -*- encoding : utf-8 -*-
class StaticPagesController < ApplicationController
layout 'master'
rescue_from ActionView::MissingTemplate, :with => :transmogrify_to_404
before_filter :clear_flash
def show
response.headers['Cache-Control'] = "public, max-age=#{1.hours}"
# remove unsafe characters
page = params[:page].strip.gsub(/[^A-Za-z0-9\/_-]/, '')
render "static_pages/#{page}"
end
private
def transmogrify_to_404
raise ActionController::RoutingError.new('Not Found')
end
def clear_flash
flash.clear
end
end
# -*- encoding : utf-8 -*-
require 'spec_helper'
describe StaticPagesController do
# create some test templates
around(:each) do |example|
paths = [
Rails.root.join('app', 'views', 'static_pages', 'testpages-50-top-ukcat-tips', '01-what-is-ukcat-and-is-it-fair.html.erb'),
Rails.root.join('app', 'views', 'static_pages', 'testpages-privacy.html.erb')
]
paths.each {|path| `mkdir -p #{File.dirname(path)} && touch #{path}` }
example.run
paths.each {|path| `rm #{path}; rmdir #{File.dirname(path)}` }
end
describe "routing depth-1 static pages to actions" do
it "routes to show with :page set to the path" do
{ :get => "testpages-privacy" }.should route_to(:controller => "static_pages", :action => "show", :page => 'testpages-privacy')
end
end
describe "rendering all included static pages" do
# glob the app/views/static_pages dir to find all templates
path = Rails.root.join('app', 'views', 'static_pages') + '**/*.html.erb'
pages = Dir.glob(path)
# reduce the glob matches to the path the users will visit
# strip off the base path
paths = pages.map {|p| p.sub!(Rails.root.join('app', 'views', 'static_pages').to_s + '/', '')}
# strip off the filetype
paths.map{|p| p.sub!('.html.erb', '')}
paths.each do |page|
specify "GET '#{page}' routes to the file" do
get :show, :page => page
response.should render_template("static_pages/#{page}")
end
end
end
describe "routing nested depth-n static pages" do
it "routing GET <path> to #show, :page => full path" do
{ :get => "/50-top-ukcat-tips/01-what-is-ukcat-and-is-it-fair" }.should route_to(:controller => "static_pages", :action => "show", :page => '50-top-ukcat-tips/01-what-is-ukcat-and-is-it-fair')
end
specify "controller responds to GET show, :page => '50-top-ukcat-tips/01-what-is-ukcat-and-is-it-fair with that template'" do
get :show, :page => 'testpages-50-top-ukcat-tips/01-what-is-ukcat-and-is-it-fair'
response.should render_template('testpages-50-top-ukcat-tips/01-what-is-ukcat-and-is-it-fair')
end
end
describe "Security" do
it "should allow a-zA-Z in the page path" do
alphabet = (('a'..'z').to_a + ('A'..'Z').to_a).join
{ :get => "/#{alphabet}" }.should route_to(:controller => "static_pages", :action => "show", :page => alphabet)
end
it "should allow numbers in the page path" do
numbers = (0..9).to_a.map(&:to_s).join
{ :get => "/#{numbers}" }.should route_to(:controller => "static_pages", :action => "show", :page => numbers)
end
it "should allow -_ in the page path" do
syms = "-_"
{ :get => "/#{syms}" }.should route_to(:controller => "static_pages", :action => "show", :page => syms)
end
end
describe "GET page which does not exist" do
describe "GET 'no-such-page'" do
it "should raise a 404 error" do
lambda {get 'no-such-page'}.should raise_error(AbstractController::ActionNotFound)
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment