Class: SitemapGenerator::Builder::SitemapFile

Inherits:
Object
  • Object
show all
Includes:
Helper
Defined in:
lib/sitemap_generator/builder/sitemap_file.rb

Overview

General Usage:

sitemap = SitemapFile.new('public/', 'sitemap.xml', 'http://example.com')
    <- creates a new sitemap file in directory public/
sitemap.add_link({ ... })    <- add a link to the sitemap
sitemap.finalize!            <- write and close the sitemap file

Direct Known Subclasses

SitemapIndexFile

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Helper

#w3c_date

Constructor Details

#initialize(public_path, sitemap_path, hostname) ⇒ SitemapFile

public_path full path of the directory to write sitemaps in.

Usually your Rails <tt>public/</tt> directory.

sitemap_path relative path including filename of the sitemap

file relative to <tt>public_path</tt>

hostname hostname including protocol to use in all links

e.g. http://en.google.ca


28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 28

def initialize(public_path, sitemap_path, hostname)
  self.sitemap_path = sitemap_path
  self.public_path = public_path
  self.hostname = hostname
  self.link_count = 0

  @xml_content       = ''     # XML urlset content
  @xml_wrapper_start = <<-HTML
    <?xml version="1.0" encoding="UTF-8"?>
      <urlset
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"
        xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
          http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"
        xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"
      >
  HTML
  @xml_wrapper_start.gsub!(/\s+/, ' ').gsub!(/ *> */, '>').strip!
  @xml_wrapper_end   = %q[</urlset>]
  self.filesize = bytesize(@xml_wrapper_start) + bytesize(@xml_wrapper_end)
end

Instance Attribute Details

#filesizeObject

Returns the value of attribute filesize.



18
19
20
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 18

def filesize
  @filesize
end

#hostnameObject

Returns the value of attribute hostname.



18
19
20
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 18

def hostname
  @hostname
end

Returns the value of attribute link_count.



18
19
20
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 18

def link_count
  @link_count
end

#public_pathObject

Returns the value of attribute public_path.



18
19
20
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 18

def public_path
  @public_path
end

#sitemap_pathObject

Returns the value of attribute sitemap_path.



18
19
20
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 18

def sitemap_path
  @sitemap_path
end

Instance Method Details

Add a link to the sitemap file and return a boolean indicating whether the link was added.

If a link cannot be added, the file is too large or the link limit has been reached.



77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 77

def add_link(link)
  xml = build_xml(::Builder::XmlMarkup.new, link)
  unless file_can_fit?(bytesize(xml))
    self.finalize!
    return false
  end

  @xml_content << xml
  self.filesize += bytesize(xml)
  self.link_count += 1
  true
end

#build_xml(builder, link) ⇒ Object

Return XML as a String



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 92

def build_xml(builder, link)
  builder.url do
    builder.loc        link[:loc]
    builder.lastmod    w3c_date(link[:lastmod])   if link[:lastmod]
    builder.changefreq link[:changefreq]          if link[:changefreq]
    builder.priority   link[:priority]            if link[:priority]

    unless link[:images].blank?
      link[:images].each do |image|
        builder.image:image do
          builder.image :loc, image[:loc]
          builder.image :caption, image[:caption]             if image[:caption]
          builder.image :geo_location, image[:geo_location]   if image[:geo_location]
          builder.image :title, image[:title]                 if image[:title]
          builder.image :license, image[:license]             if image[:license]
        end
      end
    end

    unless link[:video].blank?
      video = link[:video]
      builder.video :video do
        # required elements
        builder.video :content_loc, video[:content_loc]           if video[:content_loc]
        if video[:player_loc]
          builder.video :player_loc, video[:player_loc], :allow_embed => (video[:allow_embed] ? 'yes' : 'no'), :autoplay => video[:autoplay]
        end
        builder.video :thumbnail_loc, video[:thumbnail_loc]
        builder.video :title, video[:title]
        builder.video :description, video[:description]

        builder.video :rating, video[:rating]                     if video[:rating]
        builder.video :view_count, video[:view_count]             if video[:view_count]
        builder.video :publication_date, video[:publication_date] if video[:publication_date]
        builder.video :expiration_date, video[:expiration_date]   if video[:expiration_date]
        builder.video :duration, video[:duration]                 if video[:duration]
        builder.video :family_friendly, (video[:family_friendly] ? 'yes' : 'no')  if video[:family_friendly]
        builder.video :duration, video[:duration]                 if video[:duration]
        video[:tags].each {|tag| builder.video :tag, tag }        if video[:tags]
        builder.video :tag, video[:tag]                           if video[:tag]
        builder.video :category, video[:category]                 if video[:category]
        builder.video :gallery_loc, video[:gallery_loc]           if video[:gallery_loc]
      end
    end
  end
  builder << ''
end

#bytesize(string) ⇒ Object

Return the bytesize length of the string



159
160
161
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 159

def bytesize(string)
  string.respond_to?(:bytesize) ? string.bytesize : string.length
end

#empty?Boolean

Returns:

  • (Boolean)


55
56
57
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 55

def empty?
  self.link_count == 0
end

#file_can_fit?(bytes) ⇒ Boolean

Return a boolean indicating whether the sitemap file can fit another link of bytes bytes in size.

Returns:

  • (Boolean)


69
70
71
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 69

def file_can_fit?(bytes)
  (self.filesize + bytes) < SitemapGenerator::MAX_SITEMAP_FILESIZE && self.link_count < SitemapGenerator::MAX_SITEMAP_LINKS
end

#finalize!Object

Insert the content into the XML “wrapper” and write and close the file.

All the xml content in the instance is cleared, but attributes like filesize are still available.



144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 144

def finalize!
  return if self.frozen?

  open(self.full_path, 'wb') do |file|
    gz = Zlib::GzipWriter.new(file)
    gz.write @xml_wrapper_start
    gz.write @xml_content
    gz.write @xml_wrapper_end
    gz.close
  end
  @xml_content = @xml_wrapper_start = @xml_wrapper_end = ''
  self.freeze
end

#full_pathObject



63
64
65
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 63

def full_path
  @full_path ||= File.join(self.public_path, self.sitemap_path)
end

#full_urlObject



59
60
61
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 59

def full_url
  URI.join(self.hostname, self.sitemap_path).to_s
end

#lastmodObject



51
52
53
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 51

def lastmod
  File.mtime(self.full_path) rescue nil
end