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.
-
#protocol ⇒ Object
Returns the value of attribute protocol.
-
#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.
-
#literal(target_url, options = {}) ⇒ Object
Adds the literal url (for consistency, starting with a “/” as in “/my_url”) accepts similar options to path and resources.
-
#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 25 |
# File 'lib/sitemap/generator.rb', line 17 def initialize self.class.send(:include, Rails.application.routes.url_helpers) self.protocol = "http" self.fragments = [] self.store = Store.new(:max_entries => Sitemap.configuration.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 |
#protocol ⇒ Object
Returns the value of attribute protocol.
13 14 15 |
# File 'lib/sitemap/generator.rb', line 13 def protocol @protocol 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.
160 161 162 163 |
# File 'lib/sitemap/generator.rb', line 160 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
.
188 189 190 |
# File 'lib/sitemap/generator.rb', line 188 def file_url(path = "sitemap.xml") URI::HTTP.build(:host => host, :path => File.join("/", path)).to_s end |
#literal(target_url, options = {}) ⇒ Object
Adds the literal url (for consistency, starting with a “/” as in “/my_url”) accepts similar options to path and resources
70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/sitemap/generator.rb', line 70 def literal(target_url, = {}) search = Sitemap.configuration.search.clone.merge!(.select { |k, v| SEARCH_ATTRIBUTES.keys.include?(k) }) search.merge!(search) { |type, value| get_data(nil, value) } output_host = [:host] || host output_protocol = [:protocol] || protocol self.store << { :url =>"#{output_protocol}://#{output_host}#{target_url}", :search => search } 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
Literal paths can be added as follows:
Sitemap::Generator.instance.load :host => "mywebsite.com" do
literal "/some_fancy_url"
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
61 62 63 64 65 66 |
# File 'lib/sitemap/generator.rb', line 61 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
.
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/sitemap/generator.rb', line 95 def path(object, = {}) params = Sitemap.configuration.params.clone.merge!([:params] || {}) params[:protocol] ||= protocol # Use global protocol if none was specified. params[:host] ||= host # Use global host if none was specified. params.merge!(params) { |type, value| get_data(object, value) } search = Sitemap.configuration.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.
152 153 154 155 156 157 |
# File 'lib/sitemap/generator.rb', line 152 def process_fragment! file = Tempfile.new("sitemap.xml") file.write(render) file.close self.fragments << file end |
#remove_saved_files(location) ⇒ Object
192 193 194 195 196 |
# File 'lib/sitemap/generator.rb', line 192 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.
145 146 147 148 149 |
# File 'lib/sitemap/generator.rb', line 145 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.
133 134 135 136 137 138 139 140 141 142 |
# File 'lib/sitemap/generator.rb', line 133 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.configuration.query_batch_size) do |object| path(object, link_params) end end |
#save(location) ⇒ Object
Creates the sitemap index file and saves any existing fragments.
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/sitemap/generator.rb', line 166 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") file.close end File.chmod(0755, location) end |