Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Internationalization #25

Closed
arenowebdev opened this issue Mar 21, 2016 · 15 comments
Closed

Internationalization #25

arenowebdev opened this issue Mar 21, 2016 · 15 comments
Labels
2.0 Targeted for v2.0

Comments

@arenowebdev
Copy link

Would be cool also to be able to use the trans() helper to load translated content within a static site also...

@afontcu
Copy link

afontcu commented Apr 25, 2017

I know this is old but I think this hasn't been addressed yet and it is preventing me from using Jigsaw in a lot of projects :(

Any idea to work something out with current implementation of Jigsaw? Any idea if this is ever gonna be solved?

Thank you!

@damiani
Copy link
Contributor

damiani commented Apr 25, 2017

Yes, it's the most-requested feature at the moment! Can you give a little more detail about what your needs are? We'd need to sort out how to define the current locale, presumably by specifying a language code as part of the URI; and then perhaps indicating which languages to use for a particular template by specifying the language codes in the YAML front matter of the template.

@afontcu
Copy link

afontcu commented Apr 25, 2017

Oh, this is really great to hear!

I guess my needs are quite simple, nothing fancy:

  1. Enable several languages
  2. Defining the translated version of each page/content (Gettext with Poedit, maybe?)
  3. Serving the translated content depending on the URI the user requested.

FYI I've been using LaravelLocalization since before Laravel introduced its custom translation system and it's been great. Actually way better than the built-in system.

Thank you :) and thanks for your quick response.

@damiani
Copy link
Contributor

damiani commented May 2, 2017

We're gonna be working on this feature soon, and would love to get input on what people think would be the most useful and user-friendly way to handle internationalization. Keeping close to Laravel's implementation of things like trans() is definitely a goal, and I personally don't have any experience w/ Poedit to know if that's applicable here or not. To those who are interested...how would you like to see internationalization implemented in Jigsaw?

@morpheus7CS
Copy link

Hi,
let me preface this by saying that I believe that Jigsaw as a static generator solves a real world need of people wanting to use Blade templating without the additional weight of unnecessary Laravel components, etc.

I personally like to use example.com/lang/ in my URLs to specify a language. It is a feature I'm missing in a lot of the static generators that avoid using nested collections or its equivalent. Here if I use language as a top-level collection, my URL structure immediately becomes very hard to structure as something as simple as baseURL/en/blog/post-title is no longer possible.

I really like the way Laravel let's users choose their own directory structure inside resources/views & their own way of creating URL slugs, making them as (non-)complicated (or even business specific) as they want. It's an opinionated feature I'd like to see implemented in some way.

For the folks that use trans(), I think the implementation closest to "the Laravel way" is the best, as this is how most people discover Blade & subsequently Jigsaw.

@damiani
Copy link
Contributor

damiani commented May 4, 2017

You can somewhat do this already, and in fact I wonder if having language as a collection isn't really the best solution for an internationalized site—considering that the number of languages is likely small, not subject to frequent change, and doesn't require many of the features that collections is designed to provide (you don't generally need to do things like change the sort order of languages, see a paginated subset of languages, count them, etc.). I'm not opposed to considering the concept of nested collections, but it would be worth considering other scenarios where that would be useful, before we go down that road.

To do what you outlined above, you could do something like this. In config.php:

<?php

return [
    'baseUrl' => 'https://example.com',
    'path' => '{language}/{type}/{-title}',
    'collections' => [
        'posts-sl' => [
            'type' => 'blog',
            'language' => 'sl',
        ],

        'posts-en' => [
            'type' => 'blog',
            'language' => 'en',
        ],
    ],
];

...and then store your translated blog posts in _posts-sl and _posts-en, extending a common template like _layouts.post or, if the post template had language-specific components, _layouts.sl.post and _layouts.en.post. So your directory structure would look something like this:

screen shot 2017-05-04 at 8 21 36 am

which would build to this:

screen shot 2017-05-04 at 8 21 52 am

Note that I'm using path at the top-level in config.php and allowing it to cascade to the collections; you could also just define the path within each collection. Also note that I used the token {type} instead of what I wanted to use, {section}, since section is a reserved word by Jigsaw...something we should probably change.

I threw in non-collection translated pages as well, about.md and o.md.

So you'd end up with:

example.com/en/about
example.com/en/blog/my-first-post

example.com/sl/o
example.com/sl/blog/moj-prvi-post


The issues I'd like to sort out are:

  1. Would a collection of languages offer any benefits over a solution like this
  2. Are there other potential use cases for "nested" collections
  3. As far as internationalization is concerned, what would be a good structure for storing the translated content; is it generally preferable to keep translated content in separate files, or in the same file but somehow designated by language, or in an array of strings, or (probably) all three?

@morpheus7CS
Copy link

@damiani Your proposition perfectly describes my use case! Also, actually including Slovene text in them, made me laugh. You've made my day again :)

@afontcu
Copy link

afontcu commented May 4, 2017

Hi again,

I'm giving it a try and outlining my concerns once tested. But I think that, using this approach, there's no way I could provide a user (ang Google) the alternative lang link (i.e. en/blog/my-first-post --> sl/blog/moj-prvi-post). This is quite a caveat imho.

But just as I said, i'll give it a go and come back with some ideas or feedback.
Thanks!

@damiani
Copy link
Contributor

damiani commented May 4, 2017

@morpheus7CS Blame Google for any translation errors :)

@afontcu Yes, please report back with your thoughts. You could have alternative links for users/Google pretty easily if you weren't customizing the blog post title by language (i.e. en/blog/my-first-post and sl/blog/my-first-post, but like I said, I'm not well-versed enough in the requirements of a fully-internationalized site to know the nuances. So I'm very interested in your input here.

@afontcu
Copy link

afontcu commented May 23, 2017

Hi there! Been testing the approach outlined above and while it covers 80% of the requirements of a translated site, there are some important flaws:

  • As we discussed, the inability to provide alternatives (translated) links if permalink is different is a major issue. Internationalization makes really no sense if every permalink has to be the same, or if we cannot provide alternative links.
    I'm guessing this would need some logic which cannot be solved by setting Collections or some kind of settings, am I right?

  • You are right when you say that "the number of languages is likely small, not subject to frequent change, and doesn't require many of the features that collections is designed to provide". But languages should offer some kind of static information, such as locale code ('es_ES', 'en_GB', 'de_DE') or native name ('Español', 'English, 'Deutsch`). I may be able to get this by populating the Settings file, but doesn't feel right.

  • I feel bad when I have to duplicate (or more) my pages schema just to add translations, where an array would be enough if implement. I'm thinkin of some function such as _t($title), where $title gets its value from a lang array, with as many positions as active languages.

Thank you very much!

@damiani damiani changed the title [PROPOSAL] Internationalization [Proposal] Internationalization Sep 29, 2017
@damiani damiani changed the title [Proposal] Internationalization Internationalization Oct 2, 2018
@JoshuaBehrens
Copy link

I was thinking about pagedata which has an array of locales to render the page in. This locale property can later on be used in url generators and as a parameter for the illuminate/translation provided translator.

@amadeann
Copy link

amadeann commented Feb 4, 2019

I'm also building a multi-locale site, and realized that you can include Illuminate\Translation component, and then define a translation helper in config.php, as in:

use Illuminate\Filesystem\Filesystem;
use Illuminate\Translation\FileLoader;
use Illuminate\Translation\Translator;

return [
    '__' => function ($page, $key, $locale =null) {
        if (is_null($locale)) {
            $locale = $page->locale;
        }

        // Prepare the FileLoader
        $loader = new FileLoader(new Filesystem(), './lang');

        // Register the Translator
        $translator = new Translator($loader, $locale);
        return $translator->get($key);
    },
];

Then you can define a 'master' layout for each page (e.g. about-us, services, home), an extend the layout specifying only page metadata. For example, you can have a master 'about-us' layout in source/_about-us.blade.php, with something like:

@extends('_layouts.master')

@section('body')
<p>{{ $page->__('some.key', $page->locale) }}</p>
@endsection

And locale-specific pages in source/en/about-us.blade.php

---
extends: '_about-us'
locale: de
---

and source/de/ueber-uns.blade.php:

---
extends: '_about-us'
locale: en
---

With this setup, translation strings can be organized in the same way as in a regular Laravel project.

This is something that I only quickly tested, and it works. I'm not sure how slow the build will get with more translation strings - it can probaly be optimized by loading FileLoader and FileSystem once.

@molerat619
Copy link

molerat619 commented May 8, 2020

I like both approaches, but in @amadeann's approach: what if you want to translate a whole post with HTML inside (e.g. for formatting)? Do you keep all that in the translation strings?

@amadeann
Copy link

amadeann commented May 8, 2020

I like both approaches, but in @amadeann's approach: what if you want to translate a whole post with HTML inside (e.g. for formatting)? Do you keep all that in the translation strings?

If the formatting is very different between languages, and the layout changes as well, then just create separate pages. If you need minor formatting (like wrapping some text in <span class="font-bold"></span>), then get the unescaped translation string (see Laravel docs): Hello, {{ $name }}..

@molerat619
Copy link

I followed @damiani 's suggestions, but how do you access the blog posts then?

If the blog is just called blog you can access it with $blog. But when it's blog-en, $blogEn won't work for me.

@tighten tighten locked and limited conversation to collaborators Sep 3, 2021
@damiani damiani closed this as completed Sep 3, 2021

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
2.0 Targeted for v2.0
Projects
None yet
Development

No branches or pull requests

8 participants