jekyll-multiple-languages 1.0.0
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.
- checksums.yaml +15 -0
- data/lib/jekyll-multiple-languages.rb +329 -0
- metadata +44 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
OTFiOGQzMTRlMTFiMTJiYjY0MmZlMzBlM2UxNDUwZTJiMGUwOGRlMw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
MmY3ZDBjYWJlMWFiM2U0ODBiMzMxNWNhOTcyMzIwYzVmMmJhNzZlNA==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
M2FlM2IyMGJhZWYwZWYyYjZjMDM0M2FjNmM4N2U1OTc0ZWFlMzAyM2Y3NjU1
|
10
|
+
YjZjM2Y4N2ExODkwNGZkZGQ3MjFlMWQ4ODQ1ZTY5YTM3MWM3ZDM5YjIzYzYy
|
11
|
+
ZWVmYzM0MWE3NmY1OGVhYzg1OGNjOTc1MjU2MGMyYjMxZGM3NWM=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NWYwYWRiNDA4MTQ2ZDk4MDI0NjQ4OTFjZjViZDAwMzI4NjhhMjQ0YWFhZmU0
|
14
|
+
MjYyYWM5OTMxOGY5NzYzYWNmODAyYmNmMmRlOTJlZmFkOTY5NWQ4Y2Q0YTVl
|
15
|
+
MjUzMjVmZWI5OWY5ZjJiY2ZiOTZmOGNjNzU3NzdiMTJjZTQ3NzY=
|
@@ -0,0 +1,329 @@
|
|
1
|
+
module Jekyll
|
2
|
+
module MultiLang
|
3
|
+
attr_accessor :language, :name_no_language, :is_default_language, :url_no_language, :dir_source
|
4
|
+
|
5
|
+
def process_initialize(site, base, dir, name)
|
6
|
+
name_no_language = name.dup
|
7
|
+
|
8
|
+
lang = ''
|
9
|
+
# xxx.$lang.md / $lang.xxx.md
|
10
|
+
site.config['languages'].each{ |item|
|
11
|
+
lang_str = item + '.'
|
12
|
+
if name_no_language.include? lang_str
|
13
|
+
lang = item
|
14
|
+
name_no_language.slice! lang_str
|
15
|
+
end
|
16
|
+
}
|
17
|
+
|
18
|
+
!lang || lang == '' && lang = site.config['language_default']
|
19
|
+
@language = lang
|
20
|
+
@dir_source = dir
|
21
|
+
@name_no_language = name_no_language
|
22
|
+
@is_default_language = lang == site.config['language_default']
|
23
|
+
|
24
|
+
initialize_org(site, base, dir, name)
|
25
|
+
end
|
26
|
+
|
27
|
+
def url_no_language
|
28
|
+
if !@url_no_language
|
29
|
+
process_url
|
30
|
+
end
|
31
|
+
@url_no_language
|
32
|
+
end
|
33
|
+
|
34
|
+
def process_url
|
35
|
+
if !@url
|
36
|
+
url = self.url_org
|
37
|
+
@url_no_language = url
|
38
|
+
lang_prefix = '/' + self.language
|
39
|
+
if !self.is_default_language && (url && url.index(lang_prefix) != 0)
|
40
|
+
url = lang_prefix + url
|
41
|
+
end
|
42
|
+
@url = url
|
43
|
+
end
|
44
|
+
@url
|
45
|
+
end
|
46
|
+
|
47
|
+
def process_to_liquid(attrs = nil)
|
48
|
+
data_for_liquid = self.to_liquid_org(attrs)
|
49
|
+
attrs_for_lang = self.language_attributes_for_liquid || []
|
50
|
+
attrs_for_lang.concat(%w[language is_default_language url_no_language])
|
51
|
+
further_data = Hash[attrs_for_lang.map { |attribute|
|
52
|
+
[attribute, send(attribute)]
|
53
|
+
}]
|
54
|
+
data_for_liquid = Utils.deep_merge_hashes(data_for_liquid, further_data)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Rewrite Jekyll.site
|
59
|
+
#
|
60
|
+
class Site
|
61
|
+
attr_accessor :language_default, :languages, :posts_by_language, :pages_by_language, :fill_default_content
|
62
|
+
alias :process_org :process
|
63
|
+
def process
|
64
|
+
self.begin_inject
|
65
|
+
process_org
|
66
|
+
rescue Exception => e
|
67
|
+
print e.backtrace.join("\n")
|
68
|
+
end
|
69
|
+
|
70
|
+
alias :read_org :read
|
71
|
+
def read
|
72
|
+
read_org
|
73
|
+
group_posts_and_pages
|
74
|
+
end
|
75
|
+
|
76
|
+
# Group the post by the language
|
77
|
+
#
|
78
|
+
def group_posts_and_pages
|
79
|
+
lang_default = self.language_default
|
80
|
+
langs_remain = self.languages.dup
|
81
|
+
langs_remain.delete(lang_default)
|
82
|
+
|
83
|
+
@posts_by_language = {}
|
84
|
+
@pages_by_language = {}
|
85
|
+
|
86
|
+
self.languages.dup.each { |lang|
|
87
|
+
@posts_by_language[lang] ||= {}
|
88
|
+
@pages_by_language[lang] ||= {}
|
89
|
+
}
|
90
|
+
|
91
|
+
self.posts.each {|post|
|
92
|
+
@posts_by_language[post.language][post.url_no_language] = post
|
93
|
+
}
|
94
|
+
self.pages.each {|page|
|
95
|
+
@pages_by_language[page.language][page.url_no_language] = page
|
96
|
+
}
|
97
|
+
|
98
|
+
if (@fill_default_content)
|
99
|
+
self.fill_default_content(@posts, @posts_by_language, lang_default, langs_remain, Post)
|
100
|
+
self.fill_default_content(@pages, @pages_by_language, lang_default, langs_remain, Page)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def fill_default_content(contents, grouped_contents, default, targets, kclass)
|
105
|
+
grouped_contents[default].select{|k,v| !v.data['no_fill_default_content']}.each{ |k, content|
|
106
|
+
targets.each{|lang|
|
107
|
+
if !grouped_contents[lang][k]
|
108
|
+
c = kclass.new(self, @source, content.dir_source, content.name)
|
109
|
+
c.language = lang
|
110
|
+
c.is_default_language = false
|
111
|
+
grouped_contents[lang][k] = c
|
112
|
+
contents << c
|
113
|
+
end
|
114
|
+
}
|
115
|
+
}
|
116
|
+
end
|
117
|
+
|
118
|
+
# Only when site is initialized, this plugin will be loaded
|
119
|
+
def begin_inject
|
120
|
+
self.update_config(self.config)
|
121
|
+
end
|
122
|
+
|
123
|
+
# Public: Update site config, process languages and language_default options.
|
124
|
+
#
|
125
|
+
def update_config(config)
|
126
|
+
!config['languages'] && config['languages'] = []
|
127
|
+
!config['language_default'] && config['language_default'] = config['languages'].first;
|
128
|
+
|
129
|
+
%w[languages language_default fill_default_content].each do |opt|
|
130
|
+
self.send("#{opt}=", config[opt])
|
131
|
+
end
|
132
|
+
self.config = config
|
133
|
+
end
|
134
|
+
|
135
|
+
alias :site_payload_org :site_payload
|
136
|
+
def site_payload
|
137
|
+
payload = site_payload_org
|
138
|
+
payload.merge({
|
139
|
+
"posts_by_language" => self.posts_by_language,
|
140
|
+
"pages_by_language" => self.pages_by_language,
|
141
|
+
})
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
class Page
|
147
|
+
|
148
|
+
include MultiLang
|
149
|
+
|
150
|
+
LANGUAGE_ATTRIBUTES_FOR_LIQUID = %w[]
|
151
|
+
|
152
|
+
alias :initialize_org :initialize
|
153
|
+
def initialize(site, base, dir, name)
|
154
|
+
process_initialize(site, base, dir, name)
|
155
|
+
end
|
156
|
+
|
157
|
+
alias :url_org :url
|
158
|
+
def url
|
159
|
+
process_url
|
160
|
+
end
|
161
|
+
|
162
|
+
alias :process_org :process
|
163
|
+
def process(name)
|
164
|
+
process_org(@name_no_language)
|
165
|
+
end
|
166
|
+
|
167
|
+
alias :to_liquid_org :to_liquid
|
168
|
+
def to_liquid(attrs = nil)
|
169
|
+
process_to_liquid(attrs)
|
170
|
+
end
|
171
|
+
|
172
|
+
def language_attributes_for_liquid
|
173
|
+
LANGUAGE_ATTRIBUTES_FOR_LIQUID
|
174
|
+
end
|
175
|
+
|
176
|
+
def inspect
|
177
|
+
"#<Jekyll:Page @name=#{self.name.inspect} @url=#{self.url.inspect}>"
|
178
|
+
end
|
179
|
+
|
180
|
+
end
|
181
|
+
|
182
|
+
class Post
|
183
|
+
include MultiLang
|
184
|
+
|
185
|
+
MATCHER_WITH_LANG = /^(.+\/)*(?:.+\.)*(\d+-\d+-\d+)-(.*)(\.[^.]+)$/
|
186
|
+
|
187
|
+
alias :initialize_org :initialize
|
188
|
+
def initialize(site, source, dir, name)
|
189
|
+
process_initialize(site, source, dir, name)
|
190
|
+
end
|
191
|
+
|
192
|
+
alias :url_org :url
|
193
|
+
def url
|
194
|
+
process_url
|
195
|
+
end
|
196
|
+
|
197
|
+
alias :process_org :process
|
198
|
+
def process(name)
|
199
|
+
process_org(@name_no_language)
|
200
|
+
end
|
201
|
+
|
202
|
+
def inspect
|
203
|
+
"<Post: id: #{self.id} url: #{self.url} language: #{self.language}>"
|
204
|
+
end
|
205
|
+
|
206
|
+
# For match /blog/$lang.2014-02-14-the-blog-name.md
|
207
|
+
# or /blog/2014-02-14-the-blog-name.$lang.md
|
208
|
+
#
|
209
|
+
def self.valid?(name)
|
210
|
+
name =~ MATCHER_WITH_LANG
|
211
|
+
end
|
212
|
+
|
213
|
+
def language_attributes_for_liquid
|
214
|
+
|
215
|
+
end
|
216
|
+
|
217
|
+
alias :to_liquid_org :to_liquid
|
218
|
+
def to_liquid(attrs = nil)
|
219
|
+
process_to_liquid(attrs)
|
220
|
+
end
|
221
|
+
|
222
|
+
end
|
223
|
+
|
224
|
+
module Generators
|
225
|
+
|
226
|
+
# index.$lang.html / index.html
|
227
|
+
#
|
228
|
+
# => /$lang/... /...
|
229
|
+
#
|
230
|
+
class Pagination < Generator
|
231
|
+
def generate(site)
|
232
|
+
if Pager.pagination_enabled?(site)
|
233
|
+
pages = find_template_pages(site)
|
234
|
+
if pages && !pages.empty?
|
235
|
+
pages.each {|page| paginate_for_language(site, page)}
|
236
|
+
else
|
237
|
+
Jekyll.logger.warn "Pagination:", "Pagination is enabled, but I couldn't find " +
|
238
|
+
"an index.html page to use as the pagination template. Skipping pagination."
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
def paginate_for_language(site, the_template_page)
|
244
|
+
lang = the_template_page.language
|
245
|
+
all_posts = site.posts_by_language[lang] || {}
|
246
|
+
all_posts = all_posts.values.sort { |a, b| b <=> a }
|
247
|
+
pages = Pager.calculate_pages(all_posts, site.config['paginate'].to_i)
|
248
|
+
(1..pages).each do |num_page|
|
249
|
+
pager = Pager.new(site, the_template_page, num_page, all_posts, pages)
|
250
|
+
if num_page > 1
|
251
|
+
newpage = Page.new(site, site.source, the_template_page.dir_source, the_template_page.name)
|
252
|
+
newpage.pager = pager
|
253
|
+
newpage.dir = Pager.calc_paginate_path(site, the_template_page, num_page)
|
254
|
+
site.pages << newpage
|
255
|
+
else
|
256
|
+
the_template_page.pager = pager
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
# Find all the cadidate pages
|
262
|
+
#
|
263
|
+
def find_template_pages(site)
|
264
|
+
site.pages.dup.select do |page|
|
265
|
+
Pager.pagination_candidate?(site.config, page)
|
266
|
+
end.sort do |one, two|
|
267
|
+
two.path.size <=> one.path.size
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
class Pager
|
274
|
+
|
275
|
+
# Static: Return the pagination path of the page
|
276
|
+
#
|
277
|
+
# site - the Jekyll::Site object
|
278
|
+
# the_template_page - template page
|
279
|
+
# num_page - the pagination page number
|
280
|
+
#
|
281
|
+
# Returns the pagination path as a string
|
282
|
+
def self.calc_paginate_path(site, the_template_page, num_page)
|
283
|
+
return nil if num_page.nil?
|
284
|
+
return the_template_page.url if num_page <= 1
|
285
|
+
format = site.config['paginate_path']
|
286
|
+
format = format.sub(':num', num_page.to_s)
|
287
|
+
path = ensure_leading_slash(format)
|
288
|
+
path
|
289
|
+
end
|
290
|
+
|
291
|
+
def self.calc_paginate_path_with_lang(site, the_template_page, num_page)
|
292
|
+
path = self.calc_paginate_path(site, the_template_page, num_page)
|
293
|
+
return nil if path.nil?
|
294
|
+
lang_prefix = '/' + the_template_page.language
|
295
|
+
if !the_template_page.is_default_language && (path && path.index(lang_prefix) != 0)
|
296
|
+
path = '/' + the_template_page.language + path
|
297
|
+
end
|
298
|
+
path
|
299
|
+
end
|
300
|
+
|
301
|
+
def self.pagination_candidate?(config, page)
|
302
|
+
page_dir = File.dirname(File.expand_path(remove_leading_slash(page.path), config['source']))
|
303
|
+
paginate_path = remove_leading_slash(config['paginate_path'])
|
304
|
+
paginate_path = File.expand_path(paginate_path, config['source'])
|
305
|
+
page.basename == 'index' &&
|
306
|
+
in_hierarchy(config['source'], page_dir, File.dirname(paginate_path))
|
307
|
+
end
|
308
|
+
|
309
|
+
def initialize(site, the_template_page, page, all_posts, num_pages = nil)
|
310
|
+
@page = page
|
311
|
+
@per_page = site.config['paginate'].to_i
|
312
|
+
@total_pages = num_pages || Pager.calculate_pages(all_posts, @per_page)
|
313
|
+
|
314
|
+
if @page > @total_pages
|
315
|
+
raise RuntimeError, "page number can't be greater than total pages: #{@page} > #{@total_pages}"
|
316
|
+
end
|
317
|
+
|
318
|
+
init = (@page - 1) * @per_page
|
319
|
+
offset = (init + @per_page - 1) >= all_posts.size ? all_posts.size : (init + @per_page - 1)
|
320
|
+
|
321
|
+
@total_posts = all_posts.size
|
322
|
+
@posts = all_posts[init..offset]
|
323
|
+
@previous_page = @page != 1 ? @page - 1 : nil
|
324
|
+
@previous_page_path = Pager.calc_paginate_path_with_lang(site, the_template_page, @previous_page)
|
325
|
+
@next_page = @page != @total_pages ? @page + 1 : nil
|
326
|
+
@next_page_path = Pager.calc_paginate_path_with_lang(site, the_template_page, @next_page)
|
327
|
+
end
|
328
|
+
end
|
329
|
+
end
|
metadata
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jekyll-multiple-languages
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Srain
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-08-15 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: ''
|
14
|
+
email: srain@php.net
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- lib/jekyll-multiple-languages.rb
|
20
|
+
homepage: http://jekyll-langs.liaohuqiu.net/
|
21
|
+
licenses:
|
22
|
+
- MIT
|
23
|
+
metadata: {}
|
24
|
+
post_install_message:
|
25
|
+
rdoc_options: []
|
26
|
+
require_paths:
|
27
|
+
- lib
|
28
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
requirements: []
|
39
|
+
rubyforge_project:
|
40
|
+
rubygems_version: 2.2.2
|
41
|
+
signing_key:
|
42
|
+
specification_version: 4
|
43
|
+
summary: Another Multiple Languages Plugin for Jekyll!
|
44
|
+
test_files: []
|