<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>Ruby on Rails development in Barcelona :: - Home</title>
  <id>tag:www.eduvoyage.com,2008:mephisto/</id>
  <generator version="0.8.0" uri="http://mephistoblog.com">Mephisto Drax</generator>
  <link href="http://www.eduvoyage.com/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://www.eduvoyage.com/" rel="alternate" type="text/html"/>
  <updated>2008-09-26T17:11:24Z</updated>
  <entry xml:base="http://www.eduvoyage.com/">
    <author>
      <name>admin</name>
    </author>
    <id>tag:www.eduvoyage.com,2008-09-26:6</id>
    <published>2008-09-26T16:40:00Z</published>
    <updated>2008-09-26T17:11:24Z</updated>
    <category term="blog"/>
    <link href="http://www.eduvoyage.com/ajax-tabs-and-rails" rel="alternate" type="text/html"/>
    <title>Ajax, tabs and Rails: Part 1</title>
<content type="html">
            &lt;p&gt;Developing a horizontal tabbed menu with Ajax functionality with Ruby on Rails, provides us with a fine example of why unobtrusive JavaScript is important, and worth bothering with.&lt;/p&gt;

&lt;p&gt;I'll quickly set up a skeleton of a rails app with an 'about us' section showing several related pages with information about something or another.&lt;/p&gt;

&lt;pre&gt;
&lt;code class=&quot;shell&quot;&gt;
$ rails tabs
$ script/generate controller about page_1 page_2 page_3 page_4
&lt;/code&gt;
&lt;/pre&gt;

&lt;pre&gt;
&lt;code class=&quot;ruby&quot;&gt;
class AboutController &amp;lt; ApplicationController
  #specify layout  
  layout 'application'
 
  #I don't need to define any methods, Rails will simply go looking for the called page in the 'about' folder under 'views'   
end
&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;My layout 'application' is minimal so as to keep things simple.&lt;/p&gt;

&lt;pre&gt;
&lt;code class=&quot;html&quot;&gt;
&amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.01//EN&amp;quot;
&amp;quot;http://www.w3.org/TR/html4/strict.dtd&amp;quot;&amp;gt;
&amp;lt;html&amp;gt;

&amp;lt;head&amp;gt;
 &amp;lt;meta http-equiv=&amp;quot;Content-type&amp;quot; content=&amp;quot;text/html; charset=utf-8&amp;quot;&amp;gt;
 # be sure to include javascript defaults, we&amp;#x27;ll be using Prototype    
 &amp;lt;%= javascript_include_tag :all, :cache =&amp;gt; true %&amp;gt;
 # ...and a style sheet	
 &amp;lt;%= stylesheet_link_tag &amp;#x27;screen&amp;#x27; %&amp;gt;		
 &amp;lt;title&amp;gt;Tabs&amp;lt;/title&amp;gt;				
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
 
 &amp;lt;div id=&amp;quot;content&amp;quot;&amp;gt;

  # Tabbed navigation is appropriately represented in HTML as an unordered list.
  &amp;lt;ul id=&amp;quot;tabnav&amp;quot;&amp;gt;
  
 	 # To help keep my template clean, I&amp;#x27;ll call a helper method (yet to be written), for generating a link. 
 	 &amp;lt;%= link(&amp;#x27;page_1&amp;#x27;, &amp;#x27;Page One&amp;#x27;) %&amp;gt;
 	 &amp;lt;%= link(&amp;#x27;page_2&amp;#x27;, &amp;#x27;Page Two&amp;#x27;) %&amp;gt;				
	 &amp;lt;%= link(&amp;#x27;page_3&amp;#x27;, &amp;#x27;Page Three&amp;#x27;) %&amp;gt;				
	 &amp;lt;%= link(&amp;#x27;page_4&amp;#x27;, &amp;#x27;Page Four&amp;#x27;) %&amp;gt;				
  &amp;lt;/ul&amp;gt;

  &amp;lt;div id=&amp;quot;tabContent&amp;quot;&amp;gt;
   &amp;lt;%= yield %&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;

&lt;/code&gt;
&lt;/pre&gt;


&lt;p&gt;Here is my helper method in about_helper.rb:&lt;/p&gt;
&lt;pre&gt;
&lt;code class=&quot;ruby&quot;&gt;
# helpers/about_helper.rb
# Method takes a page id and label and generates a link inside a list element, attaching a class name of 'active' on list element for active link. 
def link(id, label)
  &amp;quot;&amp;lt;li#{ &amp;#x27; class=&amp;quot;active&amp;quot;&amp;#x27; if controller.action_name == id}&amp;gt;#{link_to(label, send(&amp;#x27;about_&amp;#x27; + id + &amp;quot;_path&amp;quot;))}&amp;lt;/li&amp;gt;&amp;quot;
end
&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;I'll need to write some routes before we have something that works:&lt;/p&gt;
&lt;pre&gt;
&lt;code class=&quot;ruby&quot;&gt;
# config/routes.rb
ActionController::Routing::Routes.draw do |map|
  def map.controller_actions(controller, actions)
    actions.each do |action|
      self.send(&quot;#{controller}_#{action}&quot;, &quot;#{controller}/#{action}&quot;, :controller =&gt; controller, :action =&gt; action)
    end
  end

  map.controller_actions 'about', %w[page_1 page_2 page_3 page_4]
end
&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;And now for a lick of paint:&lt;/p&gt;
&lt;pre&gt;
&lt;code class=&quot;css&quot;&gt;
/* screen.css */
body {
	font: 100% verdana, arial, sans-serif;
	background-color: #fff;
	margin: 50px;
}

ul#tabnav { 
	text-align: left;
	margin: 1em 0 1em 0;
	font: bold 11px verdana, arial, sans-serif; 
	border-bottom: 1px solid #6c6;
	list-style-type: none;
	padding: 3px 10px 3px 10px; 
}

ul#tabnav li { 
	display: inline;
}

ul#tabnav li.active {
	border-bottom: 1px solid #fff; 
	background-color: #fff;	
}

ul#tabnav li.active a {
	background-color: #fff; 
	color: #000; 
	position: relative;
	top: 1px;
	padding-top: 4px;	
}

ul#tabnav li a { 
	padding: 3px 4px; 
	border: 1px solid #6c6; 
	background-color: #cfc; 
	color: #666; 
	margin-right: 0px; 
	text-decoration: none;
	border-bottom: none;
}

ul#tabnav a:hover {
	background: #fff; 
}

&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;Within the 'about' folder under views, you'll find several pages created earlier that need some dummy content. After adding some lorem text I kick-start mongrel and visit http://0.0.0.0:3000/about/page_1:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://eduvoyage.com/assets/2008/9/26/pic_a.gif&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Clicking through each tab works like a charm. I now have a simple, but functionally sound tab menu device. I'll consider adding a behavioral layer on top of what I've created, in order to provide Ajax functionality, and will write about it very soon in part two.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.eduvoyage.com/">
    <author>
      <name>admin</name>
    </author>
    <id>tag:www.eduvoyage.com,2008-08-03:4</id>
    <published>2008-08-03T16:06:00Z</published>
    <updated>2008-08-03T16:20:25Z</updated>
    <category term="blog"/>
    <link href="http://www.eduvoyage.com/" rel="alternate" type="text/html"/>
    <title>Widget with Rails</title>
<summary type="html">Widgets offer a simple and effective form of content distribution. Creating a JavaScript widget for your Rails app couldn't be easier. Here's how:</summary><content type="html">
            Widgets offer a simple and effective form of content distribution. Creating a JavaScript widget for your Rails app couldn't be easier. Here's how:
&lt;p&gt;I'll create a demo app called 'leaf recipes', a resource for salad lovers, where people can share favourite salad recipes: &lt;/p&gt;

&lt;pre&gt;
&lt;code class=&quot;shell&quot;&gt;
$ rails salad
$ cd salad
&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;Now for the  recipe resource. My first iteration will be simple, all I want is a title and a description:&lt;/p&gt;

&lt;pre&gt;
&lt;code class=&quot;shell&quot;&gt;	
$ script/generate scaffold recipe title:string description:text
$ rake db:migrate
&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;Now some content. I'll do this through the console:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;shell&quot;&gt;
$ script/console	
&gt;&gt; Recipe.create(:title =&gt; 'Crunchy Romaine Toss')
&gt;&gt; Recipe.create(:title =&gt; 'Roquefort Pear Salad')
&gt;&gt; Recipe.create(:title =&gt; 'Cranberry Spinach Salad')
&gt;&gt; exit
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Fire up webrick and visit &lt;strong&gt;http://localhost:3000/recipe&lt;/strong&gt;, which displays an index view, listing the three salads I just created.&lt;p&gt;

&lt;p&gt;I want my JavaScript widget to access my recipe resource with the same URL, but instead of returning HTML, I want it to spit out some JavaScript which the client browser can interpret. I need to visit the recipe controller:&lt;/p&gt;

&lt;p&gt;
&lt;span class=&quot;code&quot;&gt;app/controllers/recipes_controller.rb&lt;/span&gt;
&lt;/p&gt;

&lt;p&gt;I'm interested in the index method:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;
def index
  @recipes = Recipe.find(:all)
  respond_to do |format|
    format.html # index.html.erb
    format.xml  { render :xml =&gt; @recipes }
  end
end	
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;The &lt;strong&gt;respond_to&lt;/strong&gt; block is ready to respond to requests for html and xml. My widget's going to want JavaScript. I'll add it to the block:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;
def index
  @recipes = Recipe.find(:all)
  respond_to do |format|
    format.js # index.js.erb - this is where I'll craft my JavaScript
    format.html # index.html.erb
    format.xml  { render :xml =&gt; @recipes }
  end
end	
&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;
I'll create a corresponding view template:
&lt;/p&gt;

&lt;p&gt;&lt;span class=&quot;code&quot;&gt;app/views/recipes/index.js.erb&lt;/span&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;
var txt = &amp;#x27;&amp;#x27;

txt += &amp;quot;&amp;lt;div id=&amp;#x27;salads_widget&amp;#x27;&amp;gt;&amp;quot;;
txt += &amp;quot;&amp;lt;h2&amp;gt;Fine green salads from salads.com&amp;lt;/h2&amp;gt;&amp;quot;;
txt += &amp;quot;&amp;lt;ul&amp;gt;&amp;quot;;
&amp;lt;% for recipe in @recipes do %&amp;gt;
  txt += &amp;quot;&amp;lt;li&amp;gt;&amp;quot;;
  txt += &amp;quot;&amp;lt;%= escape_javascript(link_to recipe.title, recipe_url(recipe)) %&amp;gt;&amp;quot;;
  txt += &amp;quot;&amp;lt;/li&amp;gt;&amp;quot;
&amp;lt;% end %&amp;gt;
txt += &amp;quot;&amp;lt;/ul&amp;gt;&amp;quot;
txt += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;

document.write(txt);
&lt;/code&gt;&lt;/pre&gt; 

&lt;p&gt;Actual JavaScript code is minimal. Past txt += all we have is HTML markup with some erb template code for looping through the @recipes instance variable assigned in the recipes controller and displaying the title attribute within an HTML list. All of this is assigned to a JavaScript variable I've named &lt;strong&gt;txt&lt;/strong&gt; which is eventually written to the client's web page with &lt;strong&gt;document.write(txt)&lt;/strong&gt;.

&lt;p&gt;Our (very basic) JavaScript widget is ready for public consumption. Here's my 'copy and embed' snippet:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; language=&amp;quot;JavaScript&amp;quot; src=&amp;quot;http://localhost:3000/recipes.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt; 

&lt;p&gt;It is clear to see from the URL that the recipe resource is being called. The .js at the end is for the repsond_to block, letting it know to reply with JavaScript.&lt;/p&gt;
          </content>  </entry>
</feed>
