jekyll-polyglot 1.6.0 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 52fcf4f09a9d96c2255ca7226c0a26d5dc7cf5e337fc03805e3e3d18ff00d7d9
4
- data.tar.gz: 6a136ac3a5459c28c39ec71876e01ebee0582154f448ead285169bede86acb9f
3
+ metadata.gz: 55de36ccc381edcf3d22e5f275b99ceb59a4e684bb528516157963c8ebb41cac
4
+ data.tar.gz: 8bdcc86093ad1c3af1133a05e3993317dc7ced60e74f596acf6934d5a92b7792
5
5
  SHA512:
6
- metadata.gz: 9fe64a2a499c51edd8e3a861d8b2805f4283dc89301be66c942d297f44923a3a1203b58ffd5183615fa34a4d01b1a30df01c76bb29626f57258e8b5e7396cbb3
7
- data.tar.gz: f22f0727628cfed097dc18845fbd44de02629909d1a4db22767b1b9d52538a1a1287103bab7e8cc85e4e611f74365a7e789515b9b807d7c85751e8a660ef6a1e
6
+ metadata.gz: fb5bc80fda64369a25f465704993bc914af411ab8f285ee4bf5651ab7f7b036ff495426de44f4c3550aa75fd5d1b85cb21119389c031c36c44c6601daddc73b2
7
+ data.tar.gz: c4f560e754305637589ae43c90d8dbf101ef3283761177db0be579ff3e1d3139e19f1c003d3b3b7f61b7b543a93598a41b1595ec3f6a2dbb7196c59b497e5c14
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![Gem Version](https://badge.fury.io/rb/jekyll-polyglot.svg)](https://badge.fury.io/rb/jekyll-polyglot)
4
4
  [![CircleCI](https://circleci.com/gh/untra/polyglot/tree/master.svg?style=svg)](https://circleci.com/gh/untra/polyglot/?branch=master)
5
5
 
6
- __Polyglot__ is a fast, painless, open-source internationalization plugin for [Jekyll](http://jekyllrb.com) blogs. Polyglot is easy to setup and use with any Jekyll project, and it scales to the languages you want to support. With fallback support for missing content, automatic url relativization, and powerful SEO tools, Polyglot allows any multi-language jekyll blog to focus on content without the cruft.
6
+ __Polyglot__ is a fast, painless, open-source internationalization plugin for [Jekyll](http://jekyllrb.com) blogs. Polyglot is easy to set up and use with any Jekyll project, and it scales to the languages you want to support. With fallback support for missing content, automatic url relativization, and powerful SEO tools, Polyglot allows any multi-language jekyll blog to focus on content without the cruft.
7
7
 
8
8
  ## Why?
9
9
  Jekyll doesn't provide native support for multi-language blogs. This plugin was modeled after the [jekyll-multiple-languages-plugin](https://github.com/screeninteraction/jekyll-multiple-languages-plugin), whose implementation I liked, but execution I didn't.
@@ -34,7 +34,7 @@ These configuration preferences indicate
34
34
  - what i18n languages you wish to support
35
35
  - what is your default "fallback" language for your content
36
36
  - what root level files/folders are excluded from localization, based
37
- on if their paths start with any of the excluded regexp substrings. (this is different than the jekyll `exclude: [ .gitignore ]` ; you should `exclude` files and directories in your repo you dont want in your built site at all, and `exclude_from_localization` files and directories you want to see in your built site, but not in your sublanguage sites.)
37
+ on if their paths start with any of the excluded regexp substrings. (this is different from the jekyll `exclude: [ .gitignore ]` ; you should `exclude` files and directories in your repo you dont want in your built site at all, and `exclude_from_localization` files and directories you want to see in your built site, but not in your sublanguage sites.)
38
38
  - whether to run language processing in parallel or serial
39
39
 
40
40
  The optional `lang_from_path: true` option enables getting page
@@ -50,7 +50,7 @@ or whatever appropriate [I18n language code](https://developer.chrome.com/websto
50
50
  the page should build for. And you're done. Ideally, when designing your site, you should
51
51
  organize files by their relative urls.
52
52
 
53
- You can see how the live polyglot website [configures and supports multiple languages](https://github.com/untra/polyglot/blob/master/site/_config.yml#L28-L37), and examples of [community](https://github.com/untra/polyglot/pull/155) [language](https://github.com/untra/polyglot/pull/167) [contributions](https://github.com/untra/polyglot/pull/177).
53
+ You can see how the live Polyglot website [configures and supports multiple languages](https://github.com/untra/polyglot/blob/master/site/_config.yml#L28-L37), and examples of [community](https://github.com/untra/polyglot/pull/155) [language](https://github.com/untra/polyglot/pull/167) [contributions](https://github.com/untra/polyglot/pull/177).
54
54
 
55
55
  Polyglot works by associating documents with similar permalinks to the `lang` specified in their frontmatter. Files that correspond to similar routes should have identical permalinks. If you don't provide a permalink for a post, ___make sure you are consistent___ with how you place and name corresponding files:
56
56
  ```
@@ -59,7 +59,7 @@ _posts/2010-03-01-salad-recipes-sv.md
59
59
  _posts/2010-03-01-salad-recipes-fr.md
60
60
  ```
61
61
 
62
- Organized names will generate consistent permalinks when the post is rendered, and polyglot will know to build seperate language versions of
62
+ Organized names will generate consistent permalinks when the post is rendered, and Polyglot will know to build separate language versions of
63
63
  the website using only the files with the correct `lang` variable in the front matter.
64
64
 
65
65
  In short:
@@ -68,14 +68,60 @@ In short:
68
68
  * Don't overthink it, :wink:
69
69
 
70
70
 
71
+ ### Translation permalink information in page
72
+ _New in 1.8.0_
73
+
74
+ Whenever `page_id` frontmatter properties are used to identify translations, permalink information for the available languages is available in `permalink_lang`.
75
+ This is useful in order to generate language menus and even localization meta information without redirects!
76
+
77
+ Sample code for meta link generation:
78
+ ```
79
+ {% for lang in site.languages %}
80
+ {% capture lang_href %}{{site.baseurl}}/{% if lang != site.default_lang %}{{ lang }}/{% endif %}{% if page.permalink_lang[lang] != '/' %}{{page.permalink_lang[lang]}}{% endif %}{% endcapture %}
81
+ <link rel="alternate" hreflang="{{ lang }}" {% static_href %}href="{{ lang_href }}"{% endstatic_href %} />
82
+ {% endfor %}
83
+ ```
84
+
85
+
86
+ #### Using different permalinks per language
87
+ _New in 1.7.0_
88
+
89
+ Optionally, for those who may want different URLs on different languages, translations may be identified by specifying a `page_id` in the frontmatter.
90
+
91
+ If available, Polyglot will use `page_id` to identify the page, and will default to the `permalink` otherwise.
92
+
93
+ As an example, you may have an about page located in `/about/` while being in `/acerca-de/` in Spanish just by changing the permalink and specifying a `page_id` that will link the files as translations:
94
+ ```md
95
+ ---
96
+ title: About
97
+ permalink: /about
98
+ lang: en
99
+ page_id: about
100
+ ---
101
+ This is us!
102
+ ```
103
+
104
+ ```md
105
+ ---
106
+ title: Acerca de
107
+ permalink: /acerca-de
108
+ lang: es
109
+ page_id: about
110
+ ---
111
+ Estos somos nosotros!
112
+ ```
113
+
114
+ Additionally, if you are also using the `jekyll-redirect-from` plugin, pages coordinated this way will automatically have redirects created between pages.
115
+ So `/es/about` will automatically redirect to `/es/acerca-de` and `/acerca-de` can redirect to `/about`. If you use this approach, be sure to also employ a customized [redirect.html](https://github.com/untra/polyglot/blob/master/site/_layouts/redirect.html).
116
+
71
117
  #### Fallback Language Support
72
118
  Lets say you are building your website. You have an `/about/` page written in *english*, *german* and
73
119
  *swedish*. You are also supporting a *french* website, but you never designed a *french* version of your `/about/` page!
74
120
 
75
121
  No worries. Polyglot ensures the sitemap of your *english* site matches your *french* site, matches your *swedish* and *german* sites too. In this case, because you specified a `default_lang` variable in your `_config.yml`, all sites missing their languages' counterparts will fallback to your `default_lang`, so content is preserved across different languages of your site.
76
122
 
77
- #### Relativized Local Urls
78
- No need to meticulously manage anchor tags to link to your correct language. Polyglot modifies how pages get written to the site so your *french* links keep vistors on your *french* blog.
123
+ ### Relativized Local Urls
124
+ No need to meticulously manage anchor tags to link to your correct language. Polyglot modifies how pages get written to the site so your *french* links keep visitors on your *french* blog.
79
125
  ```md
80
126
  ---
81
127
  title: au sujet de notre entreprise
@@ -98,8 +144,8 @@ Notice the link `<a href="/fr/menu/">...` directs to the french website.
98
144
 
99
145
  Even if you are falling back to `default_lang` page, relative links built on the *french* site will still link to *french* pages.
100
146
 
101
- #### Relativized Absolute Urls
102
- If you defined a site `url` in your `_config.yaml`, polyglot will automatically relativize absolute links pointing to your website directory:
147
+ ### Relativized Absolute Urls
148
+ If you defined a site `url` in your `_config.yaml`, Polyglot will automatically relativize absolute links pointing to your website directory:
103
149
 
104
150
  ```md
105
151
  ---
@@ -112,7 +158,7 @@ becomes
112
158
  <p>Cliquez <a href="https://mywebsite.com/fr/">ici</a> pour aller à l'entrée du site.
113
159
  ```
114
160
 
115
- #### Disabling Url Relativizing
161
+ ### Disabling Url Relativizing
116
162
  _New in 1.4.0_
117
163
  If you dont want a href attribute to be relativized (such as for making [a language switcher](https://github.com/untra/polyglot/blob/master/site/_includes/sidebar.html#L40)), you can use the block tag:
118
164
 
@@ -128,11 +174,10 @@ that will generate `<a href="/about">click this static link</a>` which is what y
128
174
 
129
175
  Combine with a [html minifier](https://github.com/digitalsparky/jekyll-minifier) for a polished and production ready website.
130
176
 
131
- #### Exclusive site language generation
177
+ ### Exclusive site language generation
132
178
  _New in 1.4.0_
133
179
 
134
- If you want to control which languages a document can be generated for, you can specify `lang-exclusive: [ ]` frontmatter.
135
- If you include this frontmatter in your post, it will only generate for the specified site languages.
180
+ If you want to control which languages a document can be generated for, you can specify `lang-exclusive: [ ]` frontmatter. If you include this frontmatter in your post, it will only generate for the specified site languages.
136
181
 
137
182
  For Example, the following frontmatter will only generate in the `en` and `fr` site language builds:
138
183
  ```
@@ -141,29 +186,73 @@ lang-exclusive: ['en', 'fr']
141
186
  ---
142
187
  ```
143
188
 
144
- #### Machine-aware site building
145
- _New in 1.5.0_
189
+ ### Localized site.data
190
+ There are cases where you may want to have a list of `key: value` pairs of translated content. For example, instead of creating a complete separate file for each language containing the layout structure and localized content, you can create a single file with the layout that will be shared among pages, and then create a language-specific file with the localized content that will be used.
146
191
 
147
- Polyglot will only start builds after it confirms there is a cpu core ready to accept the build thread. This ensures that jekyll will build large sites efficiently, streamlining build processes instead of overloading machines with process thrash.
192
+ To do this, you can create a file like `_data/:lang/strings.yml`, one for each language, and Polyglot will bring those keys under `site.data[:lang].strings`. For example, suppose you have the following files:
148
193
 
149
- #### Localized site.data
194
+ `_data/en/strings.yml`
195
+ ```yaml
196
+ hello: "Hello"
197
+ greetings:
198
+ morning: "Good morning"
199
+ evening: "Good evening"
200
+ ```
150
201
 
151
- There are cases when `site.data` localization is required.
152
- For instance: you might need to localize `_data/navigation.yml` that holds "navigation menu".
153
- In order to localize it, just place language-specific files in `_data/:lang/...` folder, and Polyglot will bring those keys to the top level.
202
+ `_data/pt-br/strings.yml`
203
+ ```yaml
204
+ hello: "Olá"
205
+ greetings:
206
+ morning: "Bom dia"
207
+ evening: "Boa noite"
208
+ ```
209
+
210
+ You can use the `site.data` to access the localized content in your layouts and pages:
211
+
212
+ ```liquid
213
+ <p>{{ site.data[site.active_lang].strings.hello }}, {{ site.data[site.active_lang].strings.greetings.morning }}</p>
214
+ ```
215
+
216
+ For more information on this matter, check out this [post](https://polyglot.untra.io/2024/02/29/localized-variables/).
217
+
218
+ ### Localized collections
219
+
220
+ To localize collections, you first have to properly define the collection in your `_config.yml` file. For example, if you have a collection of `projects`, you can define it like this:
221
+
222
+ ```yaml
223
+ collections:
224
+ projects:
225
+ output: true
226
+ permalink: /:collection/:title/
227
+ ```
228
+
229
+ Note that the [permalink](https://jekyllrb.com/docs/permalinks/#collections) definition here is important. Then, you can create a file for each language in the `_projects` directory, and Polyglot will bring those files under `site.projects`. For more information, check the related discussion #188.
154
230
 
155
231
  ## How It Works
156
232
  This plugin makes modifications to existing Jekyll classes and modules, namely `Jekyll::StaticFile` and `Jekyll::Site`. These changes are as lightweight and slim as possible. The biggest change is in `Jekyll::Site.process`. Polyglot overwrites this method to instead spawn a separate process for each language you intend to process the site for. Each of those processes calls the original `Jekyll::Site.process` method with its language in mind, ensuring your website scales to support any number of languages, while building all of your site languages simultaneously.
157
233
 
158
234
  `Jekyll::Site.process` is the entry point for the Jekyll build process. Take care whatever other plugins you use do not also attempt to overwrite this method. You may have problems.
159
235
 
236
+ ### (:polyglot, :post_write) hook
237
+ _New in 1.8.0_
238
+ Polyglot issues a `:polyglot, :post_write` hook event once all languages have been built for the site. This hook runs exactly once, after all site languages been processed:
239
+
240
+ ```rb
241
+ Jekyll::Hooks.register :polyglot, :post_write do |site|
242
+ # do something custom and cool here!
243
+ end
244
+ ```
245
+
246
+ ### Machine-aware site building
247
+ _New in 1.5.0_
248
+
249
+ Polyglot will only start builds after it confirms there is a cpu core ready to accept the build thread. This ensures that jekyll will build large sites efficiently, streamlining build processes instead of overloading machines with process thrash.
160
250
 
161
251
  ### Writing Tests and Debugging
162
252
  _:wave: I need assistance with modern ruby best practices for test maintenance with rake and rspec. If you got the advice I have the ears._
163
253
 
164
254
  Tests are run with `bundle exec rake`. Tests are in the `/spec` directory, and test failure output detail can be examined in the `rspec.xml` file.
165
255
 
166
-
167
256
  ## Features
168
257
  This plugin stands out from other I18n Jekyll plugins.
169
258
  - automatically corrects your relative links, keeping your *french* visitors on your *french* website, even when content has to fallback to the `default_lang`.
@@ -177,20 +266,11 @@ This plugin stands out from other I18n Jekyll plugins.
177
266
  - a creator that will answer all of your questions and issues.
178
267
 
179
268
  ## SEO Recipes
180
- Jekyll-polyglot has a few spectacular [Search Engine Optimization techniques](https://untra.github.io/polyglot/seo) to ensure your Jekyll blog gets the most out of it's multilingual audience. Check them out!
269
+ Jekyll-polyglot has a few spectacular [Search Engine Optimization techniques](https://untra.github.io/polyglot/seo) to ensure your Jekyll blog gets the most out of its multilingual audience. Check them out!
181
270
 
182
- ### Other Websites Built with Polyglot
183
- Feel free to open a PR and list your multilingual blog here you may want to share:
271
+ ### Sitemap generation
184
272
 
185
- * [Polyglot project website](https://polyglot.untra.io)
186
- * [LogRhythm Corporate Website](https://logrhythm.com)
187
- * [All Over Earth](https://allover.earth/)
188
- * [Hanare Cafe in Toshijima, Japan](https://hanarecafe.com)
189
- * [F-Droid](https://f-droid.org)
190
- * [Ubuntu MATE](https://ubuntu-mate.org)
191
- * [Leo3418 blog](https://leo3418.github.io/)
192
- * [Gaphor](https://gaphor.org)
193
- * [Yi Yunseok's personal blog website](https://Yi-Yunseok.GitHub.io)
273
+ See the example [sitemap.xml](/site/sitemap.xml) and [robots.txt](/site/robots.txt) for how to automatically generate a multi-language sitemap for your page and turn it in for the SEO i18n credit.
194
274
 
195
275
  ## Compatibility
196
276
  Currently supports Jekyll 3.0 , and Jekyll 4.0
@@ -207,10 +287,38 @@ Please! I need all the support I can get! 🙏
207
287
  But for real I would appreciate any code contributions and support. This started as an open-source side-project and has gotten bigger than I'd ever imagine!
208
288
  If you have something you'd like to contribute to jekyll-polyglot, please open a PR!
209
289
 
290
+ ### Contributors
291
+ These are talented and considerate software developers across the world that have lent their support to this project.
292
+ **Thank You! ¡Gracias! Merci! Danke! 감사합니다! תודה רבה! Спасибо! Dankjewel! 谢谢!Obrigado!**
293
+
294
+ * [@jerturowetz](https://github.com/jerturowetz) 1.7.1
295
+ * [@antoniovazquezblanco](https://github.com/antoniovazquezblanco) [1.7.0](https://polyglot.untra.io/2023/10/29/polyglot-1.7.0/)
296
+ * [@salinatedcoffee](https://github.com/SalinatedCoffee) [ko support](https://polyglot.untra.io/2023/02/27/korean-support/)
297
+ * [@aturret](https://github.com/aturret) [zh-CN support](https://polyglot.untra.io/2023/06/08/polyglot-1.6.0-chinese-support/)
298
+ * [@dougieh](https://github.com/dougieh) [1.5.1](https://polyglot.untra.io/2022/10/01/polyglot-1.5.1/)
299
+ * [@pandermusubi](https://github.com/PanderMusubi) [nl support](https://polyglot.untra.io/2022/01/15/dutch-site-support/)
300
+ * [@obfusk](https://github.com/obfusk) [1.5.0](https://polyglot.untra.io/2021/07/17/polyglot-1.5.0/)
301
+ * [@eighthave](https://github.com/eighthave) [1.5.0](https://polyglot.untra.io/2021/07/17/polyglot-1.5.0/)
302
+ * [@george-gca](https://github.com/george-gca) [Localized Variables](https://polyglot.untra.io/2024/02/29/localized-variables.md)
303
+
304
+ ### Other Websites Built with Polyglot
305
+ Feel free to open a PR and list your multilingual blog here you may want to share:
306
+
307
+ * [**Polyglot project website**](https://polyglot.untra.io)
308
+ * [LogRhythm Corporate Website](https://logrhythm.com)
309
+ * [All Over Earth](https://allover.earth/)
310
+ * [Hanare Cafe in Toshijima, Japan](https://hanarecafe.com)
311
+ * [F-Droid](https://f-droid.org)
312
+ * [Ubuntu MATE](https://ubuntu-mate.org)
313
+ * [Leo3418 blog](https://leo3418.github.io/)
314
+ * [Gaphor](https://gaphor.org)
315
+ * [Yi Yunseok's personal blog website](https://Yi-Yunseok.GitHub.io)
316
+ * [Tarlogic Cybersecurity](https://www.tarlogic.com/)
317
+ * [A beautiful, simple, clean, and responsive Jekyll theme for academics](https://github.com/george-gca/multi-language-al-folio)
210
318
 
211
319
  ## 2.0 Roadmap
212
- * [ ] - **site language**: portuguese Brazil `pt-BR` `pt-PT`
213
- * [ ] - **site language**: portuguese Portugal `pt-BR` `pt-PT`
320
+ * [x] - **site language**: portuguese Brazil `pt-BR`
321
+ * [ ] - **site language**: portuguese Portugal `pt-PT`
214
322
  * [ ] - **site language**: arabic `ar`
215
323
  * [ ] - **site language**: japanese `ja`
216
324
  * [x] - **site language**: russian `ru`
@@ -218,7 +326,7 @@ If you have something you'd like to contribute to jekyll-polyglot, please open a
218
326
  * [x] - **site language**: korean `ko`
219
327
  * [x] - **site language**: hebrew `he`
220
328
  * [x] - **site language**: chinese China `zh-CN`
221
- * [ ] - **site language**: chinese Taiwan `zh_TW`
329
+ * [ ] - **site language**: chinese Taiwan `zh-TW`
222
330
  * [ ] - get whitelisted as an official github-pages jekyll plugin
223
331
  * [x] - update CI provider
224
332
 
@@ -12,6 +12,7 @@ module Jekyll
12
12
  def render(context)
13
13
  site = context.registers[:site]
14
14
  permalink = context.registers[:page]['permalink']
15
+ permalink_lang = context.registers[:page]['permalink_lang']
15
16
  site_url = @url.empty? ? site.config['url'] : @url
16
17
  i18n = "<meta http-equiv=\"Content-Language\" content=\"#{site.active_lang}\">\n"
17
18
  i18n += "<link rel=\"alternate\" hreflang=\"#{site.default_lang}\" "\
@@ -19,8 +20,9 @@ module Jekyll
19
20
  site.languages.each do |lang|
20
21
  next if lang == site.default_lang
21
22
 
23
+ url = permalink_lang && permalink_lang[lang] ? permalink_lang[lang] : permalink
22
24
  i18n += "<link rel=\"alternate\" hreflang=\"#{lang}\" "\
23
- "href=\"#{site_url}/#{lang}#{permalink}\"/>\n"
25
+ "href=\"#{site_url}/#{lang}/#{url}\"/>\n"
24
26
  end
25
27
  i18n
26
28
  end
@@ -13,7 +13,7 @@ module Jekyll
13
13
  @lang_from_path = config.fetch('lang_from_path', false)
14
14
  @exclude_from_localization = config.fetch('exclude_from_localization', []).map do |e|
15
15
  if File.directory?(e) && e[-1] != '/'
16
- e + '/'
16
+ "#{e}/"
17
17
  else
18
18
  e
19
19
  end
@@ -28,7 +28,7 @@ module Jekyll
28
28
  @lang_vars = config.fetch('lang_vars', [])
29
29
  end
30
30
 
31
- alias_method :process_orig, :process
31
+ alias process_orig process
32
32
  def process
33
33
  prepare
34
34
  all_langs = (@languages + [@default_lang]).uniq
@@ -43,13 +43,17 @@ module Jekyll
43
43
  while pids.length >= (lang == all_langs[-1] ? 1 : nproc)
44
44
  sleep 0.1
45
45
  pids.map do |lang, pid|
46
- pids.delete lang if waitpid pid, Process::WNOHANG
46
+ next unless waitpid pid, Process::WNOHANG
47
+
48
+ pids.delete lang
49
+ raise "Polyglot subprocess #{pid} (#{lang}) failed (#{$?.exitstatus})" unless $?.success?
47
50
  end
48
51
  end
49
52
  end
50
53
  rescue Interrupt
51
54
  all_langs.each do |lang|
52
55
  next unless pids.key? lang
56
+
53
57
  puts "Killing #{pids[lang]} : #{lang}"
54
58
  kill('INT', pids[lang])
55
59
  end
@@ -59,9 +63,10 @@ module Jekyll
59
63
  process_language lang
60
64
  end
61
65
  end
66
+ Jekyll::Hooks.trigger :polyglot, :post_write
62
67
  end
63
68
 
64
- alias_method :site_payload_orig, :site_payload
69
+ alias site_payload_orig site_payload
65
70
  def site_payload
66
71
  payload = site_payload_orig
67
72
  payload['site']['default_lang'] = default_lang
@@ -81,7 +86,8 @@ module Jekyll
81
86
  end
82
87
  if @active_lang == @default_lang
83
88
  then process_default_language
84
- else process_active_language
89
+ else
90
+ process_active_language
85
91
  end
86
92
  end
87
93
 
@@ -95,7 +101,7 @@ module Jekyll
95
101
  old_dest = @dest
96
102
  old_exclude = @exclude
97
103
  @file_langs = {}
98
- @dest = @dest + '/' + @active_lang
104
+ @dest = "#{@dest}/#{@active_lang}"
99
105
  @exclude += @exclude_from_localization
100
106
  process_orig
101
107
  @dest = old_dest
@@ -103,9 +109,10 @@ module Jekyll
103
109
  end
104
110
 
105
111
  def derive_lang_from_path(doc)
106
- if !@lang_from_path
112
+ unless @lang_from_path
107
113
  return nil
108
114
  end
115
+
109
116
  segments = doc.relative_path.split('/')
110
117
  if doc.relative_path[0] == '_' \
111
118
  && segments.length > 2 \
@@ -114,9 +121,9 @@ module Jekyll
114
121
  elsif segments.length > 1 \
115
122
  && segments[0] =~ /^[a-z]{2,3}(:?[_-](:?[A-Za-z]{2}){1,2}){0,2}$/
116
123
  return segments[0]
117
- else
118
- return nil
119
124
  end
125
+
126
+ nil
120
127
  end
121
128
 
122
129
  # assigns natural permalinks to documents and prioritizes documents with
@@ -130,20 +137,54 @@ module Jekyll
130
137
  lang = doc.data['lang'] || derive_lang_from_path(doc) || @default_lang
131
138
  lang_exclusive = doc.data['lang-exclusive'] || []
132
139
  url = doc.url.gsub(regex, '/')
133
- doc.data['permalink'] = url
140
+ page_id = doc.data['page_id'] || url
141
+ doc.data['permalink'] = url unless defined?(doc.data['permalink'])
142
+
143
+ # skip entirely if nothing to check
144
+ next if @file_langs.nil?
134
145
  # skip this document if it has already been processed
135
- next if @file_langs[url] == @active_lang
146
+ next if @file_langs[page_id] == @active_lang
136
147
  # skip this document if it has a fallback and it isn't assigned to the active language
137
- next if @file_langs[url] == @default_lang && lang != @active_lang
148
+ next if @file_langs[page_id] == @default_lang && lang != @active_lang
138
149
  # skip this document if it has lang-exclusive defined and the active_lang is not included
139
150
  next if !lang_exclusive.empty? && !lang_exclusive.include?(@active_lang)
140
151
 
141
- approved[url] = doc
142
- @file_langs[url] = lang
152
+ approved[page_id] = doc
153
+ @file_langs[page_id] = lang
143
154
  end
155
+ approved.values.each {|doc| assignPageRedirects(doc, docs) }
156
+ approved.values.each {|doc| assignPageLanguagePermalinks(doc, docs) }
144
157
  approved.values
145
158
  end
146
159
 
160
+ def assignPageRedirects(doc, docs)
161
+ pageId = doc.data['page_id']
162
+ if !pageId.nil? && !pageId.empty?
163
+ lang = doc.data['lang'] || derive_lang_from_path(doc) || @default_lang
164
+ langPrefix = lang === @default_lang ? '' : "#{lang}/"
165
+ redirectDocs = docs.select do |dd|
166
+ doclang = dd.data['lang'] || derive_lang_from_path(dd) || @default_lang
167
+ dd.data['page_id'] == pageId && doclang != lang && dd.data['permalink'] != doc.data['permalink']
168
+ end
169
+ redirects = redirectDocs.map { |dd| dd.data['permalink'] }
170
+ doc.data['redirect_from'] = redirects
171
+ end
172
+ end
173
+
174
+ def assignPageLanguagePermalinks(doc, docs)
175
+ pageId = doc.data['page_id']
176
+ if !pageId.nil? && !pageId.empty?
177
+ unless doc.data['permalink_lang'] then doc.data['permalink_lang'] = {} end
178
+ permalinkDocs = docs.select do |dd|
179
+ dd.data['page_id'] == pageId
180
+ end
181
+ permalinkDocs.each do |dd|
182
+ doclang = dd.data['lang'] || derive_lang_from_path(dd) || @default_lang
183
+ doc.data['permalink_lang'][doclang] = dd.data['permalink']
184
+ end
185
+ end
186
+ end
187
+
147
188
  # performs any necesarry operations on the documents before rendering them
148
189
  def process_documents(docs)
149
190
  # return if @active_lang == @default_lang
@@ -168,11 +209,11 @@ module Jekyll
168
209
  # made by jekyll when parsing documents without explicitly set permalinks
169
210
  def document_url_regex
170
211
  regex = ''
171
- @languages.each do |lang|
212
+ (@languages || []).each do |lang|
172
213
  regex += "([\/\.]#{lang}[\/\.])|"
173
214
  end
174
215
  regex.chomp! '|'
175
- %r{#{regex}}
216
+ /#{regex}/
176
217
  end
177
218
 
178
219
  # a regex that matches relative urls in a html document
@@ -190,7 +231,7 @@ module Jekyll
190
231
  end
191
232
  end
192
233
  start = disabled ? 'ferh' : 'href'
193
- %r{#{start}=\"?#{@baseurl}\/((?:#{regex}[^,'\"\s\/?\.]+\.?)*(?:\/[^\]\[\)\(\"\'\s]*)?)\"}
234
+ %r{#{start}="?#{@baseurl}/((?:#{regex}[^,'"\s/?.]+\.?)*(?:/[^\]\[)("'\s]*)?)"}
194
235
  end
195
236
 
196
237
  # a regex that matches absolute urls in a html document
@@ -208,11 +249,12 @@ module Jekyll
208
249
  end
209
250
  end
210
251
  start = disabled ? 'ferh' : 'href'
211
- %r{(?<!hreflang="#{@default_lang}" )#{start}=\"?#{url}#{@baseurl}\/((?:#{regex}[^,'\"\s\/?\.]+\.?)*(?:\/[^\]\[\)\(\"\'\s]*)?)\"}
252
+ %r{(?<!hreflang="#{@default_lang}" )#{start}="?#{url}#{@baseurl}/((?:#{regex}[^,'"\s/?.]+\.?)*(?:/[^\]\[)("'\s]*)?)"}
212
253
  end
213
254
 
214
255
  def relativize_urls(doc, regex)
215
256
  return if doc.output.nil?
257
+
216
258
  modified_output = doc.output.dup
217
259
  modified_output.gsub!(regex, "href=\"#{@baseurl}/#{@active_lang}/" + '\1"')
218
260
  doc.output = modified_output
@@ -220,6 +262,7 @@ module Jekyll
220
262
 
221
263
  def relativize_absolute_urls(doc, regex, url)
222
264
  return if doc.output.nil?
265
+
223
266
  modified_output = doc.output.dup
224
267
  modified_output.gsub!(regex, "href=\"#{url}#{@baseurl}/#{@active_lang}/" + '\1"')
225
268
  doc.output = modified_output
@@ -227,6 +270,7 @@ module Jekyll
227
270
 
228
271
  def correct_nonrelativized_absolute_urls(doc, regex, url)
229
272
  return if doc.output.nil?
273
+
230
274
  modified_output = doc.output.dup
231
275
  modified_output.gsub!(regex, "href=\"#{url}#{@baseurl}/" + '\1"')
232
276
  doc.output = modified_output
@@ -234,6 +278,7 @@ module Jekyll
234
278
 
235
279
  def correct_nonrelativized_urls(doc, regex)
236
280
  return if doc.output.nil?
281
+
237
282
  modified_output = doc.output.dup
238
283
  modified_output.gsub!(regex, "href=\"#{@baseurl}/" + '\1"')
239
284
  doc.output = modified_output
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-polyglot
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.0
4
+ version: 1.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Volin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-06-08 00:00:00.000000000 Z
11
+ date: 2024-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jekyll