Rails for Designers – Using Haml/Sass for all projects
I have recently acquired a newfound drive for designing sites(as opposed to my earlier desire to be a great design/backend mediator). As of now, due to some reent developments, I am the main designer for most of our projects, not to mention some of which are personal or freelance related. One pet peeve I had though was the diversity of my projects: meaning some were in rails(of course I was happy with fixing views and adding some javascript-fu), php, and some, just plain XHTML/CSS.
With that said, things can get pretty messy when multiple projects are at hand and I have to shift continually from regular XHTML/CSS coding and HAML/SASS. Though it is not a great hindrance, having to keep remembering which language I was using was kinda annoying. Add to the fact that I work twice(or thrice) as fast using HAML/SASS and the tiny nuisance becomes a glaring problem(for me that is).
At first, I made a semi-solution. A compromise of sorts: since I use the ever cool Elements CSS framework(actually I just use the general html structure and a modified reset.css which I have discussed with the author, Ben Henschel), my html is usually almost ready-made so my usual focus is just the css file. For projects that used Rails(I still didn’t have a solution for ones that didn’t) but not Haml, I just installed Haml on my part, and continued developing with Sass. Since Sass generates a .css file, that’s the one I usually push in repos(if the client can’t be bothered with installing Haml).
But that was just for Rails projects. The problem lies with normal design projects or ones that used PHP. Recently, I had another solution(I doubt this is the most efficient though): make a blank rails app and keep using Haml/Sass for myself and when done with coding the design, I just do a view source, copy-paste the whole thing in a blank html file, modify the paths for the css and javascripts, then just copy the images/stylesheets/javascripts folders in my public/ folder. Nifty!
It was a good thing for me, since now, I can just keep coding in Haml and Sass to my heart’s content. Thing is, I just realized I just can’t keep making blank rails apps for each project! So the plan was to separate the projects in self-titled folders and just use some routes.rb and controller magic suggested by my friend Greg:
In routes.rb:
map.connect 'projects/:id', :controller => 'projects', :action => 'index'
and in my single controller named projects_controller.rb:
def index
render :action => "#{params[:id]}/index"
end
With that, I can just go to say /projects/projectA and it will then render projectA. This also works as a portfolio and future-reference of sorts for me, which is excellent. Now I only need to think of a good way to organize the images and the stylesheets(especially the javascripts) so they won’t interfere with each other but basically, I’m just planning to put them in separate folders too(except for reset.css and jquery.js of course – every project needs that!)
Extra note:
Forgot to mention that I had to add
config.frameworks -= [ :active_record, :active_resource, :action_mailer ]
since I wasn’t using any db.
Rack-based Session Stores on Rails
Rails edge is now using Rack-based session stores. That means you can access the same session on any Rack applications. Read about it on the Rails blog.
Nothing changes though on how you use sessions on Rails. On your Rails app, you’ll have something like
session[:user] = some_user_id
Let’s see how we can access the same session on a Rack application. You can read about Rack here.
Rack handles session using Rack::Session::Cookie. Create a file config.ru
use Rack::Session::Cookie, :key => '_railssession_session', :domain => 'railssession.labs.admoolabs.com'
run Proc.new {|env| [200, {"Content-Type" => "text/html"}, "Rack session 'user' has a value of #{env['rack.session'][:user] || 'nil'}."]}
The key should be the same key that you used on config/environment.rb on your Rails app.
Check out the demo. Set session[:user] on the Rails app, then view the session on the Rack app.
Scraping bot
I just recently found the joys of scraping. Yes, the “technique” is a bit underhanded, but it sure is fun. I guess as long as you don’t profit off of it, it’s ok(and it doesn’t affect the site you’re scraping). If you scraped a site just to present it in a different design(like scrape all the news off CNN and then make a site called BNN or something and then charged users with a smaller fee), then yeah, that’s just plain dirty.
I scrape for fun and that’s it. Anyways, there I was, scraping movie schedules off the only movie schedule site that I know of( clickthecity.com ) and suddenly, I had an idea. What if I just made an RSS feed for a movie house that I liked? It would be just so cool since clickthecity(or CTC) doesn’t have an RSS feed. So I started researching about makign RSS feed, and while doing so, Topher brought about the idea of making a bot. He showed me how jabberbot and from there I went on and played around with it.
To make the scraper, I used the Rubyful-soup plugin for Ruby on Rails(along with Mechanize). Using it was easy, and the main problem actually was how to traverse the atrocious table layout of clickthecity. Once I got over that hurdle though, getting the info I wanted was easy. And what did I need? I only just needed the date of the showtimes(so I’ll know if it was the latest update), the location of the cinemas(the mall the cinemas were located), the cinema name(or number), the movies being shown on each movie house, and the show times of each. These were saved into a database I made(I had a bit of a trouble in putting them in, especially since there were movie houses that had two different movies being shown the same day)
Next was the bot itself. Like I said, I used jabberbot, which was also a handy plugin for Ruby on Rails. The syntax was easy, and this was the easiest part. I made a new google account just for the bot and now it is up. I still have yet to make it work on yahoo messenger(Topher tried it and it didn’t work, but I haven’t tried it for myself yet) so I’ll just have to settle with Gtalk.
The flow of the program is simple: scrape the data from clickthecity.com and then save it to the database(done using a rake task I made). I have yet to automate these tasks, along with the connection of the bot(I still have to manually start it using another rake task). Anyways, after manually callign the rake tasks for scraping the site and starting the bot, movieschedule-bot is ready to go.
So far, I only added a select few movie houses that me and my friends usually go to. You can actually add movieschedules (yes, google mail) to your gtalk/gmail contact list and start using it(don’t worry about down times. that just means I am currently updating/restarting it – try again after five minutes if it doesn’t work) Don’t try to spam it though as right now it is running from my local machine. I have yet to upload it to my free Heroku account and make it run the bot forever.
So there you have it. A scraper bot. There are a LOT of other uses for this, like a thesaurus bot, wikipedia bot, imdb bot or something but that’s for another discussion. As you can see, bots can be useful too! Right now, movieschedules is looking for more friends. Be kind to it!
To start using movieschedules, just add it to your Google contact list then type “help” and send it. It will return you a list of commands that are currently available. Have fun!
Railsconf 2008
I will be at Railsconf 2008 at Portland. I still haven’t finalized the sessions I’m attending but I’m sure it will be great.
Alphabar on Rails
I am working on this little project right now using Ruby on Rails and I ran into some trouble with the alphabar plugin. First, alphabar uses the with_scope method which, since Rails 2.0 I believe, has been protected, giving me some errors since I froze my Rails version. I was able to overcome this obstacle by using the send method instead. Just change the last part of the find method of the plugin from:
model.with_scope({:find => {:conditions => conditions}})
{model.find :all}
to:
model.send(:with_scope, {:find => {:conditions => conditions}})
{model.find :all}
After I finally got that to work the plugin was very useful, although the alphabar was limited to letters and blank which is useful if you don’t need numbers. To accomodate numbers just add this to the alphabar helper:
('0'..'9').to_a.each do |i|
slots << i
end
Theoretically it should work for any character but I haven’t tried it yet.
So there you have it. Hoepfully somebody having trouble with this plugin will find this post useful.
Run from Capistrano
You can run shell commands from capistrano using the run method. For example, to create a symlink from the shared directory to the current directory, you’ll write
run "ln -nfs #{deploy_to}/shared/config/database.yml #{release_path}/config/database.yml"
run can also take a block like this
run "rsync /path/to/file host:/path/to/file" do |channel, stream, text|
logger.info "[#{stream}] #{text}"
output = case text
when /\bpassword.*:/i
"#{password}\n"
when %r{\(yes/no\)}
"yes\n"
end
channel.send_data(output) if output
end
When you run a command it might ask for your password. To handle this in capistrano, use send_data to send a response.
Check lib/capistrano/recipes/deploy/scm/subversion.rb on the capistrano gem to see how capistrano handles subversion commands.
RailsConf 2007 Keynote Videos
The keynote videos from RailsConf 2007 are now available online. Get them here.
DHH’s presentation is available here. DHH made a live demo showing REST and made a mistake. He said he wanted to show how easy it is to debug in Rails. I say the same thing when something goes wrong in my live demos.
nl2br in RoR
I recently found out that line breaks are not recognized when displaying a large block of text on the view (e.g. a post body). In PHP this was handled by the nl2br method but I had no luck finding a similar function in RoR. So I did what any sane person would do, create one myself. I placed this method in our model to format a particular field but it seems a better choice to put it in a helper.
def nl2br(text)
return text.gsub(/\n/, ‘<br/>’)
end
And there you have it, your very own nl2br method. Either you just found something really useful or I just wasted 2 minutes of your time. If anyone has a better solution or if I missed a function for this let us know by dropping a comment.
January 2008 PhRUG Meet-up
A PhRUG meet-up was held on Jan 16, 2008 at Ateneo de Manila University sponsored by Admoo Labs. 30 people attended the event. I gave a presentation on ‘Website Development with Ruby on Rails’. Greg Moreno talked about RSpec.You can download a copy of my presentation here. Pictures are here.
