milk-it-sitemapper 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- 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: milk-it-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
|
@@ -39,8 +39,12 @@ files:
|
|
39
39
|
- init.rb
|
40
40
|
- tasks/sitemaper_tasks.rake
|
41
41
|
- lib/sitemapper.rb
|
42
|
+
- lib/sitemapper/accessors.rb
|
42
43
|
- lib/sitemapper/helpers.rb
|
43
44
|
- lib/sitemapper/map.rb
|
45
|
+
- lib/sitemapper/sitemap_xml.rb
|
46
|
+
- lib/sitemapper/map_index.rb
|
47
|
+
- lib/sitemapper/object_mapper.rb
|
44
48
|
- lib/sitemapper/adapters/rails_adapter.rb
|
45
49
|
has_rdoc: true
|
46
50
|
homepage: http://redmine.milk-it.net/projects
|