<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>The Vose Way: Cascading page attributes</title>
    <link>http://www.chuckvose.com/articles/2006/05/08/cascading-page-attributes</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>A Blog about Butter, Cheese, and Ruby on Rails</description>
    <item>
      <title>Cascading page attributes</title>
      <description>&lt;h2&gt;Intro and Concept&lt;/h2&gt;


	&lt;p&gt;One of the first things I tried to do in Rails was to figure out how to make a nice, generic website that anyone could update. After about sixteen iterations I&amp;#8217;ve finally stumbled on one that I think will finally work.&lt;/p&gt;


	&lt;p&gt;As of now it&amp;#8217;s only partially complete. I&amp;#8217;m really only using this method to generate the titles and meta information but each time I have to make a change to the website I find more and more information going into what I call the welcome message.&lt;/p&gt;


The idea is as follows: 
	&lt;ul&gt;
	&lt;li&gt;Making an action for each page is almost always rediculous and hard to update. So that&amp;#8217;s pretty much out.&lt;/li&gt;
		&lt;li&gt;Making a loader page that loads a Page object and displays the content works for the most part if you don&amp;#8217;t have special content (and as long as you remember to change the :parameter if you ever try to paginate a series of pages.) &lt;/li&gt;
		&lt;li&gt;Making the content an optional part of an initialize function in the application.rb will ensure that you can always access page related information on any page (ever dynamic pages).&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;In order to do this I have a function called `initialize` in my application.rb that parses the @params and looks through the database for a entry in the welcomes table. As I said, I&amp;#8217;m only using parts of this but it would be easy to extend; initially this was just to display a welcome message on any page they wanted.&lt;/p&gt;


	&lt;p&gt;If there&amp;#8217;s an entry in the welcomes table with controller  params[:controller], action  params[:action], and id == params[:id], then it returns a raft of information such as the page title, a background image, meta values, etc. These override the defaults in the page (and there must be defaults) and make the page dynamic.&lt;/p&gt;


	&lt;p&gt;The beauty of this approach is that it&amp;#8217;s very easy to take an action that actually has an action (such as /admin/delete_user) and pop a new title on it, or meta values, or custom css, or whatever you can think of. If you have this table contain content you could have a blank template by default that gets overridden by the content in the row.&lt;/p&gt;


	&lt;h2&gt;Steps&lt;/h2&gt;


	&lt;ul&gt;
	&lt;li&gt;Create the table and figure out what you want to be able to apply to any action. Titles and meta values are a great start. Make sure to make a unique index on the controller, action, and id rows (This is very important). &lt;/li&gt;
		&lt;li&gt;Create an initializer function that searches this new table for the controller, action, and id in the params.&lt;/li&gt;
		&lt;li&gt;Create before_filters in each controller you want this to be available in. This may be possible in the application.rb but I haven&amp;#8217;t tried it (and it can be extremely picky). &lt;/li&gt;
		&lt;li&gt;Create forms that make editing these items easy. Definitely note that it&amp;#8217;s entirely possible to have /page/page_loader override /page/page_loader/3. This may be intended and a good idea but it&amp;#8217;s pretty important to note that it could completely wreck things until you figure out why things aren&amp;#8217;t working.&lt;/li&gt;
		&lt;li&gt;Lastly, create sane defaults in the initializer function for pages that don&amp;#8217;t have entries. This is incredibly important.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h2&gt;Conclusion&lt;/h2&gt;


	&lt;p&gt;I realize that I breezed over all the details, this was intentional. Because I&amp;#8217;ve not actually done this entirely in a site (only as far as titles and whatnot) I don&amp;#8217;t want to give fake code samples. I&amp;#8217;ll get there eventually but it may be a while until I start a new project.&lt;/p&gt;


	&lt;p&gt;At any rate, the idea is sound and is working in part very well in my sites so far. There are a lot of gotchas, mostly in the defaults, but there&amp;#8217;s also a lot of room to innovate. The idea of the defaults cascading is a wonderful extension especially when so many sites are in tree/nested set formations.&lt;/p&gt;


	&lt;p&gt;Keeping the attributes away from the actual code is a  great way to make it easy for customers to interact with the website. Customers often want to change little things and it&amp;#8217;s important that they be able to change as much as possible even when the code is mostly hidden in a template or you&amp;#8217;ll end up making little changes for the rest of your existence.&lt;/p&gt;</description>
      <pubDate>Mon, 08 May 2006 01:15:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:e4480249-7a5c-4901-b0a9-9765d1e5cdf4</guid>
      <author>vosechu@create-on.com (Chuck Vose)</author>
      <link>http://www.chuckvose.com/articles/2006/05/08/cascading-page-attributes</link>
      <category>Rails</category>
      <category>MySQL</category>
      <trackback:ping>http://www.chuckvose.com/articles/trackback/5</trackback:ping>
    </item>
  </channel>
</rss>
