How to automatically ping search engines when your sitemap has changed
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
SEO optimized image URLs with the Paperclip Rails plugin
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
How to use the new internationalization (I18n) API available in Rails 2.2
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
How to parse CSV data with Ruby
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
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 }
How to unzip, gunzip, untar files with Ruby
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…