{"id":13410595,"url":"https://github.com/untra/polyglot","last_synced_at":"2025-05-15T14:06:17.129Z","repository":{"id":41839863,"uuid":"43034994","full_name":"untra/polyglot","owner":"untra","description":":abc: Multilingual and i18n support tool for Jekyll Blogs","archived":false,"fork":false,"pushed_at":"2025-05-03T17:51:33.000Z","size":4067,"stargazers_count":453,"open_issues_count":19,"forks_count":68,"subscribers_count":11,"default_branch":"main","last_synced_at":"2025-05-12T08:28:06.920Z","etag":null,"topics":["i18n","jekyll","jekyll-blog","multi-language-blogs","polyglot","seo"],"latest_commit_sha":null,"homepage":"https://polyglot.untra.io","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/untra.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2015-09-24T00:31:22.000Z","updated_at":"2025-05-03T17:45:34.000Z","dependencies_parsed_at":"2023-10-12T04:22:51.421Z","dependency_job_id":"e9f7a38f-0191-4624-be1b-0390aa3c3806","html_url":"https://github.com/untra/polyglot","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/untra%2Fpolyglot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/untra%2Fpolyglot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/untra%2Fpolyglot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/untra%2Fpolyglot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/untra","download_url":"https://codeload.github.com/untra/polyglot/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254355335,"owners_count":22057354,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["i18n","jekyll","jekyll-blog","multi-language-blogs","polyglot","seo"],"created_at":"2024-07-30T20:01:07.864Z","updated_at":"2025-05-15T14:06:12.120Z","avatar_url":"https://github.com/untra.png","language":"HTML","funding_links":[],"categories":["Multi Language / Multi Lingual","HTML","Plugins","Ruby","Tools"],"sub_categories":["Favicon and other head element customizations","Libraries and tools for developers"],"readme":"🔤 Polyglot\n---\n[![Gem Version](https://badge.fury.io/rb/jekyll-polyglot.svg)](https://badge.fury.io/rb/jekyll-polyglot)\n[![CircleCI](https://circleci.com/gh/untra/polyglot/tree/master.svg?style=svg)](https://circleci.com/gh/untra/polyglot/?branch=master)\n[![codecov](https://codecov.io/gh/untra/polyglot/graph/badge.svg?token=AAIYBIxdWr)](https://codecov.io/gh/untra/polyglot)\n\n__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.\n\n## Why?\nJekyll 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.\n\n## Installation\nAdd jekyll-polyglot to your `Gemfile` if you are using Bundler:\n```Ruby\ngroup :jekyll_plugins do\n   gem \"jekyll-polyglot\"\nend\n```\n\nOr install the gem manually by doing `gem install jekyll-polyglot` and specify the plugin using `_config.yml`:\n```YAML\nplugins:\n  - jekyll-polyglot\n```\n\n## Configuration\nIn your `_config.yml` file, add the following preferences\n```YAML\nlanguages: [\"en\", \"sv\", \"de\", \"fr\"]\ndefault_lang: \"en\"\nexclude_from_localization: [\"javascript\", \"images\", \"css\", \"public\", \"sitemap\"]\nparallel_localization: true\nurl: https://polyglot.untra.io\n```\nThese configuration preferences indicate\n- what i18n languages you wish to support\n- what is your default \"fallback\" language for your content\n- what root level files/folders are excluded from localization, based 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.)\n- whether to run language processing in parallel or serial. Set to `false` if building on Windows hosts, or if Polyglot collides with other Jekyll plugins.\n- your jekyll website production url. Make sure this value is set; Polyglot requires this to relative site urls correctly, and to make functioning language switchers.\n\nThe optional `lang_from_path: true` option enables getting the page language from a filepath segment seperated by `/` or `.`, e.g `de/first-one.md`, or `_posts/zh_HK/use-second-segment.md` , if the lang frontmatter isn't defined.\n\n## How To Use It\nWhen adding new posts and pages, add to the YAML front matter:\n```\nlang: sv\n```\nor whatever appropriate [I18n language code](https://developer.chrome.com/docs/extensions/reference/api/i18n#locales)\nthe page should build for. And you're done. Ideally, when designing your site, you should\norganize files by their relative urls.\n\nYou 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).\n\nPolyglot 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:\n```\n_posts/2010-03-01-salad-recipes-en.md\n_posts/2010-03-01-salad-recipes-sv.md\n_posts/2010-03-01-salad-recipes-fr.md\n```\n\nOrganized names will generate consistent permalinks when the post is rendered, and Polyglot will know to build separate language versions of\nthe website using only the files with the correct `lang` variable in the front matter.\n\nIn short:\n* Be consistent with how you name and place your *posts* files\n* Always give your *pages* permalinks in the frontmatter\n* Don't overthink it, :wink:\n\n\n### Translation permalink information in page\n_New in 1.8.0_\n\nWhenever `page_id` frontmatter properties are used to identify translations, permalink information for the available languages is available in `permalink_lang`.\nThis is useful in order to generate language menus and even localization meta information without redirects!\n\nSample code for meta link generation:\n```\n{% for lang in site.languages %}\n  {% capture lang_href %}{{site.baseurl}}/{% if lang != site.default_lang %}{{ lang }}/{% endif %}{% if page.permalink_lang[lang] != '/' %}{{page.permalink_lang[lang]}}{% endif %}{% endcapture %}\n  \u003clink rel=\"alternate\" hreflang=\"{{ lang }}\" {% static_href %}href=\"{{ lang_href }}\"{% endstatic_href %} /\u003e\n{% endfor %}\n```\n\n\n#### Using different permalinks per language\n_New in 1.7.0_\n\nOptionally, for those who may want different URLs on different languages, translations may be identified by specifying a `page_id` in the frontmatter.\n\nIf available, Polyglot will use `page_id` to identify the page, and will default to the `permalink` otherwise.\n\nAs 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:\n```md\n---\ntitle: About\npermalink: /about\nlang: en\npage_id: about\n---\nThis is us!\n```\n\n```md\n---\ntitle: Acerca de\npermalink: /acerca-de\nlang: es\npage_id: about\n---\nEstos somos nosotros!\n```\n\nAdditionally, if you are also using the `jekyll-redirect-from` plugin, pages coordinated this way will automatically have redirects created between pages.\nSo `/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).\n\n#### Fallback Language Support\nLets say you are building your website. You have an `/about/` page written in *english*, *german* and\n*swedish*. You are also supporting a *french* website, but you never designed a *french* version of your `/about/` page!\n\nNo 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.\n\n### Relativized Local Urls\nNo 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.\n```md\n---\ntitle: au sujet de notre entreprise\npermalink: /about/\nlang: fr\n---\nNous sommes un restaurant situé à Paris . [Ceci est notre menu.](/menu/)\n```\nbecomes\n```html\n\u003cheader class=\"post-header\"\u003e\n  \u003ch1 class=\"post-title\"\u003eau sujet de notre entreprise\u003c/h1\u003e\n\u003c/header\u003e\n\n\u003carticle class=\"post-content\"\u003e\n  \u003cp\u003eNous sommes un restaurant situé à Paris . \u003ca href=\"/fr/menu/\"\u003eCeci est notre menu.\u003c/a\u003e\u003c/p\u003e\n\u003c/article\u003e\n```\nNotice the link `\u003ca href=\"/fr/menu/\"\u003e...` directs to the french website.\n\nEven if you are falling back to `default_lang` page, relative links built on the *french* site will still link to *french* pages.\n\n### Relativized Absolute Urls\nIf you defined a site `url` in your `_config.yaml`, Polyglot will automatically relativize absolute links pointing to your website directory:\n\n```md\n---\nlang: fr\n---\nCliquez [ici]({{site.url}}) pour aller à l'entrée du site.\n```\nbecomes\n```html\n\u003cp\u003eCliquez \u003ca href=\"https://mywebsite.com/fr/\"\u003eici\u003c/a\u003e pour aller à l'entrée du site.\n```\n\n### Disabling Url Relativizing\n_New in 1.4.0_\nIf 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:\n\n```html\n{% static_href %}href=\"...\"{% endstatic_href %}\n```\n\n```html\n\u003ca {% static_href %}href=\"/about\"{% endstatic_href %}\u003eclick this static link\u003c/a\u003e\n```\n\nthat will generate `\u003ca href=\"/about\"\u003eclick this static link\u003c/a\u003e` which is what you would normally use to create a url unmangled by invisible language relativization.\n\nCombine with a [html minifier](https://github.com/digitalsparky/jekyll-minifier) for a polished and production ready website.\n\n### Exclusive site language generation\n_New in 1.4.0_\n\nIf 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.\n\nFor Example, the following frontmatter will only generate in the `en` and `fr` site language builds:\n```\n---\nlang-exclusive: ['en', 'fr']\n---\n```\n\n### Localized site.data\nThere 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.\n\nTo 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:\n\n`_data/en/strings.yml`\n```yaml\nhello: \"Hello\"\ngreetings:\n  morning: \"Good morning\"\n  evening: \"Good evening\"\n```\n\n`_data/pt-br/strings.yml`\n```yaml\nhello: \"Olá\"\ngreetings:\n  morning: \"Bom dia\"\n  evening: \"Boa noite\"\n```\n\nYou can use the `site.data` to access the localized content in your layouts and pages:\n\n```liquid\n\u003cp\u003e{{ site.data[site.active_lang].strings.hello }}, {{ site.data[site.active_lang].strings.greetings.morning }}\u003c/p\u003e\n```\n\nFor more information on this matter, check out this [post](https://polyglot.untra.io/2024/02/29/localized-variables/).\n\n### Localized collections\n\nTo 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:\n\n```yaml\ncollections:\n  projects:\n    output: true\n    permalink: /:collection/:title/\n```\n\nNote 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.\n\n## How It Works\nThis 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.\n\n`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.\n\n### (:polyglot, :post_write) hook\n_New in 1.8.0_\nPolyglot 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:\n\n```rb\nJekyll::Hooks.register :polyglot, :post_write do |site|\n  # do something custom and cool here!\nend\n```\n\n### Machine-aware site building\n_New in 1.5.0_\n\nPolyglot 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.\n\n### Writing Tests and Debugging\n_: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._\n\nTests are run with `test.sh`. Tests are in the `/spec` directory, and test failure output detail can be examined in the `rspec.json` file. Code Coverage details are in the the `coverage` directory.\n\n## Features\nThis plugin stands out from other I18n Jekyll plugins.\n- automatically corrects your relative links, keeping your *french* visitors on your *french* website, even when content has to fallback to the `default_lang`.\n- builds all versions of your website *simultaneously*, allowing big websites to scale efficiently.\n- provides the liquid tag `{{ site.languages }}` to get an array of your I18n strings.\n- provides the liquid tag `{{ site.default_lang }}` to get the default_lang I18n string.\n- provides the liquid tag `{{ site.active_lang }}` to get the I18n language string the website was built for. Alternative names for `active_lang` can be configured via `config.lang_vars`.\n- provides the liquid tag `{{ I18n_Headers }}` to append SEO bonuses to your website.\n- provides the liquid tag `{{ Unrelativized_Link href=\"/hello\" }}` to make urls that do not get influenced by url correction regexes.\n- provides `site.data` localization for efficient rich text replacement.\n- a creator that will answer all of your questions and issues.\n\n## SEO Recipes\nJekyll-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!\n\n### Sitemap generation\n\nSee 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.\n\nThe [official Sitemap protocol documentation](https://www.sitemaps.org/protocol.html#location) states:\n\u003e \"The location of a Sitemap file determines the set of URLs that can be included in that Sitemap. A Sitemap file located at http://example.com/catalog/sitemap.xml can include any URLs starting with http://example.com/catalog/ but can not include URLs starting with http://example.com/images/.\"\n\n\u003e \"It is strongly recommended that you place your Sitemap at the root directory of your web server.\"\n\nTo comply with this, 'sitemap.xml' should be added to the 'exclude_from_localization' list to ensure that only one `sitemap.xml` file exists in the root directory, rather than creating separate ones for each language.\n\n## Compatibility\nCurrently supports Jekyll 3.0 , and Jekyll 4.0\n* Windows users will need to disable parallel_localization on their machines by setting `parallel_localization: false` in the `_config.yml`\n* In Jekyll 4.0 , SCSS source maps will generate improperly due to how Polyglot operates. The workaround is to disable the CSS sourcemaps. Adding the following to your `config.yml` will disable sourcemap generation:\n```yaml\nsass:\n    sourcemap: never\n```\n\n## Contributions\nPlease! I need all the support I can get! 🙏\n\nBut 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!\nIf you have something you'd like to contribute to jekyll-polyglot, please open a PR!\n\n### Contributors\nThese are talented and considerate software developers across the world that have lent their support to this project.\n**Thank You! ¡Gracias! Merci! Danke! 감사합니다! תודה רבה! Спасибо! Dankjewel! 谢谢！Obrigado!**\n\n* [@yunseo-kim](https://github.com/yunseo-kim) [improved i18n sitemaps]((https://polyglot.untra.io/2025/01/18/polyglot-1.9.0/))\n* [@blackpill](https://github.com/blackpill) [1.8.1](https://polyglot.untra.io/2024/08/18/polyglot-1.8.1/)\n* [@hacketiwack](https://github.com/hacketiwack) [1.8.1](https://polyglot.untra.io/2024/08/18/polyglot-1.8.1/)\n* [@jerturowetz](https://github.com/jerturowetz) [sitemap generation](https://polyglot.untra.io/2024/03/17/polyglot-1.8.0/)\n* [@antoniovazquezblanco](https://github.com/antoniovazquezblanco) [1.7.0](https://polyglot.untra.io/2023/10/29/polyglot-1.7.0/)\n* [@salinatedcoffee](https://github.com/SalinatedCoffee) [ko support](https://polyglot.untra.io/ko/2023/02/27/korean-support/)\n* [@aturret](https://github.com/aturret) [zh-CN support](https://polyglot.untra.io/zh-CN/2023/06/08/polyglot-1.6.0-chinese-support/)\n* [@dougieh](https://github.com/dougieh) [1.5.1](https://polyglot.untra.io/2022/10/01/polyglot-1.5.1/)\n* [@pandermusubi](https://github.com/PanderMusubi) [nl support](https://polyglot.untra.io/nl/2022/01/15/dutch-site-support/)\n* [@obfusk](https://github.com/obfusk) [1.5.0](https://polyglot.untra.io/2021/07/17/polyglot-1.5.0/)\n* [@eighthave](https://github.com/eighthave) [1.5.0](https://polyglot.untra.io/2021/07/17/polyglot-1.5.0/)\n* [@george-gca](https://github.com/george-gca) [pt-BR support](https://polyglot.untra.io/pt-BR/2024/02/29/localized-variables.md)\n\n### Other Websites Built with Polyglot\nFeel free to open a PR and list your multilingual blog here you may want to share:\n\n* [**Polyglot project website**](https://polyglot.untra.io)\n* [LogRhythm Corporate Website](https://logrhythm.com)\n* [All Over Earth](https://allover.earth/)\n* [Hanare Cafe in Toshijima, Japan](https://hanarecafe.com)\n* [F-Droid](https://f-droid.org)\n* [Ubuntu MATE](https://ubuntu-mate.org)\n* [Leo3418 blog](https://leo3418.github.io/)\n* [Gaphor](https://gaphor.org)\n* [Yi Yunseok's personal blog website](https://Yi-Yunseok.GitHub.io)\n* [Tarlogic Cybersecurity](https://www.tarlogic.com/)\n* [A beautiful, simple, clean, and responsive Jekyll theme for academics](https://github.com/george-gca/multi-language-al-folio)\n* [AnotherTurret just another study note blog](https://aturret.space/)\n* [Diciotech is a collaborative online tech dictionary](https://diciotech.netlify.app/)\n* [Yunseo Kim's Study Notes](https://www.yunseo.kim/)\n\n## 2.0 Roadmap\n* [x] - **site language**: portuguese Brazil `pt-BR`\n* [ ] - **site language**: portuguese Portugal `pt-PT`\n* [ ] - **site language**: arabic `ar`\n* [ ] - **site language**: japanese `ja`\n* [x] - **site language**: russian `ru`\n* [x] - **site language**: dutch `nl`\n* [x] - **site language**: korean `ko`\n* [x] - **site language**: hebrew `he`\n* [x] - **site language**: chinese China `zh-CN`\n* [ ] - **site language**: chinese Taiwan `zh-TW`\n* [ ] - get whitelisted as an official github-pages jekyll plugin\n* [x] - update CI provider\n\n## Copyright\nCopyright (c) Samuel Volin 2025. License: MIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funtra%2Fpolyglot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Funtra%2Fpolyglot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funtra%2Fpolyglot/lists"}