Class: Sitemap::Generator
- Inherits:
-
Object
- Object
- Sitemap::Generator
- Includes:
- Singleton
- Defined in:
- lib/sitemap/generator.rb
Constant Summary collapse
- SEARCH_ATTRIBUTES =
{ :updated_at => "lastmod", :change_frequency => "changefreq", :priority => "priority" }
Instance Attribute Summary collapse
-
#fragments ⇒ Object
Returns the value of attribute fragments.
-
#host ⇒ Object
Returns the value of attribute host.
-
#routes ⇒ Object
Returns the value of attribute routes.
-
#store ⇒ Object
Returns the value of attribute store.
Instance Method Summary collapse
-
#build! ⇒ Object
Generates fragments.
-
#file_url(path = "sitemap.xml") ⇒ Object
URL to the sitemap file.
-
#initialize ⇒ Generator
constructor
Instantiates a new object.
-
#load(options = {}, &block) ⇒ Object
Sets the urls to be indexed.
-
#path(object, options = {}) ⇒ Object
Adds the specified url or object (such as an ActiveRecord model instance).
-
#process_fragment! ⇒ Object
Creates a temporary file from the existing entries.
- #remove_saved_files(location) ⇒ Object
-
#render(object = "fragment") ⇒ Object
Parses the loaded data and returns the xml entries.
-
#resources(type, options = {}) ⇒ Object
Adds the associated object types.
-
#save(location) ⇒ Object
Creates the sitemap index file and saves any existing fragments.
Constructor Details
#initialize ⇒ Generator
Instantiates a new object. Should never be called directly.
17 18 19 20 21 22 23 24 |
# File 'lib/sitemap/generator.rb', line 17 def initialize self.class.send(:include, Rails.application.routes.url_helpers) self.fragments = [] self.store = Store.new(:max_entries => Sitemap.defaults[:max_urls]) self.store.before_reset do |entries| self.process_fragment! end end |
Instance Attribute Details
#fragments ⇒ Object
Returns the value of attribute fragments.
13 14 15 |
# File 'lib/sitemap/generator.rb', line 13 def fragments @fragments end |
#host ⇒ Object
Returns the value of attribute host.
13 14 15 |
# File 'lib/sitemap/generator.rb', line 13 def host @host end |
#routes ⇒ Object
Returns the value of attribute routes.
13 14 15 |
# File 'lib/sitemap/generator.rb', line 13 def routes @routes end |
#store ⇒ Object
Returns the value of attribute store.
13 14 15 |
# File 'lib/sitemap/generator.rb', line 13 def store @store end |
Instance Method Details
#build! ⇒ Object
Generates fragments.
138 139 140 141 |
# File 'lib/sitemap/generator.rb', line 138 def build! instance_exec(self, &routes) process_fragment! unless store.entries.empty? end |
#file_url(path = "sitemap.xml") ⇒ Object
URL to the sitemap file.
Defaults to sitemap.xml
.
164 165 166 |
# File 'lib/sitemap/generator.rb', line 164 def file_url(path = "sitemap.xml") URI::HTTP.build(:host => host, :path => File.join("/", path)).to_s end |
#load(options = {}, &block) ⇒ Object
Sets the urls to be indexed.
The host
, or any other global option can be set here:
Sitemap::Generator.instance.load :host => "mywebsite.com" do
...
end
Simple paths can be added as follows:
Sitemap::Generator.instance.load :host => "mywebsite.com" do
path :faq
end
Object collections are supported too:
Sitemap::Generator.instance.load :host => "mywebsite.com" do
resources :activities
end
Search options such as frequency and priority can be declared as an options hash:
Sitemap::Generator.instance.load :host => "mywebsite.com" do
path :root, :priority => 1
path :faq, :priority => 0.8, :change_frequency => "daily"
resources :activities, :change_frequency => "weekly"
end
54 55 56 57 58 59 |
# File 'lib/sitemap/generator.rb', line 54 def load( = {}, &block) .each do |k, v| self.send("#{k}=", v) end self.routes = block end |
#path(object, options = {}) ⇒ Object
Adds the specified url or object (such as an ActiveRecord model instance). In either case the data is being looked up in the current application routes.
Params can be specified as follows:
# config/routes.rb
match "/frequent-questions" => "static#faq", :as => "faq"
# config/sitemap.rb
path :faq, :params => { :filter => "recent" }
The resolved url would be http://mywebsite.com/frequent-questions?filter=recent
.
74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/sitemap/generator.rb', line 74 def path(object, = {}) params = Sitemap.defaults[:params].clone.merge!([:params] || {}) params[:host] ||= host # Use global host if none was specified. params.merge!(params) { |type, value| get_data(object, value) } search = Sitemap.defaults[:search].clone.merge!(.select { |k, v| SEARCH_ATTRIBUTES.keys.include?(k) }) search.merge!(search) { |type, value| get_data(object, value) } self.store << { :object => object, :search => search, :params => params } end |
#process_fragment! ⇒ Object
Creates a temporary file from the existing entries.
130 131 132 133 134 135 |
# File 'lib/sitemap/generator.rb', line 130 def process_fragment! file = Tempfile.new("sitemap.xml") file.write(render) file.close self.fragments << file end |
#remove_saved_files(location) ⇒ Object
168 169 170 171 172 |
# File 'lib/sitemap/generator.rb', line 168 def remove_saved_files(location) root = File.join(Pathname.new(location).dirname, "sitemaps") Dir[File.join(root, "sitemap-fragment-*.xml")].each { |file| File.unlink(file) } File.unlink(location) if File.exist?(location) end |
#render(object = "fragment") ⇒ Object
Parses the loaded data and returns the xml entries.
123 124 125 126 127 |
# File 'lib/sitemap/generator.rb', line 123 def render(object = "fragment") xml = Builder::XmlMarkup.new(:indent => 2) file = File.read(File.("../../views/#{object}.xml.builder", __FILE__)) instance_eval file end |
#resources(type, options = {}) ⇒ Object
Adds the associated object types.
The following will map all Activity entries, as well as the index (/activities
) page:
resources :activities
You can also specify which entries are being mapped:
resources :articles, :objects => proc { Article.published }
To skip the index action and map only the records:
resources :articles, :skip_index => true
As with the path, you can specify params through the params
options hash. The params can also be build conditionally by using a proc
:
resources :activities, :params => { :host => proc { |activity| [activity.location, host].join(".") } }, :skip_index => true
In this case the host will change based the each of the objects associated location
attribute. Because the index page doesn’t have this attribute it’s best to skip it.
111 112 113 114 115 116 117 118 119 120 |
# File 'lib/sitemap/generator.rb', line 111 def resources(type, = {}) path(type) unless [:skip_index] link_params = .reject { |k, v| k == :objects } get_objects = lambda { [:objects] ? [:objects].call : type.to_s.classify.constantize } get_objects.call.find_each(:batch_size => Sitemap.defaults[:query_batch_size]) do |object| path(object, link_params) end end |
#save(location) ⇒ Object
Creates the sitemap index file and saves any existing fragments.
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/sitemap/generator.rb', line 144 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) end file = File.new(location, "w") file.write(render "index") file.close end end |