Register now and start sharing your code snippets.
-->

How to automatically ping search engines when your sitemap has changed

Ruby posted 2 months ago by christian

I prefer letting cron update sitemaps in the background, and at the end of the script I ping search engines to let them know it’s been updated:

   1  # Recreate sitemap goes here
   2  
   3  # Let search engines know about the update
   4  [ "http://www.google.com/webmasters/tools/ping?sitemap=http://xxx/sitemap.xml",
   5    "http://search.yahooapis.com/SiteExplorerService/V1/ping?sitemap=http://xxx/sitemap.xml",
   6    "http://submissions.ask.com/ping?sitemap=http://xxx/sitemap.xml",
   7    "http://webmaster.live.com/ping.aspx?siteMap=http://xxx/sitemap.xml" ].each do |url|
   8    open(url) do |f|
   9      if f.status[0] == "200"
  10        puts "Sitemap successfully submitted to #{url}"      
  11      else
  12        puts "Failed to submit sitemap to #{url}"
  13      end
  14    end
  15  end
  16  

More about sitemaps: http://en.wikipedia.org/wiki/Sitemaps

Tagged sitemap, ruby, ping, search, google

SEO optimized image URLs with the Paperclip Rails plugin

Ruby posted 3 months ago by christian

Create config/initializers/paperclip.rb:

   1  Paperclip::Attachment.interpolations[:permalink] = lambda do |attachment, style|
   2     attachment.instance.permalink
   3  end

In the model:

   1  has_attached_file :image, 
   2                      :path => ":rails_root/public/images:permalink/:style/:basename.:extension",
   3                      :url => "/images:permalink/:style/:basename.:extension",
   4                      :styles => { :large  => "250x360#",
   5                                   :medium => "150x230#",
   6                                   :small  => "110x150#" }

Instead of URLs like:

/images/products/249/large/temp.jpg

You can get a URL based on, for example, a permalink as in the example above. In my case I get URLs like this:

/images/games/nintendo-wii/large/super-mario-galaxy.jpg

Tagged paperclip, rails, ruby, plugin, seo, url

How to use the new internationalization (I18n) API available in Rails 2.2

Ruby posted 3 months ago by christian

Not yet released, but you can try it out by first installing the i18n gem:

   1  sudo gem install i18n 

And then testing the following code:

   1  require 'rubygems'
   2  require 'i18n'
   3  
   4  I18n.store_translations 'en-US',
   5  	:yes => "yes",
   6  	:no => "no", 
   7  	:inbox => {
   8  	  :one => '1 message', 
   9  	  :other => '{{count}} messages'
  10  	}
  11  
  12  I18n.store_translations 'sv',
  13  	:yes => "ja",
  14  	:no => "nej", 
  15  	:inbox => {
  16  	  :one => '1 meddelande', 
  17  	  :other => '{{count}} meddelanden'
  18  	}
  19  
  20  I18n.locale = 'en-US'
  21  
  22  puts I18n.translate(:yes)
  23  puts I18n.translate(:inbox, :count => 1)
  24  puts I18n.translate(:inbox, :count => 2)
  25  puts I18n.localize Time.now
  26  
  27  
  28  I18n.locale = 'sv'
  29  
  30  
  31  puts I18n.translate(:yes)
  32  puts I18n.translate(:inbox, :count => 1)
  33  puts I18n.translate(:inbox, :count => 2)
  34  puts I18n.localize Time.now

Troubleshooting

Note that the gem doesn’t contain localization data, so you’ll get the following error:

   1  translation missing: en-US, time, formats (I18n::MissingTranslationData)

To fix this, simply tell the I18n gem where to find the locales you want to use:

   1  I18n.load_translations "#{RAILS_ROOT}/locales/#{locale}.rb"

Creating a shortcut for i18n.translate

I recommend you create a shortcut for I18n.translate to the Symbol and String classes:

   1  class Symbol
   2  	def t(params = {})
   3  		I18n.t(self, params)
   4  	end
   5  end
   6  
   7  class String
   8  	def t(params = {})
   9  		I18n.t(self.to_s, params)
  10  	end
  11  end
  12  

Now instead of this:

   1  puts I18n.translate(:yes)
   2  puts I18n.translate(:inbox, :count => 1)
   3  puts I18n.translate(:inbox, :count => 2)

You can type:

   1  puts :yes.t
   2  puts :inbox.t(:count => 1)
   3  puts :inbox.t(:count => 2)

Handling missing translations

You can use this code to change the default behavior for missing translations, instead of showing “Missing translation” this code allows you to log the missing translation:

   1  class Symbol
   2    def t(params = {})
   3      params.update({:raise => true})
   4  
   5      begin
   6        I18n.t(self, params)
   7      rescue I18n::MissingTranslationData
   8        RAILS_DEFAULT_LOGGER.info("Translation for '#{self}' is missing")
   9        self
  10      end
  11    end
  12  end
  13  
  14  
  15  class String
  16    def t(params = {})
  17      params.update({:raise => true})
  18      key = self.downcase.to_s
  19        
  20      begin
  21        I18n.t(key, params)
  22      rescue I18n::MissingTranslationData
  23        RAILS_DEFAULT_LOGGER.info("Translation for '#{key}' is missing")
  24        self
  25      end
  26    end
  27  end

References
  1. http://github.com/svenfuchs/i18n/
  2. http://github.com/clemens/i18n_demo_app/
  3. http://www.artweb-design.de/2008/7/18/the-ruby-on-rails-i18n-core-api
  4. How to use the new I18n API with Rails

Tagged ruby, rails, i18n

How to parse CSV data with Ruby

Ruby posted 3 months ago by christian

Ruby alternatives for parsing CSV files

  • Ruby split (slow)
  • Ruby CSV (slow)
  • FasterCSV (slow)
  • ccsv (fastest & recommended if you have control over CSV format)
  • CSVScan (fastest & recommended if you have control over CSV format)

CSV library benchmarks can be found here and here

Parsing with plain Ruby

   1  filename = 'data.csv'
   2  file = File.new(filename, 'r')
   3  
   4  file.each_line('\n') do |row|
   5    columns = row.split(",")
   6    
   7    break if file.lineno > 10
   8  end

This option doesn’t support quoted text…

Parsing with the CSV library

   1  require 'csv'
   2  
   3  CSV.open('data.csv', 'r', ';') do |row|
   4    p row
   5  end
   6  

Parsing with the FasterCSV library

   1  require 'rubygems'
   2  require 'faster_csv'
   3  
   4  FasterCSV.foreach("data.csv", :quote_char => '"', :col_sep =>';', :row_sep =>:auto) do |row|
   5    puts row[0]
   6    break
   7  end

Parsing with the ccsv library

ccsv is hosted on GitHub.

   1  require 'rubygems'
   2  require 'ccsv'
   3  
   4  Ccsv.foreach(file) do |values|
   5    puts values[0]
   6  end

Parsing with the CSVScan library

CSVScan can be downloaded from here.

   1  require "csvscan"
   2  
   3  open("data.csv") {|io|
   4    CSVScan.scan(io) {|row|
   5      p row
   6    }
   7  }

Tagged csv, parse, ruby, fastercsv, ccsv, csvscan

How to unzip, gunzip, untar files with Ruby

Ruby posted 3 months ago by christian

This is a very advanced and resource efficient algorithm for expanding compressed content with Ruby:

   1  def gunzip(filename)
   2    command = "gunzip --force #{filename}"
   3    success = system(command)
   4    
   5    success && $?.exitstatus == 0
   6  end

To customize, change gunzip to whatever command you like.

For example, to avoid 100% CPU utilization during uncompression, set the niceness value of the command with nice -n 5 <command>:

   1  command = "nice -n 5 gunzip --force #{filename}"

There’s also ionice…

Tagged gunzip, ruby, untar, unzip, nice, ionice