untra/polyglot

Collections

ctsstc opened this issue ยท 17 comments

Documentation

Jekyll

I'm following the documentation for how collections are handled here:

Polyglot

There does not seem to be any documentation around how to handle collections in Polyglot.

Research

I did find these issues:

Configuration

I've included lang in the front matter, but the given page continues to render English/default for the included collection.

We do have have the output: true for those collections so they do end up in the build of the site, but as for including them as described in the Jekyll documentation, does not seem to work unfortunately.

We're also utilizing the manual ordering which points to a direct document:

?ยฟ

I'm wondering what the best way to go about this is?

Some Thoughts...

  • Should I transition everything to data?
  • What if we need those outputted directories?
  • I could include all of those and use the regex filter to filter out on language, this feels hacky, but might be the best short-term fix, but then we also lose defaulting capabilities.

Expectations

There's a couple of interesting issues that collections bring up that I would expect them to behave a certain way.

Build Outputting

You can apply a layout to collections so that those pages are output against a template during build time. Currently if you have something like _collections/_posts/some-post.md and _collections/_posts/some-post-zh.md it will build that out, but we end up with some oddities because we'll have all of these files:

  • /posts/some-post (displays in English)
  • /posts/some-post-zh (displays in Chinese) ๐Ÿคท
  • /zh/posts/some-post (displays in English) ๐Ÿ‘Ž
  • /zh/posts/some-post-zh (displays in Chinese) -- prefixed and suffixed ๐Ÿ‘Ž

I would expect there to only be the following:

  • /posts/some-post
  • /zh/posts/some-post

Includes Outputting

https://jekyllrb.com/docs/collections/#output

I would expect it to pull the associated language when utilizing the globals, or to have some escape hatch to access them.

{% for staff_member in site.staff_members %}
  <h2>{{ staff_member.name }} - {{ staff_member.position }}</h2>
  <p>{{ staff_member.content | markdownify }}</p>
{% endfor %}

My current hacky method is something like this:

{% assign filtered-portfolio = site.portfolio | where_exp:"item","item.profile-status != 'hidden' and item.lang == 'en'" %}

{% for item in filtered-portfolio %}
  {% include portfolio-card.html %}
{% endfor %}

I also then need to add the other language file to the configuration for sorting purposes as well under: _config.yml collections.portfolio.order.

I was able to implement this. Take a look at my template site, where I have the projects collection.

@george-gca was there anything special you had to do to get this to work?

I was checking out the config and the localization-exists plugin (I imagine that's not required though? but wasn't sure what that's doing).

Thanks for posting your template site, it seems to be quite feature loaded ๐Ÿ’ฏ ๐Ÿ™

I just realized that in my template the projects are correctly translated, but when I try to change languages inside one of them it fails. I will fix this and come back to explain it more thoroughly.

I noticed you are running the Jekyll serve it seems for the docker container. I was was interested if that's just for development purposes? I was able to grab all the dependencies on my Mac and get your site to build out.

It does seem that your pt-br projects directory builds out like: /pt-br/projects/pt-br/ which is likely an issue.

The other part that kind of felt odd to me was seeing /projects/en-us/ Shouldn't it drop the en-us since it's the default language?

image

Ok I just fixed it. And yes, docker here is for development purposes. It is easier to ensure you have the right versions of the libraries and everything with a docker image.

I have in my template 2 custom collections: news and projects, as you can see here.

To make it work, what I did was:

  1. Add the collections to _config.yml. Note that the permalink here is important. I added it as:
collections:
  news:
    defaults:
      layout: post
    output: true
    permalink: /:collection/:title/
  projects:
    output: true
    permalink: /:collection/:title/
  1. Create the collections, for example, projects, with one subdir per language. In my case, for the project 1 page, I needed to create _projects/en-us/1_project.md and _projects/pt-br/1_project.md. In both files' frontmatter I added:
---
page_id: project_1
---
  1. Note that I didn't use any language in the frontmatter. The language is going to be defined by its path, since I added lang_from_path: true to my _config.yml from polyglot configuration. The code will know which file to select for the translation based on the page_id variable here.

Thanks for all the help on this. I'm finding this commit quite useful as well: george-gca/multi-language-al-folio@5bb365a

This is also helping answer a question that I've had that didn't seem to be documented for Polyglot either which is having a centralized i18n file like I'm used to with so many other languages/libraries, so that I don't have to duplicate templates everywhere for each language which would result in a ton of duplication and a pain maintaining/changing later on ie: _data/en-us/strings.yml.

I'm rather new to Jekyll so seeing stuff like: george-gca/multi-language-al-folio@c1f1684 or the how you handled plugins to give additional functionality to liquid is super helpful as well thank you ^__^

This definitely look much better! ๐ŸŽ‰
image

Thanks for all the help on this. I'm finding this commit quite useful as well: george-gca/multi-language-al-folio@5bb365a

This was the commit where I fixed the issue lol.

This is also helping answer a question that I've had that didn't seem to be documented for Polyglot either which is having a centralized i18n file like I'm used to with so many other languages/libraries, so that I don't have to duplicate templates everywhere for each language which would result in a ton of duplication and a pain maintaining/changing later on ie: _data/en-us/strings.yml.

I recently answered questions about this here and here. This was how I used to do with the previous multi language plugin that was discontinued. I decided to still do it like this in some places, while in other places it makes more sense to use the translated string directly.

I'm rather new to Jekyll so seeing stuff like: george-gca/multi-language-al-folio@c1f1684 or the how you handled plugins to give additional functionality to liquid is super helpful as well thank you ^__^

You're welcome. Check the blog posts in the template demo, it is the best way to check what kind of stuff you can add to your site. In the end most of the stuff we added to the template is "web stuff" (not jekyll or ruby related). We only use liquid to include or not some specific code needed to make these libraries work. This helps avoid for example including mermaid.js in the about page, where we don't need it.

I was wondering with this bit of code, is it necessary to use the lookup, I didn't have to do that elsewhere, or is this specific to collections?

<a id="{{ site.data[site.active_lang].strings.categories[category] }}" href=".#{{ site.data[site.active_lang].strings.categories[category] }}">

george-gca/multi-language-al-folio@5bb365a#diff-9f395b13d19af022840e74dd2cb4da4750d8818e6a41fad57ceae24f29cb5e7cR18

My Example

When I first started adding multiple languages to the navigation on the project I'm working on all I had to do was the following and it seems to pull the proper language without a code change.

Add Files

  • /_data/navigation.yml
  • /_data/zh/navigation.yml

No Change in Code ๐Ÿช„

{% for item in site.data.navigation %}

@untra I can add my answers to the documentation. Where should I put them? In the site, in the README, or both?

That specific code is responsible for the localization of the projects' categories, which in this screenshot is trabalho:
image

I decided to make all localizations that are in layouts that should be shared between multiple pages to be made that way, using the strings.yml solution.

So far my i18n journey is going much better thanks to your example.

One thing to note, it does seem that it will grab the proper language for a collection if it exists when iterating through it with a for, but it does not seem to update the url on the collection item unfortunately.

What do you mean?

Collection URLs

In this scenario the URL is always the default/english version for me, but it will pull, the translation for the item.title.

{% for item in filtered-portfolio %} 
	<a href="{{ item.url }}">item.title</a>
{% endfor %}

In my scenario we are firing off an AJAX request for the given URL, so I was able to pass along the currently active language through a data attribute and perform some logic when building out the URL before requesting it.

I was just looking at this again, should I instead maybe be using the relative_path instead to maintain the localization path? ๐Ÿค”


One thing I just ran into with the /_data/LANG/strings.yml implementation is that Polyglot is normally great at defaulting back to the default language, but if strings.yml exists for a language but the key:value does not exist in that file, it will return an empty string rather than the default language unfortunately. This means there needs to be an exact mapping between all of the languages to utilize that pattern to avoid empty strings, or you need to be more granular with the implementation rather than storing everything into a single strings.yml to help avoid it a bit. You still will need a 1:1 lookup for any files that are defined.

When in doubt, always print what is its value. For example:

{% for item in filtered-portfolio %} 
  <a href="{{ item.url }}">item.title</a>
  <script>
    console.log("{{ item.url }}");
    console.log("{{ item.url | relative_url }}");
  </script>
{% endfor %}

That's how I debug it.

but if strings.yml exists for a language but the key:value does not exist in that file, it will return an empty string rather than the default language unfortunately

For this case I wrote a plugin to check if the value exists in strings.yml. Check this answer.

@untra I can add my answers to the documentation. Where should I put them? In the site, in the README, or both?

https://github.com/untra/polyglot#localized-sitedata

All of this is a great discussion, and you expand on this little section currently in the readme. If you can make this section a proper h2 and expand on it, adding in the words from here (great answer and example!) that'd be appreciated.

Additionally, your other example here is more worthy of a small blog post where you can describe the liquid strategy and challenge of translation tags. If you can write a small markdown post describing this approach, I can release it before the next release.

Also optional If you include a PT-br blog post copy as well, I might also expand the languages a little more. And happy to cross-promote your own blog and liquid examples. ๐Ÿค

Thank you for your help @george-gca you're a credit to the community!

It is always good to contribute back after being helped a lot. I will create this content and submit a PR.

I believe this can be closed now.