jekyll-l10n 1.2.8 → 1.3.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 +4 -4
- data/README.md +43 -63
- data/lib/jekyll-l10n/constants.rb +6 -1
- data/lib/jekyll-l10n/jekyll/generator.rb +12 -0
- data/lib/jekyll-l10n/jekyll/post_write_processor.rb +13 -0
- data/lib/jekyll-l10n/translation/html_translator.rb +2 -2
- data/lib/jekyll-l10n/utils/page_locales_config.rb +6 -5
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7fa24f781e7892870dbdd97d38606b511024be5d0bf026ff4f9fca0b4d680738
|
|
4
|
+
data.tar.gz: 298e9757f9dd189fdc41d5c545e019c4f2a82a607512944efa31ac61df639100
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6153450cfcf936014afac2e2c96aa7d6be1b6995de8c03c7551a329bdad32ae7f4b353bd82068e14aa64b6612bfdfa0f69a53bfabcf850a5401e43f097bf02c8
|
|
7
|
+
data.tar.gz: a366a109b99e560a8ec305a1a0db3807dbdc903d2a45007f47382d2a5f7a19a13ce8de7b7eb2010a933bcd9ac72b2016e49e65c890c7b98e29eea6602e9c420c
|
data/README.md
CHANGED
|
@@ -1,85 +1,65 @@
|
|
|
1
1
|
# jekyll-l10n
|
|
2
2
|
|
|
3
|
-
`jekyll-l10n` is a Jekyll plugin that streamlines the localization of static
|
|
4
|
-
websites using industry-standard GNU Gettext PO files. Creating multilingual
|
|
5
|
-
sites presents unique challenges: maintaining consistent translations across
|
|
6
|
-
multiple pages, managing translation workflows with non-technical translators,
|
|
7
|
-
and keeping translations synchronized as content evolves. This plugin automates
|
|
8
|
-
these challenges by integrating the proven Gettext workflow directly into your
|
|
9
|
-
Jekyll build pipeline.
|
|
10
|
-
|
|
11
|
-
The plugin works by extracting translatable strings from your site's generated
|
|
12
|
-
HTML and organizing them into PO files that translators can edit using standard
|
|
13
|
-
translation tools. As your content changes, the plugin intelligently updates
|
|
14
|
-
these translation files, preserving existing translations while flagging
|
|
15
|
-
changed or new content. When you rebuild your site, translated strings are
|
|
16
|
-
automatically applied to localized versions of your pages, producing fully
|
|
17
|
-
translated HTML output with locale-prefixed URLs.
|
|
3
|
+
`jekyll-l10n` is a Jekyll plugin that streamlines the localization of static websites using industry-standard GNU Gettext PO files. It extracts translatable strings from your site's HTML, organizes them into PO files for professional translation, and automatically applies translations to generate fully localized pages with locale-prefixed URLs.
|
|
18
4
|
|
|
19
5
|

|
|
20
6
|
|
|
21
|
-
|
|
22
|
-
prefixes, flexible fallback modes when translations are incomplete (display
|
|
23
|
-
original English, mark untranslated strings, or leave blank), and support for
|
|
24
|
-
compendium files to share common translations across your site. By leveraging
|
|
25
|
-
the standard Gettext format and workflow, `jekyll-l10n` enables collaboration
|
|
26
|
-
with professional translators and integrates with existing translation
|
|
27
|
-
management systems, while keeping your source content in Markdown where it
|
|
28
|
-
belongs.
|
|
7
|
+
## Installation
|
|
29
8
|
|
|
30
|
-
|
|
9
|
+
Add to your Jekyll site's `Gemfile`:
|
|
31
10
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
bundle install # Install Ruby dependencies
|
|
36
|
-
pip install pre-commit # Install pre-commit framework
|
|
37
|
-
pre-commit install # Install pre-commit hooks
|
|
11
|
+
```ruby
|
|
12
|
+
gem "jekyll-l10n", "~> 1.1"
|
|
38
13
|
```
|
|
39
14
|
|
|
40
|
-
|
|
15
|
+
Run `bundle install`, then enable in `_config.yml`:
|
|
41
16
|
|
|
42
|
-
|
|
17
|
+
```yaml
|
|
18
|
+
plugins:
|
|
19
|
+
- jekyll-l10n
|
|
20
|
+
|
|
21
|
+
defaults:
|
|
22
|
+
- scope:
|
|
23
|
+
type: "pages"
|
|
24
|
+
values:
|
|
25
|
+
with_locales: true
|
|
26
|
+
with_locales_data:
|
|
27
|
+
locales: ["es", "fr", "de"]
|
|
28
|
+
locales_dir: "_locales"
|
|
29
|
+
extract_on_build: true
|
|
30
|
+
```
|
|
43
31
|
|
|
44
|
-
|
|
32
|
+
## Quick Example
|
|
45
33
|
|
|
46
|
-
|
|
47
|
-
sites with many locales, this can impact build performance. You can enable
|
|
48
|
-
incremental build support to skip regenerating pages that haven't changed:
|
|
34
|
+
Edit PO files in `_locales/` with translations. On rebuild, your site will generate:
|
|
49
35
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
incremental: true # Enable incremental builds
|
|
54
|
-
```
|
|
36
|
+
- `/es/` - Spanish pages
|
|
37
|
+
- `/fr/` - French pages
|
|
38
|
+
- `/de/` - German pages
|
|
55
39
|
|
|
56
|
-
|
|
40
|
+
## Documentation
|
|
57
41
|
|
|
58
|
-
|
|
59
|
-
localization_gettext:
|
|
60
|
-
incremental: true
|
|
61
|
-
```
|
|
42
|
+
Complete documentation is available in the [docs/](docs/) directory:
|
|
62
43
|
|
|
63
|
-
|
|
44
|
+
- **[Getting Started](docs/getting-started/)** - Installation requirements and first-site setup
|
|
45
|
+
- **[Configuration Guide](docs/configuration/)** - All configuration options and settings
|
|
46
|
+
- **[Guides](docs/guides/)** - Fallback modes, Liquid filters, machine translation, incremental builds
|
|
47
|
+
- **[Development](docs/development/)** - Setup, testing, API documentation
|
|
48
|
+
- **[Examples](docs/examples/)** - Real-world usage examples
|
|
64
49
|
|
|
65
|
-
|
|
66
|
-
- Any PO translation files have been updated
|
|
67
|
-
- The Jekyll configuration has changed
|
|
50
|
+
## Key Features
|
|
68
51
|
|
|
69
|
-
|
|
70
|
-
translations
|
|
52
|
+
- **Automatic extraction** - Extract translatable strings during Jekyll builds
|
|
53
|
+
- **Professional workflows** - Edit translations using standard Gettext tools (Poedit, Weblate, etc.)
|
|
54
|
+
- **Fallback modes** - Display English, mark untranslated strings, or leave blank
|
|
55
|
+
- **Incremental builds** - Skip regenerating unchanged localized pages for faster builds
|
|
56
|
+
- **Machine translation** - Optional LibreTranslate integration for initial translations
|
|
57
|
+
- **Compendium files** - Share common translations across your entire site
|
|
71
58
|
|
|
72
|
-
##
|
|
59
|
+
## Requirements
|
|
73
60
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
automatically translate newly extracted strings during the extraction workflow.
|
|
77
|
-
You can enable this optional integration on a per-locale basis, allowing
|
|
78
|
-
LibreTranslate to generate initial translations for compendia files that serve
|
|
79
|
-
as a foundation for professional translators to refine. This significantly
|
|
80
|
-
reduces the initial translation effort and helps bootstrap localization for new
|
|
81
|
-
content, though professional review is still recommended for
|
|
82
|
-
publication-quality results.
|
|
61
|
+
- **Ruby**: >= 2.7.0
|
|
62
|
+
- **Jekyll**: >= 4.0, < 5.0
|
|
83
63
|
|
|
84
64
|
## License
|
|
85
65
|
|
|
@@ -88,7 +68,7 @@ MIT License - see LICENSE file for details.
|
|
|
88
68
|
## Contributing
|
|
89
69
|
|
|
90
70
|
1. Fork the repository
|
|
91
|
-
2. Create
|
|
71
|
+
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
92
72
|
3. Commit your changes (`git commit -m 'feat: Add amazing feature'`)
|
|
93
73
|
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
94
74
|
5. Open a Pull Request
|
|
@@ -30,7 +30,7 @@ module Jekyll
|
|
|
30
30
|
# @return [String] "english"
|
|
31
31
|
FALLBACK_MODE_ENGLISH = "english"
|
|
32
32
|
|
|
33
|
-
# Fallback mode: wrap untranslated text with markers (e.g., "[UNTRANSLATED
|
|
33
|
+
# Fallback mode: wrap untranslated text with markers (e.g., "[UNTRANSLATED] text")
|
|
34
34
|
# @return [String] "marker"
|
|
35
35
|
FALLBACK_MODE_MARKER = "marker"
|
|
36
36
|
|
|
@@ -94,6 +94,11 @@ module Jekyll
|
|
|
94
94
|
|
|
95
95
|
# ## LibreTranslate Integration Defaults
|
|
96
96
|
|
|
97
|
+
# Default LibreTranslate API endpoint URL
|
|
98
|
+
# Uses localhost:5000 as default for local development
|
|
99
|
+
# @return [String] "http://localhost:5000"
|
|
100
|
+
DEFAULT_LIBRETRANSLATE_API_URL = "http://localhost:5000"
|
|
101
|
+
|
|
97
102
|
# Default timeout (in seconds) for LibreTranslate API requests
|
|
98
103
|
# @return [Integer] 300 seconds (5 minutes)
|
|
99
104
|
DEFAULT_LIBRETRANSLATE_TIMEOUT = 300
|
|
@@ -42,10 +42,14 @@ module Jekyll
|
|
|
42
42
|
# It iterates through all pages in the site, identifies those marked for localization,
|
|
43
43
|
# and creates locale-specific variants.
|
|
44
44
|
#
|
|
45
|
+
# Returns early with no output if no pages are marked for localization.
|
|
46
|
+
#
|
|
45
47
|
# @param site [Jekyll::Site] The Jekyll site object containing pages to process
|
|
46
48
|
# @return [void]
|
|
47
49
|
# @see LocalizedPage for details on page structure
|
|
48
50
|
def generate(site)
|
|
51
|
+
return unless any_pages_to_localize?(site)
|
|
52
|
+
|
|
49
53
|
Jekyll.logger.info "Localization", "Generating localized pages..."
|
|
50
54
|
generate_localized_pages(site)
|
|
51
55
|
end
|
|
@@ -117,6 +121,14 @@ module Jekyll
|
|
|
117
121
|
|
|
118
122
|
locale.match?(%r!^[a-z]{2}(_[A-Z]{2})?$!)
|
|
119
123
|
end
|
|
124
|
+
|
|
125
|
+
# Check if any pages in the site are marked for localization
|
|
126
|
+
#
|
|
127
|
+
# @param site [Jekyll::Site] The Jekyll site object
|
|
128
|
+
# @return [Boolean] True if at least one page has with_locales set to true
|
|
129
|
+
def any_pages_to_localize?(site)
|
|
130
|
+
site.pages.any? { |page| page.data["with_locales"] == true }
|
|
131
|
+
end
|
|
120
132
|
end
|
|
121
133
|
end
|
|
122
134
|
end
|
|
@@ -54,9 +54,13 @@ module Jekyll
|
|
|
54
54
|
# 2. Updates PO files with new entries and modified translations
|
|
55
55
|
# 3. If PO files were created or updated, reprocess localized pages to apply translations
|
|
56
56
|
#
|
|
57
|
+
# Returns early with no output if no pages are marked for localization.
|
|
58
|
+
#
|
|
57
59
|
# @return [void]
|
|
58
60
|
# @note This is automatically called by Jekyll's site:post_write hook
|
|
59
61
|
def process_localizations
|
|
62
|
+
return unless any_pages_localized?
|
|
63
|
+
|
|
60
64
|
extractor = Extractor.new(@site)
|
|
61
65
|
extraction_result = extractor.extract_site
|
|
62
66
|
|
|
@@ -66,6 +70,15 @@ module Jekyll
|
|
|
66
70
|
reprocessor.reprocess_localized_pages
|
|
67
71
|
end
|
|
68
72
|
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
# Check if any pages in the site are marked for localization
|
|
77
|
+
#
|
|
78
|
+
# @return [Boolean] True if at least one page has with_locales set to true
|
|
79
|
+
def any_pages_localized?
|
|
80
|
+
@site.pages.any? { |page| page.data["with_locales"] == true }
|
|
81
|
+
end
|
|
69
82
|
end
|
|
70
83
|
end
|
|
71
84
|
end
|
|
@@ -160,9 +160,9 @@ module Jekyll
|
|
|
160
160
|
# Example: "Hello World" -> "Hello World" (if no translation found)
|
|
161
161
|
#
|
|
162
162
|
# 2. :marker
|
|
163
|
-
# Wraps text with visible marker "[UNTRANSLATED
|
|
163
|
+
# Wraps text with visible marker "[UNTRANSLATED] ..."
|
|
164
164
|
# Best for: QA/Development - clearly identifies missing translations
|
|
165
|
-
# Example: "Hello World" -> "[UNTRANSLATED
|
|
165
|
+
# Example: "Hello World" -> "[UNTRANSLATED] Hello World"
|
|
166
166
|
# Why: Stakeholders can see exactly which content needs translation
|
|
167
167
|
#
|
|
168
168
|
# 3. :empty
|
|
@@ -215,9 +215,9 @@ module Jekyll
|
|
|
215
215
|
#
|
|
216
216
|
# Example: "https://api.libretranslate.de" or "http://localhost:5000"
|
|
217
217
|
#
|
|
218
|
-
# @return [String
|
|
218
|
+
# @return [String] The API URL (default: "http://localhost:5000")
|
|
219
219
|
def libretranslate_api_url
|
|
220
|
-
libretranslate_config["libretranslate_api_url"]
|
|
220
|
+
libretranslate_config["libretranslate_api_url"] || Constants::DEFAULT_LIBRETRANSLATE_API_URL
|
|
221
221
|
end
|
|
222
222
|
|
|
223
223
|
# Get the LibreTranslate API key (if required)
|
|
@@ -267,10 +267,11 @@ module Jekyll
|
|
|
267
267
|
# If true, any API error will halt the translation process. If false, errors are logged
|
|
268
268
|
# but translation continues with other entries.
|
|
269
269
|
#
|
|
270
|
-
# @return [Boolean] true if errors should stop translation
|
|
271
|
-
# translation continues
|
|
270
|
+
# @return [Boolean] true if errors should stop translation, false if
|
|
271
|
+
# translation continues (default: false)
|
|
272
272
|
def libretranslate_stop_on_error?
|
|
273
|
-
libretranslate_config["libretranslate_stop_on_error"]
|
|
273
|
+
val = libretranslate_config["libretranslate_stop_on_error"]
|
|
274
|
+
val.nil? ? Constants::DEFAULT_LIBRETRANSLATE_STOP_ON_ERROR : val != false
|
|
274
275
|
end
|
|
275
276
|
|
|
276
277
|
# Get the interval for logging LibreTranslate translation progress
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jekyll-l10n
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- ReleaseBot
|
|
@@ -55,7 +55,7 @@ dependencies:
|
|
|
55
55
|
requirements:
|
|
56
56
|
- - ">="
|
|
57
57
|
- !ruby/object:Gem::Version
|
|
58
|
-
version: '1.
|
|
58
|
+
version: '1.12'
|
|
59
59
|
- - "<"
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
61
|
version: '2.0'
|
|
@@ -65,7 +65,7 @@ dependencies:
|
|
|
65
65
|
requirements:
|
|
66
66
|
- - ">="
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '1.
|
|
68
|
+
version: '1.12'
|
|
69
69
|
- - "<"
|
|
70
70
|
- !ruby/object:Gem::Version
|
|
71
71
|
version: '2.0'
|