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 +7 -0
- data/.travis.yml +2 -2
- data/Gemfile +1 -2
- data/LICENSE +18 -0
- data/README.md +80 -25
- data/Rakefile +1 -0
- data/lib/xml-sitemap/index.rb +23 -6
- data/lib/xml-sitemap/item.rb +123 -0
- data/lib/xml-sitemap/map.rb +76 -65
- data/lib/xml-sitemap/options.rb +7 -3
- data/lib/xml-sitemap/render_engine.rb +185 -0
- data/lib/xml-sitemap/version.rb +7 -1
- data/lib/xml-sitemap.rb +8 -0
- data/spec/fixtures/empty_index.xml +2 -2
- data/spec/fixtures/encoded_image_map.xml +58 -0
- data/spec/fixtures/encoded_map.xml +0 -3
- data/spec/fixtures/encoded_video_map.xml +53 -0
- data/spec/fixtures/group_index.xml +2 -2
- data/spec/fixtures/sample_index.xml +2 -2
- data/spec/fixtures/sample_index_secure.xml +11 -0
- data/spec/fixtures/sample_many_subdomains_index.xml +11 -0
- data/spec/fixtures/saved_map.xml +0 -7
- data/spec/fixtures/simple_map.xml +1 -1
- data/spec/index_spec.rb +85 -60
- data/spec/item_spec.rb +10 -0
- data/spec/map_spec.rb +277 -115
- data/spec/spec_helper.rb +10 -0
- data/spec/xmlsitemap_spec.rb +21 -6
- data/xml-sitemap.gemspec +6 -5
- metadata +62 -25
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
data/Gemfile
CHANGED
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 [](http://travis-ci.org/sosedoff/xml-sitemap)
|
|
2
2
|
|
|
3
|
-
XmlSitemap is a
|
|
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
|
-
|
|
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
|
|
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.
|
|
74
|
+
By default XmlSitemap creates a map with link to homepage of your domain.
|
|
63
75
|
|
|
64
|
-
|
|
76
|
+
Homepage priority is `1.0`.
|
|
65
77
|
|
|
66
|
-
|
|
67
|
-
- :always
|
|
68
|
-
- :hourly
|
|
69
|
-
- :daily
|
|
70
|
-
- :weekly
|
|
71
|
-
- :monthly
|
|
72
|
-
- :yearly
|
|
73
|
-
- :never
|
|
78
|
+
List of available update periods:
|
|
74
79
|
|
|
75
|
-
|
|
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
|
-
-
|
|
86
|
-
-
|
|
87
|
-
-
|
|
88
|
-
-
|
|
89
|
-
-
|
|
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
|
-
|
|
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
|
|
163
|
+
Copyright (c) 2010-2013 Dan Sosedoff.
|
|
120
164
|
|
|
121
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
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
|
|
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
|
|
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
data/lib/xml-sitemap/index.rb
CHANGED
|
@@ -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
|
-
|
|
14
|
-
|
|
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.
|
|
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
|
-
|
|
40
|
-
|
|
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
|
data/lib/xml-sitemap/map.rb
CHANGED
|
@@ -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
|
-
#
|
|
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
|
-
#
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
#
|
|
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
|
|
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
|
-
|
|
88
|
-
|
|
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
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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, '
|
|
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}")
|
data/lib/xml-sitemap/options.rb
CHANGED
|
@@ -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
|
-
'
|
|
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
|