module SitemapGenerator class SitemapLocation < Hash [:host, :adapter].each do |method| define_method(method) do raise SitemapGenerator::SitemapError, "No value set for #{method}" unless self[method] self[method] end end [:public_path, :sitemaps_path].each do |method| define_method(method) do Pathname.new(SitemapGenerator::Utilities.append_slash(self[method])) end end # If no +filename+ or +namer+ is provided, the default namer is used, which # generates names like sitemap.xml.gz, sitemap1.xml.gz, sitemap2.xml.gz and so on. # # === Options # * adapter - SitemapGenerator::Adapter subclass # * filename - full name of the file e.g. 'sitemap1.xml.gz' # * host - host name for URLs. The full URL to the file is then constructed from # the host, sitemaps_path and filename # * namer - a SitemapGenerator::SimpleNamer instance. Can be passed instead of +filename+. # * public_path - path to the "public" directory, or the directory you want to # write sitemaps in. Default is a directory public/ # in the current working directory, or relative to the Rails root # directory if running under Rails. # * sitemaps_path - gives the path relative to the public_path in which to # write sitemaps e.g. sitemaps/. # * verbose - whether to output summary into to STDOUT. Default +false+. # * create_index - whether to create a sitemap index. Default `:auto`. See LinkSet. # Only applies to the SitemapIndexLocation object. def initialize(opts={}) SitemapGenerator::Utilities.assert_valid_keys(opts, [:adapter, :public_path, :sitemaps_path, :host, :filename, :namer, :verbose, :create_index]) opts[:adapter] ||= SitemapGenerator::FileAdapter.new opts[:public_path] ||= SitemapGenerator.app.root + 'public/' opts[:namer] = SitemapGenerator::SitemapNamer.new(:sitemap) if !opts[:filename] && !opts[:namer] opts[:verbose] = !!opts[:verbose] self.merge!(opts) end # Return a new Location instance with the given options merged in def with(opts={}) self.merge(opts) end # Full path to the directory of the file. def directory (public_path + sitemaps_path).expand_path.to_s end # Full path of the file including the filename. def path (public_path + sitemaps_path + filename).expand_path.to_s end # Relative path of the file (including the filename) relative to public_path def path_in_public (sitemaps_path + filename).to_s end # Full URL of the file. def url URI.join(host, sitemaps_path.to_s, filename.to_s).to_s end # Return the size of the file at path def filesize File.size?(path) end # Return the filename. Raises an exception if no filename or namer is set. # If using a namer once the filename has been retrieved from the namer its # value is locked so that it is unaffected by further changes to the namer. def filename raise SitemapGenerator::SitemapError, "No filename or namer set" unless self[:filename] || self[:namer] unless self[:filename] self.send(:[]=, :filename, self[:namer].to_s, :super => true) end self[:filename] end # If a namer is set, reserve the filename and increment the namer. # Returns the reserved name. def reserve_name if self[:namer] filename self[:namer].next end self[:filename] end # Return true if this location has a fixed filename. If no name has been # reserved from the namer, for instance, returns false. def reserved_name? !!self[:filename] end def namer self[:namer] end def verbose? self[:verbose] end # If you set the filename, clear the namer and vice versa. def []=(key, value, opts={}) if !opts[:super] case key when :namer super(:filename, nil) when :filename super(:namer, nil) end end super(key, value) end def write(data) adapter.write(self, data) end end class SitemapIndexLocation < SitemapLocation def initialize(opts={}) if !opts[:filename] && !opts[:namer] opts[:namer] = SitemapGenerator::SitemapIndexNamer.new(:sitemap) end super(opts) end # Really just a placeholder for an option which should really go into some # kind of options class. def create_index self[:create_index] end end end