milk-it-sitemapper 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.rdoc +23 -0
- data/Rakefile +22 -0
- data/init.rb +6 -0
- data/install.rb +2 -0
- data/lib/sitemapper.rb +20 -0
- data/lib/sitemapper/adapters/rails_adapter.rb +54 -0
- data/lib/sitemapper/helpers.rb +91 -0
- data/lib/sitemapper/map.rb +122 -0
- data/tasks/sitemaper_tasks.rake +4 -0
- data/test/sitemapper_test.rb +8 -0
- metadata +82 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 Carlos Júnior, Milk-it Software House
|
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.rdoc
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
= Sitemapper - Easy SEO engine
|
2
|
+
|
3
|
+
Sitemapper will help you in various SEO techniques such as sitemap.xml
|
4
|
+
auto generation.
|
5
|
+
|
6
|
+
== Installation
|
7
|
+
|
8
|
+
You can install the development version with
|
9
|
+
|
10
|
+
% sudo gem sources -a http://gems.github.com # (you only need to do this once)
|
11
|
+
% sudo gem install milk-it-sitemapper
|
12
|
+
|
13
|
+
Or the release version with
|
14
|
+
|
15
|
+
% sudo gem install sitemapper
|
16
|
+
|
17
|
+
|
18
|
+
== Example
|
19
|
+
|
20
|
+
TODO: examples
|
21
|
+
|
22
|
+
Copyright (c) 2008 Carlos Júnior, released under the MIT license
|
23
|
+
Copyright (c) 2008 Milk-it Software House, released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
desc 'Default: run unit tests.'
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
desc 'Test the sitemaper plugin.'
|
9
|
+
Rake::TestTask.new(:test) do |t|
|
10
|
+
t.libs << 'lib'
|
11
|
+
t.pattern = 'test/**/*_test.rb'
|
12
|
+
t.verbose = true
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Generate documentation for the sitemaper plugin.'
|
16
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
17
|
+
rdoc.rdoc_dir = 'rdoc'
|
18
|
+
rdoc.title = 'Sitemaper'
|
19
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
20
|
+
rdoc.rdoc_files.include('README')
|
21
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
22
|
+
end
|
data/init.rb
ADDED
data/install.rb
ADDED
data/lib/sitemapper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'sitemapper/helpers'
|
2
|
+
require 'sitemapper/map'
|
3
|
+
require 'sitemapper/accessors'
|
4
|
+
|
5
|
+
module Sitemapper
|
6
|
+
MAJOR, MINOR, TINY = 0, 2, 0 #:nodoc:
|
7
|
+
|
8
|
+
# Get the running version of Sitemapper
|
9
|
+
def version
|
10
|
+
[MAJOR, MINOR, TINY].join('.')
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.map=(map)
|
14
|
+
@map = map
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.map
|
18
|
+
@map or raise 'Uninitialized Sitemapper.map'
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Sitemapper
|
2
|
+
module Adapters
|
3
|
+
module RailsAdapter
|
4
|
+
module RoutesMapperExtension
|
5
|
+
include Sitemapper::Accessors
|
6
|
+
|
7
|
+
def self.included(base)
|
8
|
+
base.class_eval do
|
9
|
+
alias_method_chain :named_route, :sitemap
|
10
|
+
alias_method_chain :connect, :sitemap
|
11
|
+
alias_method_chain :root, :sitemap
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def named_route_with_sitemap(name, path, options = {})
|
16
|
+
map_if_possible(path, options)
|
17
|
+
named_route_without_sitemap(name, path, options)
|
18
|
+
end
|
19
|
+
|
20
|
+
def connect_with_sitemap(path, options = {})
|
21
|
+
map_if_possible(path, options)
|
22
|
+
connect_without_sitemap(path, options)
|
23
|
+
end
|
24
|
+
|
25
|
+
def root_with_sitemap(options = {})
|
26
|
+
map_if_possible('/', options)
|
27
|
+
root_without_sitemap(options)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def map_if_possible(path, options)
|
33
|
+
# Don't map dynamic URLs
|
34
|
+
method = options[:conditions][:method] rescue :get
|
35
|
+
# TODO: extract options to map
|
36
|
+
unless path =~ /[:*]/ || method != :get
|
37
|
+
map_path(path)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Install routing hooks, view helpers and initialize the
|
43
|
+
# sitemap.xml file
|
44
|
+
def self.install!
|
45
|
+
Sitemapper::Map.site_root = ActionController::Base.relative_url_root rescue
|
46
|
+
ActionController::AbstractRequest.relative_url_root
|
47
|
+
Sitemapper::map = Sitemapper::Map.new(File.join(Rails.root, 'public', 'sitemap.xml'))
|
48
|
+
ActionController::Routing::RouteSet::Mapper.send :include, RoutesMapperExtension
|
49
|
+
ActionView::Base.send :include, Sitemapper::Helpers
|
50
|
+
ActionController::Base.send :include, Sitemapper::Accessors
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Sitemapper
|
2
|
+
module Helpers
|
3
|
+
# Set the page data for title and meta tags
|
4
|
+
#
|
5
|
+
# ==== Parameters
|
6
|
+
# * <tt>:title</tt> the title of the page
|
7
|
+
# * <tt>:desc</tt> the description of the current page
|
8
|
+
# * <tt>:keywords</tt> the keywords that represent the current page
|
9
|
+
#
|
10
|
+
# ==== The parameter can also be an object that respond to (used preferentially on this order):
|
11
|
+
# * <tt>title</tt> OR <tt>name</tt> (for title)
|
12
|
+
# * <tt>short_description</tt> OR <tt>description</tt> (for description)
|
13
|
+
# * <tt>tag_list</tt> OR <tt>keywords</tt> (for keywords)
|
14
|
+
#
|
15
|
+
# See <tt>page_meta</tt> for further information and examples.
|
16
|
+
#
|
17
|
+
def page(defs)
|
18
|
+
@_title = defs.delete(:title)
|
19
|
+
@_desc = defs.delete(:desc)
|
20
|
+
@_keys = defs.delete(:keywords)
|
21
|
+
end
|
22
|
+
|
23
|
+
def page_with_object(defs) # :nodoc:
|
24
|
+
return page_without_object(defs) if defs.is_a?(Hash)
|
25
|
+
@_title = if defs.respond_to?(:title)
|
26
|
+
defs.title
|
27
|
+
elsif defs.respond_to?(:name)
|
28
|
+
defs.name
|
29
|
+
end
|
30
|
+
@_desc = if defs.respond_to?(:short_description)
|
31
|
+
defs.short_description
|
32
|
+
elsif defs.respond_to?(:description)
|
33
|
+
defs.description
|
34
|
+
end
|
35
|
+
@_keys = if defs.respond_to?(:tag_list)
|
36
|
+
defs.tag_list
|
37
|
+
elsif defs.respond_to?(:keywords)
|
38
|
+
defs.keywords
|
39
|
+
end
|
40
|
+
end
|
41
|
+
alias_method_chain :page, :object
|
42
|
+
|
43
|
+
# Returns the title of the page with the website title
|
44
|
+
#
|
45
|
+
# ==== Parameters
|
46
|
+
#
|
47
|
+
# * the first parameter is the website title
|
48
|
+
# * the second parameter is a options hash:
|
49
|
+
# * <tt>:separator</tt> is the separator of the page and the website title
|
50
|
+
#
|
51
|
+
# See <tt>page_meta</tt> for further information and examples.
|
52
|
+
#
|
53
|
+
def title(title, opts={})
|
54
|
+
separator = opts[:separator] || ' :: '
|
55
|
+
content_tag(:title, @_title.nil?? title : "#{@_title}#{separator}#{title}")
|
56
|
+
end
|
57
|
+
|
58
|
+
# Returns the meta tags for the current page, for example:
|
59
|
+
#
|
60
|
+
# app/views/foo/bar.html.erb
|
61
|
+
#
|
62
|
+
# page(:title => 'Foo bar!',
|
63
|
+
# :description => 'Lorem ipsum dollar sit amet',
|
64
|
+
# :keywords => 'lorem, ipsum dollar, sit, amet')
|
65
|
+
#
|
66
|
+
# app/views/layouts/application.html.erb
|
67
|
+
#
|
68
|
+
# ...
|
69
|
+
# <head>
|
70
|
+
# <%= title('My Webste') %>
|
71
|
+
# <%= page_meta %>
|
72
|
+
# </head>
|
73
|
+
# ...
|
74
|
+
#
|
75
|
+
# The example above will output the following on the rendered page:
|
76
|
+
#
|
77
|
+
# ...
|
78
|
+
# <head>
|
79
|
+
# <title>Foo bar! :: My Website</title>
|
80
|
+
# <meta name="description" content="Lorem ipsum dollar sit amet" />
|
81
|
+
# <meta name="keywords" content="lore, ipsum dollar, sit, amet" />
|
82
|
+
# </head>
|
83
|
+
#
|
84
|
+
def page_meta
|
85
|
+
res = ''
|
86
|
+
res << tag(:meta, :name => 'description', :content => @_desc) if @_desc
|
87
|
+
res << tag(:meta, :name => 'keywords', :content => @_keys) if @_desc
|
88
|
+
return res
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
require 'thread'
|
3
|
+
require 'uri'
|
4
|
+
|
5
|
+
module Sitemapper
|
6
|
+
class Map
|
7
|
+
SCHEMA = 'http://www.sitemaps.org/schemas/sitemap/0.9' #:nodoc:
|
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
|
+
initialize_map
|
30
|
+
end
|
31
|
+
|
32
|
+
# Map the given localization
|
33
|
+
#
|
34
|
+
# <tt>loc</tt> is the URL to me mapped
|
35
|
+
# <tt>opts</tt> is a hash with the following parameters:
|
36
|
+
#
|
37
|
+
# * <tt>url</tt> or <tt>path</tt> is the complete URL or path (ex.: /articles/rails-doesnt-scale) [required]
|
38
|
+
# * <tt>lastmod</tt> a date object to the last modification [optional]
|
39
|
+
# * <tt>changefreq</tt> the frequency of change (:daily, :monthly, :yearly) [optional]
|
40
|
+
# * <tt>priority</tt> the priority of the URL (0..1) [optional]
|
41
|
+
#
|
42
|
+
# See http://www.sitemaps.org/protocol.php
|
43
|
+
def map_url(loc, opts={})
|
44
|
+
lastmod, changefreq, priority = extract_options(opts)
|
45
|
+
@locker.synchronize do
|
46
|
+
url = get_url(loc) || @builder.root.add_element('url')
|
47
|
+
(url.elements['loc'] || url.add_element('loc')).text = loc
|
48
|
+
(url.elements['lastmod'] || url.add_element('lastmod')).text = lastmod.strftime('%Y-%m-%d') if lastmod
|
49
|
+
(url.elements['changefreq'] || url.add_element('change_freq')).text = changefreq.to_s if changefreq
|
50
|
+
(url.elements['priority'] || url.add_element('priority')).text = '%.2f' % priority if priority
|
51
|
+
|
52
|
+
write_file
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Map the given path
|
57
|
+
#
|
58
|
+
# <tt>path</tt> is the path to be mapped
|
59
|
+
# <tt>opts</tt> is a hash containing options for this url (see <tt>map_url</tt>)
|
60
|
+
def map_path(path, opts={})
|
61
|
+
map_url(URI.join(Map.site_root, path), opts)
|
62
|
+
end
|
63
|
+
|
64
|
+
def map_urls #:nodoc:
|
65
|
+
# TODO: method to add various URLs and just write in the end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Unmap the given localization (<tt>loc</tt>)
|
69
|
+
#
|
70
|
+
# * <tt>loc</tt> is the URL to be unmaped
|
71
|
+
def unmap_url(loc)
|
72
|
+
@locker.synchronize do
|
73
|
+
url = get_url(loc)
|
74
|
+
url.remove if url
|
75
|
+
|
76
|
+
write_file
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Unmap the given path
|
81
|
+
#
|
82
|
+
# * <tt>loc</tt> is the Path t be unmaped
|
83
|
+
def unmap_path(loc)
|
84
|
+
unmap_url(URI.join(Map.site_root, loc))
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
# Extract the options to map an URL
|
90
|
+
#
|
91
|
+
# see <tt>map_url</tt> to understand.
|
92
|
+
def extract_options(opts)
|
93
|
+
lastmod = opts.delete(:lastmod)
|
94
|
+
changefreq = opts.delete(:changefreq)
|
95
|
+
priority = opts.delete(:priority)
|
96
|
+
|
97
|
+
[lastmod, changefreq, priority]
|
98
|
+
end
|
99
|
+
|
100
|
+
# Return the Element for the given <tt>url</tt>
|
101
|
+
def get_url(url)
|
102
|
+
@builder.elements["//url[loc='#{url}']"]
|
103
|
+
end
|
104
|
+
|
105
|
+
# Write the file to disk (run only synchronized with @locker)
|
106
|
+
def write_file
|
107
|
+
File.open(@file, 'w') {|file| @builder.write(file, INDENT)}
|
108
|
+
end
|
109
|
+
|
110
|
+
# Initialize the map (called on the boot, normally)
|
111
|
+
def initialize_map
|
112
|
+
if @builder.root.nil?
|
113
|
+
@builder << REXML::XMLDecl.new('1.0', 'UTF-8')
|
114
|
+
@builder.add_element('urlset', 'xmlns' => SCHEMA)
|
115
|
+
else
|
116
|
+
raise InvalidMap unless @builder.root.attributes.key? 'xmlns'
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
class InvalidMap < StandardError; end
|
122
|
+
end
|
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: milk-it-sitemapper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Carlos Junior
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-01-06 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rails
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: "2.1"
|
23
|
+
version:
|
24
|
+
description: Sitemapper helps you to apply SEO techniques on your Ruby on Rails application, including auto generation of a sitemap.
|
25
|
+
email:
|
26
|
+
- carlos@milk-it.net
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- README.rdoc
|
33
|
+
- MIT-LICENSE
|
34
|
+
files:
|
35
|
+
- README.rdoc
|
36
|
+
- Rakefile
|
37
|
+
- MIT-LICENSE
|
38
|
+
- install.rb
|
39
|
+
- init.rb
|
40
|
+
- tasks/sitemaper_tasks.rake
|
41
|
+
- lib/sitemapper.rb
|
42
|
+
- lib/sitemapper/helpers.rb
|
43
|
+
- lib/sitemapper/map.rb
|
44
|
+
- lib/sitemapper/adapters/rails_adapter.rb
|
45
|
+
has_rdoc: true
|
46
|
+
homepage: http://redmine.milk-it.net/projects
|
47
|
+
post_install_message: |
|
48
|
+
|
49
|
+
Thank you for using Sitemapper.
|
50
|
+
|
51
|
+
Consider help us to maintain Sitemapper by donating (github.com/milk-it/sitemapper) if you like it!
|
52
|
+
|
53
|
+
rdoc_options:
|
54
|
+
- --line-numbers
|
55
|
+
- --inline-source
|
56
|
+
- --main
|
57
|
+
- README.rdoc
|
58
|
+
- --title
|
59
|
+
- Sitemapper
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: "0"
|
67
|
+
version:
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: "0"
|
73
|
+
version:
|
74
|
+
requirements: []
|
75
|
+
|
76
|
+
rubyforge_project: sitemapper
|
77
|
+
rubygems_version: 1.2.0
|
78
|
+
signing_key:
|
79
|
+
specification_version: 2
|
80
|
+
summary: Sitemapper helps you to apply SEO techniques on your Ruby on Rails application, including auto generation of a sitemap.
|
81
|
+
test_files:
|
82
|
+
- test/sitemapper_test.rb
|