getpelican / pelican

Static site generator that supports Markdown and reST syntax. Powered by Python.
https://getpelican.com
GNU Affero General Public License v3.0
12.57k stars 1.81k forks source link

I18N support #92

Closed svetlyak40wt closed 12 years ago

svetlyak40wt commented 13 years ago

I want to add a internationalization support, using Jinja2's gettext extension.

Work in progress.

almet commented 13 years ago

On 05/04/2011 08:23, svetlyak40wt wrote:

I want to add a internationalization support, using Jinja2's gettext extension.

Work in progress.

That would be really great !

almet commented 13 years ago

@svetlyak40wt any news? :)

svetlyak40wt commented 13 years ago

No any news. I've read about gettext support in Jinja2, but stuck, because all pages should be generated for all available languages. And I can't decide if these languages list should be defined in the config file or should be calculated dynamically, based on articles metadata.

ghost commented 13 years ago

Hello,

Maybe we can load the gettext files from the theme path and directly use gettext instead of using the Jinja2 extension ?!

svetlyak40wt commented 13 years ago

Why not to use Jinja2 functions? We can load .po files from any place anyway.

ghost commented 13 years ago

@svetlyak40w: Maybe we can do something like this:

 #!/usr/bin/env python
 # -*- coding: utf-8 -*- #

 import jinja2, gettext

 class JinjaTranslations():
      def __init__(self):
           self.t= gettext.translation('domain', 'locale', fallback=True)

      def gettext(self, message): 
           return self.t.gettext(message)

      def ngettext(self, singular, plural, number): 
           return self.t.ungettext(singular, plural, number)

 loader = jinja2.FileSystemLoader("templates")
 env = jinja2.Environment(loader=loader, extensions=['jinja2.ext.i18n'])
 env.install_gettext_translations(JinjaTranslations(), newstyle=True)

 index = env.get_template('index.html')

 print index.render({'count': 0})

Or something like this:

 #!/usr/bin/env python
 # -*- coding: utf-8 -*- #
 import jinja2, gettext

 t= gettext.translation('domain', 'locale', fallback=True)

 loader = jinja2.FileSystemLoader("templates")
 env = jinja2.Environment(loader=loader)
 index = env.get_template('index.html')

 print index.render({
      'count': 0,
      '_': t.ugettext,
      'ngettext': t.ungettext
      }
 )
svetlyak40wt commented 13 years ago

The problem not in translations but the way how to choose which files should be generated. You not only have to have a translated articles pages, but you have to have different versions of every page for every supported language.

For example, I want my blog contain articles in English and Russian. I have each article in each of these languages, but my theme is in russian and when somebody opens article, written in english, he see page capthion and navigation links in Russian. This is very confusing.

First task, we have to translate all elements on the article page into the article's language.

Moreover, we have translations for other pages (like static), and to have a links from pages in English to pages in English and so on. For example, /some-article-ru.html should link to /index-ru.html, but /some-article-en.html, should link to /index-en.html, and we have to create a symlinks /some-article.html and /index.html, pointing to pages in DEFAULT language.

On Mon, Jun 6, 2011 at 4:52 PM, Skami18 reply@reply.github.com wrote:

@svetlyak40w: Maybe we can do something like this:

    #!/usr/bin/env python     # -- coding: utf-8 -- #

    import jinja2, gettext

    class JinjaTranslations():          def init(self):               self.t= gettext.translation('domain', 'locale', fallback=True)

         def gettext(self, message):               return self.t.gettext(message)

         def ngettext(self, singular, plural, number):               return self.t.ungettext(singular, plural, number)

    loader = jinja2.FileSystemLoader("templates")     env = jinja2.Environment(loader=loader, extensions=['jinja2.ext.i18n'])     env.install_gettext_translations(JinjaTranslations(), newstyle=True)

    index = env.get_template('index.html')

    print index.render({'count': 0})

Or something like this:

    #!/usr/bin/env python     # -- coding: utf-8 -- #     import jinja2, gettext

    t= gettext.translation('domain', 'locale', fallback=True)

    loader = jinja2.FileSystemLoader("templates")     env = jinja2.Environment(loader=loader)     index = env.get_template('index.html')

    print index.render({          'count': 0,          '_': t.ugettext,          'ngettext': t.ungettext          }     )

Reply to this email directly or view it on GitHub: https://github.com/ametaireau/pelican/issues/92#comment_1308947

Alexander Artemenko (a.k.a. Svetlyak 40wt) Blog: http://dev.svetlyak.ru Photos: http://svetlyak.ru Jabber: svetlyak.40wt@gmail.com

ghost commented 13 years ago

In fact, I was thinking of implementing i18n to avoid having to translate themes before use them...

My idea was to allow themes developers to easily implement i18n by including a locales folder containing the .mo files in the themes, and by using the gettext functions in the templates.

But the both ideas are not incompatible: Maybe me can enhance the JinjaTranslations class in the first template to allow switching between locales...

With this system, it would be possible to switch between languages depending of the content :lang: metadata. In addition, maybe we could modify the generators to allow sorting content by language: the pages containing only articles in a specific language would be written in this language and the other would be written in the DEFAULT_LANG...

So I think the first thing to do to obtain this behaviour is to make Pelican sort the content by language...

svetlyak40wt commented 13 years ago

This is wrong direction. Some pages may not include :lang: tag and you don't have to sort content by lang too.

On Mon, Jun 6, 2011 at 9:07 PM, Skami18 reply@reply.github.com wrote:

In fact, I was thinking of implementing i18n to avoid having to translate themes before use them...

My idea was to allow themes developers to easily implement i18n by including a locales folder containing the .mo files in the themes, and by using the gettext functions in the templates.

But the both ideas are not incompatible: Maybe me can enhance the JinjaTranslations class in the first template to allow switching between locales...

With this system, it would be possible to switch between languages depending of the content :lang: metadata. In addition, maybe we could modify the generators to allow sorting content by language: the pages containing only articles in a specific language would be written in this language and the other would be written in the DEFAULT_LANG...

So I think the first thing to do to obtain this behaviour is to make Pelican sort the content by language...

Reply to this email directly or view it on GitHub: https://github.com/ametaireau/pelican/issues/92#comment_1310478

Alexander Artemenko (a.k.a. Svetlyak 40wt) Blog: http://dev.svetlyak.ru Photos: http://svetlyak.ru Jabber: svetlyak.40wt@gmail.com

svetlyak40wt commented 13 years ago

Let me think about i18n in pelican and implement some prototype.

On Mon, Jun 6, 2011 at 9:07 PM, Skami18 reply@reply.github.com wrote:

In fact, I was thinking of implementing i18n to avoid having to translate themes before use them...

My idea was to allow themes developers to easily implement i18n by including a locales folder containing the .mo files in the themes, and by using the gettext functions in the templates.

But the both ideas are not incompatible: Maybe me can enhance the JinjaTranslations class in the first template to allow switching between locales...

With this system, it would be possible to switch between languages depending of the content :lang: metadata. In addition, maybe we could modify the generators to allow sorting content by language: the pages containing only articles in a specific language would be written in this language and the other would be written in the DEFAULT_LANG...

So I think the first thing to do to obtain this behaviour is to make Pelican sort the content by language...

Reply to this email directly or view it on GitHub: https://github.com/ametaireau/pelican/issues/92#comment_1310478

Alexander Artemenko (a.k.a. Svetlyak 40wt) Blog: http://dev.svetlyak.ru Photos: http://svetlyak.ru Jabber: svetlyak.40wt@gmail.com

almet commented 13 years ago

@svetlyak40wt piiiing :) Any news on this?

svetlyak40wt commented 13 years ago

Not really. Leaved side projects for a while because very loaded on the fulltime job.

jokull commented 12 years ago

Flask-Babel does a good job with this. I want Calepin to be i18N at some point, but it's not a huge priority now. If were to tackle this however, I'd go with pybabel and have a look at Flask-Babel, since Flask is Jinja2 based.

PiotrCzapla commented 12 years ago

Any working prototype?

almet commented 12 years ago

Not anyone I know anything about. this is still open to work on if anyone wants to do so.

almet commented 12 years ago

Closing for now.

smartass101 commented 10 years ago

I suggest using a similar scheme like nikola uses. However, they did not use the jinja i18n extensions, hacked their own way around. But they already have some code for use with Transifex, could be reused.

Essentially it would boil down to modifying the Pelican.run() function

def run(self):
        """Run the generators and return"""
        start_time = time.time()

        context = self.settings.copy()
        context['filenames'] = get_translated(SHOW_ONLY_TRANSLATED) # boolean setting to show only articles in given lang or all
        for lang in LANGS: # could be a list in conf or generated dynamically from found translations
             context['lang'] = lang
             context['localsiteurl'] = urljoin(self.settings['SITEURL'], lang) # or LANG_DEST[lang]
             generators = [
             cls(
                context=context,
                settings=self.settings,
                path=self.path,
                theme=self.theme, # with jinja.ext.i18n
                output_path=os.path.join(lang, self.output_path), # this could be specified in conf, could be LANG_DEST[lang] = "./lang"
             ) for cls in self.get_generator_classes()
             ]
             for p in generators:
                 ...
smartass101 commented 10 years ago

I implemented the functionality described in my previous comment in the i18n_subsites plugin https://github.com/getpelican/pelican-plugins/pull/139