ftbpro_sitemap_generator 5.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +13 -0
  3. data/Gemfile.lock +35 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +1139 -0
  6. data/Rakefile +43 -0
  7. data/VERSION +1 -0
  8. data/lib/capistrano/sitemap_generator.rb +1 -0
  9. data/lib/capistrano/tasks/sitemap_generator.cap +36 -0
  10. data/lib/sitemap_generator.rb +85 -0
  11. data/lib/sitemap_generator/adapters.rb +0 -0
  12. data/lib/sitemap_generator/adapters/file_adapter.rb +43 -0
  13. data/lib/sitemap_generator/adapters/fog_adapter.rb +28 -0
  14. data/lib/sitemap_generator/adapters/s3_adapter.rb +41 -0
  15. data/lib/sitemap_generator/adapters/wave_adapter.rb +21 -0
  16. data/lib/sitemap_generator/application.rb +49 -0
  17. data/lib/sitemap_generator/builder.rb +8 -0
  18. data/lib/sitemap_generator/builder/sitemap_file.rb +172 -0
  19. data/lib/sitemap_generator/builder/sitemap_index_file.rb +149 -0
  20. data/lib/sitemap_generator/builder/sitemap_index_url.rb +28 -0
  21. data/lib/sitemap_generator/builder/sitemap_url.rb +250 -0
  22. data/lib/sitemap_generator/core_ext.rb +3 -0
  23. data/lib/sitemap_generator/core_ext/big_decimal.rb +45 -0
  24. data/lib/sitemap_generator/core_ext/numeric.rb +48 -0
  25. data/lib/sitemap_generator/helpers/number_helper.rb +237 -0
  26. data/lib/sitemap_generator/interpreter.rb +80 -0
  27. data/lib/sitemap_generator/link_set.rb +677 -0
  28. data/lib/sitemap_generator/railtie.rb +7 -0
  29. data/lib/sitemap_generator/sitemap_location.rb +192 -0
  30. data/lib/sitemap_generator/sitemap_namer.rb +75 -0
  31. data/lib/sitemap_generator/tasks.rb +53 -0
  32. data/lib/sitemap_generator/templates.rb +41 -0
  33. data/lib/sitemap_generator/utilities.rb +181 -0
  34. data/lib/tasks/sitemap_generator_tasks.rake +1 -0
  35. data/rails/install.rb +2 -0
  36. data/rails/uninstall.rb +2 -0
  37. data/spec/blueprint.rb +15 -0
  38. data/spec/files/sitemap.create.rb +12 -0
  39. data/spec/files/sitemap.groups.rb +49 -0
  40. data/spec/sitemap_generator/adapters/s3_adapter_spec.rb +23 -0
  41. data/spec/sitemap_generator/alternate_sitemap_spec.rb +79 -0
  42. data/spec/sitemap_generator/application_spec.rb +69 -0
  43. data/spec/sitemap_generator/builder/sitemap_file_spec.rb +110 -0
  44. data/spec/sitemap_generator/builder/sitemap_index_file_spec.rb +124 -0
  45. data/spec/sitemap_generator/builder/sitemap_index_url_spec.rb +28 -0
  46. data/spec/sitemap_generator/builder/sitemap_url_spec.rb +186 -0
  47. data/spec/sitemap_generator/core_ext/bigdecimal_spec.rb +20 -0
  48. data/spec/sitemap_generator/core_ext/numeric_spec.rb +43 -0
  49. data/spec/sitemap_generator/file_adaptor_spec.rb +20 -0
  50. data/spec/sitemap_generator/geo_sitemap_spec.rb +30 -0
  51. data/spec/sitemap_generator/helpers/number_helper_spec.rb +196 -0
  52. data/spec/sitemap_generator/interpreter_spec.rb +90 -0
  53. data/spec/sitemap_generator/link_set_spec.rb +864 -0
  54. data/spec/sitemap_generator/mobile_sitemap_spec.rb +27 -0
  55. data/spec/sitemap_generator/news_sitemap_spec.rb +42 -0
  56. data/spec/sitemap_generator/pagemap_sitemap_spec.rb +57 -0
  57. data/spec/sitemap_generator/sitemap_generator_spec.rb +582 -0
  58. data/spec/sitemap_generator/sitemap_groups_spec.rb +144 -0
  59. data/spec/sitemap_generator/sitemap_location_spec.rb +210 -0
  60. data/spec/sitemap_generator/sitemap_namer_spec.rb +96 -0
  61. data/spec/sitemap_generator/templates_spec.rb +24 -0
  62. data/spec/sitemap_generator/utilities/existence_spec.rb +26 -0
  63. data/spec/sitemap_generator/utilities/hash_spec.rb +57 -0
  64. data/spec/sitemap_generator/utilities/rounding_spec.rb +31 -0
  65. data/spec/sitemap_generator/utilities_spec.rb +101 -0
  66. data/spec/sitemap_generator/video_sitemap_spec.rb +117 -0
  67. data/spec/spec_helper.rb +24 -0
  68. data/spec/support/file_macros.rb +39 -0
  69. data/spec/support/schemas/siteindex.xsd +73 -0
  70. data/spec/support/schemas/sitemap-geo.xsd +41 -0
  71. data/spec/support/schemas/sitemap-mobile.xsd +32 -0
  72. data/spec/support/schemas/sitemap-news.xsd +159 -0
  73. data/spec/support/schemas/sitemap-pagemap.xsd +97 -0
  74. data/spec/support/schemas/sitemap-video.xsd +643 -0
  75. data/spec/support/schemas/sitemap.xsd +115 -0
  76. data/spec/support/xml_macros.rb +67 -0
  77. data/templates/sitemap.rb +27 -0
  78. metadata +226 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 38d50814ab864ce3e8ff89f445d2391f327f2c2c
4
+ data.tar.gz: ec08722f2e14cbea0e46038cb3a422e910aee66b
5
+ SHA512:
6
+ metadata.gz: 938908d9764e1772d189fbbd25a506233e513ac274648245fecd1cf564a11012cf7bf992bd9e84d832fcd79a7e81a443e8a1b145a0f06be71b230d29d1620d5e
7
+ data.tar.gz: b48a4ce595b1fad0b0e812fca9171cc86260e72c30320ba2e62760ae41dc677b856f894584dde5bf5217c413619347a4deea77f6c1961326ca2eb828f76968bb
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'builder'
4
+ gem 'sitemap_generator', :path => './'
5
+
6
+ group :development, :test do
7
+ gem 'mocha'
8
+ gem 'nokogiri', '=1.5.10' # last release to support Ruby 1.8.7
9
+ gem 'rake'
10
+ gem 'rspec'
11
+ #gem 'ruby-debug19', :require => 'ruby-debug'
12
+ #gem 'simplecov', :require => false
13
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,35 @@
1
+ PATH
2
+ remote: ./
3
+ specs:
4
+ sitemap_generator (5.0.4)
5
+ builder
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ builder (3.0.0)
11
+ diff-lcs (1.1.3)
12
+ metaclass (0.0.1)
13
+ mocha (0.10.0)
14
+ metaclass (~> 0.0.1)
15
+ nokogiri (1.5.10)
16
+ rake (10.0.4)
17
+ rspec (2.8.0)
18
+ rspec-core (~> 2.8.0)
19
+ rspec-expectations (~> 2.8.0)
20
+ rspec-mocks (~> 2.8.0)
21
+ rspec-core (2.8.0)
22
+ rspec-expectations (2.8.0)
23
+ diff-lcs (~> 1.1.2)
24
+ rspec-mocks (2.8.0)
25
+
26
+ PLATFORMS
27
+ ruby
28
+
29
+ DEPENDENCIES
30
+ builder
31
+ mocha
32
+ nokogiri (= 1.5.10)
33
+ rake
34
+ rspec
35
+ sitemap_generator!
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 [name of plugin creator]
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,1139 @@
1
+ # SitemapGenerator
2
+
3
+ SitemapGenerator is the easiest way to generate Sitemaps in Ruby. Rails integration provides access to the Rails route helpers within your sitemap config file and automatically makes the rake tasks available to you. Or if you prefer to use another framework, you can! You can use the rake tasks provided or run your sitemap configs as plain ruby scripts.
4
+
5
+ Sitemaps adhere to the [Sitemap 0.9 protocol][sitemap_protocol] specification.
6
+
7
+ ## Features
8
+
9
+ * Framework agnostic
10
+ * Supports [News sitemaps][sitemap_news], [Video sitemaps][sitemap_video], [Image sitemaps][sitemap_images], [Geo sitemaps][sitemap_geo], [Mobile sitemaps][sitemap_mobile], [PageMap sitemaps][sitemap_pagemap] and [Alternate Links][alternate_links]
11
+ * Supports read-only filesystems like Heroku via uploading to a remote host like Amazon S3
12
+ * Compatible with Rails 2, 3 & 4 and tested with Ruby REE, 1.9.2 & 1.9.3
13
+ * Adheres to the [Sitemap 0.9 protocol][sitemap_protocol]
14
+ * Handles millions of links
15
+ * Customizable sitemap compression
16
+ * Notifies search engines (Google, Bing) of new sitemaps
17
+ * Ensures your old sitemaps stay in place if the new sitemap fails to generate
18
+ * Gives you complete control over your sitemap contents and naming scheme
19
+ * Intelligent sitemap indexing
20
+
21
+ ### Show Me
22
+
23
+ This is a simple standalone example. For Rails installation see the Install section.
24
+
25
+ Install:
26
+
27
+ ```
28
+ gem install sitemap_generator
29
+ ```
30
+
31
+ Create `sitemap.rb`:
32
+
33
+ ```ruby
34
+ require 'rubygems'
35
+ require 'sitemap_generator'
36
+
37
+ SitemapGenerator::Sitemap.default_host = 'http://example.com'
38
+ SitemapGenerator::Sitemap.create do
39
+ add '/home', :changefreq => 'daily', :priority => 0.9
40
+ add '/contact_us', :changefreq => 'weekly'
41
+ end
42
+ SitemapGenerator::Sitemap.ping_search_engines # Not needed if you use the rake tasks
43
+ ```
44
+
45
+ Run it:
46
+
47
+ ```
48
+ ruby sitemap.rb
49
+ ```
50
+
51
+ Output:
52
+
53
+ ```
54
+ In /Users/karl/projects/sitemap_generator-test/public/
55
+ + sitemap.xml.gz 3 links / 364 Bytes
56
+ Sitemap stats: 3 links / 1 sitemaps / 0m00s
57
+
58
+ Successful ping of Google
59
+ Successful ping of Bing
60
+ ```
61
+
62
+
63
+ ## Contribute
64
+
65
+ Does your website use SitemapGenerator to generate Sitemaps? Where would you be without Sitemaps? Probably still knocking rocks together. Consider donating to the project to keep it up-to-date and open source.
66
+
67
+ <a href='http://www.pledgie.com/campaigns/15267'><img alt='Click here to lend your support to: SitemapGenerator and make a donation at www.pledgie.com !' src='http://pledgie.com/campaigns/15267.png?skin_name=chrome' border='0' /></a>
68
+
69
+ ## Deprecation Notices and Non-Backwards Compatible Changes
70
+
71
+ ### Version 5.0.0
72
+
73
+ In version 5.0.0 I've removed a few deprecated methods that have been deprecated for a long time. The reason being that they would have made some new features more difficult and complex to implement. I never actually ouput deprecation notices from these methods, so I understand it you're a little annoyed that your config has suddenly broken. Apologies.
74
+
75
+ Here's a list of the methods that have been removed:
76
+ * Removed options to `LinkSet::add()`: `:sitemaps_namer` and `:sitemap_index_namer` (use `:namer` option)
77
+ * Removed `LinkSet::sitemaps_namer=`, `LinkSet::sitemaps_namer` (use `LinkSet::namer=` and `LinkSet::namer`)
78
+ * Removed `LinkSet::sitemaps_index_namer=`, `LinkSet::sitemaps_index_namer` (use `LinkSet::namer=` and `LinkSet::namer`)
79
+ * Removed the `SitemapGenerator::SitemapNamer` class (use `SitemapGenerator::SimpleNamer`)
80
+ * Removed `LinkSet::add_links()` (use `LinkSet::create()`)
81
+
82
+ ### Version 4.0.0
83
+
84
+ Version 4.0 introduces a new **non-backwards compatible** naming scheme. **If you are running version 3 or earlier and you upgrade to version 4, you need to make a couple small changes to ensure that search engines can still find your sitemaps!** Your sitemaps will still work fine, but the name of the index file has changed.
85
+
86
+ #### So what has changed?
87
+
88
+ * **The index is generated intelligently**. SitemapGenerator now detects whether you need an index or not, and only generates one if you need it or have requested it. So small sites (less than 50,000 links) won't have one, large sites will. You don't have to worry about anything. And with the `create_index` option, it's easier than ever to control index creation to suit your needs.
89
+
90
+ * **The default index file name has changed** from `sitemap_index.xml.gz` to just `sitemap.xml.gz`. So the `_index` part has been removed. This is a more standard naming scheme for the sitemaps. Any further sitemaps are named `sitemap1.xml.gz`, `sitemap2.xml.gz`, `sitemap3.xml.gz` etc, just as before.
91
+
92
+ * **Everyone now points search engines to the `sitemap.xml.gz` file**. It doesn't matter whether your site has 10 links or a million links, just point to `sitemap.xml.gz`. If your site needs an index, that is the index. If it doesn't, then that's your sitemap. Simple.
93
+
94
+ * **It's easier to write custom namers** because the index and the sitemaps share the same namer instance (which is now a `SitemapGenerator::SimpleNamer` instance).
95
+
96
+ * **Groups share the new naming convention**. So the files in your `geo` group will be named `geo.xml.gz`, `geo1.xml.gz`, `geo2.xml.gz` etc. Pre-version 4 these files would have been named `geo1.xml.gz`, `geo2.xml.gz`, `geo3.xml.gz` etc.
97
+
98
+ #### I don't want it! How can I keep everything as it was?
99
+
100
+ You don't care, you just want to get on with your day. To resort to pre-version 4 behaviour add the following to your sitemap config:
101
+
102
+ ```ruby
103
+ SitemapGenerator::Sitemap.create_index = true
104
+ SitemapGenerator::Sitemap.namer = SitemapGenerator::SimpleNamer.new(:sitemap, :zero => '_index')
105
+ ```
106
+
107
+ This tells SitemapGenerator to always create an index file and to name it `sitemap_index.xml.gz`. If you are already using custom namers, you don't need to set `namer`; your old namers should still work as before. If you are using named groups, setting the sitemap namer in this way won't affect your groups, which will still be using the new naming scheme. If this is an issue for you, you may have to create namers for your groups.
108
+
109
+ #### I want it! What do I need to do?
110
+
111
+ 1. Update your `robots.txt` file and make sure it points to `sitemap.xml.gz`.
112
+ 2. Generate your sitemaps to create the new `sitemap.xml.gz` file.
113
+ 3. Optionally remove the old `sitemap_index.xml.gz` file (or link it to the new file if you want to make sure that search engines can find it while you update them.)
114
+ 4. Go to your Google Webmaster tools and other places where you've pointed search engines to your sitemaps and point them to your new `sitemap.xml.gz` file.
115
+
116
+ That's it! Welcome to the future!
117
+
118
+ ## Changelog
119
+
120
+ * v5.0.4: Don't include the `media` attribute on alternate links unless it's given
121
+ * v5.0.3: Add support for Video sitemaps options `:live` and ':requires_subscription'
122
+ * v5.0.2: Set maximum filesize to 10,000,000 bytes rather than 10,485,760 bytes.
123
+ * v5.0.1: Include new `SitemapGenerator::FogAdapter` ([#138](https://github.com/kjvarga/sitemap_generator/pull/138)). Fix usage of attr_* methods in LinkSet; don't override custom getters/setters ([#144](https://github.com/kjvarga/sitemap_generator/pull/144)). Fix breaking spec in Ruby 2 ([#142](https://github.com/kjvarga/sitemap_generator/pull/142)). Include Capistrano 3.x tasks ([#141](https://github.com/kjvarga/sitemap_generator/pull/141)).
124
+ * v5.0.0: Support new `:compress` option for customizing which files get compressed. Remove old deprecated methods (see deprecation notices above). Support `fog_path_style` option in the `SitemapGenerator::S3Adapter` so buckets with dots in the name work over HTTPS without SSL certificate problems.
125
+ * v4.3.1: Support integer timestamps. Update README for new features added in last release.
126
+ * 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)).
127
+ * 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)).
128
+ * 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.
129
+ * v4.1.0: [PageMap sitemap][using_pagemaps] support. Tested with Rails 4 pre-release.
130
+ * v4.0.1: Add a post install message regarding the naming convention change.
131
+ * **v4.0: NEW, NON-BACKWARDS COMPATIBLE CHANGES.** See above for more info. `create_index` defaults to `:auto`. Define `SitemapGenerator::SimpleNamer` class for simpler custom namers compatible with the new naming conventions. Deprecate `sitemaps_namer`, `sitemap_index_namer` and their respective namer classes. It's more just that their usage is discouraged. Support `nofollow` option on alternate links. Fix formatting of `publication_date` in News sitemaps.
132
+ * v3.4: Support [alternate links][alternate_links] for urls; Support configurable options in the `SitemapGenerator::S3Adapter`
133
+ * v3.3: **Support creating sitemaps with no index file**. A big thank-you to [Eric Hochberger][ehoch] for generously paying for this feature.
134
+ * v3.2.1: Fix syntax error in SitemapGenerator::S3Adapter
135
+ * v3.2: **Support mobile tags**, **SitemapGenerator::S3Adapter** a simple S3 adapter which uses Fog and doesn't require CarrierWave; Remove Ask from the sitemap ping because the service has been shutdown; [Turn off `include_index`][include_index_change] by default; Fix the news XML namespace; Only include autoplay attribute if present
136
+ * v3.1.1: Bugfix: Groups inherit current adapter
137
+ * v3.1.0: Add `add_to_index` method to add links to the sitemap index. Add `sitemap` method for accessing the LinkSet instance from within `create()`. Don't modify options hashes passed to methods. Fix and improve `yield_sitemap` option handling.
138
+ * **v3.0.0: Framework agnostic**; fix alignment in output, show directory sitemaps are being generated into, only show sitemap compressed file size; toggle output using VERBOSE environment variable; remove tasks/ directory because it's deprecated in Rails 2; Simplify dependencies.
139
+ * v2.2.1: Support adding new search engines to ping and modifying the default search engines.
140
+ Allow the URL of the sitemap index to be passed as an argument to `ping_search_engines`. See **Pinging Search Engines**.
141
+ * v2.1.8: Extend and improve Video Sitemap support. Include sitemap docs in the README, support all element attributes, properly format values.
142
+ * v2.1.7: Improve format of float priorities; Remove Yahoo from ping - the Yahoo
143
+ service has been shut down.
144
+ * v2.1.6: Fix the lastmod value on sitemap file links
145
+ * v2.1.5: Fix verbose setting in the rake tasks; should default to true
146
+ * v2.1.4: Allow special characters in URLs (don't use URI.join to construct URLs)
147
+ * v2.1.3: Fix calling create with both `filename` and `sitemaps_namer` options
148
+ * v2.1.2: Support multiple videos per url using the new `videos` option to `add()`.
149
+ * v2.1.1: Support calling `create()` multiple times in a sitemap config. Support host names with path segments so you can use a `default_host` like `'http://mysite.com/subdirectory/'`. Turn off `include_index` when the `sitemaps_host` differs from `default_host`. Add docs about how to upload to remote hosts.
150
+ * v2.1.0: [News sitemap][sitemap_news] support
151
+ * v2.0.1.pre2: Fix uploading to the (bucket) root on a remote server
152
+ * v2.0.1.pre1: Support read-only filesystems like Heroku by supporting uploading to remote host
153
+ * v2.0.1: Minor improvements to verbose handling; prevent missing Timeout issue
154
+ * **v2.0.0: Introducing a new simpler API, Sitemap Groups, Sitemap Namers and more!**
155
+ * v1.5.0: New options `include_root`, `include_index`; Major testing & refactoring
156
+ * v1.4.0: [Geo sitemap][geo_tags] support, multiple sitemap support via CONFIG_FILE rake option
157
+ * v1.3.0: Support setting the sitemaps path
158
+ * v1.2.0: Verified working with Rails 3 stable release
159
+ * v1.1.0: [Video sitemap][sitemap_video] support
160
+ * v0.2.6: [Image Sitemap][sitemap_images] support
161
+ * v0.2.5: Rails 3 prerelease support (beta)
162
+
163
+
164
+ ## Foreword
165
+
166
+ Adam Salter first created SitemapGenerator while we were working together in Sydney, Australia. Unfortunately, he passed away in 2009. Since then I have taken over development of SitemapGenerator.
167
+
168
+ Those who knew him know what an amazing guy he was, and what an excellent Rails programmer he was. His passing is a great loss to the Rails community.
169
+
170
+ The canonical repository is now: [http://github.com/kjvarga/sitemap_generator][canonical_repo]
171
+
172
+
173
+ ## Install
174
+
175
+ ### Ruby
176
+
177
+ ```
178
+ gem install 'sitemap_generator'
179
+ ```
180
+
181
+ To use the rake tasks add the following to your `Rakefile`:
182
+
183
+ ```ruby
184
+ require 'sitemap_generator/tasks'
185
+ ```
186
+
187
+ The Rake tasks expect your sitemap to be at `config/sitemap.rb` but if you need to change that call like so: `rake sitemap:refresh CONFIG_FILE="path/to/sitemap.rb"`
188
+
189
+ ### Rails
190
+
191
+ SitemapGenerator works will all versions of Rails and has been tested in Rails 2, 3 and 4.
192
+
193
+ Add the gem to your `Gemfile`:
194
+
195
+ ```ruby
196
+ gem 'sitemap_generator'
197
+ ```
198
+
199
+ Alternatively, if you are not using a `Gemfile` add the gem to your `config/environment.rb` file config block:
200
+
201
+ ```ruby
202
+ config.gem 'sitemap_generator'
203
+ ```
204
+
205
+
206
+ **Rails 1 or 2 only**, add the following code to your `Rakefile` to include the gem's Rake tasks in your project (Rails 3 does this for you automatically, so this step is not necessary):
207
+
208
+ ```ruby
209
+ begin
210
+ require 'sitemap_generator/tasks'
211
+ rescue Exception => e
212
+ puts "Warning, couldn't load gem tasks: #{e.message}! Skipping..."
213
+ end
214
+ ```
215
+
216
+ _If you would prefer to install as a plugin (deprecated) don't do any of the above. Simply run `script/plugin install git://github.com/kjvarga/sitemap_generator.git` from your application root directory._
217
+
218
+ ## Getting Started
219
+
220
+ ### Preventing Output
221
+
222
+ To disable all non-essential output set the environment variable `VERBOSE=false` when calling Rake or running your Ruby script.
223
+
224
+ Alternatively you can pass the `-s` option to Rake, for example `rake -s sitemap:refresh`.
225
+
226
+ To disable output in-code use the following:
227
+
228
+ ```ruby
229
+ SitemapGenerator.verbose = false
230
+ ```
231
+
232
+ ### Rake Tasks
233
+
234
+ * `rake sitemap:install` will create a `config/sitemap.rb` file which is your sitemap configuration and contains everything needed to build your sitemap. See **Sitemap Configuration** below for more information about how to define your sitemap.
235
+ * `rake sitemap:refresh` will create or rebuild your sitemap files as needed. Sitemaps are generated into the `public/` folder and by default are named `sitemap_index.xml.gz`, `sitemap1.xml.gz`, `sitemap2.xml.gz`, etc. As you can see they are automatically gzip compressed for you.
236
+ * `rake sitemap:refresh` will output information about each sitemap that is written including its location, how many links it contains and the size of the file.
237
+
238
+
239
+ ### Pinging Search Engines
240
+
241
+ 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`.
242
+
243
+ If you want to customize the hash of search engines you can access it at:
244
+
245
+ ```ruby
246
+ SitemapGenerator::Sitemap.search_engines
247
+ ```
248
+
249
+ Usually you would be adding a new search engine to ping. In this case you can modify the `search_engines` hash directly. This ensures that when `SitemapGenerator::Sitemap.ping_search_engines` is called your new search engine will be included.
250
+
251
+ If you are calling `ping_search_engines` manually (for example if you have to wait some time or perform a custom action after your sitemaps have been regenerated) then you can pass you new search engine directly in the call as in the following example:
252
+
253
+ ```ruby
254
+ SitemapGenerator::Sitemap.ping_search_engines(:newengine => 'http://newengine.com/ping?url=%s')
255
+ ```
256
+
257
+ The key gives the name of the search engine as a string or symbol and the value is the full URL to ping with a string interpolation that will be replaced by the CGI escaped sitemap index URL. If you have any literal percent characters in your URL you need to escape them with `%%`.
258
+
259
+ If you are calling `SitemapGenerator::Sitemap.ping_search_engines` from outside of your sitemap config file then you will need to set `SitemapGenerator::Sitemap.default_host` and any other options that you set in your sitemap config which affect the location of the sitemap index file. For example:
260
+
261
+ ```ruby
262
+ SitemapGenerator::Sitemap.default_host = 'http://example.com'
263
+ SitemapGenerator::Sitemap.ping_search_engines
264
+ ```
265
+
266
+ Alternatively you can pass in the full URL to your sitemap index in which case we would have just the following:
267
+
268
+ ```ruby
269
+ SitemapGenerator::Sitemap.ping_search_engines('http://example.com/sitemap.xml.gz')
270
+ ```
271
+
272
+ ### Crontab
273
+
274
+ To keep your sitemaps up-to-date, setup a cron job. Make sure to pass the `-s` option to silence rake. That way you will only get email if the sitemap build fails.
275
+
276
+ If you're using Whenever, your schedule would look something like this:
277
+
278
+ ```ruby
279
+ # config/schedule.rb
280
+ every 1.day, :at => '5:00 am' do
281
+ rake "-s sitemap:refresh"
282
+ end
283
+ ```
284
+
285
+
286
+ ### Robots.txt
287
+
288
+ You should add the URL of the sitemap index file to `public/robots.txt` to help search engines find your sitemaps. The URL should be the complete URL to the sitemap index. For example:
289
+
290
+ ```
291
+ Sitemap: http://www.example.com/sitemap.xml.gz
292
+ ```
293
+
294
+ ### Ruby Modules
295
+
296
+ If you need to include a module (e.g. a rails helper) you can add the following line:
297
+
298
+ ```ruby
299
+ SitemapGenerator::Interpreter.send :include, RoutingHelper
300
+ ```
301
+
302
+ ## Deployments & Capistrano
303
+
304
+ To include the capistrano tasks just add the following to your Capfile:
305
+
306
+ ```ruby
307
+ require 'capistrano/sitemap_generator'
308
+ ```
309
+
310
+ Available capistrano tasks:
311
+
312
+ ```ruby
313
+ deploy:sitemap:create #Create sitemaps without pinging search engines
314
+ deploy:sitemap:refresh #Create sitemaps and ping search engines
315
+ deploy:sitemap:clean #Clean up sitemaps in the sitemap path
316
+ ```
317
+
318
+ **Generate sitemaps into a directory which is shared by all deployments.**
319
+
320
+ You can set your sitemaps path to your shared directory using the `sitemaps_path` option. For example if we have a directory `public/shared/` that is shared by all deployments we can have our sitemaps generated into that directory by setting:
321
+
322
+ ```ruby
323
+ SitemapGenerator::Sitemap.sitemaps_path = 'shared/'
324
+ ```
325
+
326
+ ### Sitemaps with no Index File
327
+
328
+ 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`.
329
+
330
+ You may want to always create an index, even if you only have a small site. Or you may never want to create an index. For these cases, you can use the `create_index` option to control index creation. You can read about this option in the Sitemap Options section below.
331
+
332
+ To always create an index:
333
+
334
+ ```ruby
335
+ SitemapGenerator::Sitemap.create_index = true
336
+ ```
337
+
338
+ To never create an index:
339
+
340
+ ```ruby
341
+ SitemapGenerator::Sitemap.create_index = false
342
+ ```
343
+ Your sitemaps will still be called `sitemap.xml.gz`, `sitemap1.xml.gz`, `sitemap2.xml.gz`, etc.
344
+
345
+ And the default "intelligent" behaviour:
346
+
347
+ ```ruby
348
+ SitemapGenerator::Sitemap.create_index = :auto
349
+ ```
350
+
351
+ ### Upload Sitemaps to a Remote Host using Adapters
352
+
353
+ _This section needs better documentation. Please consider contributing._
354
+
355
+ #### Supported Adapters
356
+ * `SitemapGenerator::FileAdapter`
357
+
358
+ Standard adapter, writes out to a file
359
+
360
+ * `SitemapGenerator::FogAdapter`
361
+
362
+ Uses `fog` to upload to any service supported by Fog.
363
+
364
+ * `SitemapGenerator::S3Adapter`
365
+
366
+ Uses `fog` to upload to Amazon S3 storage.
367
+
368
+ * `SitemapGenerator::WaveAdapter`
369
+
370
+ Uses `carrierwave` to upload to any service supported by CarrierWave.
371
+
372
+ Some documentation exists [on the wiki page][remote_hosts].
373
+
374
+ Sometimes it is desirable to host your sitemap files on a remote server and point robots
375
+ and search engines to the remote files. For example if you are using a host like Heroku
376
+ which doesn't allow writing to the local filesystem. You still require *some* write access
377
+ because the sitemap files need to be written out before uploading, so generally a host will
378
+ give you write access to a temporary directory. On Heroku this is `tmp/` in your application
379
+ directory.
380
+
381
+ Sitemap Generator uses CarrierWave to support uploading to Amazon S3 store, Rackspace Cloud Files store, and MongoDB's GridF - whatever CarrierWave supports.
382
+
383
+ 1. Please see [this wiki page][remote_hosts] for more information about setting up CarrierWave, SitemapGenerator and Rails.
384
+
385
+ 2. Once you have CarrierWave setup and configured all you need to do is set some options in your sitemap config, such as
386
+
387
+ ```ruby
388
+ # Your website's host name
389
+ SitemapGenerator::Sitemap.default_host = "http://www.example.com"
390
+
391
+ # The remote host where your sitemaps will be hosted
392
+ SitemapGenerator::Sitemap.sitemaps_host = "http://s3.amazonaws.com/sitemap-generator/"
393
+
394
+ # The directory to write sitemaps to locally
395
+ SitemapGenerator::Sitemap.public_path = 'tmp/'
396
+
397
+ # Set this to a directory/path if you don't want to upload to the root of your `sitemaps_host`
398
+ SitemapGenerator::Sitemap.sitemaps_path = 'sitemaps/'
399
+
400
+ # Instance of `SitemapGenerator::WaveAdapter`
401
+ SitemapGenerator::Sitemap.adapter = SitemapGenerator::WaveAdapter.new
402
+ ```
403
+
404
+ 3. Update your `robots.txt` file to point robots to the remote sitemap index file, e.g:
405
+
406
+ ```
407
+ Sitemap: http://s3.amazonaws.com/sitemap-generator/sitemaps/sitemap_index.xml.gz
408
+ ```
409
+
410
+ You generate your sitemaps as usual using `rake sitemap:refresh`.
411
+
412
+ Note that SitemapGenerator will automatically turn off `include_index` in this case because
413
+ the `sitemaps_host` does not match the `default_host`. The link to the sitemap index file
414
+ that would otherwise be included would point to a different host than the rest of the links
415
+ in the sitemap, something that the sitemap rules forbid. (Since version 3.2 this is no
416
+ longer an issue because [`include_index` is off by default][include_index_change].)
417
+
418
+ 4. Verify to google that you own the s3 url
419
+
420
+ In order for Google to use your sitemap, you need to prove you own the s3 bucket through [google webmaster tools](https://www.google.com/webmasters/tools/home?hl=en). In the example above, you would add the site `http://s3.amazonaws.com/sitemap-generator/sitemaps`. Once you have verified you own the directory then add your `sitemap.xml.gz` to this list of sitemaps for the site.
421
+
422
+ ### Generating Multiple Sitemaps
423
+
424
+ Each call to `create` creates a new sitemap index and associated sitemaps. You can call `create` as many times as you want within your sitemap configuration.
425
+
426
+ You must remember to use a different filename or location for each set of sitemaps, otherwise they will
427
+ overwrite each other. You can use the `filename`, `namer` and `sitemaps_path` options for this.
428
+
429
+ In the following example we generate three sitemaps each in its own subdirectory:
430
+
431
+ ```ruby
432
+ %w(google bing apple).each do |subdomain|
433
+ SitemapGenerator::Sitemap.default_host = "https://#{subdomain}.mysite.com"
434
+ SitemapGenerator::Sitemap.sitemaps_path = "sitemaps/#{subdomain}"
435
+ SitemapGenerator::Sitemap.create do
436
+ add '/home'
437
+ end
438
+ end
439
+ ```
440
+
441
+ Outputs:
442
+
443
+ ```
444
+ + sitemaps/google/sitemap1.xml.gz 2 links / 822 Bytes / 328 Bytes gzipped
445
+ + sitemaps/google/sitemap.xml.gz 1 sitemaps / 389 Bytes / 217 Bytes gzipped
446
+ Sitemap stats: 2 links / 1 sitemaps / 0m00s
447
+ + sitemaps/bing/sitemap1.xml.gz 2 links / 820 Bytes / 330 Bytes gzipped
448
+ + sitemaps/bing/sitemap.xml.gz 1 sitemaps / 388 Bytes / 217 Bytes gzipped
449
+ Sitemap stats: 2 links / 1 sitemaps / 0m00s
450
+ + sitemaps/apple/sitemap1.xml.gz 2 links / 820 Bytes / 330 Bytes gzipped
451
+ + sitemaps/apple/sitemap.xml.gz 1 sitemaps / 388 Bytes / 214 Bytes gzipped
452
+ Sitemap stats: 2 links / 1 sitemaps / 0m00s
453
+ ```
454
+
455
+ If you don't want to have to generate all the sitemaps at once, or you want to refresh some more often than others, you can split them up into their own configuration files. Using the above example we would have:
456
+
457
+ ```ruby
458
+ # config/google_sitemap.rb
459
+ SitemapGenerator::Sitemap.default_host = "https://google.mysite.com"
460
+ SitemapGenerator::Sitemap.sitemaps_path = "sitemaps/google"
461
+ SitemapGenerator::Sitemap.create do
462
+ add '/home'
463
+ end
464
+
465
+ # config/apple_sitemap.rb
466
+ SitemapGenerator::Sitemap.default_host = "https://apple.mysite.com"
467
+ SitemapGenerator::Sitemap.sitemaps_path = "sitemaps/apple"
468
+ SitemapGenerator::Sitemap.create do
469
+ add '/home'
470
+ end
471
+
472
+ # config/bing_sitemap.rb
473
+ SitemapGenerator::Sitemap.default_host = "https://bing.mysite.com"
474
+ SitemapGenerator::Sitemap.sitemaps_path = "sitemaps/bing"
475
+ SitemapGenerator::Sitemap.create do
476
+ add '/home'
477
+ end
478
+ ```
479
+
480
+
481
+ To generate each one specify the configuration file to run by passing the `CONFIG_FILE` option to `rake sitemap:refresh`, e.g.:
482
+
483
+ ```
484
+ rake sitemap:refresh CONFIG_FILE="config/google_sitemap.rb"
485
+ rake sitemap:refresh CONFIG_FILE="config/apple_sitemap.rb"
486
+ rake sitemap:refresh CONFIG_FILE="config/bing_sitemap.rb"
487
+ ```
488
+
489
+ ## Sitemap Configuration
490
+
491
+ A sitemap configuration file contains all the information needed to generate your sitemaps. By default SitemapGenerator looks for a configuration file in `config/sitemap.rb` - relative to your application root or the current working directory. (Run `rake sitemap:install` to have this file generated for you if you have not done so already.)
492
+
493
+ If you want to use a non-standard configuration file, or have multiple configuration files, you can specify which one to run by passing the `CONFIG_FILE` option like so:
494
+
495
+ ```
496
+ rake sitemap:refresh CONFIG_FILE="config/geo_sitemap.rb"
497
+ ```
498
+
499
+
500
+ ### A Simple Example
501
+
502
+ So what does a sitemap configuration look like? Let's take a look at a simple example:
503
+
504
+ ```ruby
505
+ SitemapGenerator::Sitemap.default_host = "http://www.example.com"
506
+ SitemapGenerator::Sitemap.create do
507
+ add '/welcome'
508
+ end
509
+ ```
510
+
511
+ A few things to note:
512
+
513
+ * `SitemapGenerator::Sitemap` is a lazy-initialized sitemap object provided for your convenience.
514
+ * Every sitemap must set `default_host`. This is the hostname that is used when building links to add to the sitemap (and all links in a sitemap must belong to the same host).
515
+ * The `create` method takes a block with calls to `add` to add links to the sitemap.
516
+ * The sitemaps are written to the `public/` directory in the directory from which the script is run. You can specify a custom location using the `public_path` or `sitemaps_path` option.
517
+
518
+ Now let's see what is output when we run this configuration with `rake sitemap:refresh:no_ping`:
519
+
520
+ ```
521
+ In /Users/karl/projects/sitemap_generator-test/public/
522
+ + sitemap.xml.gz 2 links / 347 Bytes
523
+ Sitemap stats: 2 links / 1 sitemaps / 0m00s
524
+ ```
525
+
526
+ Weird! The sitemap has two links, even though we only added one! This is because SitemapGenerator adds the root URL `/` for you by default. (Note that prior to version 3.2 the URL of the sitemap index file was also added to the sitemap by default but [this behaviour has been changed][include_index_change] because of Google complaining about nested indexing. This also doesn't make sense anymore because indexes are not always needed.) You can change the default behaviour by setting the `include_root` or `include_index` option.
527
+
528
+ Now let's take a look at the file that was created. After uncompressing and XML-tidying the contents we have:
529
+
530
+
531
+ * `public/sitemap.xml.gz`
532
+
533
+ ```xml
534
+ <?xml version="1.0" encoding="UTF-8"?>
535
+ <urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1" xmlns:geo="http://www.google.com/geo/schemas/sitemap/1.0" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
536
+ <url>
537
+ <loc>http://www.example.com/</loc>
538
+ <lastmod>2011-05-21T00:03:38+00:00</lastmod>
539
+ <changefreq>always</changefreq>
540
+ <priority>1.0</priority>
541
+ </url>
542
+ <url>
543
+ <loc>http://www.example.com/welcome</loc>
544
+ <lastmod>2011-05-21T00:03:38+00:00</lastmod>
545
+ <changefreq>weekly</changefreq>
546
+ <priority>0.5</priority>
547
+ </url>
548
+ </urlset>
549
+ ```
550
+
551
+ The sitemaps conform to the [Sitemap 0.9 protocol][sitemap_protocol]. Notice the value for `priority` and `changefreq` on the root link, the one that was added for us? The values tell us that this link is the highest priority and should be checked regularly because it are constantly changing. You can specify your own values for these options in your call to `add`.
552
+
553
+ In this example no sitemap index was created because we have so few links, so none was needed. If we run the same example above and set `create_index = true` we can take a look at what an index file looks like:
554
+
555
+ ```ruby
556
+ SitemapGenerator::Sitemap.default_host = "http://www.example.com"
557
+ SitemapGenerator::Sitemap.create_index = true
558
+ SitemapGenerator::Sitemap.create do
559
+ add '/welcome'
560
+ end
561
+ ```
562
+
563
+ And the output:
564
+
565
+ ```
566
+ In /Users/karl/projects/sitemap_generator-test/public/
567
+ + sitemap1.xml.gz 2 links / 347 Bytes
568
+ + sitemap.xml.gz 1 sitemaps / 228 Bytes
569
+ Sitemap stats: 2 links / 1 sitemaps / 0m00s
570
+ ```
571
+
572
+ Now if we look at the uncompressed and formatted contents of `sitemap.xml.gz` we can see that it is a sitemap index and `sitemap1.xml.gz` is a sitemap:
573
+
574
+ * `public/sitemap.xml.gz`
575
+
576
+ ```xml
577
+ <?xml version="1.0" encoding="UTF-8"?>
578
+ <sitemapindex xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/siteindex.xsd">
579
+ <sitemap>
580
+ <loc>http://www.example.com/sitemap1.xml.gz</loc>
581
+ <lastmod>2013-05-01T18:10:26-07:00</lastmod>
582
+ </sitemap>
583
+ </sitemapindex>
584
+ ```
585
+
586
+ ### Adding Links
587
+
588
+ You call `add` in the block passed to `create` to add a **path** to your sitemap. `add` takes a string path and optional hash of options, generates the URL and adds it to the sitemap. You only need to pass a **path** because the URL will be built for us using the `default_host` we specified. However, if we want to use a different host for a particular link, we can pass the `:host` option to `add`.
589
+
590
+ Let's see another example:
591
+
592
+ ```ruby
593
+ SitemapGenerator::Sitemap.default_host = "http://www.example.com"
594
+ SitemapGenerator::Sitemap.create do
595
+ add '/contact_us'
596
+ Content.find_each do |content|
597
+ add content_path(content), :lastmod => content.updated_at
598
+ end
599
+ end
600
+ ```
601
+
602
+ In this example first we add the `/contact_us` page to the sitemap and then we iterate through the Content model's records adding each one to the sitemap using the `content_path` helper method to generate the path for each record.
603
+
604
+ The **Rails URL/path helper methods are automatically made available** to us in the `create` block. This keeps the logic for building our paths out of the sitemap config and in the Rails application where it should be. You use those methods just like you would in your application's view files.
605
+
606
+ In the example about we pass a `lastmod` (last modified) option with the value of the record's `updated_at` attribute so that search engines know to only re-index the page when the record changes.
607
+
608
+ Looking at the output from running this sitemap, we see that we have a few more links than before:
609
+
610
+ ```
611
+ + sitemap.xml.gz 12 links / 2.3 KB / 365 Bytes gzipped
612
+ Sitemap stats: 12 links / 1 sitemaps / 0m00s
613
+ ```
614
+
615
+ From this example we can see that:
616
+
617
+ * The `create` block can contain Ruby code
618
+ * The Rails URL/path helper methods are made available to us, and
619
+ * The basic syntax for adding paths to the sitemap using `add`
620
+
621
+ You can read more about `add` in the [XML Specification](http://sitemaps.org/protocol.php#xmlTagDefinitions).
622
+
623
+ ### Supported Options to `add`
624
+
625
+ For other options be sure to check out the **Sitemap Extensions** section below.
626
+
627
+ * `changefreq` - Default: `'weekly'` (String).
628
+
629
+ Indicates how often the content of the page changes. One of `'always'`, `'hourly'`, `'daily'`, `'weekly'`, `'monthly'`, `'yearly'` or `'never'`. Example:
630
+
631
+ ```ruby
632
+ add '/contact_us', :changefreq => 'monthly'
633
+ ```
634
+
635
+ * `lastmod` - Default: `Time.now` (Integer, Time, Date, DateTime, String).
636
+
637
+ The date and time of last modification. Example:
638
+
639
+ ```ruby
640
+ add content_path(content), :lastmod => content.updated_at
641
+ ```
642
+
643
+ * `host` - Default: `default_host` (String).
644
+
645
+ Host to use when building the URL. It's not technically valid to specify a different host for a link in a sitemap according to the spec, but this facility exists in case you have a need. Example:
646
+
647
+ ```ruby
648
+ add '/login', :host => 'https://securehost.com'
649
+ ```
650
+
651
+ * `priority` - Default: `0.5` (Float).
652
+
653
+ The priority of the URL relative to other URLs on a scale from 0 to 1. Example:
654
+
655
+ ```ruby
656
+ add '/about', :priority => 0.75
657
+ ```
658
+
659
+ * `expires` - Optional (Integer, Time, Date, DateTime, String)
660
+
661
+ [expires][Request removal of this URL from search engines' indexes]. Example (uses ActiveSupport):
662
+
663
+ ```ruby
664
+ add '/about', :expires => Time.now + 2.weeks
665
+
666
+
667
+ ### Adding Links to the Sitemap Index
668
+
669
+ Sometimes you may need to manually add some links to the sitemap index file. For example if you are generating your sitemaps incrementally you may want to create a sitemap index which includes the files which have already been generated. To achieve this you can use the `add_to_index` method which works exactly the same as the `add` method described above.
670
+
671
+ It supports the same options as `add`, namely:
672
+
673
+ * `changefreq`
674
+ * `lastmod`
675
+ * `host`
676
+
677
+ The value for `host` defaults to whatever you have set as your `sitemaps_host`. Remember that the `sitemaps_host` is the host where your sitemaps reside. If your sitemaps are on the same host as your `default_host`, then the value for `default_host` is used. Example:
678
+
679
+ ```ruby
680
+ add_to_index '/mysitemap1.xml.gz', :host => 'http://sitemaphostingserver.com'
681
+ ```
682
+
683
+ * `priority`
684
+
685
+ An example:
686
+
687
+ ```ruby
688
+ SitemapGenerator::Sitemap.default_host = "http://www.example.com"
689
+ SitemapGenerator::Sitemap.create do
690
+ add_to_index '/mysitemap1.xml.gz'
691
+ add_to_index '/mysitemap2.xml.gz'
692
+ # ...
693
+ end
694
+ ```
695
+
696
+ When you add links in this way, an index is always created, unless you've explicitly set `create_index` to `false`.
697
+
698
+ ### Accessing the LinkSet instance
699
+
700
+ Sometimes you need to mess with the internals to do custom stuff. If you need access to the LinkSet instance from within `create()` you can use the `sitemap` method to do so.
701
+
702
+ In this example, say we have already pre-generated three sitemap files: `sitemap1.xml.gz`, `sitemap2.xml.gz`, `sitemap3.xml.gz`. Now we want to start the sitemap generation at `sitemap4.xml.gz` and create a bunch of new sitemaps. There are a few ways we can do this, but this is an easy way:
703
+
704
+ ```ruby
705
+ SitemapGenerator::Sitemap.default_host = "http://www.example.com"
706
+ SitemapGenerator::Sitemap.namer = SitemapGenerator::SimpleNamer.new(:sitemap, :start => 4)
707
+ SitemapGenerator::Sitemap.create do
708
+ (1..3).each do |i|
709
+ add_to_index "sitemap#{i}.xml.gz"
710
+ end
711
+ add '/home'
712
+ add '/another'
713
+ end
714
+ ```
715
+
716
+ The output looks something like this:
717
+
718
+ ```
719
+ In /Users/karl/projects/sitemap_generator-test/public/
720
+ + sitemap4.xml.gz 3 links / 355 Bytes
721
+ + sitemap.xml.gz 4 sitemaps / 242 Bytes
722
+ Sitemap stats: 3 links / 4 sitemaps / 0m00s
723
+ ```
724
+
725
+ ### Speeding Things Up
726
+
727
+ For large ActiveRecord collections with thousands of records it is advisable to iterate through them in batches to avoid loading all records into memory at once. For this reason in the example above we use `Content.find_each` which is a batched iterator available since Rails 2.3.2, rather than `Content.all`.
728
+
729
+
730
+ ## Customizing your Sitemaps
731
+
732
+ SitemapGenerator supports a number of options which allow you to control every aspect of your sitemap generation. How they are named, where they are stored, the contents of the links and the location that the sitemaps will be hosted from can all be set.
733
+
734
+ The options can be set in the following ways.
735
+
736
+ On `SitemapGenerator::Sitemap`:
737
+
738
+ ```ruby
739
+ SitemapGenerator::Sitemap.default_host = 'http://example.com'
740
+ SitemapGenerator::Sitemap.sitemaps_path = 'sitemaps/'
741
+ ```
742
+
743
+ These options will apply to all sitemaps. This is how you set most options.
744
+
745
+ Passed as options in the call to `create`:
746
+
747
+ ```ruby
748
+ SitemapGenerator::Sitemap.create(
749
+ :default_host => 'http://example.com',
750
+ :sitemaps_path => 'sitemaps/') do
751
+ add '/home'
752
+ end
753
+ ```
754
+
755
+ This is useful if you are setting a lot of options.
756
+
757
+ Finally, passed as options in a call to `group`:
758
+
759
+ ```ruby
760
+ SitemapGenerator::Sitemap.create(:default_host => 'http://example.com') do
761
+ group(:filename => :somegroup, :sitemaps_path => 'sitemaps/') do
762
+ add '/home'
763
+ end
764
+ end
765
+ ```
766
+
767
+ The options passed to `group` only apply to the links and sitemaps generated in the group. Sitemap Groups are useful to group links into specific sitemaps, or to set options that you only want to apply to the links in that group.
768
+
769
+ ### Sitemap Options
770
+
771
+ The following options are supported.
772
+
773
+ * `:create_index` - Supported values: `true`, `false`, `:auto`. Default: `true`. Whether to create a sitemap index file. If `true` an index file is always created regardless of how many sitemap files are generated. If `false` an index file is never created. If `:auto` an index file is created only when you have more than one sitemap file (i.e. you have added more than 50,000 - `SitemapGenerator::MAX_SITEMAP_LINKS` - links).
774
+
775
+ * `:default_host` - String. Required. **Host including protocol** to use when building a link to add to your sitemap. For example `http://example.com`. Calling `add '/home'` would then generate the URL `http://example.com/home` and add that to the sitemap. You can pass a `:host` option in your call to `add` to override this value on a per-link basis. For example calling `add '/home', :host => 'https://example.com'` would generate the URL `https://example.com/home`, for that link only.
776
+
777
+ * `:filename` - Symbol. The **base name for the files** that will be generated. The default value is `:sitemap`. This yields files with names like `sitemap.xml.gz`, `sitemap1.xml.gz`, `sitemap2.xml.gz`, `sitemap3.xml.gz` etc. If we now set the value to `:geo` the files would be named `geo.xml.gz`, `geo1.xml.gz`, `geo2.xml.gz`, `geo3.xml.gz` etc.
778
+
779
+ * `:include_index` - Boolean. Whether to **add a link pointing to the sitemap index** to the current sitemap. This points search engines to your Sitemap Index to include it in the indexing of your site. 2012-07: This is now turned off by default because Google may complain about there being 'Nested Sitemap indexes'. Default is `false`. Turned off when `sitemaps_host` is set or within a `group()` block.
780
+
781
+ * `:include_root` - Boolean. Whether to **add the root** url i.e. '/' to the current sitemap. Default is `true`. Turned off within a `group()` block.
782
+
783
+ * `:public_path` - String. A **full or relative path** to the `public` directory or the directory you want to write sitemaps into. Defaults to `public/` under your application root or relative to the current working directory.
784
+
785
+ * `:sitemaps_host` - String. **Host including protocol** to use when generating a link to a sitemap file i.e. the hostname of the server where the sitemaps are hosted. The value will differ from the hostname in your sitemap links. For example: `'http://amazon.aws.com/'`. Note that `include_index` is
786
+ automatically turned off when the `sitemaps_host` does not match `default_host`.
787
+ Because the link to the sitemap index file that would otherwise be added would point to a different host than the rest of the links in the sitemap. Something that the sitemap rules forbid.
788
+
789
+ * `:namer` - A `SitemapGenerator::SimpleNamer` instance **for generating sitemap names**. You can read about Sitemap Namers by reading the API docs. Allows you to set the name, extension and number sequence for sitemap files, as well as modify the name of the first file in the sequence, which is often the index file. A simple example if we want to generate files like 'newname.xml.gz', 'newname1.xml.gz', etc is `SitemapGenerator::SimpleNamer.new(:newname)`.
790
+
791
+ * `:sitemaps_path` - String. A **relative path** giving a directory under your `public_path` at which to write sitemaps. The difference between the two options is that the `sitemaps_path` is used when generating a link to a sitemap file. For example, if we set `SitemapGenerator::Sitemap.sitemaps_path = 'en/'` and use the default `public_path` sitemaps will be written to `public/en/`. The URL to the sitemap index would then be `http://example.com/en/sitemap.xml.gz`.
792
+
793
+ * `:verbose` - Boolean. Whether to **output a sitemap summary** describing the sitemap files and giving statistics about your sitemap. Default is `false`. When using the Rake tasks `verbose` will be `true` unless you pass the `-s` option.
794
+
795
+ * `:adapter` - Instance. The default adapter is a `SitemapGenerator::FileAdapter` which simply writes files to the filesystem. You can use a `SitemapGenerator::WaveAdapter` for uploading sitemaps to remote servers - useful for read-only hosts such as Heroku. Or you can provide an instance of your own class to provide custom behavior. Your class must define a write method which takes a `SitemapGenerator::Location` and raw XML data.
796
+
797
+ * `:compress` - Specifies which files to compress with gzip. Default is `true`. Accepted values:
798
+ * `true` - Boolean; compress all files.
799
+ * `false` - Boolean; Do not compress any files.
800
+ * `:all_but_first` - Symbol; leave the first file uncompressed but compress all remaining files.
801
+
802
+ The compression setting applies to groups too. So `:all_but_first` will have the same effect (the first file in the group will not be compressed, the rest will). So if you require different behaviour for your groups, pass in a `:compress` option e.g. `group(:compress => false) { add('/link') }`
803
+
804
+ ## Sitemap Groups
805
+
806
+ Sitemap Groups is a powerful feature that is also very simple to use.
807
+
808
+ * All options are supported except for `public_path`. You cannot change the public path.
809
+ * Groups inherit the options set on the default sitemap.
810
+ * `include_index` and `include_root` are `false` by default in a group.
811
+ * The sitemap index file is shared by all groups.
812
+ * Groups can handle any number of links.
813
+ * Group sitemaps are finalized (written out) as they get full and at the end of each group.
814
+ * It's a good idea to name your groups
815
+
816
+ ### A Groups Example
817
+
818
+ When you create a new group you pass options which will apply only to that group. You pass a block to `group`. Inside your block you call `add` to add links to the group.
819
+
820
+ Let's see an example that demonstrates a few interesting things about groups:
821
+
822
+ ```ruby
823
+ SitemapGenerator::Sitemap.default_host = "http://www.example.com"
824
+ SitemapGenerator::Sitemap.create do
825
+ add '/rss'
826
+
827
+ group(:sitemaps_path => 'en/', :filename => :english) do
828
+ add '/home'
829
+ end
830
+
831
+ group(:sitemaps_path => 'fr/', :filename => :french) do
832
+ add '/maison'
833
+ end
834
+ end
835
+ ```
836
+
837
+ And the output from running the above:
838
+
839
+ ```
840
+ In /Users/karl/projects/sitemap_generator-test/public/
841
+ + en/english.xml.gz 1 links / 328 Bytes
842
+ + fr/french.xml.gz 1 links / 329 Bytes
843
+ + sitemap1.xml.gz 2 links / 346 Bytes
844
+ + sitemap.xml.gz 3 sitemaps / 252 Bytes
845
+ Sitemap stats: 4 links / 3 sitemaps / 0m00s
846
+ ```
847
+
848
+ So we have two sitemaps with one link each and one sitemap with two links. The sitemaps from the groups are easy to spot by their filenames. They are `english.xml.gz` and `french.xml.gz`. They contain only one link each because **`include_index` and `include_root` are set to `false` by default** in a group.
849
+
850
+ On the other hand, the default sitemap which we added `/rss` to has two links. The root url was added to it when we added `/rss`. If we hadn't added that link `sitemap1.xml.gz` would not have been created. So **when we are using groups, the default sitemap will only be created if we add links to it**.
851
+
852
+ **The sitemap index file is shared by all groups**. You can change its filename by setting `SitemapGenerator::Sitemap.filename` or by passing the `:filename` option to `create`.
853
+
854
+ The options you use when creating your groups will determine which and how many sitemaps are created. Groups will inherit the default sitemap when possible, and will continue the normal series. However a group will often specify an option which requires the links in that group to be in their own files. In this case, if the default sitemap were being used it would be finalized before starting the next sitemap in the series.
855
+
856
+ If you have changed your sitemaps physical location in a group, then the default sitemap will not be used and it will be unaffected by the group. **Group sitemaps are finalized as they get full and at the end of each group.**
857
+
858
+
859
+ ## Sitemap Extensions
860
+
861
+ ### News Sitemaps
862
+
863
+ A news item can be added to a sitemap URL by passing a `:news` hash to `add`. The hash must contain tags defined by the [News Sitemap][news_tags] specification.
864
+
865
+ #### Example
866
+
867
+ ```ruby
868
+ SitemapGenerator::Sitemap.default_host = "http://www.example.com"
869
+ SitemapGenerator::Sitemap.create do
870
+ add('/index.html', :news => {
871
+ :publication_name => "Example",
872
+ :publication_language => "en",
873
+ :title => "My Article",
874
+ :keywords => "my article, articles about myself",
875
+ :stock_tickers => "SAO:PETR3",
876
+ :publication_date => "2011-08-22",
877
+ :access => "Subscription",
878
+ :genres => "PressRelease"
879
+ })
880
+ end
881
+ ```
882
+
883
+ #### Supported options
884
+
885
+ * `:news` - Hash
886
+ * `:publication_name`
887
+ * `:publication_language`
888
+ * `:publication_date`
889
+ * `:genres`
890
+ * `:access`
891
+ * `:title`
892
+ * `:keywords`
893
+ * `:stock_tickers`
894
+
895
+ ### Image Sitemaps
896
+
897
+ Images can be added to a sitemap URL by passing an `:images` array to `add`. Each item in the array must be a Hash containing tags defined by the [Image Sitemap][image_tags] specification.
898
+
899
+ #### Example
900
+
901
+ ```ruby
902
+ SitemapGenerator::Sitemap.default_host = "http://www.example.com"
903
+ SitemapGenerator::Sitemap.create do
904
+ add('/index.html', :images => [{
905
+ :loc => 'http://www.example.com/image.png',
906
+ :title => 'Image' }])
907
+ end
908
+ ```
909
+
910
+ #### Supported options
911
+
912
+ * `:images` - Array of hashes
913
+ * `:loc` Required, location of the image
914
+ * `:caption`
915
+ * `:geo_location`
916
+ * `:title`
917
+ * `:license`
918
+
919
+ ### Video Sitemaps
920
+
921
+ A video can be added to a sitemap URL by passing a `:video` Hash to `add()`. The Hash can contain tags defined by the [Video Sitemap specification][video_tags].
922
+
923
+ To add more than one video to a url, pass an array of video hashes using the `:videos` option.
924
+
925
+ #### Example
926
+
927
+ ```ruby
928
+ SitemapGenerator::Sitemap.default_host = "http://www.example.com"
929
+ SitemapGenerator::Sitemap.create do
930
+ add('/index.html', :video => {
931
+ :thumbnail_loc => 'http://www.example.com/video1_thumbnail.png',
932
+ :title => 'Title',
933
+ :description => 'Description',
934
+ :content_loc => 'http://www.example.com/cool_video.mpg',
935
+ :tags => %w[one two three],
936
+ :category => 'Category'
937
+ })
938
+ end
939
+ ```
940
+
941
+ #### Supported options
942
+
943
+ * `:video` or `:videos` - Hash or array of hashes, respectively
944
+ * `:thumbnail_loc` - Required. String, URL of the thumbnail image.
945
+ * `:title` - Required. String, title of the video.
946
+ * `:description` - Required. String, description of the video.
947
+ * `:content_loc` - Depends. String, URL. One of content_loc or player_loc must be present.
948
+ * `:player_loc` - Depends. String, URL. One of content_loc or player_loc must be present.
949
+ * `:allow_embed` - Boolean, attribute of player_loc.
950
+ * `:autoplay` - Boolean, default true. Attribute of player_loc.
951
+ * `:duration` - Recommended. Integer or string. Duration in seconds.
952
+ * `:expiration_date` - Recommended when applicable. The date after which the video will no longer be available.
953
+ * `:rating` - Optional
954
+ * `:view_count` - Optional. Integer or string.
955
+ * `:publication_date` - Optional
956
+ * `:tags` - Optional. Array of string tags.
957
+ * `:tag` - Optional. String, single tag.
958
+ * `:category` - Optional
959
+ * `:family_friendly`- Optional. Boolean
960
+ * `:gallery_loc` - Optional. String, URL.
961
+ * `:gallery_title` - Optional. Title attribute of the gallery location element
962
+ * `:uploader` - Optional.
963
+ * `:uploader_info` - Optional. Info attribute of uploader element
964
+ * `:price` - Optional. Only one price supported at this time
965
+ * `:price_currency` - Required. In [ISO_4217][iso_4217] format.
966
+ * `:price_type` - Optional. `rent` or `own`
967
+ * `:price_resolution` - Optional. `HD` or `SD`
968
+ * `:live` - Optional. Boolean.
969
+ * `:requires_subscription` - Optional. Boolean.
970
+
971
+ ### Geo Sitemaps
972
+
973
+ Pages with geo data can be added by passing a `:geo` Hash to `add`. The Hash only supports one tag of `:format`. Google provides an [example of a geo sitemap link here][geo_tags]. Note that the sitemap does not actually contain your KML or GeoRSS. It merely links to a page that has this content.
974
+
975
+ #### Example:
976
+
977
+ ```ruby
978
+ SitemapGenerator::Sitemap.default_host = "http://www.example.com"
979
+ SitemapGenerator::Sitemap.create do
980
+ add('/stores/1234.xml', :geo => { :format => 'kml' })
981
+ end
982
+ ```
983
+
984
+ #### Supported options
985
+
986
+ * `:geo` - Hash
987
+ * `:format` - Required, string, either `'kml'` or `'georss'`
988
+
989
+ ### PageMap Sitemaps
990
+
991
+ Pagemaps can be added by passing a `:pagemap` hash to `add`. The hash must contain a `:dataobjects` key with an array of dataobject hashes. Each dataobject hash contains a `:type` and `:id`, and an optional array of `:attributes`. Each attribute hash can contain two keys: `:name` and `:value`, with string values. For more information consult the [official documentation on PageMaps][using_pagemaps].
992
+
993
+ #### Supported options
994
+
995
+ * `:pagemap` - Hash
996
+ * `:dataobjects` - Required, array of hashes
997
+ * `:type` - Required, string, type of the object
998
+ * `:id` - String, ID of the object
999
+ * `:attributes` - Array of hashes
1000
+ * `:name` - Required, string, name of the attribute.
1001
+ * `:value` - String, value of the attribute.
1002
+
1003
+ #### Example:
1004
+
1005
+ ```ruby
1006
+ SitemapGenerator::Sitemap.default_host = "http://www.example.com"
1007
+ SitemapGenerator::Sitemap.create do
1008
+ add('/blog/post', :pagemap => {
1009
+ :dataobjects => [{
1010
+ :type => 'document',
1011
+ :id => 'hibachi',
1012
+ :attributes => [
1013
+ { :name => 'name', :value => 'Dragon' },
1014
+ { :name => 'review', :value => '3.5' },
1015
+ ]
1016
+ }]
1017
+ })
1018
+ end
1019
+ ```
1020
+
1021
+ ### Alternate Links
1022
+
1023
+ A useful feature for internationalization is to specify alternate links for a url.
1024
+
1025
+ Alternate links can be added by passing an `:alternate` Hash to `add`. You can pass more than one alternate link by passing an array of hashes using the `:alternates` option.
1026
+
1027
+ Check out the Google specification [here][alternate_links].
1028
+
1029
+ #### Example
1030
+
1031
+ ```ruby
1032
+ SitemapGenerator::Sitemap.default_host = "http://www.example.com"
1033
+ SitemapGenerator::Sitemap.create do
1034
+ add('/index.html', :alternate => {
1035
+ :href => 'http://www.example.de/index.html',
1036
+ :lang => 'de',
1037
+ :nofollow => true
1038
+ })
1039
+ end
1040
+ ```
1041
+
1042
+ #### Supported options
1043
+
1044
+ * `:alternate`/`:alternates` - Hash or array of hashes, respectively
1045
+ * `:href` - Required, string.
1046
+ * `:lang` - Required, string.
1047
+ * `:nofollow` - Optional, boolean. Used to mark link as "nofollow".
1048
+ * `:media` - Optional, string. Specify [media targets for responsive design pages][media].
1049
+
1050
+ ## Raison d'être
1051
+
1052
+ Most of the Sitemap plugins out there seem to try to recreate the Sitemap links by iterating the Rails routes. In some cases this is possible, but for a great deal of cases it isn't.
1053
+
1054
+ a) There are probably quite a few routes in your routes file that don't need inclusion in the Sitemap. (AJAX routes I'm looking at you.)
1055
+
1056
+ and
1057
+
1058
+ b) How would you infer the correct series of links for the following route?
1059
+
1060
+ ```ruby
1061
+ map.zipcode 'location/:state/:city/:zipcode', :controller => 'zipcode', :action => 'index'
1062
+ ```
1063
+
1064
+ Don't tell me it's trivial, because it isn't. It just looks trivial.
1065
+
1066
+ So my idea is to have another file similar to 'routes.rb' called 'sitemap.rb', where you can define what goes into the Sitemap.
1067
+
1068
+ Here's my solution:
1069
+
1070
+ ```ruby
1071
+ Zipcode.find(:all, :include => :city).each do |z|
1072
+ add zipcode_path(:state => z.city.state, :city => z.city, :zipcode => z)
1073
+ end
1074
+ ```
1075
+
1076
+ Easy hey?
1077
+
1078
+ ## Compatibility
1079
+
1080
+ Tested and working on:
1081
+
1082
+ * **Rails** 3.0.0, 3.0.7
1083
+ * **Rails** 1.x - 2.3.8
1084
+ * **Ruby** 1.8.6, 1.8.7, 1.8.7 Enterprise Edition, 1.9.1, 1.9.2
1085
+
1086
+
1087
+ ## Known Bugs
1088
+
1089
+ * There's no check on the size of a URL which [isn't supposed to exceed 2,048 bytes][sitemaps_xml].
1090
+ * Currently only supports one Sitemap Index file, which can contain 50,000 Sitemap files which can each contain 50,000 urls, so it _only_ supports up to 2,500,000,000 (2.5 billion) urls.
1091
+
1092
+
1093
+ ## Wishlist & Coming Soon
1094
+
1095
+
1096
+ ## Thanks (in no particular order)
1097
+
1098
+ I've kind of stopped maintaining the list of contributors. To all those who have contributed code or a donation, many thanks!
1099
+
1100
+ Some past contributors:
1101
+
1102
+ * [Eric Hochberger][ehoch]
1103
+ * [Rodrigo Flores](https://github.com/rodrigoflores) for News sitemaps
1104
+ * [Alex Soto](http://github.com/apsoto) for Video sitemaps
1105
+ * [Alexadre Bini](http://github.com/alexandrebini) for Image sitemaps
1106
+ * [Dan Pickett](http://github.com/dpickett)
1107
+ * [Rob Biedenharn](http://github.com/rab)
1108
+ * [Richie Vos](http://github.com/jerryvos)
1109
+ * [Adrian Mugnolo](http://github.com/xymbol)
1110
+ * [Jason Weathered](http://github.com/jasoncodes)
1111
+ * [Andy Stewart](http://github.com/airblade)
1112
+ * [Brian Armstrong](https://github.com/barmstrong) for Geo sitemaps
1113
+
1114
+ Copyright (c) 2009 Karl Varga released under the MIT license
1115
+
1116
+ [canonical_repo]:http://github.com/kjvarga/sitemap_generator
1117
+ [enterprise_class]:https://twitter.com/dhh/status/1631034662 "I use enterprise in the same sense the Phusion guys do - i.e. Enterprise Ruby. Please don't look down on my use of the word 'enterprise' to represent being a cut above. It doesn't mean you ever have to work for a company the size of IBM. Or constantly fight inertia, writing crappy software, adhering to change management practices and spending hours in meetings... Not that there's anything wrong with that - Wait, what?"
1118
+ [sitemaps_org]:http://www.sitemaps.org/protocol.php "http://www.sitemaps.org/protocol.php"
1119
+ [sitemaps_xml]:http://www.sitemaps.org/protocol.php#xmlTagDefinitions "XML Tag Definitions"
1120
+ [sitemap_generator_usage]:http://wiki.github.com/adamsalter/sitemap_generator/sitemapgenerator-usage "http://wiki.github.com/adamsalter/sitemap_generator/sitemapgenerator-usage"
1121
+ [sitemap_images]:http://www.google.com/support/webmasters/bin/answer.py?answer=178636
1122
+ [sitemap_video]:http://www.google.com/support/webmasters/bin/topic.py?topic=10079
1123
+ [sitemap_news]:http://www.google.com/support/webmasters/bin/topic.py?hl=en&topic=10078
1124
+ [sitemap_geo]:http://www.google.com/support/webmasters/bin/topic.py?hl=en&topic=14688
1125
+ [sitemap_mobile]:http://support.google.com/webmasters/bin/answer.py?hl=en&answer=34648
1126
+ [sitemap_pagemap]:https://developers.google.com/custom-search/docs/structured_data#addtositemap
1127
+ [sitemap_protocol]:http://sitemaps.org/protocol.php
1128
+ [video_tags]:http://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=80472#4
1129
+ [image_tags]:http://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=178636
1130
+ [geo_tags]:http://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=94555
1131
+ [news_tags]:http://www.google.com/support/news_pub/bin/answer.py?answer=74288
1132
+ [remote_hosts]:https://github.com/kjvarga/sitemap_generator/wiki/Generate-Sitemaps-on-read-only-filesystems-like-Heroku
1133
+ [include_index_change]:https://github.com/kjvarga/sitemap_generator/issues/70
1134
+ [ehoch]:https://github.com/ehoch
1135
+ [alternate_links]:http://support.google.com/webmasters/bin/answer.py?hl=en&answer=2620865
1136
+ [using_pagemaps]:https://developers.google.com/custom-search/docs/structured_data#pagemaps
1137
+ [iso_4217]:http://en.wikipedia.org/wiki/ISO_4217
1138
+ [media]:https://developers.google.com/webmasters/smartphone-sites/details
1139
+ [expires]:https://support.google.com/customsearch/answer/2631051?hl=en