sitemap на Rails 3. rails-sitemap
Писать rake-файл, который сделает sitemap самому уже давно не модно т.к. существует 2 вагона готовых гемов для этого. Ниже я немного опишу гем rails-sitemap и самое главное покажу как его заставить делать несколько карт, например, для ситуации когда у сайта локация определяется поддоменом (напр.: ru.site.com и en.site.com).
установка
Как обычно закидываем в Gemfile:
gem 'sitemap' |
и бандлим:
# bundle install |
Далее надо сгенерировать конфигурационный файл:
$ rails g sitemap:install |
настройка
Все настройки хранятся в config/sitemap.rb
. На странице гема на гитхабе приведены примеры некоторых настроек, для создания более тонкой конфигурации рекомендуется читать доки, ссылка на которые не указанна и в гугле не числится.
Суть настройки сводится к указанию моделей по которым будет создаваться карта. Приведу пример конфигурационного файла простого сайта, у которого есть 3 модели: страницы (Pages), статьи (Articles) и новости (News). Статьи должны быть одобрены модератором, а новости интересуют только последние 100. Статей очень много.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Sitemap.configure do |config| config.max_urls = 50000 end Sitemap::Generator.instance.load :host=>'site.com' do path :root, :priority => 1 resources :pages, :skip_index => true, :change_frequency => "monthly" resources :articles, :objects => proc {Article.where(moderatable: true)}, :change_frequency => "weekly" resources :news, :objects => proc {News.last(100)}, :change_frequency => "never" end |
несколько карт
изменение гема
Чтобы создать несколько карт для начала нужно сделать несколько rake’овых заданий в геме, для этого нужно найти файл типа /usr/local/rvm/gems/ruby-1.9.2-p290/gems/sitemap-0.3.2/lib/tasks/sitemap.rake
, у меня Fedora 15.1 и Ruby 1.9.2-p290 через RVM, поэтому весьма вероятно, что у вас абсолютный путь до этого файла немного другой.
Далее его нужно открыть и изменить (у него рутовские права, так что либо изменяйте под рутом, либо дайте права).
Ниже приведен его вариант на 2 sitemap’а для английской версии сайта (en.site.com) и русской (ru.site.com), вообще-то это не принципиально, тут просто выбраны такие названия для удобства.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | namespace :sitemap do namespace :ru do def ru_setup require File.join(Rails.root, "config", "rusitemap") end desc "Generates a new sitemap." task :generate => :environment do ru_setup root = Sitemap.configuration.save_path || ENV["LOCATION"] || Rails.public_path path = File.join(root, "sitemap.xml") Sitemap::Generator.instance.build! Sitemap::Generator.instance.save path end end namespace :en do def en_setup require File.join(Rails.root, "config", "ensitemap") end desc "Generates a new sitemap." task :generate => :environment do en_setup root = Sitemap.configuration.save_path || ENV["LOCATION"] || Rails.public_path path = File.join(root, "sitemap.xml") Sitemap::Generator.instance.build! Sitemap::Generator.instance.save path end end desc "Ping engines." task :ping => :environment do Sitemap::Ping.send_request ENV["LOCATION"] end end |
Тут я просто разбил пространство имен sitemap
на 2 подпространства ru
и en
. Каждое подпространство содержит код идентичный коду исходного sitemap
, где изменены названия конфигурационных файлов.
Теперь надо отредактировать генератор /usr/local/rvm/gems/ruby-1.9.2-p290/gems/sitemap-0.3.2/lib/sitemap/generator.rb
(абсолютный путь тоже может не совпадать). Тут надо изменить метод save
, заменить ее на:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | def save(location) if fragments.length == 1 FileUtils.mv(fragments.first.path, location) else remove_saved_files(location) root = File.join(Pathname.new(location).dirname, "sitemaps") Dir.mkdir(root) unless File.directory?(root) fragments.each_with_index do |fragment, i| file_pattern = File.join(root,"sitemap-fragment-#{i + 1}.xml") FileUtils.mv(fragment.path, file_pattern) File.chmod(0755, file_pattern) end file = File.new(location, "w") file.write(render("index").gsub!('/sitemaps/','/'+Sitemap.configuration.locale_fragment_path+'/')) file.close end File.chmod(0755, location) end |
В этом методе я только заменил file.write(render "index")
.
файлы настроек
Т.к. теперь будут 2 карты, то и файлов настроек будет 2, их имена должны быть в соответствии с именами из /usr/local/rvm/gems/ruby-1.9.2-p290/gems/sitemap-0.3.2/lib/tasks/sitemap.rake
т.е. rusitemap.rb
и ensitemap.rb
.
Пример конфига config/rusitemap.rb
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | Sitemap.configure do |config| config.max_urls = 1000 config.save_path = File. join(Rails.root, "public",'sitemaps','ru') config.locale_fragment_path=File. join('sitemaps','ru','sitemaps') end Sitemap::Generator.instance.load :host=>'ru.site.com' do path :root, :priority => 1 resources :pages, :skip_index => true, :change_frequency => "monthly" resources :articles, :objects => proc {Article.where(moderatable: true)}, :change_frequency => "weekly" resources :news, :objects => proc {News.last(100)}, :change_frequency => "never" end |
В файле config/ensitemap.rb
все аналогично.
запуск
Теперь нужно сделать директории public/sitemaps/en
и public/sitemaps/ru
. После такого колдовства русская карта генерируется по команде:
$ rake sitemap:ru:generate |
английская:
$ rake sitemap:en:generate |
Карты соответственно будут лежать в только что созданных директориях.