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

Карты соответственно будут лежать в только что созданных директориях.

No Comments.

Leave a Reply

(обязательно)

(обязательно)