Rails Static Pages
2011-04-18 13:00:00 +0000
Static pages are one of those things that you have to get around to doing for every website. This is how we implemented them on StillAlive to make them maintainable and also cacheable.
On pretty much every website, you will have a bunch of pages that are just plain old static content. Good examples of these are Privacy Policies, Terms of Use, Contact Pages and the like. These generally contain content that rarely changes.
To make these simple static pages, we first add a catch all route at the bottom of config/routes.rb which looks like this:
match ':page_name' => 'site/pages#show'
As this is a catchall route, you need to put this right at the bottom of your routes file. Basically it just catches anything that is not defined in the above routes and send it off to PagesController#show with the params[:page_name] set to the requested path.
So if the user navigates to http://stillalive.com/plans_and_pricing then the PagesController will have the show method called with plans_and_pricing set as the params[:page_name]
With the routing set, we then make a Pages controller that looks like this:
class PagesController < ApplicationController
layout 'site'
def show
@page_name = params[:page_name].to_s.gsub(/\W/,'')
end
end
Some key points here, firstly, we set the @page_name variable to be the value of the params[:page_name], call #to_s on this (which handles the case of params[:page_name] being nil) and then call #gsub on the string stripping out anything that is not a word character.
With that done, we then drop through to rendering pages/show.html.erb which looks like this:
<%= cache "site-page-#{@page_name}-#{App.git_revision}" do %>
<%= render :partial => @page_name %>
<% end %>
So this just renders the partial with the page name requested.
So in the example above, we have a partial called pages/_plans_and_pricing.html.erb that gets rendered.
We also wrap it in a cache block. The cache block includes the page name, and also our git revision. We set the git revision so that every time we push new code to our server, all the prior cached pages get expired. This provides a no brainer way to make sure the latest code is showing on the site.
The App.git_revision call is using the App Config gem and is set by modifying config/app.rb to look like this:
class App < Configurable # :nodoc: # Settings in config/app/* take precedence over those specified here. config.name = Rails.application.class.parent.name config.git_revision = `git rev-parse HEAD 2>/dev/null`.to_s.strip end
This sets the value git_revision on boot. Simple.
Now the above code is good, but what happens when someone requests a page that does not exist on our site, we’ll, we can’t handle this the simple way, as the MissingTemplate exception gets raised outside of our controller, inside the show view.
One solution would be to wrap the render :partial call in the show.html.erb template in a rescue block, rescue the ActionController::MissingTemplate exception and render a missing template instead, however, the problem with this is that the response code will still be 200 OK, where we really want it to return a 404 page not found status.
So we need a way to check to see if the partial is valid or not, before we render the show action. There is no simple way to do this, so the way we handle it is by creating a partial_exists? method in the controller which checks, like so:
class PagesController < ApplicationController
layout 'site'
def show
@page_name = params[:page_name].to_s.gsub(/\W/,'')
unless partial_exists?(@page_name)
render 'missing', :status => 404
end
end
private
def partial_exists?(partial)
ValidPartials.include?(partial)
end
def self.find_partials
Dir.glob(Rails.root.join('app', 'views', 'site', 'pages', '_*.erb')).map do |file|
file = Pathname.new(file).basename.to_s
# Strip leading _ and then everything from the first . to the end of the name
file.sub(/^_/, '').sub(/\..+$/, '')
end
end
# Do this once on boot
ValidPartials = Site::PagesController.find_partials
end
By using a constant at the bottom, we only run the Dir.glob once at boot time to reduce the overhead (instead of running it on every request). The find_partials method returns a list of partials that look like:
['about', 'plans_and_pricing', 'privacy_policy'...]
This way, every time we restart our server, we get a new list of partials in production mode, and every time we refresh in development mode, this list gets updated in any case.
Hope this helps :)
blogLater
Mikel




2012-08-10 20:23:35 +0000
Nice Article, I feel strongly that love and read more on this topic. it’s very spectaculer….
Mesin Kasir | Komputer Kasir | Jual Barcode | Printer Kasir
Printer Kartu
2012-08-10 20:33:12 +0000
I realy like this article. This is a hash of default values for any email you send, in this case we are setting from the header to a value for all messages in this class, this can be overridden on a per email basis..
Mesin Kasir | Komputer Kasir | Jual Barcode | Printer Kasir
Printer Kartu
2011-04-18 05:04:01 +0000
I was wondering how to do that myself, so, I’m glad you did show me that way :-)
Now, the thing is, I went a slightly different way with the exception handling, I did :
rescue_from ActionView::MissingTemplate, :with => :no_page protected def no_page @page_name = 'missing' render 'show', :status => 404 endwith a partial named missing containing the appropriate message.
2011-04-26 18:55:53 +0000
Thanks for posting this Mikel, it’s always interesting seeing what solutions are being used in production.
I recently discovered HighVoltage by the ThoughtBot guys (https://github.com/thoughtbot/high_voltage) which seems to handle pages quite nicely also.
– Ivan
2012-09-17 00:55:37 +0000
Great article. A bit of sanity in this usually passionate matter.idateasia scam
2012-12-22 20:13:43 +0000
We ship the product from our European office, depending on the customer address
hardware keylogger
2012-11-03 19:08:15 +0000
It is possible to take an ged social studies official GED practice test which gives you an excellent idea of the questions involved and the www.pass4ged.com score you can achieve. It will also help you easily point out your weaknesses and where you need to improve before your real GED test. It is said that the most ged math practice test common reason people fail their GED exam is simply because they do not study the correct material. The only reason for this problem is that ged prep book they do not know what to study or more so, what to focus on. By taking practice tests you will get a feel for the areas you must study.
2012-11-03 19:10:36 +0000
It is possible to take an ged social studies official GED practice test which gives you an excellent idea of the questions involved and the www.pass4ged.com score you can achieve. It will also help you easily point out your weaknesses and where you need to improve before your real GED test. It is said that the most ged math practice test common reason people fail their GED exam is simply because they do not study the correct material. The only reason for this problem is that ged prep book they do not know what to study or more so, what to focus on. By taking practice tests you will get a feel for the areas you must study.
2012-12-22 20:12:43 +0000
We ship the product from our European office, depending on the customer address
hardware keylogger
2012-12-10 18:52:36 +0000
The accessories they use were very fashionable and i love to use those accessories.The football players also look handsome with good structure. usb safe
2013-01-04 09:37:34 +0000
The website is looking bit flashy and it catches the visitors eyes. Design is pretty simple and a good user friendly interface.PS3 Emulator
2013-01-19 09:53:24 +0000
So informative things are provided here,I really happy to read this post,I was just imagine about it and you provided me the correct information I really bookmark it,for further reading, So thanks for sharing the information.Xbox Emulator
2013-01-21 08:57:04 +0000
Hi Friends,
I’d like to tell you about a very good resource to earn cash daily. Here you can get paid for multi-tasking which includes:
1) Daily Surveys (Excellent for Tier 1 & 2 Countries as they can make many dollars in a single day and every day).
2) Completing Micro-Tasks (Excellent for Worldwide members). Here you can earn more than $20 per day if the proper tasks are available.
3) Getting Paid For Clicking
4) Completing Offers (Offers ranging from signing up to a site to install a software etc)
Apart from 4 points mentioned above, there are many more ways to earn which you can find out right after registering. If you decide to join from my link, I will give you full support in learning about how this thing actually works.
If you haven’t given it a try yet, it is the time now.. You’ve got nothing to lose here..
Here is the link: http://www.clixsense.com/?3956223
Well Wishes
2013-05-11 02:15:11 +0000
Great post. bean bags It’s good to see you to verbalize your heart and your clarity on this important issue can be easily detected. chairs Looking forward to read more. furniture beanbagnerd.com sofa