-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathjekyll-sitemap-tag.rb
161 lines (117 loc) · 3.38 KB
/
jekyll-sitemap-tag.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#
# {% sitemap skip_url_regex_string %}
#
module Jekyll
class SiteMapTag < Liquid::Tag
def initialize(tag_name, params, tokens)
super
regex_string = params.split(' ').first
if( regex_string )
@regex = Regexp.new(regex_string)
end
end
def lookup(context, name)
lookup = context
name.split(".").each { |value| lookup = lookup[value] }
lookup
end
def render(context)
sitemap = SiteMapNode.new
pages = lookup(context, 'site.pages')
output = ""
sorted_pages = pages.sort { |x,y|
x.url <=> y.url
}
pages.each do |page|
# Filter non-html files (.xml for feeds, .css from sass, etc.)
if !(/\.html$/ =~ page.url )
next
end
# Skip blog pagination
if /^\/page\// =~ page.url
next
end
# Skip urls that match the passed Regexp (if assigned)
if @regex && @regex =~ page.url
next
end
sitemap.add_page(page)
end
%{<ul><li>#{sitemap.markup}</li></ul>}.to_s
end
end
class SiteMapNode
attr_reader :page, :key, :children
def initialize
@children = Hash.new
end
def add_page(page)
sitemap_page = SiteMapPage.new(page.url,page.data['title'])
# create the array of segments and prepare it for populate_page
segments = page.url.split('/')
# Now we should have something like this for segments:
# ['', 'index.html']
# or ['', 'page.html']
# or ['', 'segment', 'index.html']
# or ['', 'segment', 'page.html']
# pull off the leading '', that's the root node (this node).
@key = segments.shift
self.populate_page(segments,sitemap_page)
end
def populate_leaf(key,page)
@page = page
@key = key
end
def populate_page(segments,sitemap_page)
first_segment = segments.shift
if segments.size == 0
# leaf node
if first_segment == 'index.html'
@key = '' # makes sorting easier later...
@page = sitemap_page
else
leaf_node = SiteMapNode.new
leaf_node.populate_leaf(first_segment,sitemap_page)
@children[first_segment] = leaf_node
end
else
# recurse
node = @children[first_segment]
if !node
node = SiteMapNode.new
@children[first_segment] = node
end
node.populate_page(segments,sitemap_page)
end
end
def markup
output = @page.link
if @children.size
output += "<ul>"
@children.values.sort {|x,y| x.page.title <=> y.page.title}.each do |sitemap_node|
output += "<li>#{sitemap_node.markup}</li>"
end
output += "</ul>"
end
output
end
def print_segments(segments)
output = "["
segments.each do |segment|
output += "#{segment}, "
end
output += "]"
end
end
class SiteMapPage
attr_reader :url, :title
def initialize(url, title)
@url = url
@title = title
end
def link
%{<a href="#{@url}">#{@title}</a>}.to_s
end
end
end
Liquid::Template.register_tag('render_sitemap', Jekyll::SiteMapTag)