xml-sitemap 1.1.3 → 1.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b467c55eb24039a8652c3a189cf487bf04d99dc3
4
+ data.tar.gz: 971eb8094137094e68c3a0d152f49d40ff9f48f3
5
+ SHA512:
6
+ metadata.gz: c44a0304eb5bed9861639d5e57c8efbff456d674e87ff2bcc92e0243b60f8e87f893b7d2e2ffe9617a33183abcbabd446641b0454e7baf2bd5c896ac733ac226
7
+ data.tar.gz: 6fc0c7f1c1954934a914aa6a02e3525e13d84b7b4c73cfd6ae6eb7c0a5e569bd971af3da4139a375d7d851cefbaba9485792690d31acfc65878d635b05345b11
data/.travis.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  rvm:
2
- - 1.8.7
3
2
  - 1.9.2
4
- - ree
3
+ - 1.9.3
4
+ - 2.0.0
data/Gemfile CHANGED
@@ -1,3 +1,2 @@
1
- source 'http://rubygems.org'
2
-
1
+ source 'https://rubygems.org'
3
2
  gemspec
data/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ Copyright (c) 2010-2013 Dan Sosedoff <dan.sosedoff@gmail.com>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ the Software, and to permit persons to whom the Software is furnished to do so,
8
+ subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # XmlSitemap
1
+ # XmlSitemap [![Build Status](https://secure.travis-ci.org/sosedoff/xml-sitemap.png?branch=master)](http://travis-ci.org/sosedoff/xml-sitemap)
2
2
 
3
- XmlSitemap is a Ruby library that provides an easy way to generate XML sitemaps and indexes.
3
+ XmlSitemap is a ruby library that provides an easy way to generate XML sitemaps and indexes.
4
4
 
5
5
  It does not have any web-framework dependencies and could be used in any ruby-based application.
6
6
 
@@ -8,7 +8,15 @@ It does not have any web-framework dependencies and could be used in any ruby-ba
8
8
 
9
9
  Install via rubygems:
10
10
 
11
- $ gem install xml-sitemap
11
+ ```
12
+ gem install xml-sitemap
13
+ ```
14
+
15
+ Or using latest source code:
16
+
17
+ ```
18
+ rake install
19
+ ```
12
20
 
13
21
  ## Configuration
14
22
 
@@ -30,13 +38,17 @@ map = XmlSitemap::Map.new('domain.com') do |m|
30
38
  # You can drop leading slash, it will be automatically added
31
39
  m.add 'page2'
32
40
 
33
- # Set the page priority (default is 0.5)
41
+ # Set the page priority
34
42
  m.add 'page3', :priority => 0.2
35
43
 
36
44
  # Specify last modification date and update frequiency
37
45
  m.add 'page4', :updated => Date.today, :period => :never
38
46
  end
47
+ ```
48
+
49
+ Render map output:
39
50
 
51
+ ```ruby
40
52
  # Render the sitemap XML
41
53
  map.render
42
54
 
@@ -59,20 +71,22 @@ map = XmlSitemap.new('foobar.com')
59
71
  map = XmlSitemap.map('foobar.com')
60
72
  ```
61
73
 
62
- By default XmlSitemap creates a map with link to homepage of your domain. It's a priority 1.0. Default priority is 0.5.
74
+ By default XmlSitemap creates a map with link to homepage of your domain.
63
75
 
64
- List of periods:
76
+ Homepage priority is `1.0`.
65
77
 
66
- - :none,
67
- - :always
68
- - :hourly
69
- - :daily
70
- - :weekly
71
- - :monthly
72
- - :yearly
73
- - :never
78
+ List of available update periods:
74
79
 
75
- ## XmlSitemap::Map
80
+ - `:none`
81
+ - `:always`
82
+ - `:hourly`
83
+ - `:daily`
84
+ - `:weekly`
85
+ - `:monthly`
86
+ - `:yearly`
87
+ - `:never`
88
+
89
+ ### Generating Maps
76
90
 
77
91
  When creating a new map object, you can specify a set of options.
78
92
 
@@ -82,13 +96,23 @@ map = XmlSitemap::Map.new('mydomain.com', options)
82
96
 
83
97
  Available options:
84
98
 
85
- - :secure - Will add all sitemap items with https prefix. *(default: false)*
86
- - :home - Disable homepage autocreation, but you still can do that manually. *(default: true)*
87
- - :root - Force all links to fall under the main domain. You can add full urls (not paths) if set to false. *(default: true)*
88
- - :time - Provide a creation time for the sitemap. (default: current time)
89
- - :group - Group name for sitemap index. *(default: sitemap)*
99
+ - `:secure` - Will add all sitemap items with https prefix. *(default: false)*
100
+ - `:home` - Disable homepage autocreation, but you still can do that manually. *(default: true)*
101
+ - `:root` - Force all links to fall under the main domain. You can add full urls (not paths) if set to false. *(default: true)*
102
+ - `:time` - Provide a creation time for the sitemap. (default: current time)
103
+ - `:group` - Group name for sitemap index. *(default: sitemap)*
104
+
105
+ ### Render Engines
106
+
107
+ XmlSitemap has a few different rendering engines. You can select one passing argument to `render` method.
90
108
 
91
- ## XmlSitemap::Index
109
+ Available engines:
110
+
111
+ - `:string` - Uses plain strings (for performance). Default.
112
+ - `:builder` - Uses Builder::XmlMarkup.
113
+ - `:nokogiri` - Uses Nokogiri library. Requires `nokogiri` gem.
114
+
115
+ ### Sitemap Indexes
92
116
 
93
117
  Regular sitemap does not support more than 50k records, so if you're generating a huge sitemap you need to use XmlSitemap::Index.
94
118
 
@@ -101,6 +125,10 @@ map = XmlSitemap::Map.new('domain.com')
101
125
  map.add 'page'
102
126
 
103
127
  index = XmlSitemap::Index.new
128
+
129
+ # or if you want the URLs to use HTTPS
130
+ index = XmlSitemap::Index.new(:secure => true)
131
+
104
132
  # or via shortcut
105
133
  index = XmlSitemap.index
106
134
 
@@ -114,12 +142,39 @@ index.render
114
142
  index.render_to('/path/to/file.xml')
115
143
  ```
116
144
 
145
+ ## Testing
146
+
147
+ To execute test suite run:
148
+
149
+ ```
150
+ bundle exec rake test
151
+ ```
152
+
153
+ ## Contributing
154
+
155
+ 1. Fork it
156
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
157
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
158
+ 4. Push to the branch (`git push origin my-new-feature`)
159
+ 5. Create new Pull Request
160
+
117
161
  ## License
118
162
 
119
- Copyright &copy; 2010-2011 Dan Sosedoff.
163
+ Copyright (c) 2010-2013 Dan Sosedoff.
120
164
 
121
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
165
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
166
+ this software and associated documentation files (the "Software"), to deal in
167
+ the Software without restriction, including without limitation the rights to
168
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
169
+ the Software, and to permit persons to whom the Software is furnished to do so,
170
+ subject to the following conditions:
122
171
 
123
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
172
+ The above copyright notice and this permission notice shall be included in all
173
+ copies or substantial portions of the Software.
124
174
 
125
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
175
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
176
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
177
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
178
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
179
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
180
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'bundler'
2
+ require 'bundler/gem_tasks'
2
3
  require "rspec/core/rake_task"
3
4
 
4
5
  RSpec::Core::RakeTask.new(:test) do |t|
@@ -2,30 +2,41 @@ module XmlSitemap
2
2
  class Index
3
3
  attr_reader :maps
4
4
 
5
+ # Initialize a new Index instance
6
+ #
7
+ # opts - Index options
8
+ #
9
+ # opts[:secure] - Force HTTPS for all items. (default: false)
10
+ #
5
11
  def initialize(opts={})
6
12
  @maps = []
7
13
  @offsets = Hash.new(0)
14
+ @secure = opts[:secure] || false
8
15
 
9
16
  yield self if block_given?
10
17
  end
11
18
 
12
19
  # Add map object to index
13
- def add(map)
14
- raise ArgumentError, 'XmlSitemap::Map object requred!' unless map.kind_of?(XmlSitemap::Map)
20
+ #
21
+ # map - XmlSitemap::Map instance
22
+ #
23
+ def add(map, use_offsets=true)
24
+ raise ArgumentError, 'XmlSitemap::Map object required!' unless map.kind_of?(XmlSitemap::Map)
15
25
  raise ArgumentError, 'Map is empty!' if map.empty?
16
26
 
17
27
  @maps << {
18
- :loc => map.index_url(@offsets[map.group]),
28
+ :loc => use_offsets ? map.index_url(@offsets[map.group], @secure) : map.plain_index_url(@secure),
19
29
  :lastmod => map.created_at.utc.iso8601
20
30
  }
21
31
  @offsets[map.group] += 1
22
32
  end
23
33
 
24
34
  # Generate sitemap XML index
35
+ #
25
36
  def render
26
37
  xml = Builder::XmlMarkup.new(:indent => 2)
27
38
  xml.instruct!(:xml, :version => '1.0', :encoding => 'UTF-8')
28
- xml.urlset(XmlSitemap::INDEX_SCHEMA_OPTIONS) { |s|
39
+ xml.sitemapindex(XmlSitemap::INDEX_SCHEMA_OPTIONS) { |s|
29
40
  @maps.each do |item|
30
41
  s.sitemap do |m|
31
42
  m.loc item[:loc]
@@ -36,8 +47,14 @@ module XmlSitemap
36
47
  end
37
48
 
38
49
  # Render XML sitemap index into the file
39
- def render_to(path, opts={})
40
- overwrite = opts[:overwrite] || true
50
+ #
51
+ # path - Output filename
52
+ # options - Options hash
53
+ #
54
+ # options[:ovewrite] - Overwrite file contents (default: true)
55
+ #
56
+ def render_to(path, options={})
57
+ overwrite = options[:overwrite] || true
41
58
  path = File.expand_path(path)
42
59
 
43
60
  if File.exists?(path) && !overwrite
@@ -0,0 +1,123 @@
1
+ module XmlSitemap
2
+ class Item
3
+ DEFAULT_PRIORITY = 0.5
4
+
5
+ # ISO8601 regex from here: http://www.pelagodesign.com/blog/2009/05/20/iso-8601-date-validation-that-doesnt-suck/
6
+ ISO8601_REGEX = /^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/
7
+
8
+ attr_reader :target, :updated, :priority, :changefreq, :validate_time, :image_location, :image_caption, :image_geolocation, :image_title, :image_license,
9
+ :video_thumbnail_location, :video_title, :video_description, :video_content_location, :video_player_location,
10
+ :video_duration, :video_expiration_date, :video_rating, :video_view_count, :video_publication_date, :video_family_friendly, :video_category,
11
+ :video_restriction, :video_gallery_location, :video_price, :video_requires_subscription, :video_uploader, :video_platform, :video_live
12
+
13
+ def initialize(target, opts={})
14
+ @target = target.to_s.strip
15
+ @updated = opts[:updated] || Time.now
16
+ @priority = opts[:priority]
17
+ @changefreq = opts[:period]
18
+ @validate_time = (opts[:validate_time] != false)
19
+
20
+ # Refer to http://support.google.com/webmasters/bin/answer.py?hl=en&answer=178636 for requirement to support images in sitemap
21
+ @image_location = opts[:image_location]
22
+ @image_caption = opts[:image_caption]
23
+ @image_geolocation = opts[:image_geolocation]
24
+ @image_title = opts[:image_title]
25
+ @image_license = opts[:image_license]
26
+
27
+ # Refer to http://support.google.com/webmasters/bin/answer.py?hl=en&answer=80472&topic=10079&ctx=topic#2 for requirement to support videos in sitemap
28
+ @video_thumbnail_location = opts[:video_thumbnail_location]
29
+ @video_title = opts[:video_title]
30
+ @video_description = opts[:video_description]
31
+ @video_content_location = opts[:video_content_location]
32
+ @video_player_location = opts[:video_player_location]
33
+ @video_duration = opts[:video_duration]
34
+ @video_expiration_date = opts[:video_expiration_date]
35
+ @video_rating = opts[:video_rating]
36
+ @video_view_count = opts[:video_view_count]
37
+ @video_publication_date = opts[:video_publication_date]
38
+ @video_family_friendly = opts[:video_family_friendly]
39
+ # tag
40
+ @video_category = opts[:video_category]
41
+ @video_restriction = opts[:video_restriction]
42
+ @video_gallery_location = opts[:video_gallery_location]
43
+ @video_price = opts[:video_price]
44
+ @video_requires_subscription = opts[:video_requires_subscription]
45
+ @video_uploader = opts[:video_uploader]
46
+ @video_platform = opts[:video_platform]
47
+ @video_live = opts[:video_live]
48
+
49
+ if @changefreq
50
+ @changefreq = @changefreq.to_sym
51
+ unless XmlSitemap::PERIODS.include?(@changefreq)
52
+ raise ArgumentError, "Invalid :period value '#{@changefreq}'"
53
+ end
54
+ end
55
+
56
+ unless @updated.kind_of?(Time) || @updated.kind_of?(Date) || @updated.kind_of?(String)
57
+ raise ArgumentError, "Time, Date, or ISO8601 String required for :updated!"
58
+ end
59
+
60
+ if @validate_time && @updated.kind_of?(String) && !(@updated =~ ISO8601_REGEX)
61
+ raise ArgumentError, "String provided to :updated did not match ISO8601 standard!"
62
+ end
63
+
64
+ @updated = @updated.to_time if @updated.kind_of?(Date)
65
+
66
+ ##############################################################################################
67
+ ##############################################################################################
68
+
69
+ unless @video_expiration_date.kind_of?(Time) || @video_expiration_date.kind_of?(Date) || @video_expiration_date.kind_of?(String)
70
+ raise ArgumentError, "Time, Date, or ISO8601 String required for :video_expiration_date!" unless @video_expiration_date.nil?
71
+ end
72
+
73
+ if @validate_time && @video_expiration_date.kind_of?(String) && !(@video_expiration_date =~ ISO8601_REGEX)
74
+ raise ArgumentError, "String provided to :video_expiration_date did not match ISO8601 standard!"
75
+ end
76
+
77
+ @video_expiration_date = @video_expiration_date.to_time if @video_expiration_date.kind_of?(Date)
78
+
79
+ ##############################################################################################
80
+ ##############################################################################################
81
+
82
+ unless @video_publication_date.kind_of?(Time) || @video_publication_date.kind_of?(Date) || @video_publication_date.kind_of?(String)
83
+ raise ArgumentError, "Time, Date, or ISO8601 String required for :video_publication_date!" unless @video_publication_date.nil?
84
+ end
85
+
86
+ if @validate_time && @video_publication_date.kind_of?(String) && !(@video_publication_date =~ ISO8601_REGEX)
87
+ raise ArgumentError, "String provided to :video_publication_date did not match ISO8601 standard!"
88
+ end
89
+
90
+ @video_publication_date = @video_publication_date.to_time if @video_publication_date.kind_of?(Date)
91
+ end
92
+
93
+ # Returns the timestamp value of lastmod for renderer
94
+ #
95
+ def lastmod_value
96
+ if @updated.kind_of?(Time)
97
+ @updated.utc.iso8601
98
+ else
99
+ @updated.to_s
100
+ end
101
+ end
102
+
103
+ # Returns the timestamp value of video:expiration_date for renderer
104
+ #
105
+ def video_expiration_date_value
106
+ if @video_expiration_date.kind_of?(Time)
107
+ @video_expiration_date.utc.iso8601
108
+ else
109
+ @video_expiration_date.to_s
110
+ end
111
+ end
112
+
113
+ # Returns the timestamp value of video:publication_date for renderer
114
+ #
115
+ def video_publication_date_value
116
+ if @video_publication_date.kind_of?(Time)
117
+ @video_publication_date.utc.iso8601
118
+ else
119
+ @video_publication_date.to_s
120
+ end
121
+ end
122
+ end
123
+ end
@@ -1,122 +1,132 @@
1
1
  module XmlSitemap
2
- class Item
3
- DEFAULT_PRIORITY = 0.5
4
-
5
- attr_reader :target, :updated, :priority, :changefreq
6
-
7
- def initialize(target, opts={})
8
- @target = target.to_s.strip
9
- @updated = opts[:updated] || Time.now
10
- @priority = opts[:priority] || DEFAULT_PRIORITY
11
- @changefreq = opts[:period] || :weekly
12
-
13
- # allow only date or time object
14
- unless @updated.kind_of?(Time) || @updated.kind_of?(Date)
15
- raise ArgumentError, "Time or Date required for :updated!"
16
- end
17
-
18
- # use full time and date only!
19
- @updated = @updated.to_time if @updated.kind_of?(Date)
20
- end
21
- end
22
-
23
2
  class Map
3
+ include XmlSitemap::RenderEngine
4
+
24
5
  attr_reader :domain, :items
25
6
  attr_reader :buffer
26
7
  attr_reader :created_at
27
8
  attr_reader :root
28
9
  attr_reader :group
29
-
30
- # Creates new Map class for specified domain
10
+
11
+ # Initializa a new Map instance
12
+ #
13
+ # domain - Primary domain for the map (required)
14
+ # opts - Map options
15
+ #
16
+ # opts[:home] - Automatic homepage creation. To disable set to false. (default: true)
17
+ # opts[:secure] - Force HTTPS for all items. (default: false)
18
+ # opts[:time] - Set default lastmod timestamp for items (default: current time)
19
+ # opts[:group] - Group name for sitemap index. (default: sitemap)
20
+ # opts[:root] - Force all links to fall under the main domain.
21
+ # You can add full urls (not paths) if set to false. (default: true)
22
+ #
31
23
  def initialize(domain, opts={})
32
24
  @domain = domain.to_s.strip
33
25
  raise ArgumentError, 'Domain required!' if @domain.empty?
34
-
26
+
35
27
  @created_at = opts[:time] || Time.now.utc
36
28
  @secure = opts[:secure] || false
37
29
  @home = opts.key?(:home) ? opts[:home] : true
38
30
  @root = opts.key?(:root) ? opts[:root] : true
39
31
  @group = opts[:group] || "sitemap"
40
32
  @items = []
41
-
33
+
42
34
  self.add('/', :priority => 1.0) if @home === true
43
-
35
+
44
36
  yield self if block_given?
45
37
  end
46
-
47
- # Yields Map class for easier access
48
- def generate
49
- raise ArgumentError, 'Block required' unless block_given?
50
- yield self
51
- end
52
-
53
- # Add new item to sitemap list
38
+
39
+ # Adds a new item to the map
40
+ #
41
+ # target - Path or url
42
+ # opts - Item options
43
+ #
44
+ # opts[:updated] - Lastmod property of the item
45
+ # opts[:period] - Update frequency.
46
+ # opts[:priority] - Item priority.
47
+ # opts[:validate_time] - Skip time validation if want to insert raw strings.
48
+ #
54
49
  def add(target, opts={})
55
- raise RuntimeError, 'Only less than 50k records allowed!' if @items.size >= 50000
50
+ raise RuntimeError, 'Only up to 50k records allowed!' if @items.size > 50000
56
51
  raise ArgumentError, 'Target required!' if target.nil?
57
52
  raise ArgumentError, 'Target is empty!' if target.to_s.strip.empty?
58
-
53
+
59
54
  url = process_target(target)
60
-
55
+
61
56
  if url.length > 2048
62
57
  raise ArgumentError, "Target can't be longer than 2,048 characters!"
63
58
  end
64
-
59
+
65
60
  opts[:updated] = @created_at unless opts.key?(:updated)
66
61
  item = XmlSitemap::Item.new(url, opts)
67
62
  @items << item
68
63
  item
69
64
  end
70
-
65
+
71
66
  # Get map items count
67
+ #
72
68
  def size
73
69
  @items.size
74
70
  end
75
-
71
+
76
72
  # Returns true if sitemap does not have any items
73
+ #
77
74
  def empty?
78
75
  @items.empty?
79
76
  end
80
-
77
+
81
78
  # Generate full url for path
79
+ #
82
80
  def url(path='')
83
81
  "#{@secure ? 'https' : 'http'}://#{@domain}#{path}"
84
82
  end
85
-
83
+
86
84
  # Get full url for index
87
- def index_url(offset)
88
- "http://#{@domain}/#{@group}-#{offset}.xml"
85
+ #
86
+ def index_url(offset, secure)
87
+ "#{secure ? 'https' : 'http'}://#{@domain}/#{@group}-#{offset}.xml"
88
+ end
89
+
90
+ def plain_index_url(secure)
91
+ "#{secure ? 'https' : 'http'}://#{@domain}/#{@group}.xml"
89
92
  end
90
-
93
+
91
94
  # Render XML
92
- def render
93
- xml = Builder::XmlMarkup.new(:indent => 2)
94
- xml.instruct!(:xml, :version => '1.0', :encoding => 'UTF-8')
95
- xml.urlset(XmlSitemap::MAP_SCHEMA_OPTIONS) { |s|
96
- @items.each do |item|
97
- s.url do |u|
98
- u.loc item.target
99
- u.lastmod item.updated.utc.iso8601
100
- u.changefreq item.changefreq.to_s
101
- u.priority item.priority.to_s
102
- end
103
- end
104
- }.to_s
95
+ #
96
+ # method - Pick a render engine (:builder, :nokogiri, :string).
97
+ # Default is :string
98
+ #
99
+ def render(method = :string)
100
+ case method
101
+ when :nokogiri
102
+ render_nokogiri
103
+ when :builder
104
+ render_builder
105
+ else
106
+ render_string
107
+ end
105
108
  end
106
-
109
+
107
110
  # Render XML sitemap into the file
111
+ #
112
+ # path - Output filename
113
+ # options - Options hash
114
+ #
115
+ # options[:overwrite] - Overwrite the file contents (default: true)
116
+ # options[:gzip] - Gzip file contents (default: false)
117
+ #
108
118
  def render_to(path, options={})
109
119
  overwrite = options[:overwrite] == true || true
110
120
  compress = options[:gzip] == true || false
111
-
121
+
112
122
  path = File.expand_path(path)
113
123
  path << ".gz" unless path =~ /\.gz\z/i if compress
114
-
124
+
115
125
  if File.exists?(path) && !overwrite
116
126
  raise RuntimeError, "File already exists and not overwritable!"
117
127
  end
118
-
119
- File.open(path, 'w') do |f|
128
+
129
+ File.open(path, 'wb') do |f|
120
130
  unless compress
121
131
  f.write(self.render)
122
132
  else
@@ -126,10 +136,11 @@ module XmlSitemap
126
136
  end
127
137
  end
128
138
  end
129
-
139
+
130
140
  protected
131
-
141
+
132
142
  # Process target path or url
143
+ #
133
144
  def process_target(str)
134
145
  if @root == true
135
146
  url(str =~ /^\// ? str : "/#{str}")
@@ -9,14 +9,18 @@ module XmlSitemap
9
9
  :yearly,
10
10
  :never
11
11
  ].freeze
12
-
12
+
13
13
  MAP_SCHEMA_OPTIONS = {
14
14
  'xsi:schemaLocation' => "http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd",
15
15
  'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
16
+ 'xmlns:image' => "http://www.google.com/schemas/sitemap-image/1.1",
17
+ 'xmlns:video' => "http://www.google.com/schemas/sitemap-video/1.1",
16
18
  'xmlns' => "http://www.sitemaps.org/schemas/sitemap/0.9"
17
19
  }.freeze
18
-
20
+
19
21
  INDEX_SCHEMA_OPTIONS = {
20
- 'xmlns' => "http://www.sitemaps.org/schemas/sitemap/0.9"
22
+ 'xsi:schemaLocation' => "http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/siteindex.xsd",
23
+ 'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
24
+ 'xmlns' => "http://www.sitemaps.org/schemas/sitemap/0.9"
21
25
  }.freeze
22
26
  end