-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathlanguage_generator.rb
311 lines (274 loc) · 9.74 KB
/
language_generator.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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
module Jekyll
class Site
def instantiate_subclasses(klass)
if klass.name == 'Jekyll::Generator'
[Jekyll::LanguagePageGenerator.new(config), Jekyll::LanguagePostGenerator.new(config)].concat(klass.descendants.select do |c|
c.name.split('::').last !~ /^Language.+Generator/
end.select do |c|
!safe || c.safe
end.sort.map do |c|
c.new(config)
end)
else
klass.descendants.select do |c|
!safe || c.safe
end.sort.map do |c|
c.new(config)
end
end
end
end
# Monkey Patches
class Page
# The generated relative url of this page. e.g. /about.html.
#
# Returns the String url.
alias orig_url url
def url
theurl = URL.new({
:template => template,
:placeholders => url_placeholders,
:permalink => permalink
}).to_s
# Get the language of the page from the name of the post
languageFromFile = GetLanguage.get_language(theurl)
if(languageFromFile)
self.data = GetLanguage.merge_data(self.data, languageFromFile, true)
theurl.gsub!(".#{languageFromFile}",'')
end
language = self.data['language']
if(language)
theurl.sub!("/#{language}/",'/')
if (language != 'none')
theurl = "/#{language}#{theurl}"
end
end
@url = theurl
end
alias orig_dir dir
def dir
directory = orig_dir
language = self.data['language']
if(language)
directory.sub!("/#{language}",'/')
end
return directory
end
end
class Post
# The generated relative url of this page. e.g. /about.html.
#
# Returns the String url.
alias orig_init initialize
def initialize(site, base, dir, name)
orig_init(site, base, dir, name)
languageFromFile = GetLanguage.get_language(path)
if(languageFromFile)
self.data = GetLanguage.merge_data(self.data, languageFromFile, true)
end
end
def url
theurl = URL.new({
:template => template,
:placeholders => url_placeholders,
:permalink => permalink
}).to_s
language = self.data['language']
#puts "#{@url}: #{language}"
if (language != 'none')
theurl.gsub!(".#{language}",'')
theurl = "/#{language}#{theurl}"
end
@url = theurl
end
end
module Paginate
class Pagination
priority :low
def self.createPages(site, page)
defined_language=page.data['language']
if(defined_language == nil)
defined_language = site.config['languages'][0]
end
all_posts = site.site_payload['site']['posts']
all_posts = all_posts.reject { |p| p['hidden'] }
all_posts = all_posts.reject { |p|
p['language'] != defined_language
}
pages = Pager.calculate_pages(all_posts, site.config['paginate'].to_i)
(1..pages).each do |num_page|
pager = Pager.new(site, num_page, all_posts, pages)
if num_page > 1
newpage = Page.new(site, site.source, page.dir, page.name)
newpage.data = Jekyll::Utils.deep_merge_hashes(newpage.data,{
'language' => defined_language,
'multilingual' => true
})
newpage.pager = pager
newpage.dir = Pager.paginate_path(site, num_page)
site.pages << newpage
else
page.pager = pager
end
end
end
def paginate(site, page)
Pagination.createPages(site,page)
end
def generate(site)
if Pager.pagination_enabled?(site)
if templates = template_pages(site) # ! pages instead of page
templates.each { |template|
paginate(site, template)
}
else
Jekyll.logger.warn "Pagination:", "Pagination is enabled, but I couldn't find " +
"an index.html page to use as the pagination template. Skipping pagination."
end
end
end
# Public: Find the Jekyll::Page(s) which will act as the pager templates
#
# site - the Jekyll::Site object
#
# Returns the Jekyll::Page objects which will act as the pager templates
# Original method template_page is found in jekyll-paginate/pagination.rb
# Has been modified to paginate {language}/index.html
def template_pages(site)
site.pages.dup.select do |page|
Pager.pagination_candidate?(site.config, page)
end.sort do |one, two|
two.path.size <=> one.path.size
end.slice(0, 2)
end
end
end
#Generators
class LanguagePostGenerator < Generator
priority :highest
def generate(site)
site.posts.each { |post|
languages = site.config['languages'].dup
if (post.data['multilingual'] == nil)
defined_language=post.data['language']
puts "found single language post with main language #{defined_language}: #{post.url}"
if(defined_language == nil)
defined_language = languages[0]
end
post.data = GetLanguage.merge_data(post.data, defined_language, false)
languages.delete(defined_language)
languages.each do |lang|
puts "Generating post for #{lang}"
newpost = post.dup
newpost.data = Jekyll::Utils.deep_merge_hashes(newpost.data,{
'language' => lang,
'multilingual' => false,
'mainlanguage' => defined_language,
'title' => "#{newpost.data['title']}"
})
site.posts << newpost
end
end
}
end
end
class LanguagePageGenerator < Generator
priority :lowest
def generate(site)
site.pages.each { |page|
languages = site.config['languages'].dup
if (page.data['multilingual'] == nil && page.data['language'] != 'none')
url = page.url
defined_language=page.data['language']
if(!defined_language)
defined_language = languages[0]
puts "Setting default language #{defined_language} for #{url}"
page.data = GetLanguage.merge_data(page.data, defined_language, false)
end
puts "found single language page with main language #{defined_language}: #{url}"
languages.delete(defined_language)
languages.each do |lang|
puts " Generating page for #{lang}"
newpage = page.dup
newpage.data = Jekyll::Utils.deep_merge_hashes(newpage.data,{
'language' => lang,
'multilingual' => false,
'mainlanguage' => defined_language,
'title' => "#{newpage.data['title']}"
})
site.pages << newpage
if Jekyll::Paginate::Pager.pagination_enabled?(site) && page.pager != nil
puts " Pagination found. Generating..."
Jekyll::Paginate::Pagination.createPages(site, newpage)
end
end
end
}
end
end
module LanguagePostIndicatorFilter
def language_flag(post)
if(post != nil && isNonMultilingualPostInDifferentLanguage(post))
lang = post['mainlanguage']
return "<img src='#{@context.registers[:site].baseurl}/images/#{ lang }.png' alt='#{ lang }' class='flag'/>"
end
""
end
def language_text(post)
if(post != nil && isNonMultilingualPostInDifferentLanguage(post))
return " (#{ post['mainlanguage']})"
end
""
end
def isNonMultilingualPostInDifferentLanguage(post)
return post['multilingual'] != true && (post['language'] != @context.registers[:page]['language'] || post['mainlanguage'] != nil)
end
end
class LanguageArrayFilter < Liquid::Tag
Syntax = /(\w+[.]?\w+)\s+(\w+)\s+(\w+[.]?\w+)/o
def initialize(tag_name, markup, tokens)
if markup =~ Syntax
@collection_name = $1
@taget_collection_name = $2
@taget_language = $3
else
raise SyntaxError.new("Syntax Error in 'language_array' - Valid syntax: random [source] [var] [language]")
end
super
end
def render(context)
collection = context[@collection_name]
if collection
filtered_collection = collection.select { |post|
post.data['language'] == nil || post.data['language'] == context[@taget_language]
}
context[@taget_collection_name] = filtered_collection
else
context[@taget_collection_name] = collection
end
return
end
end
end
class GetLanguage
# Get Language
def self.get_language(url)
lang=url.match(/.*\.([a-z]{2})\.(?:markdown|md|html)?(?:\/)?$/)
if(lang && lang[1] != "md")
return lang[1]
end
return nil
end
# Merge the data with the language values.
def self.merge_data(data, language, multilingual)
if (language)
data = Jekyll::Utils.deep_merge_hashes(data,{
'language' => language,
'multilingual' => multilingual,
})
end
return data
end
end
Liquid::Template.register_filter(Jekyll::LanguagePostIndicatorFilter)
Liquid::Template.register_tag('language_array', Jekyll::LanguageArrayFilter)