sitemapper 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/init.rb +0 -6
- data/lib/sitemapper.rb +35 -3
- data/lib/sitemapper/accessors.rb +25 -0
- data/lib/sitemapper/adapters/rails_adapter.rb +7 -5
- data/lib/sitemapper/map.rb +21 -79
- data/lib/sitemapper/map_index.rb +53 -0
- data/lib/sitemapper/object_mapper.rb +6 -0
- data/lib/sitemapper/sitemap_xml.rb +71 -0
- metadata +5 -1
data/init.rb
CHANGED
data/lib/sitemapper.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
$:.unshift(File.dirname(__FILE__))
|
2
2
|
require 'sitemapper/helpers'
|
3
|
+
require 'sitemapper/sitemap_xml'
|
3
4
|
require 'sitemapper/map'
|
5
|
+
require 'sitemapper/map_index'
|
4
6
|
require 'sitemapper/accessors'
|
5
7
|
require 'sitemapper/object_mapper'
|
6
8
|
|
7
9
|
module Sitemapper
|
8
|
-
MAJOR, MINOR,
|
10
|
+
MAJOR, MINOR, PATCH = 0, 3, 0 #:nodoc:
|
9
11
|
|
10
12
|
# Get the running version of Sitemapper
|
11
13
|
def self.version
|
12
|
-
[MAJOR, MINOR,
|
14
|
+
[MAJOR, MINOR, PATCH].join('.')
|
13
15
|
end
|
14
16
|
|
15
17
|
def self.map=(map)
|
@@ -17,7 +19,31 @@ module Sitemapper
|
|
17
19
|
end
|
18
20
|
|
19
21
|
def self.map
|
20
|
-
@map
|
22
|
+
@map
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.map_index=(index)
|
26
|
+
@map_index = index
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.map_index
|
30
|
+
@map_index
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns the site root (previously defined with site_root=)
|
34
|
+
def self.site_root
|
35
|
+
@@site_root ||= 'http://www.example.com/'
|
36
|
+
end
|
37
|
+
|
38
|
+
# Set the site root for the generated URLs
|
39
|
+
#
|
40
|
+
# * <tt>root</tt> is the root, (ex.: http://www.example.com)
|
41
|
+
def self.site_root=(root)
|
42
|
+
@@site_root = root
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.urlfy(url_or_path)
|
46
|
+
url_or_path =~ /^https?:/ ? url_or_path : URI.join(self.site_root, url_or_path)
|
21
47
|
end
|
22
48
|
|
23
49
|
# Define the default meta lookup for objects on <tt>page</tt> helper
|
@@ -46,3 +72,9 @@ module Sitemapper
|
|
46
72
|
}
|
47
73
|
end
|
48
74
|
end
|
75
|
+
|
76
|
+
if Object.const_defined?('Rails')
|
77
|
+
require 'sitemapper/adapters/rails_adapter'
|
78
|
+
Sitemapper::Adapters::RailsAdapter.install!
|
79
|
+
end
|
80
|
+
Object.send(:include, Sitemapper::ObjectMapper)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Sitemapper
|
2
|
+
module Accessors
|
3
|
+
def map_url(url, opts={})
|
4
|
+
Sitemapper::map.map_url(url, opts)
|
5
|
+
end
|
6
|
+
|
7
|
+
def map_path(path, opts={})
|
8
|
+
Sitemapper::map.map_path(path, opts)
|
9
|
+
end
|
10
|
+
|
11
|
+
def unmap_url(url)
|
12
|
+
Sitemapper::map.unmap_url(url)
|
13
|
+
end
|
14
|
+
|
15
|
+
def unmap_path(path)
|
16
|
+
Sitemapper::map.unmap_path(path)
|
17
|
+
end
|
18
|
+
|
19
|
+
def map_urls
|
20
|
+
Sitemapper::map.map_urls do
|
21
|
+
yield
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -2,14 +2,15 @@ module Sitemapper
|
|
2
2
|
module Adapters
|
3
3
|
module RailsAdapter
|
4
4
|
module RoutesMapperExtension
|
5
|
-
include Sitemapper::Accessors
|
6
|
-
|
7
5
|
def self.included(base)
|
8
6
|
base.class_eval do
|
9
7
|
alias_method_chain :named_route, :sitemap
|
10
8
|
alias_method_chain :connect, :sitemap
|
11
9
|
alias_method_chain :root, :sitemap
|
12
10
|
end
|
11
|
+
path = File.join(Rails.root, 'public', 'sitemap_static.xml.gz')
|
12
|
+
File.unlink(path) if File.exists?(path)
|
13
|
+
@@map = Sitemapper::map_index.build_map(path)
|
13
14
|
end
|
14
15
|
|
15
16
|
def named_route_with_sitemap(name, path, options = {})
|
@@ -34,7 +35,7 @@ module Sitemapper
|
|
34
35
|
method = options[:conditions][:method] rescue :get
|
35
36
|
# TODO: extract options to map
|
36
37
|
unless path =~ /[:*]/ || method != :get
|
37
|
-
map_path(path)
|
38
|
+
@@map.map_path(path)
|
38
39
|
end
|
39
40
|
end
|
40
41
|
end
|
@@ -42,9 +43,10 @@ module Sitemapper
|
|
42
43
|
# Install routing hooks, view helpers and initialize the
|
43
44
|
# sitemap.xml file
|
44
45
|
def self.install!
|
45
|
-
Sitemapper::
|
46
|
+
Sitemapper::site_root = ActionController::Base.relative_url_root rescue
|
46
47
|
ActionController::AbstractRequest.relative_url_root
|
47
|
-
Sitemapper::
|
48
|
+
Sitemapper::map_index = Sitemapper::MapIndex.new(File.join(Rails.root, 'public', 'sitemap_index.xml.gz'))
|
49
|
+
Sitemapper::map = Sitemapper::map_index.build_map(File.join(Rails.root, 'public', 'sitemap_dynamic.xml.gz'))
|
48
50
|
ActionController::Routing::RouteSet::Mapper.send :include, RoutesMapperExtension
|
49
51
|
ActionView::Base.send :include, Sitemapper::Helpers
|
50
52
|
ActionController::Base.send :include, Sitemapper::Accessors
|
data/lib/sitemapper/map.rb
CHANGED
@@ -1,34 +1,11 @@
|
|
1
1
|
require 'rexml/document'
|
2
2
|
require 'thread'
|
3
3
|
require 'uri'
|
4
|
+
require 'zlib'
|
4
5
|
|
5
6
|
module Sitemapper
|
6
|
-
class Map
|
7
|
-
|
8
|
-
INDENT = -1 #:nodoc:
|
9
|
-
|
10
|
-
# Returns the site root (previously defined with site_root=)
|
11
|
-
def self.site_root
|
12
|
-
@@site_root ||= 'http://www.example.com/'
|
13
|
-
end
|
14
|
-
|
15
|
-
# Set the site root for the generated URLs
|
16
|
-
#
|
17
|
-
# * <tt>root</tt> is the root, (ex.: http://www.example.com)
|
18
|
-
def self.site_root=(root)
|
19
|
-
@@site_root = root
|
20
|
-
end
|
21
|
-
|
22
|
-
# Initialize a map
|
23
|
-
#
|
24
|
-
# * <tt>file</tt> is the path to the (new or existent) sitemap.xml
|
25
|
-
def initialize(file)
|
26
|
-
@builder = REXML::Document.new(File.exists?(file)? File.read(file) : nil)
|
27
|
-
@locker = Mutex.new
|
28
|
-
@file = file
|
29
|
-
@write = true
|
30
|
-
initialize_map
|
31
|
-
end
|
7
|
+
class Map < SitemapXML
|
8
|
+
@@root_tag = 'urlset'
|
32
9
|
|
33
10
|
# Map the given localization
|
34
11
|
#
|
@@ -42,19 +19,19 @@ module Sitemapper
|
|
42
19
|
#
|
43
20
|
# See http://www.sitemaps.org/protocol.php
|
44
21
|
def map_url(loc, opts={})
|
45
|
-
|
46
|
-
|
22
|
+
self.locker.synchronize do
|
23
|
+
loc = Sitemapper.urlfy(loc)
|
24
|
+
lastmod, changefreq, priority = extract_options(opts)
|
25
|
+
url = get_url(loc) || self.builder.root.add_element('url')
|
26
|
+
(url.elements['loc'] || url.add_element('loc')).text = loc
|
27
|
+
(url.elements['lastmod'] || url.add_element('lastmod')).text = lastmod.strftime('%Y-%m-%d') if lastmod
|
28
|
+
(url.elements['changefreq'] || url.add_element('change_freq')).text = changefreq.to_s if changefreq
|
29
|
+
(url.elements['priority'] || url.add_element('priority')).text = '%.2f' % priority if priority
|
30
|
+
|
47
31
|
write_file
|
48
32
|
end
|
49
33
|
end
|
50
|
-
|
51
|
-
# Map the given path
|
52
|
-
#
|
53
|
-
# <tt>path</tt> is the path to be mapped
|
54
|
-
# <tt>opts</tt> is a hash containing options for this url (see <tt>map_url</tt>)
|
55
|
-
def map_path(path, opts={})
|
56
|
-
map_url(URI.join(Map.site_root, path), opts)
|
57
|
-
end
|
34
|
+
alias map_path map_url
|
58
35
|
|
59
36
|
# Map multiple URLs and write once (at the end)
|
60
37
|
#
|
@@ -70,42 +47,24 @@ module Sitemapper
|
|
70
47
|
yield(self)
|
71
48
|
@write = true
|
72
49
|
|
73
|
-
|
50
|
+
self.locker.synchronize { write_file }
|
74
51
|
end
|
75
52
|
|
76
53
|
# Unmap the given localization (<tt>loc</tt>)
|
77
54
|
#
|
78
55
|
# * <tt>loc</tt> is the URL to be unmaped
|
79
56
|
def unmap_url(loc)
|
80
|
-
|
81
|
-
|
82
|
-
|
57
|
+
self.locker.synchronize do
|
58
|
+
if url = get_url(Sitemapper.urlfy(loc))
|
59
|
+
url.remove
|
60
|
+
write_file
|
61
|
+
end
|
83
62
|
end
|
84
63
|
end
|
85
|
-
|
86
|
-
# Unmap the given path
|
87
|
-
#
|
88
|
-
# * <tt>loc</tt> is the Path t be unmaped
|
89
|
-
def unmap_path(loc)
|
90
|
-
unmap_url(URI.join(Map.site_root, loc))
|
91
|
-
end
|
64
|
+
alias map_path map_url
|
92
65
|
|
93
66
|
private
|
94
67
|
|
95
|
-
def set_url_node(loc, opts)
|
96
|
-
lastmod, changefreq, priority = extract_options(opts)
|
97
|
-
url = get_url(loc) || @builder.root.add_element('url')
|
98
|
-
(url.elements['loc'] || url.add_element('loc')).text = loc
|
99
|
-
(url.elements['lastmod'] || url.add_element('lastmod')).text = lastmod.strftime('%Y-%m-%d') if lastmod
|
100
|
-
(url.elements['changefreq'] || url.add_element('change_freq')).text = changefreq.to_s if changefreq
|
101
|
-
(url.elements['priority'] || url.add_element('priority')).text = '%.2f' % priority if priority
|
102
|
-
end
|
103
|
-
|
104
|
-
def unset_url_node(loc)
|
105
|
-
url = get_url(loc)
|
106
|
-
url.remove if url
|
107
|
-
end
|
108
|
-
|
109
68
|
# Extract the options to map an URL
|
110
69
|
#
|
111
70
|
# see <tt>map_url</tt> to understand.
|
@@ -119,24 +78,7 @@ module Sitemapper
|
|
119
78
|
|
120
79
|
# Return the Element for the given <tt>url</tt>
|
121
80
|
def get_url(url)
|
122
|
-
|
123
|
-
end
|
124
|
-
|
125
|
-
# Write the file to disk (run only synchronized with @locker)
|
126
|
-
def write_file
|
127
|
-
File.open(@file, 'w') {|file| @builder.write(file, INDENT)} if @write
|
128
|
-
end
|
129
|
-
|
130
|
-
# Initialize the map (called on the boot, normally)
|
131
|
-
def initialize_map
|
132
|
-
if @builder.root.nil?
|
133
|
-
@builder << REXML::XMLDecl.new('1.0', 'UTF-8')
|
134
|
-
@builder.add_element('urlset', 'xmlns' => SCHEMA)
|
135
|
-
else
|
136
|
-
raise InvalidMap unless @builder.root.attributes.key? 'xmlns'
|
137
|
-
end
|
81
|
+
self.builder.elements["//url[loc='#{url}']"]
|
138
82
|
end
|
139
83
|
end
|
140
|
-
|
141
|
-
class InvalidMap < StandardError; end
|
142
84
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# <?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
# <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
3
|
+
# <sitemap>
|
4
|
+
# <loc>http://www.example.com/sitemap1.xml.gz</loc>
|
5
|
+
# <lastmod>2004-10-01T18:23:17+00:00</lastmod>
|
6
|
+
# </sitemap>
|
7
|
+
# <sitemap>
|
8
|
+
# <loc>http://www.example.com/sitemap2.xml.gz</loc>
|
9
|
+
# <lastmod>2005-01-01</lastmod>
|
10
|
+
# </sitemap>
|
11
|
+
# </sitemapindex>
|
12
|
+
require 'rexml/document'
|
13
|
+
require 'thread'
|
14
|
+
require 'uri'
|
15
|
+
require 'zlib'
|
16
|
+
|
17
|
+
module Sitemapper
|
18
|
+
class MapIndex < SitemapXML
|
19
|
+
@@root_tag = 'sitemapindex'
|
20
|
+
|
21
|
+
def build_map(file, url_or_path=nil, lastmod=nil)
|
22
|
+
add_map(url_or_path || File.basename(file), lastmod)
|
23
|
+
map = Map.new(file)
|
24
|
+
end
|
25
|
+
|
26
|
+
def add_map(url_or_path, lastmod=nil)
|
27
|
+
self.locker.synchronize do
|
28
|
+
url_or_path = Sitemapper.urlfy(url_or_path)
|
29
|
+
map = get_sitemap(url_or_path) || self.builder.root.add_element('sitemap')
|
30
|
+
(map.elements['loc'] || map.add_element('sitemap')).text = url_or_path
|
31
|
+
(map.elements['lastmod'] || map.add_element('lastmod')).text = lastmod.strftime('%Y-%m-%d') if lastmod
|
32
|
+
|
33
|
+
write_file
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def remove_map(url_or_path)
|
38
|
+
self.locker.synchronize do
|
39
|
+
if map = get_sitemap(Sitemapper.urlfy(url_or_path))
|
40
|
+
map.remove
|
41
|
+
write_file
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# Return the sitemap Element for the given <tt>url</tt>
|
49
|
+
def get_sitemap(url)
|
50
|
+
self.builder.elements["//sitemap[loc='#{url}']"]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'zlib'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
module Sitemapper
|
5
|
+
class SitemapXML
|
6
|
+
SCHEMA = 'http://www.sitemaps.org/schemas/sitemap/0.9' #:nodoc:
|
7
|
+
INDENT = -1 #:nodoc:
|
8
|
+
@@root_tag = nil
|
9
|
+
|
10
|
+
# Initialize a map
|
11
|
+
#
|
12
|
+
# * <tt>file</tt> is the path to the (new or existent) sitemap.xml
|
13
|
+
def initialize(file)
|
14
|
+
@file = file
|
15
|
+
@write = true
|
16
|
+
@gzip = @file =~ /gz$/i
|
17
|
+
initialize_map
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
|
22
|
+
def locker
|
23
|
+
@locker ||= Mutex.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def builder
|
27
|
+
@builder
|
28
|
+
end
|
29
|
+
|
30
|
+
# Write the file to disk (run only synchronized with @locker)
|
31
|
+
def write_file
|
32
|
+
File.open(@file, 'w') do |file|
|
33
|
+
content = ''
|
34
|
+
@builder.write(content, INDENT)
|
35
|
+
|
36
|
+
if @gzip
|
37
|
+
gz = Zlib::GzipWriter.new(file)
|
38
|
+
gz.write content
|
39
|
+
gz.close
|
40
|
+
else
|
41
|
+
file.write(content)
|
42
|
+
end
|
43
|
+
end if @write
|
44
|
+
end
|
45
|
+
|
46
|
+
# Initialize the map (called on the boot, normally)
|
47
|
+
def initialize_map
|
48
|
+
@builder = REXML::Document.new(if File.exists?(@file)
|
49
|
+
content = nil
|
50
|
+
if @gzip
|
51
|
+
Zlib::GzipReader.open(@file) {|gz| content = gz.read}
|
52
|
+
else
|
53
|
+
content = File.read(@file)
|
54
|
+
end
|
55
|
+
content
|
56
|
+
else
|
57
|
+
nil
|
58
|
+
end)
|
59
|
+
|
60
|
+
if @builder.root.nil?
|
61
|
+
@builder << REXML::XMLDecl.new('1.0', 'UTF-8')
|
62
|
+
@builder.add_element(@@root_tag, 'xmlns' => SCHEMA)
|
63
|
+
write_file
|
64
|
+
else
|
65
|
+
raise InvalidMap unless @builder.root.attributes.key? 'xmlns'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
class InvalidMap < StandardError; end
|
71
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sitemapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Carlos Junior
|
@@ -40,8 +40,12 @@ files:
|
|
40
40
|
- init.rb
|
41
41
|
- tasks/sitemaper_tasks.rake
|
42
42
|
- lib/sitemapper.rb
|
43
|
+
- lib/sitemapper/accessors.rb
|
43
44
|
- lib/sitemapper/helpers.rb
|
44
45
|
- lib/sitemapper/map.rb
|
46
|
+
- lib/sitemapper/sitemap_xml.rb
|
47
|
+
- lib/sitemapper/map_index.rb
|
48
|
+
- lib/sitemapper/object_mapper.rb
|
45
49
|
- lib/sitemapper/adapters/rails_adapter.rb
|
46
50
|
has_rdoc: true
|
47
51
|
homepage: http://redmine.milk-it.net/projects
|