Sunday, December 27, 2009

Added Crummy to generate breadcrumbs for CampZero.com

According to google's SEO guideline, its a good idea to provide breadcrumbs to your web contents. This is good in two ways: a) It helps people to find path to move up the navigation stack and b) it helps the google and other search engines to get a feel about your web content's hierarchical organization.
To add this breadcrumbs support, in my application www.campzero.com, a going to be online service marketplace for Bangladesh, I simply used the Crummy plugin. You can take a look at the Crummy plugin at github. It took me less than 10 minutes to find, learn and use this plugin! You can see the plugin in action at the campzero site.
I recommend this plugin for your Ruby on Rails breadcrumbs needs!

acts_as_permalinkable: SEO friendly rails URLs using my first RoR plugin

As a byproduct of my work on www.campzero.com, I released my first ruby on rails plugin called acts_as_permalinkable on github athttp://github.com/smsohan/acts_as_permalinkable
A comprehensive documentation is given at the github page. If you ever need to use search engine friendly urls or permalink like this blog, you may consider using the acts_as_permalinkable plugin. It takes less than 3 minutes to add the permalink feature to your rails model!
Get started by the following and you are free to contribute!
script/plugin install git://github.com/smsohan/acts_as_permalinkable.git

Thursday, December 24, 2009

Sitemap-generator for your Rails App and deployment solution

When talking about Search Engine Optimization for your public web pages, you probably try to follow the google guidelines for search engine optimization. Its a good one to get started with. For my recent project, www.campzero.com, I read the document and tried to follow the steps. Today, I worked on generating sitemap for www.campzero.com using the following:
  • Installed the site-map generator plugin following this link at Aktagon's, github link
  • For some reason, probably because of permission issues, my plugin install didn't generate the sample sitemap.yml file for me. However, I created the config/sitemap.yml file myself and put the following contents there:
domain: www.campzero.com
limit: 5000
priority: 1
change_frequency: weekly
  • Then, I put the call to the sitemap method as shown in the github documentation.
  • Finally, I ran the command rake sitemap:gerenate to generate my sitemap.xml file inside the public folder.
  • So far this went well with the local environment. However, when I deployed this code and ran the rake command in my staging environment, it said it was not finding any model with the sitemap method.
  • After some debugging, I found that the problem was with the code at the file generator.rb where they put model.methods.include?('sitemap_options') to see if the model contains a method named sitemap_options. But, at my staging environment, I found that this was returning false although there was this method inside the model. I changed the code to the following so that the include? check is done both for strings and symbols and it worked fine.
if((model.methods.include?(:sitemap_options) || model.methods.include?('sitemap_options')) && model.sitemap_options != nil)
models << model
end
  • Now, I could generate sitemap at my staging environment.
  • However, soon I found another issue with deployment, as I want my sitemap file to stay between deployments. So, I had to ensure the sitemap file is generated at a shared place other than the default public folder. I did the following changes to the sitemap_generator_task.rake file:
if defined?(SITEMAP_FILE_PATH)
SitemapGenerator::Generator.new(SITEMAP_FILE_PATH).find_models_and_generate
else
SitemapGenerator::Generator.run
end
  • I added the constant SITEMAP_FILE_PATH in my config/environments/staging.rb file to get it working.
  • Finally, I changed my deployment script to define a symlink from the public folder to the shared file path as follows:
run "ln -s #{shared_path}/sitemap/sitemap.xml #{release_path}/public/sitemap.xml"

Tuesday, December 22, 2009

How to strip html tags, truncate and highlight texts in ruby on rails

Recently, I had the following requirements as I was working on CampZero.com - the going to be service marketplace of Bangladesh.
  1. Remove all html tags other than hyperlinks and new lines from a html fragment
  2. Truncate the text to show only first 200 characters of the text and append ellipsis (...) in case the text was truncated.
  3. Highlight an array of words in the text to show the search query worlds that matched
The first one, getting rid of all but hyperlinks and new lines was achieved by the following code:

<%= sanitize my_html_text, :tags => %w(br a) %>
Next, to truncate the text, I simply used the following:

<%= truncate my_sanitized_text, :length => 200 %>
Lastly, to highlight my search query words, I did the following

#in the controller
@query_words = params[:query] ? params[:query].split(/\W/) : ''
#in the view
In reality, I chained the above thee methods as shown below:
<%= highlight(truncate(sanitize(my_html_text, :tags => %w(br a)), :length => 200), @query_words) %>
These methods and their siblings are great as time savers. Rails makes the web development fun by including this as built in methods. For reference, you can check the link at SanitizeHelper and TextHelper
Happy railing!

Friday, December 18, 2009

How is Rails plugins helping me in developing CampZero.com?

I am up to a web venture called www.CampZero.com - an online market place for you service providers in Bangladesh. This is somewhat similar in spirit to classified sites like ebay and craigslist, but the target market it consciously chosen to be the service industry. Anyway, I will go to the point why I picked rails for this project and how it is paying off.

A little background about me. I have some good background on .Net/C# and I developed several projects using this technologies. Also, I have some experience with Rails and developed almost same number of projects as that of .Net. So, I made an informed decision about choosing the Ruby on Rails framework for my project over .Net/C#. Here's the rationale:

Story#1: As a CampZero developer, I want to deploy the system as soon as I am done with a feature.
Solution: Use capistrano to automate the deployment process. It took me less than 30 minutes to setup the automatic one-click deployment. The deployment steps are at a minimum as follows:
  1. Get the latest code from the code repository.
  2. Create a link to the shared log directory.
  3. Create a link to the shared assets directory.
  4. Create a link to the full text search configuration file.
  5. Migrate the database schema.
  6. Change the link to the application to the latest code.
  7. Restart the full text search engine.
  8. Restart the web server.
  9. Rollback if any step of 1-8 results in a failure.
The whole process is triggered by a single line of command "cap staging deploy:migrations" and takes less that 3 minutes to complete on an average.

Story#2: As a guest user of CampZero, I would like to sign up for an account so that I can post an ad and/or rank the service providers.
The signup process is actually a three step process as follows:
  1. Create account, with password encrypted.
  2. Get an email with an activation link.
  3. Verify email address by clicking an activation link.
Also, there are several related works as follows:
  1. Login
  2. Logout
  3. Reset password
I used Authlogic for this purpose and it has taken care of all the aspects for me. For emailing I used ActionMailer. The whole job of authentication took no more than 4 hours! Thanks again to Authlogic.

Story#3: As a user of CampZero, I want to search for service providers using natural text.
The full text search was implemented using Sphinx and Thinking-sphinx. This also comes with default support for paginating lists. So, Thinking sphinx took care of all my search needs. I used the following features:
  1. Search by full text in the service description, title.
  2. Also search the service provider names and service categories.
  3. Rank by the ratings.
  4. Search using English morphology, for example, if searching for 'cars' it also searches for 'car'.
I spent as little as 6 hours to setup and code the whole free text search! The total coding size for search is less than even 15 lines in total!

Story#4: As a service consumer, I want to rate and write comment on my service providers so that other consumers can make informed decisions.
I used two plugins called, rate-fu and acts as commentable! These plugins are great time savers as well. All the underlying logics for handling ratings and commenting are already there and you merely plug the features in. It took me 5 hours and most of it was due to the UI part!

I am convinced that for most web applications now, Ruby on Rails is an automatic best seller. But, of course, my prior experience helped me in getting things done even faster. Lets see how this project makes a business :-)


Thursday, December 17, 2009

"Promises are meant to be broken" and my 2010 promises

"One must have a good memory to be able to keep the promises that one makes"
--Friedrich Nietzsche
"Promises are like the full moon, if they are not kept at once they diminish day by day"
--German Proverb
“Better a broken promise than none at all.”
--Mark Twain

Its always good to refer to previous experiences when you do a research. This doesn't only make you fair but also eliminates the reinventing the wheel problem! Well, this is what I learned from my graduate studies :-)
So, what is this about promises today? Well, you know its the time of the year when you have vacations and enjoy with family and friends... and start thinking about the next year. Make some rough plans probably for the upcoming year. Here is what I am promising-
  1. By January 1, find two potential MS research topics and draw an outline of each!
  2. By January 1, reduce 1kg weight!
What's next? Well, I have a vision of the future but trying to be agile here. Not doing lot of useless upfront thinking and leaving it up to the retrospect session on January 1 :-) I believe agile works and so if I can follow the spirits, I should be able to reach my vision on time.
My readers can wait till Jan 1 to get the retrospect report! I will be blatant and truthful (and this is a promise!).

Tuesday, December 15, 2009

What I learned from my first semester at University of Calgary as a Grad Student?

In a single line, the first semester has been awesome.
Some of you already know that I came to Calgary, AB, Canada this fall to start a graduate research focusing agile software development. So, to get started I tried to come up with a research idea by hunting several resources including popular publications, blogs and books. This is not yet over...
However, I took a course called Applied Machine Learning and had the opportunity to work on a project that might lead to my MS thesis. The project, Auto Tagging Emails with User Stories, targets to grab and automatically tag emails with user stories based on a project's context information. The trick is, if you see the text similarity between an email and a user story and complement with their temporal and meta data similarity, you can make a guess about their relation. I wanted to make it an automatic process so that when people share knowledge in emails they can easily make use of this knowledge for future references. The project was successful in its scope and I submitted a paper day before yesterday. Keeping my fingers crossed to see the decision on this paper!
Apart from the project, this course also offered the unique opportunity to work with Prof. Dr. Richter. He was really helpful and spent a lot of time on my project and the paper.
I also did a group project for the Interactive Tabletops and Surfaces course. This project was called "Tavolo", a surface solution for conferences where people could bring their research ideas through images/videos/pdfs and annotate/share with others. This was my first ever tabletop project. We used Microsoft Surface and I liked the hardware so far. But in the end I found that the size and low resolution of the surface limited our opportunity to implement several features of the project. But in a nutshell this project gave me the opportunity to try something around Human Computer Interaction and next generation collaboration designs.
During the last week of November, I attended the ITS2009 conference. It was a 3 day international conference people came from all continents. I liked the presentations and the fact that this research community is as if its a connected web. I must say, the Bill Buxton speech was a great one. He envisioned the next generation human computer interaction and also discussed about real life commercial applications coming out of the research. It was very inspiring!
I also submitted a grant application to iCore. I am personally convinced that this was a good proposal and I have the necessary background to make it a successful research. But according to my supervisor, its a good idea to be less optimistic with iCore fund. Anyway, composing this application helped me in finding some of the holes in my writing and thinking skills. I will happily take this lesson!
In my family life, this was an eventful time as well. My wife, Shahana, got admitted to the ECE department at University of Calgary and she will start her MS this January. This means we might be graduating at similar times and be back to Bangladesh soon thereafter. Wish we make good use of the opportunity in our graduate studies.
Well, this is a pretty much a summary! But I forgot one thing, Swimming! For the last month and half, I am going to swimming 3/4 days a week and enjoying this activity. The university swimming pool, like all other games and sports venues, is really well maintained.
I am looking for a Camera and waiting for the Boxing Day sale. Let me know if you saw a good DSLR camera around $500!
Oh! I forgot another announcement! I have taken my first web venture at www.campzero.com! If you have some time stop by and let me know if you like/dislike the idea and its presentation. I am planning to go live from Jan 1 2010!
Merry Christmas!