sitemap_generator 4.2.0 → 4.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/README.md +13 -4
- data/VERSION +1 -1
- data/lib/sitemap_generator/adapters/s3_adapter.rb +7 -3
- data/lib/sitemap_generator/adapters/wave_adapter.rb +5 -1
- data/lib/sitemap_generator/builder/sitemap_url.rb +5 -3
- data/lib/sitemap_generator/builder/sitemap_url.rb.orig +248 -0
- data/lib/sitemap_generator/link_set.rb +1 -2
- data/spec/sitemap_generator/adapters/s3_adapter_spec.rb +23 -0
- data/spec/sitemap_generator/alternate_sitemap_spec.rb +6 -2
- data/spec/sitemap_generator/builder/sitemap_url_spec.rb +15 -0
- data/spec/sitemap_generator/link_set_spec.rb +4 -4
- data/spec/spec_helper.rb +1 -0
- metadata +82 -86
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -13,7 +13,7 @@ Sitemaps adhere to the [Sitemap 0.9 protocol][sitemap_protocol] specification.
|
|
13
13
|
* Adheres to the [Sitemap 0.9 protocol][sitemap_protocol]
|
14
14
|
* Handles millions of links
|
15
15
|
* Automatically compresses your sitemaps
|
16
|
-
* Notifies search engines (Google, Bing
|
16
|
+
* Notifies search engines (Google, Bing) of new sitemaps
|
17
17
|
* Ensures your old sitemaps stay in place if the new sitemap fails to generate
|
18
18
|
* Gives you complete control over your sitemap contents and naming scheme
|
19
19
|
* Intelligent sitemap indexing
|
@@ -57,7 +57,6 @@ Sitemap stats: 3 links / 1 sitemaps / 0m00s
|
|
57
57
|
|
58
58
|
Successful ping of Google
|
59
59
|
Successful ping of Bing
|
60
|
-
Successful ping of Sitemap Writer
|
61
60
|
```
|
62
61
|
|
63
62
|
|
@@ -105,7 +104,8 @@ That's it! Welcome to the future!
|
|
105
104
|
|
106
105
|
## Changelog
|
107
106
|
|
108
|
-
* v4.
|
107
|
+
* v4.3.0: Support `media` attibute on alternate links ([#125](https://github.com/kjvarga/sitemap_generator/issues/125)). Changed `SitemapGenerator::S3Adapter` to write files in a single operation, avoiding potential permissions errors when listing a directory prior to writing ([#130](https://github.com/kjvarga/sitemap_generator/issues/130)). Remove Sitemap Writer from ping task ([#129](https://github.com/kjvarga/sitemap_generator/issues/129)). Support `url:expires` element ([#126](https://github.com/kjvarga/sitemap_generator/issues/126)).
|
108
|
+
* v4.2.0: Update Google ping URL. Quote the ping URL in the output. Support Video `video:price` element ([#117](https://github.com/kjvarga/sitemap_generator/issues/117)). Support symbols as well as strings for most arguments to `add()` ([#113](https://github.com/kjvarga/sitemap_generator/issues/113)). Ensure that `public_path` and `sitemaps_path` end with a slash (`/`) ([#113](https://github.com/kjvarga/sitemap_generator/issues/118)).
|
109
109
|
* v4.1.1: Support setting the S3 region. Fixed bug where incorrect URL was being used in the ping to search engines - only affected sites with a single sitemap file and no index file. Output the URL being pinged in the verbose output. Test in Rails 4.
|
110
110
|
* v4.1.0: [PageMap sitemap][using_pagemaps] support. Tested with Rails 4 pre-release.
|
111
111
|
* v4.0.1: Add a post install message regarding the naming convention change.
|
@@ -219,7 +219,7 @@ SitemapGenerator.verbose = false
|
|
219
219
|
|
220
220
|
### Pinging Search Engines
|
221
221
|
|
222
|
-
Using `rake sitemap:refresh` will notify major search engines to let them know that a new sitemap is available (Google, Bing
|
222
|
+
Using `rake sitemap:refresh` will notify major search engines to let them know that a new sitemap is available (Google, Bing). To generate new sitemaps without notifying search engines (for example when running in a local environment) use `rake sitemap:refresh:no_ping`.
|
223
223
|
|
224
224
|
If you want to customize the hash of search engines you can access it at:
|
225
225
|
|
@@ -272,6 +272,14 @@ You should add the URL of the sitemap index file to `public/robots.txt` to help
|
|
272
272
|
Sitemap: http://www.example.com/sitemap.xml.gz
|
273
273
|
```
|
274
274
|
|
275
|
+
### Ruby Modules
|
276
|
+
|
277
|
+
If you need to include a module (e.g. a rails helper) you can add the following line:
|
278
|
+
|
279
|
+
```ruby
|
280
|
+
SitemapGenerator::Interpreter.send :include, RoutingHelper
|
281
|
+
```
|
282
|
+
|
275
283
|
## Deployments & Capistrano
|
276
284
|
|
277
285
|
To ensure that your application's sitemaps are available after a deployment you can do one of the following:
|
@@ -302,6 +310,7 @@ To ensure that your application's sitemaps are available after a deployment you
|
|
302
310
|
end
|
303
311
|
```
|
304
312
|
|
313
|
+
|
305
314
|
### Sitemaps with no Index File
|
306
315
|
|
307
316
|
The sitemap index file is created for you on-demand, meaning that if you have a large site with more than one sitemap file, you will have a sitemap index file to reference those sitemap files. If however you have a small site with only one sitemap file, you don't require an index and so no index will be created. In both cases the index and sitemap file's name, respectively, is `sitemap.xml.gz`.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
4.
|
1
|
+
4.3.0
|
@@ -1,4 +1,8 @@
|
|
1
|
-
|
1
|
+
begin
|
2
|
+
require 'fog'
|
3
|
+
rescue LoadError
|
4
|
+
raise LoadError.new("Missing required 'fog'. Please 'gem install fog' and require it in your application.")
|
5
|
+
end
|
2
6
|
|
3
7
|
module SitemapGenerator
|
4
8
|
class S3Adapter
|
@@ -15,7 +19,7 @@ module SitemapGenerator
|
|
15
19
|
def write(location, raw_data)
|
16
20
|
SitemapGenerator::FileAdapter.new.write(location, raw_data)
|
17
21
|
|
18
|
-
credentials = {
|
22
|
+
credentials = {
|
19
23
|
:aws_access_key_id => @aws_access_key_id,
|
20
24
|
:aws_secret_access_key => @aws_secret_access_key,
|
21
25
|
:provider => @fog_provider,
|
@@ -23,7 +27,7 @@ module SitemapGenerator
|
|
23
27
|
credentials[:region] = @fog_region if @fog_region
|
24
28
|
|
25
29
|
storage = Fog::Storage.new(credentials)
|
26
|
-
directory = storage.directories.
|
30
|
+
directory = storage.directories.new(:key => @fog_directory)
|
27
31
|
directory.files.create(
|
28
32
|
:key => location.path_in_public,
|
29
33
|
:body => File.open(location.path),
|
@@ -1,4 +1,8 @@
|
|
1
|
-
|
1
|
+
begin
|
2
|
+
require 'carrierwave'
|
3
|
+
rescue LoadError
|
4
|
+
raise LoadError.new("Missing required 'carrierwave'. Please 'gem install carrierwave' and require it in your application.")
|
5
|
+
end
|
2
6
|
|
3
7
|
module SitemapGenerator
|
4
8
|
class WaveAdapter < ::CarrierWave::Uploader::Base
|
@@ -37,7 +37,7 @@ module SitemapGenerator
|
|
37
37
|
path = sitemap.location.path_in_public
|
38
38
|
end
|
39
39
|
|
40
|
-
SitemapGenerator::Utilities.assert_valid_keys(options, :priority, :changefreq, :lastmod, :host, :images, :video, :geo, :news, :videos, :mobile, :alternate, :alternates, :pagemap)
|
40
|
+
SitemapGenerator::Utilities.assert_valid_keys(options, :priority, :changefreq, :lastmod, :expires, :host, :images, :video, :geo, :news, :videos, :mobile, :alternate, :alternates, :pagemap)
|
41
41
|
SitemapGenerator::Utilities.reverse_merge!(options, :priority => 0.5, :changefreq => 'weekly', :lastmod => Time.now, :images => [], :news => {}, :videos => [], :mobile => false, :alternates => [])
|
42
42
|
raise "Cannot generate a url without a host" unless SitemapGenerator::Utilities.present?(options[:host])
|
43
43
|
|
@@ -54,6 +54,7 @@ module SitemapGenerator
|
|
54
54
|
:priority => options[:priority],
|
55
55
|
:changefreq => options[:changefreq],
|
56
56
|
:lastmod => options[:lastmod],
|
57
|
+
:expires => options[:expires],
|
57
58
|
:host => options[:host],
|
58
59
|
:loc => loc,
|
59
60
|
:images => prepare_images(options[:images], options[:host]),
|
@@ -72,6 +73,7 @@ module SitemapGenerator
|
|
72
73
|
builder.url do
|
73
74
|
builder.loc self[:loc]
|
74
75
|
builder.lastmod w3c_date(self[:lastmod]) if self[:lastmod]
|
76
|
+
builder.expires w3c_date(self[:expires]) if self[:expires]
|
75
77
|
builder.changefreq self[:changefreq].to_s if self[:changefreq]
|
76
78
|
builder.priority format_float(self[:priority]) if self[:priority]
|
77
79
|
|
@@ -132,7 +134,7 @@ module SitemapGenerator
|
|
132
134
|
|
133
135
|
self[:alternates].each do |alternate|
|
134
136
|
rel = alternate[:nofollow] ? 'alternate nofollow' : 'alternate'
|
135
|
-
builder.xhtml :link, :rel => rel, :hreflang => alternate[:lang].to_s, :href => alternate[:href].to_s
|
137
|
+
builder.xhtml :link, :rel => rel, :hreflang => alternate[:lang].to_s, :href => alternate[:href].to_s, :media => alternate[:media].to_s
|
136
138
|
end
|
137
139
|
|
138
140
|
unless SitemapGenerator::Utilities.blank?(self[:geo])
|
@@ -174,7 +176,7 @@ module SitemapGenerator
|
|
174
176
|
attribs[:resolution] = video[:price_resolution] if SitemapGenerator::Utilities.present?(video[:price_resolution])
|
175
177
|
attribs
|
176
178
|
end
|
177
|
-
|
179
|
+
|
178
180
|
def prepare_news(news)
|
179
181
|
SitemapGenerator::Utilities.assert_valid_keys(news, :publication_name, :publication_language, :publication_date, :genres, :access, :title, :keywords, :stock_tickers) unless news.empty?
|
180
182
|
news
|
@@ -0,0 +1,248 @@
|
|
1
|
+
require 'builder'
|
2
|
+
require 'uri'
|
3
|
+
require 'time'
|
4
|
+
require 'date'
|
5
|
+
|
6
|
+
module SitemapGenerator
|
7
|
+
module Builder
|
8
|
+
# A Hash-like class for holding information about a sitemap URL and
|
9
|
+
# generating an XML <url> element suitable for sitemaps.
|
10
|
+
class SitemapUrl < Hash
|
11
|
+
|
12
|
+
# Return a new instance with options configured on it.
|
13
|
+
#
|
14
|
+
# == Arguments
|
15
|
+
# * sitemap - a Sitemap instance, or
|
16
|
+
# * path, options - a path string and options hash
|
17
|
+
#
|
18
|
+
# == Options
|
19
|
+
# Requires a host to be set. If passing a sitemap, the sitemap must have a +default_host+
|
20
|
+
# configured. If calling with a path and options, you must include the <tt>:host</tt> option.
|
21
|
+
#
|
22
|
+
# * +host+
|
23
|
+
# * +priority+
|
24
|
+
# * +changefreq+
|
25
|
+
# * +lastmod+
|
26
|
+
# * +images+
|
27
|
+
# * +video+/+videos+
|
28
|
+
# * +geo+
|
29
|
+
# * +news+
|
30
|
+
# * +mobile+
|
31
|
+
# * +alternate+/+alternates+
|
32
|
+
# * +pagemap+
|
33
|
+
def initialize(path, options={})
|
34
|
+
options = options.dup
|
35
|
+
if sitemap = path.is_a?(SitemapGenerator::Builder::SitemapFile) && path
|
36
|
+
SitemapGenerator::Utilities.reverse_merge!(options, :host => sitemap.location.host, :lastmod => sitemap.lastmod)
|
37
|
+
path = sitemap.location.path_in_public
|
38
|
+
end
|
39
|
+
|
40
|
+
SitemapGenerator::Utilities.assert_valid_keys(options, :priority, :changefreq, :lastmod, :expires, :host, :images, :video, :geo, :news, :videos, :mobile, :alternate, :alternates, :pagemap)
|
41
|
+
SitemapGenerator::Utilities.reverse_merge!(options, :priority => 0.5, :changefreq => 'weekly', :lastmod => Time.now, :images => [], :news => {}, :videos => [], :mobile => false, :alternates => [])
|
42
|
+
raise "Cannot generate a url without a host" unless SitemapGenerator::Utilities.present?(options[:host])
|
43
|
+
|
44
|
+
if video = options.delete(:video)
|
45
|
+
options[:videos] = video.is_a?(Array) ? options[:videos].concat(video) : options[:videos] << video
|
46
|
+
end
|
47
|
+
if alternate = options.delete(:alternate)
|
48
|
+
options[:alternates] = alternate.is_a?(Array) ? options[:alternates].concat(alternate) : options[:alternates] << alternate
|
49
|
+
end
|
50
|
+
|
51
|
+
path = path.to_s.sub(/^\//, '')
|
52
|
+
loc = path.empty? ? options[:host] : (options[:host].to_s.sub(/\/$/, '') + '/' + path)
|
53
|
+
self.merge!(
|
54
|
+
:priority => options[:priority],
|
55
|
+
:changefreq => options[:changefreq],
|
56
|
+
:lastmod => options[:lastmod],
|
57
|
+
:expires => options[:expires],
|
58
|
+
:host => options[:host],
|
59
|
+
:loc => loc,
|
60
|
+
:images => prepare_images(options[:images], options[:host]),
|
61
|
+
:news => prepare_news(options[:news]),
|
62
|
+
:videos => options[:videos],
|
63
|
+
:geo => options[:geo],
|
64
|
+
:mobile => options[:mobile],
|
65
|
+
:alternates => options[:alternates],
|
66
|
+
:pagemap => options[:pagemap]
|
67
|
+
)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Return the URL as XML
|
71
|
+
def to_xml(builder=nil)
|
72
|
+
builder = ::Builder::XmlMarkup.new if builder.nil?
|
73
|
+
builder.url do
|
74
|
+
builder.loc self[:loc]
|
75
|
+
builder.lastmod w3c_date(self[:lastmod]) if self[:lastmod]
|
76
|
+
builder.expires w3c_date(self[:expires]) if self[:expires]
|
77
|
+
builder.changefreq self[:changefreq].to_s if self[:changefreq]
|
78
|
+
builder.priority format_float(self[:priority]) if self[:priority]
|
79
|
+
|
80
|
+
unless SitemapGenerator::Utilities.blank?(self[:news])
|
81
|
+
news_data = self[:news]
|
82
|
+
builder.news:news do
|
83
|
+
builder.news:publication do
|
84
|
+
builder.news :name, news_data[:publication_name].to_s if news_data[:publication_name]
|
85
|
+
builder.news :language, news_data[:publication_language].to_s if news_data[:publication_language]
|
86
|
+
end
|
87
|
+
|
88
|
+
builder.news :access, news_data[:access].to_s if news_data[:access]
|
89
|
+
builder.news :genres, news_data[:genres].to_s if news_data[:genres]
|
90
|
+
builder.news :publication_date, w3c_date(news_data[:publication_date]) if news_data[:publication_date]
|
91
|
+
builder.news :title, news_data[:title].to_s if news_data[:title]
|
92
|
+
builder.news :keywords, news_data[:keywords].to_s if news_data[:keywords]
|
93
|
+
builder.news :stock_tickers, news_data[:stock_tickers].to_s if news_data[:stock_tickers]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
self[:images].each do |image|
|
98
|
+
builder.image:image do
|
99
|
+
builder.image :loc, image[:loc]
|
100
|
+
builder.image :caption, image[:caption].to_s if image[:caption]
|
101
|
+
builder.image :geo_location, image[:geo_location].to_s if image[:geo_location]
|
102
|
+
builder.image :title, image[:title].to_s if image[:title]
|
103
|
+
builder.image :license, image[:license].to_s if image[:license]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
self[:videos].each do |video|
|
108
|
+
builder.video :video do
|
109
|
+
builder.video :thumbnail_loc, video[:thumbnail_loc].to_s
|
110
|
+
builder.video :title, video[:title].to_s
|
111
|
+
builder.video :description, video[:description].to_s
|
112
|
+
builder.video :content_loc, video[:content_loc].to_s if video[:content_loc]
|
113
|
+
if video[:player_loc]
|
114
|
+
loc_attributes = { :allow_embed => yes_or_no_with_default(video[:allow_embed], true) }
|
115
|
+
loc_attributes[:autoplay] = video[:autoplay].to_s if SitemapGenerator::Utilities.present?(video[:autoplay])
|
116
|
+
builder.video :player_loc, video[:player_loc].to_s, loc_attributes
|
117
|
+
end
|
118
|
+
builder.video :duration, video[:duration].to_s if video[:duration]
|
119
|
+
builder.video :expiration_date, w3c_date(video[:expiration_date]) if video[:expiration_date]
|
120
|
+
builder.video :rating, format_float(video[:rating]) if video[:rating]
|
121
|
+
builder.video :view_count, video[:view_count].to_s if video[:view_count]
|
122
|
+
builder.video :publication_date, w3c_date(video[:publication_date]) if video[:publication_date]
|
123
|
+
video[:tags].each {|tag| builder.video :tag, tag.to_s } if video[:tags]
|
124
|
+
builder.video :tag, video[:tag].to_s if video[:tag]
|
125
|
+
builder.video :category, video[:category].to_s if video[:category]
|
126
|
+
builder.video :family_friendly, yes_or_no_with_default(video[:family_friendly], true) if video.has_key?(:family_friendly)
|
127
|
+
builder.video :gallery_loc, video[:gallery_loc].to_s, :title => video[:gallery_title].to_s if video[:gallery_loc]
|
128
|
+
builder.video :price, video[:price].to_s, prepare_video_price_attribs(video) if SitemapGenerator::Utilities.present?(video[:price])
|
129
|
+
if video[:uploader]
|
130
|
+
builder.video :uploader, video[:uploader].to_s, video[:uploader_info] ? { :info => video[:uploader_info].to_s } : {}
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
self[:alternates].each do |alternate|
|
136
|
+
rel = alternate[:nofollow] ? 'alternate nofollow' : 'alternate'
|
137
|
+
<<<<<<< HEAD
|
138
|
+
builder.xhtml :link, :rel => rel, :hreflang => alternate[:lang].to_s, :href => alternate[:href].to_s
|
139
|
+
=======
|
140
|
+
builder.xhtml :link, :rel => rel, :hreflang => alternate[:lang], :href => alternate[:href], :media => alternate[:media]
|
141
|
+
>>>>>>> ddeebe0aa558b4ecc08c7e8d5324842205d20b79
|
142
|
+
end
|
143
|
+
|
144
|
+
unless SitemapGenerator::Utilities.blank?(self[:geo])
|
145
|
+
geo = self[:geo]
|
146
|
+
builder.geo :geo do
|
147
|
+
builder.geo :format, geo[:format].to_s if geo[:format]
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
unless SitemapGenerator::Utilities.blank?(self[:mobile])
|
152
|
+
builder.mobile :mobile
|
153
|
+
end
|
154
|
+
|
155
|
+
unless SitemapGenerator::Utilities.blank?(self[:pagemap])
|
156
|
+
builder.pagemap :PageMap do
|
157
|
+
SitemapGenerator::Utilities.as_array(self[:pagemap][:dataobjects]).each do |dataobject|
|
158
|
+
builder.pagemap :DataObject, :type => dataobject[:type].to_s, :id => dataobject[:id].to_s do
|
159
|
+
SitemapGenerator::Utilities.as_array(dataobject[:attributes]).each do |attribute|
|
160
|
+
builder.pagemap :Attribute, attribute[:value].to_s, :name => attribute[:name].to_s
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
builder << '' # Force to string
|
168
|
+
end
|
169
|
+
|
170
|
+
def news?
|
171
|
+
SitemapGenerator::Utilities.present?(self[:news])
|
172
|
+
end
|
173
|
+
|
174
|
+
protected
|
175
|
+
|
176
|
+
def prepare_video_price_attribs(video)
|
177
|
+
attribs = {}
|
178
|
+
attribs[:currency] = video[:price_currency].to_s # required
|
179
|
+
attribs[:type] = video[:price_type] if SitemapGenerator::Utilities.present?(video[:price_type])
|
180
|
+
attribs[:resolution] = video[:price_resolution] if SitemapGenerator::Utilities.present?(video[:price_resolution])
|
181
|
+
attribs
|
182
|
+
end
|
183
|
+
|
184
|
+
def prepare_news(news)
|
185
|
+
SitemapGenerator::Utilities.assert_valid_keys(news, :publication_name, :publication_language, :publication_date, :genres, :access, :title, :keywords, :stock_tickers) unless news.empty?
|
186
|
+
news
|
187
|
+
end
|
188
|
+
|
189
|
+
# Return an Array of image option Hashes suitable to be parsed by SitemapGenerator::Builder::SitemapFile
|
190
|
+
def prepare_images(images, host)
|
191
|
+
images.delete_if { |key,value| key[:loc] == nil }
|
192
|
+
images.each do |r|
|
193
|
+
SitemapGenerator::Utilities.assert_valid_keys(r, :loc, :caption, :geo_location, :title, :license)
|
194
|
+
r[:loc] = URI.join(host, r[:loc]).to_s
|
195
|
+
end
|
196
|
+
images[0..(SitemapGenerator::MAX_SITEMAP_IMAGES-1)]
|
197
|
+
end
|
198
|
+
|
199
|
+
def w3c_date(date)
|
200
|
+
if date.is_a?(String)
|
201
|
+
date
|
202
|
+
elsif date.respond_to?(:iso8601)
|
203
|
+
date.iso8601.sub(/Z$/i, '+00:00')
|
204
|
+
elsif date.is_a?(Date) && !date.is_a?(DateTime)
|
205
|
+
date.strftime("%Y-%m-%d")
|
206
|
+
else
|
207
|
+
zulutime = if date.is_a?(DateTime)
|
208
|
+
date.new_offset(0)
|
209
|
+
elsif date.respond_to?(:utc)
|
210
|
+
date.utc
|
211
|
+
else
|
212
|
+
nil
|
213
|
+
end
|
214
|
+
|
215
|
+
if zulutime
|
216
|
+
zulutime.strftime("%Y-%m-%dT%H:%M:%S+00:00")
|
217
|
+
else
|
218
|
+
zone = date.strftime('%z').insert(-3, ':')
|
219
|
+
date.strftime("%Y-%m-%dT%H:%M:%S") + zone
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
# Accept a string or boolean and return 'yes' or 'no'. If a string, the
|
225
|
+
# value must be 'yes' or 'no'. Pass the default value as a boolean using `default`.
|
226
|
+
def yes_or_no(value)
|
227
|
+
if value.is_a?(String)
|
228
|
+
raise ArgumentError.new("Unrecognized value for yes/no field: #{value.inspect}") unless value =~ /^(yes|no)$/i
|
229
|
+
value.downcase
|
230
|
+
else
|
231
|
+
value ? 'yes' : 'no'
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
# If the value is nil, return `default` converted to either 'yes' or 'no'.
|
236
|
+
# If the value is set, return its value converted to 'yes' or 'no'.
|
237
|
+
def yes_or_no_with_default(value, default)
|
238
|
+
yes_or_no(value.nil? ? default : value)
|
239
|
+
end
|
240
|
+
|
241
|
+
# Format a float to to one decimal precision.
|
242
|
+
# TODO: Use rounding with precision once merged with framework_agnostic.
|
243
|
+
def format_float(value)
|
244
|
+
value.is_a?(String) ? value : ('%0.1f' % value)
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
@@ -124,8 +124,7 @@ module SitemapGenerator
|
|
124
124
|
:filename => :sitemap,
|
125
125
|
:search_engines => {
|
126
126
|
:google => "http://www.google.com/webmasters/tools/ping?sitemap=%s",
|
127
|
-
:bing => "http://www.bing.com/webmaster/ping.aspx?siteMap=%s"
|
128
|
-
:sitemap_writer => "http://www.sitemapwriter.com/notify.php?crawler=all&url=%s"
|
127
|
+
:bing => "http://www.bing.com/webmaster/ping.aspx?siteMap=%s"
|
129
128
|
},
|
130
129
|
:create_index => :auto
|
131
130
|
)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
# Don't run this test as part of the unit testing suite as we don't want
|
6
|
+
# Fog to be a dependency of SitemapGenerator core. This is an integration
|
7
|
+
# test. Unfortunately it doesn't really test much, so its usefullness is
|
8
|
+
# questionable.
|
9
|
+
describe 'SitemapGenerator::S3Adapter', :integration => true do
|
10
|
+
|
11
|
+
let(:location) { SitemapGenerator::SitemapLocation.new(:namer => SitemapGenerator::SitemapNamer.new(:sitemap), :public_path => 'tmp/', :sitemaps_path => 'test/', :host => 'http://example.com/') }
|
12
|
+
let(:directory) { stub(:files => stub(:create)) }
|
13
|
+
let(:directories) { stub(:directories => stub(:new => directory)) }
|
14
|
+
|
15
|
+
before do
|
16
|
+
SitemapGenerator::S3Adapter # eager load
|
17
|
+
Fog::Storage.stubs(:new => directories)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should create the file in S3 with a single operation' do
|
21
|
+
subject.write(location, 'payload')
|
22
|
+
end
|
23
|
+
end
|
@@ -8,7 +8,8 @@ describe "SitemapGenerator" do
|
|
8
8
|
:alternates => [
|
9
9
|
{
|
10
10
|
:lang => 'de',
|
11
|
-
:href => 'http://www.example.de/link_with_alternate.html'
|
11
|
+
:href => 'http://www.example.de/link_with_alternate.html',
|
12
|
+
:media => 'only screen and (max-width: 640px)'
|
12
13
|
}
|
13
14
|
]
|
14
15
|
).to_xml
|
@@ -23,6 +24,7 @@ describe "SitemapGenerator" do
|
|
23
24
|
alternate.attribute('rel').value.should == 'alternate'
|
24
25
|
alternate.attribute('hreflang').value.should == 'de'
|
25
26
|
alternate.attribute('href').value.should == 'http://www.example.de/link_with_alternate.html'
|
27
|
+
alternate.attribute('media').value.should == 'only screen and (max-width: 640px)'
|
26
28
|
end
|
27
29
|
|
28
30
|
it "should add alternate links to sitemap with rel nofollow" do
|
@@ -32,7 +34,8 @@ describe "SitemapGenerator" do
|
|
32
34
|
{
|
33
35
|
:lang => 'de',
|
34
36
|
:href => 'http://www.example.de/link_with_alternate.html',
|
35
|
-
:nofollow => true
|
37
|
+
:nofollow => true,
|
38
|
+
:media => 'only screen and (max-width: 640px)'
|
36
39
|
}
|
37
40
|
]
|
38
41
|
).to_xml
|
@@ -47,6 +50,7 @@ describe "SitemapGenerator" do
|
|
47
50
|
alternate.attribute('rel').value.should == 'alternate nofollow'
|
48
51
|
alternate.attribute('hreflang').value.should == 'de'
|
49
52
|
alternate.attribute('href').value.should == 'http://www.example.de/link_with_alternate.html'
|
53
|
+
alternate.attribute('media').value.should == 'only screen and (max-width: 640px)'
|
50
54
|
end
|
51
55
|
|
52
56
|
end
|
@@ -164,4 +164,19 @@ describe SitemapGenerator::Builder::SitemapUrl do
|
|
164
164
|
url.send(:format_float, 3.444444).should == '3.4'
|
165
165
|
end
|
166
166
|
end
|
167
|
+
|
168
|
+
describe "expires" do
|
169
|
+
let(:url) { SitemapGenerator::Builder::SitemapUrl.new('/path', :host => 'http://example.com', :expires => time) }
|
170
|
+
let(:time) { Time.at(0).utc }
|
171
|
+
|
172
|
+
it "should include the option" do
|
173
|
+
url[:expires].should == time
|
174
|
+
end
|
175
|
+
|
176
|
+
it "should format it and include it in the XML" do
|
177
|
+
xml = url.to_xml
|
178
|
+
doc = Nokogiri::XML("<root xmlns='http://www.sitemaps.org/schemas/sitemap/0.9' xmlns:xhtml='http://www.w3.org/1999/xhtml'>#{xml}</root>")
|
179
|
+
doc.css('url expires').text.should == url.send(:w3c_date, time)
|
180
|
+
end
|
181
|
+
end
|
167
182
|
end
|
@@ -85,7 +85,7 @@ describe SitemapGenerator::LinkSet do
|
|
85
85
|
ls.sitemap.location.public_path.should == path
|
86
86
|
ls.sitemap_index.location.public_path.should == path
|
87
87
|
end
|
88
|
-
|
88
|
+
|
89
89
|
it "should append a slash to the path" do
|
90
90
|
path = SitemapGenerator.app.root + 'tmp/'
|
91
91
|
ls.public_path = 'tmp'
|
@@ -109,7 +109,7 @@ describe SitemapGenerator::LinkSet do
|
|
109
109
|
ls.sitemap.location.url.should == 'http://one.com/sitemaps/sitemap.xml.gz'
|
110
110
|
ls.sitemap_index.location.url.should == 'http://one.com/sitemaps/sitemap.xml.gz'
|
111
111
|
end
|
112
|
-
|
112
|
+
|
113
113
|
it "should append a slash to the path" do
|
114
114
|
ls.default_host = 'http://one.com'
|
115
115
|
ls.sitemaps_path = 'sitemaps'
|
@@ -129,12 +129,12 @@ describe SitemapGenerator::LinkSet do
|
|
129
129
|
describe "search_engines" do
|
130
130
|
it "should have search engines by default" do
|
131
131
|
ls.search_engines.should be_a(Hash)
|
132
|
-
ls.search_engines.size.should ==
|
132
|
+
ls.search_engines.size.should == 2
|
133
133
|
end
|
134
134
|
|
135
135
|
it "should support being modified" do
|
136
136
|
ls.search_engines[:newengine] = 'abc'
|
137
|
-
ls.search_engines.size.should ==
|
137
|
+
ls.search_engines.size.should == 3
|
138
138
|
end
|
139
139
|
|
140
140
|
it "should support being set to nil" do
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,89 +1,83 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: sitemap_generator
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 4
|
7
|
+
- 3
|
8
|
+
- 0
|
9
|
+
version: 4.3.0
|
6
10
|
platform: ruby
|
7
|
-
authors:
|
11
|
+
authors:
|
8
12
|
- Karl Varga
|
9
13
|
autorequire:
|
10
14
|
bindir: bin
|
11
15
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
16
|
+
|
17
|
+
date: 2013-11-14 00:00:00 -08:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
15
21
|
name: mocha
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
22
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
17
23
|
none: false
|
18
|
-
requirements:
|
19
|
-
- -
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
22
30
|
type: :development
|
23
31
|
prerelease: false
|
24
|
-
version_requirements:
|
25
|
-
|
26
|
-
requirements:
|
27
|
-
- - ! '>='
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '0'
|
30
|
-
- !ruby/object:Gem::Dependency
|
32
|
+
version_requirements: *id001
|
33
|
+
- !ruby/object:Gem::Dependency
|
31
34
|
name: nokogiri
|
32
|
-
requirement: !ruby/object:Gem::Requirement
|
35
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
33
36
|
none: false
|
34
|
-
requirements:
|
35
|
-
- -
|
36
|
-
- !ruby/object:Gem::Version
|
37
|
-
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
segments:
|
41
|
+
- 0
|
42
|
+
version: "0"
|
38
43
|
type: :development
|
39
44
|
prerelease: false
|
40
|
-
version_requirements:
|
41
|
-
|
42
|
-
requirements:
|
43
|
-
- - ! '>='
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
version: '0'
|
46
|
-
- !ruby/object:Gem::Dependency
|
45
|
+
version_requirements: *id002
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
47
|
name: rspec
|
48
|
-
requirement: !ruby/object:Gem::Requirement
|
48
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
49
49
|
none: false
|
50
|
-
requirements:
|
51
|
-
- -
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
segments:
|
54
|
+
- 0
|
55
|
+
version: "0"
|
54
56
|
type: :development
|
55
57
|
prerelease: false
|
56
|
-
version_requirements:
|
57
|
-
|
58
|
-
requirements:
|
59
|
-
- - ! '>='
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
- !ruby/object:Gem::Dependency
|
58
|
+
version_requirements: *id003
|
59
|
+
- !ruby/object:Gem::Dependency
|
63
60
|
name: builder
|
64
|
-
requirement: !ruby/object:Gem::Requirement
|
61
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
65
62
|
none: false
|
66
|
-
requirements:
|
67
|
-
- -
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
segments:
|
67
|
+
- 0
|
68
|
+
version: "0"
|
70
69
|
type: :runtime
|
71
70
|
prerelease: false
|
72
|
-
version_requirements:
|
73
|
-
|
74
|
-
requirements:
|
75
|
-
- - ! '>='
|
76
|
-
- !ruby/object:Gem::Version
|
77
|
-
version: '0'
|
78
|
-
description: SitemapGenerator is a framework-agnostic XML Sitemap generator written
|
79
|
-
in Ruby with automatic Rails integration. It supports Video, News, Image, Geo,
|
80
|
-
Mobile, PageMap and Alternate Links sitemap extensions and includes Rake tasks for
|
81
|
-
managing your sitemaps, as well as many other great features.
|
71
|
+
version_requirements: *id004
|
72
|
+
description: SitemapGenerator is a framework-agnostic XML Sitemap generator written in Ruby with automatic Rails integration. It supports Video, News, Image, Geo, Mobile, PageMap and Alternate Links sitemap extensions and includes Rake tasks for managing your sitemaps, as well as many other great features.
|
82
73
|
email: kjvarga@gmail.com
|
83
74
|
executables: []
|
75
|
+
|
84
76
|
extensions: []
|
77
|
+
|
85
78
|
extra_rdoc_files: []
|
86
|
-
|
79
|
+
|
80
|
+
files:
|
87
81
|
- Gemfile
|
88
82
|
- Gemfile.lock
|
89
83
|
- MIT-LICENSE
|
@@ -99,6 +93,7 @@ files:
|
|
99
93
|
- lib/sitemap_generator/builder/sitemap_index_file.rb
|
100
94
|
- lib/sitemap_generator/builder/sitemap_index_url.rb
|
101
95
|
- lib/sitemap_generator/builder/sitemap_url.rb
|
96
|
+
- lib/sitemap_generator/builder/sitemap_url.rb.orig
|
102
97
|
- lib/sitemap_generator/builder.rb
|
103
98
|
- lib/sitemap_generator/core_ext/big_decimal.rb
|
104
99
|
- lib/sitemap_generator/core_ext/numeric.rb
|
@@ -121,6 +116,7 @@ files:
|
|
121
116
|
- spec/files/sitemap.create.rb
|
122
117
|
- spec/files/sitemap.deprecated.rb
|
123
118
|
- spec/files/sitemap.groups.rb
|
119
|
+
- spec/sitemap_generator/adapters/s3_adapter_spec.rb
|
124
120
|
- spec/sitemap_generator/alternate_sitemap_spec.rb
|
125
121
|
- spec/sitemap_generator/application_spec.rb
|
126
122
|
- spec/sitemap_generator/builder/sitemap_file_spec.rb
|
@@ -156,54 +152,54 @@ files:
|
|
156
152
|
- spec/support/schemas/sitemap-video.xsd
|
157
153
|
- spec/support/schemas/sitemap.xsd
|
158
154
|
- spec/support/xml_macros.rb
|
155
|
+
has_rdoc: true
|
159
156
|
homepage: http://github.com/kjvarga/sitemap_generator
|
160
157
|
licenses: []
|
161
|
-
post_install_message: ! 'NOTE: SitemapGenerator 4.x uses a new file naming scheme
|
162
|
-
which is more standards-compliant.
|
163
|
-
|
164
|
-
If you''re upgrading from 3.x, please see the release note in the README:
|
165
|
-
|
166
158
|
|
159
|
+
post_install_message: |
|
160
|
+
NOTE: SitemapGenerator 4.x uses a new file naming scheme which is more standards-compliant.
|
161
|
+
If you're upgrading from 3.x, please see the release note in the README:
|
162
|
+
|
167
163
|
https://github.com/kjvarga/sitemap_generator#important-changes-in-version-4
|
168
|
-
|
169
|
-
|
164
|
+
|
170
165
|
The simple answer is that your index file is now called sitemap.xml.gz
|
171
|
-
|
172
166
|
and not sitemap_index.xml.gz, but please take a look and see what else has changed.
|
173
167
|
|
174
|
-
'
|
175
168
|
rdoc_options: []
|
176
|
-
|
169
|
+
|
170
|
+
require_paths:
|
177
171
|
- lib
|
178
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
172
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
179
173
|
none: false
|
180
|
-
requirements:
|
181
|
-
- -
|
182
|
-
- !ruby/object:Gem::Version
|
183
|
-
|
184
|
-
segments:
|
174
|
+
requirements:
|
175
|
+
- - ">="
|
176
|
+
- !ruby/object:Gem::Version
|
177
|
+
hash: -1330086136380345562
|
178
|
+
segments:
|
185
179
|
- 0
|
186
|
-
|
187
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
180
|
+
version: "0"
|
181
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
188
182
|
none: false
|
189
|
-
requirements:
|
190
|
-
- -
|
191
|
-
- !ruby/object:Gem::Version
|
192
|
-
|
193
|
-
segments:
|
183
|
+
requirements:
|
184
|
+
- - ">="
|
185
|
+
- !ruby/object:Gem::Version
|
186
|
+
hash: -1330086136380345562
|
187
|
+
segments:
|
194
188
|
- 0
|
195
|
-
|
189
|
+
version: "0"
|
196
190
|
requirements: []
|
191
|
+
|
197
192
|
rubyforge_project:
|
198
|
-
rubygems_version: 1.
|
193
|
+
rubygems_version: 1.3.7.1
|
199
194
|
signing_key:
|
200
195
|
specification_version: 3
|
201
196
|
summary: Easily generate XML Sitemaps
|
202
|
-
test_files:
|
197
|
+
test_files:
|
203
198
|
- spec/blueprint.rb
|
204
199
|
- spec/files/sitemap.create.rb
|
205
200
|
- spec/files/sitemap.deprecated.rb
|
206
201
|
- spec/files/sitemap.groups.rb
|
202
|
+
- spec/sitemap_generator/adapters/s3_adapter_spec.rb
|
207
203
|
- spec/sitemap_generator/alternate_sitemap_spec.rb
|
208
204
|
- spec/sitemap_generator/application_spec.rb
|
209
205
|
- spec/sitemap_generator/builder/sitemap_file_spec.rb
|