i18n_subsites: add lang_subsites template var, improve docs
- the new variable makes it easier to implement language buttons - a short howto on language buttons is also provided - the dictionary mapping template vars are now OrderedDict for consistent-looking language buttons
This commit is contained in:
parent
aa5c414d0b
commit
4c33944bb9
22
README.rst
22
README.rst
@ -8,7 +8,7 @@ What it does
|
|||||||
============
|
============
|
||||||
1. The *\*_LANG_URL* and *\*_LANG_SAVE_AS* variables are set to their normal counterparts (e.g. *ARTICLE_URL*) so they don't conflict with this scheme.
|
1. The *\*_LANG_URL* and *\*_LANG_SAVE_AS* variables are set to their normal counterparts (e.g. *ARTICLE_URL*) so they don't conflict with this scheme.
|
||||||
2. While building the site for *DEFAULT_LANG* the translations of pages and articles are not generated, but their relations to the original content is kept via links to them.
|
2. While building the site for *DEFAULT_LANG* the translations of pages and articles are not generated, but their relations to the original content is kept via links to them.
|
||||||
3. For each non-default language a "sub-site" with a modified config [#conf]_ is created [#run]_, linking the translations to the originals (if available). The configured language code is appended to the *OUTPUT_PATH* and *SITEURL* of each sub-site.
|
3. For each non-default language a "sub-site" with a modified config [#conf]_ is created [#run]_, linking the translations to the originals (if available). The configured language code is appended to the *OUTPUT_PATH* and *SITEURL* of each sub-site. For each sub-site, *DEFAULT_LANG* is changed to the language of the sub-site so that articles in a different language are treated as translations.
|
||||||
|
|
||||||
If *HIDE_UNTRANSLATED_CONTENT* is True (default), content without a translation for a language is generated as hidden (for pages) or draft (for articles) for the corresponding language sub-site.
|
If *HIDE_UNTRANSLATED_CONTENT* is True (default), content without a translation for a language is generated as hidden (for pages) or draft (for articles) for the corresponding language sub-site.
|
||||||
|
|
||||||
@ -18,7 +18,9 @@ If *HIDE_UNTRANSLATED_CONTENT* is True (default), content without a translation
|
|||||||
Setting it up
|
Setting it up
|
||||||
=============
|
=============
|
||||||
|
|
||||||
For each extra used language code, a language-specific variables overrides dictionary must be given (but can be empty) in the *I18N_SUBSITES* dictionary::
|
For each extra used language code, a language-specific variables overrides dictionary must be given (but can be empty) in the *I18N_SUBSITES* dictionary
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
PLUGINS = ['i18n_subsites', ...]
|
PLUGINS = ['i18n_subsites', ...]
|
||||||
|
|
||||||
@ -40,18 +42,24 @@ Most importantly, this plugin can use localized templates for each sub-site. The
|
|||||||
- You can set a different *THEME* override for each language in *I18N_SUBSITES*, e.g. by making a copy of a theme ``my_theme`` to ``my_theme_lang`` and then editing the templates in the new localized theme. This approach means you don't have to deal with gettext ``*.po`` files, but it is harder to maintain over time.
|
- You can set a different *THEME* override for each language in *I18N_SUBSITES*, e.g. by making a copy of a theme ``my_theme`` to ``my_theme_lang`` and then editing the templates in the new localized theme. This approach means you don't have to deal with gettext ``*.po`` files, but it is harder to maintain over time.
|
||||||
- You use only one theme and localize the templates using the `jinja2.ext.i18n Jinja2 extension <http://jinja.pocoo.org/docs/templates/#i18n>`_. For a kickstart read this `guide <./localizing_using_jinja2.rst>`_.
|
- You use only one theme and localize the templates using the `jinja2.ext.i18n Jinja2 extension <http://jinja.pocoo.org/docs/templates/#i18n>`_. For a kickstart read this `guide <./localizing_using_jinja2.rst>`_.
|
||||||
|
|
||||||
It may be convenient to add language buttons to your theme in addition to the translation links. These buttons could, for example, point to the *SITEURL* of each (sub-)site. For this reason the plugin adds these variables to the template context:
|
It may be convenient to add language buttons to your theme in addition to the translation links of articles and pages. These buttons could, for example, point to the *SITEURL* of each (sub-)site. For this reason the plugin adds these variables to the template context:
|
||||||
|
|
||||||
extra_siteurls
|
|
||||||
A dictionary mapping languages to their *SITEURL*. The *DEFAULT_LANG* language of the current sub-site is not included, so this dictionary serves as a complement to current *DEFAULT_LANG* and *SITEURL*. This dictionary is useful for implementing global language buttons.
|
|
||||||
main_lang
|
main_lang
|
||||||
The language of the top-level site — the original *DEFAULT_LANG*
|
The language of the top-level site — the original *DEFAULT_LANG*
|
||||||
main_siteurl
|
main_siteurl
|
||||||
The *SITEURL* of the top-level site — the original *SITEURL*
|
The *SITEURL* of the top-level site — the original *SITEURL*
|
||||||
|
lang_siteurls
|
||||||
|
An ordered dictionary, mapping all used languages to their *SITEURL*. The ``main_lang`` is the first key with ``main_siteurl`` as the value. This dictionary is useful for implementing global language buttons that show the language of the currently viewed (sub-)site too.
|
||||||
|
extra_siteurls
|
||||||
|
An ordered dictionary, subset of ``lang_siteurls``, the current *DEFAULT_LANG* of the rendered (sub-)site is not included, so for each (sub-)site ``set(extra_siteurls) == set(lang_siteurls) - set([DEFAULT_LANG])``. This dictionary is useful for implementing global language buttons that do not show the current language.
|
||||||
|
|
||||||
|
If you don't like the default ordering of the ordered dictionaries, use a Jinja2 filter to alter the ordering.
|
||||||
|
|
||||||
|
This short `howto <./implementing_language_buttons.rst>`_ shows two example implementations of language buttons.
|
||||||
|
|
||||||
Usage notes
|
Usage notes
|
||||||
===========
|
===========
|
||||||
- It is **mandatory** to specify *lang* metadata for each article and page as *DEFAULT_LANG* is later changed for each sub-site.
|
- It is **mandatory** to specify *lang* metadata for each article and page as *DEFAULT_LANG* is later changed for each sub-site, so content without *lang* metadata woudl be rendered in every (sub-)site.
|
||||||
- As with the original translations functionality, *slug* metadata is used to group translations. It is therefore often convenient to compensate for this by overriding the content URL (which defaults to slug) using the *URL* and *Save_as* metadata.
|
- As with the original translations functionality, *slug* metadata is used to group translations. It is therefore often convenient to compensate for this by overriding the content URL (which defaults to slug) using the *URL* and *Save_as* metadata.
|
||||||
|
|
||||||
Future plans
|
Future plans
|
||||||
@ -63,5 +71,3 @@ Development
|
|||||||
===========
|
===========
|
||||||
|
|
||||||
- A demo and test site is in the ``gh-pages`` branch and can be seen at http://smartass101.github.io/pelican-plugins/
|
- A demo and test site is in the ``gh-pages`` branch and can be seen at http://smartass101.github.io/pelican-plugins/
|
||||||
|
|
||||||
.. LocalWords: lang metadata
|
|
||||||
|
@ -6,7 +6,7 @@ import os
|
|||||||
import six
|
import six
|
||||||
import logging
|
import logging
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from collections import defaultdict
|
from collections import defaultdict, OrderedDict
|
||||||
|
|
||||||
import gettext
|
import gettext
|
||||||
|
|
||||||
@ -22,6 +22,7 @@ from ._regenerate_context_helpers import regenerate_context_articles
|
|||||||
_main_site_generated = False
|
_main_site_generated = False
|
||||||
_main_site_lang = "en"
|
_main_site_lang = "en"
|
||||||
_main_siteurl = ''
|
_main_siteurl = ''
|
||||||
|
_lang_siteurls = None
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@ -32,7 +33,7 @@ def disable_lang_vars(pelican_obj):
|
|||||||
e.g. ARTICLE_LANG_URL = ARTICLE_URL
|
e.g. ARTICLE_LANG_URL = ARTICLE_URL
|
||||||
They would conflict with this plugin otherwise
|
They would conflict with this plugin otherwise
|
||||||
"""
|
"""
|
||||||
global _main_site_lang, _main_siteurl
|
global _main_site_lang, _main_siteurl, _lang_siteurls
|
||||||
s = pelican_obj.settings
|
s = pelican_obj.settings
|
||||||
for content in ['ARTICLE', 'PAGE']:
|
for content in ['ARTICLE', 'PAGE']:
|
||||||
for meta in ['_URL', '_SAVE_AS']:
|
for meta in ['_URL', '_SAVE_AS']:
|
||||||
@ -40,6 +41,10 @@ def disable_lang_vars(pelican_obj):
|
|||||||
if not _main_site_generated:
|
if not _main_site_generated:
|
||||||
_main_site_lang = s['DEFAULT_LANG']
|
_main_site_lang = s['DEFAULT_LANG']
|
||||||
_main_siteurl = s['SITEURL']
|
_main_siteurl = s['SITEURL']
|
||||||
|
_lang_siteurls = [(lang, _main_siteurl + '/' + lang) for lang in s.get('I18N_SUBSITES', {}).keys()]
|
||||||
|
# To be able to use url for main site root when SITEURL == '' (e.g. when developing)
|
||||||
|
_lang_siteurls = [(_main_site_lang, ('/' if _main_siteurl == '' else _main_siteurl))] + _lang_siteurls
|
||||||
|
_lang_siteurls = OrderedDict(_lang_siteurls)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -61,7 +66,7 @@ def create_lang_subsites(pelican_obj):
|
|||||||
for lang, overrides in orig_settings.get('I18N_SUBSITES', {}).items():
|
for lang, overrides in orig_settings.get('I18N_SUBSITES', {}).items():
|
||||||
settings = orig_settings.copy()
|
settings = orig_settings.copy()
|
||||||
settings.update(overrides)
|
settings.update(overrides)
|
||||||
settings['SITEURL'] = _main_siteurl + '/' + lang
|
settings['SITEURL'] = _lang_siteurls[lang]
|
||||||
settings['OUTPUT_PATH'] = os.path.join(orig_settings['OUTPUT_PATH'], lang, '')
|
settings['OUTPUT_PATH'] = os.path.join(orig_settings['OUTPUT_PATH'], lang, '')
|
||||||
settings['DEFAULT_LANG'] = lang # to change what is perceived as translations
|
settings['DEFAULT_LANG'] = lang # to change what is perceived as translations
|
||||||
settings['DELETE_OUTPUT_DIRECTORY'] = False # prevent deletion of previous runs
|
settings['DELETE_OUTPUT_DIRECTORY'] = False # prevent deletion of previous runs
|
||||||
@ -150,10 +155,9 @@ def install_templates_translations(generator):
|
|||||||
"""
|
"""
|
||||||
generator.context['main_siteurl'] = _main_siteurl
|
generator.context['main_siteurl'] = _main_siteurl
|
||||||
generator.context['main_lang'] = _main_site_lang
|
generator.context['main_lang'] = _main_site_lang
|
||||||
extra_siteurls = { lang: _main_siteurl + '/' + lang for lang in generator.settings.get('I18N_SUBSITES', {}).keys() }
|
generator.context['lang_siteurls'] = _lang_siteurls
|
||||||
# To be able to use url for main site root when SITEURL == '' (e.g. when developing)
|
|
||||||
extra_siteurls[_main_site_lang] = '/' if _main_siteurl == '' else _main_siteurl
|
|
||||||
current_def_lang = generator.settings['DEFAULT_LANG']
|
current_def_lang = generator.settings['DEFAULT_LANG']
|
||||||
|
extra_siteurls = _lang_siteurls.copy()
|
||||||
extra_siteurls.pop(current_def_lang)
|
extra_siteurls.pop(current_def_lang)
|
||||||
generator.context['extra_siteurls'] = extra_siteurls
|
generator.context['extra_siteurls'] = extra_siteurls
|
||||||
|
|
||||||
|
113
implementing_language_buttons.rst
Normal file
113
implementing_language_buttons.rst
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
-----------------------------
|
||||||
|
Implementing language buttons
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Each article with translations has translations links, but that's the only way to switch between language subsites.
|
||||||
|
|
||||||
|
For this reason it is convenient to add language buttons to the top menu bar to make it simple to switch between the language subsites on all pages.
|
||||||
|
|
||||||
|
Example designs
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Language buttons showing other available languages
|
||||||
|
..................................................
|
||||||
|
|
||||||
|
The ``extra_siteurls`` dictionary is a mapping of all other (not the *DEFAULT_LANG* of the current (sub-)site) languages to the *SITEURL* of the respective (sub-)sites
|
||||||
|
|
||||||
|
.. code-block:: jinja
|
||||||
|
|
||||||
|
<!-- SNIP -->
|
||||||
|
<nav><ul>
|
||||||
|
{% if extra_siteurls %}
|
||||||
|
{% for lang, url in extra_siteurls.items() %}
|
||||||
|
<li><a href="{{ url }}">{{ lang }}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
<!-- separator -->
|
||||||
|
<li style="background-color: white; padding: 5px;"> </li>
|
||||||
|
{% endif %}
|
||||||
|
{% for title, link in MENUITEMS %}
|
||||||
|
<!-- SNIP -->
|
||||||
|
|
||||||
|
Language buttons showing all available languages, current is active
|
||||||
|
..................................................................
|
||||||
|
|
||||||
|
The ``extra_siteurls`` dictionary is a mapping of all languages to the *SITEURL* of the respective (sub-)sites. This template sets the language of the current (sub-)site as active.
|
||||||
|
|
||||||
|
.. code-block:: jinja
|
||||||
|
|
||||||
|
<!-- SNIP -->
|
||||||
|
<nav><ul>
|
||||||
|
{% if lang_siteurls %}
|
||||||
|
{% for lang, url in lang_siteurls.items() %}
|
||||||
|
<li{% if lang == DEFAULT_LANG %} class="active"{% endif %}><a href="{{ url }}">{{ lang }}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
<!-- separator -->
|
||||||
|
<li style="background-color: white; padding: 5px;"> </li>
|
||||||
|
{% endif %}
|
||||||
|
{% for title, link in MENUITEMS %}
|
||||||
|
<!-- SNIP -->
|
||||||
|
|
||||||
|
|
||||||
|
Tips and tricks
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Showing more than language codes
|
||||||
|
................................
|
||||||
|
|
||||||
|
If you want the language buttons to show e.g. the names of the languages or flags [#flags]_, not just the language codes, you can use a jinja filter to translate the language codes
|
||||||
|
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
languages_lookup = {
|
||||||
|
'en': 'English',
|
||||||
|
'cz': 'Čeština',
|
||||||
|
}
|
||||||
|
|
||||||
|
def lookup_lang_name(lang_code):
|
||||||
|
return languages_lookup[lang_code]
|
||||||
|
|
||||||
|
JINJA_FILTERS = {
|
||||||
|
...
|
||||||
|
'lookup_lang_name': lookup_lang_name,
|
||||||
|
}
|
||||||
|
|
||||||
|
And then the link content becomes
|
||||||
|
|
||||||
|
.. code-block:: jinja
|
||||||
|
|
||||||
|
<!-- SNIP -->
|
||||||
|
{% for lang, siteurl in lang_siteurls.items() %}
|
||||||
|
<li{% if lang == DEFAULT_LANG %} class="active"{% endif %}><a href="{{ siteurl }}">{{ lang | lookup_lang_name }}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
<!-- SNIP -->
|
||||||
|
|
||||||
|
|
||||||
|
Changing the order of language buttons
|
||||||
|
......................................
|
||||||
|
|
||||||
|
Because ``lang_siteurls`` and ``extra_siteurls`` are instances of ``OrderedDict`` with ``main_lang`` being always the first key, you can change the order through a jinja filter.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
def my_ordered_items(ordered_dict):
|
||||||
|
items = list(ordered_dict.items())
|
||||||
|
# swap first and last using tuple unpacking
|
||||||
|
items[0], items[-1] = items[-1], items[0]
|
||||||
|
return items
|
||||||
|
|
||||||
|
JINJA_FILTERS = {
|
||||||
|
...
|
||||||
|
'my_ordered_items': my_ordered_items,
|
||||||
|
}
|
||||||
|
|
||||||
|
And then the ``for`` loop line in the template becomes
|
||||||
|
|
||||||
|
.. code-block:: jinja
|
||||||
|
|
||||||
|
<!-- SNIP -->
|
||||||
|
{% for lang, siteurl in lang_siteurls | my_ordered_items %}
|
||||||
|
<!-- SNIP -->
|
||||||
|
|
||||||
|
|
||||||
|
.. [#flags] Although it may look nice, `w3 discourages it <http://www.w3.org/TR/i18n-html-tech-lang/#ri20040808.173208643>`_.
|
@ -6,11 +6,15 @@ Localizing themes with Jinja2
|
|||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
To enable the |ext| extension in your templates, you must add it to
|
To enable the |ext| extension in your templates, you must add it to
|
||||||
*JINJA_EXTENSIONS* in your Pelican configuration::
|
*JINJA_EXTENSIONS* in your Pelican configuration
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
JINJA_EXTENSIONS = ['jinja2.ext.i18n', ...]
|
JINJA_EXTENSIONS = ['jinja2.ext.i18n', ...]
|
||||||
|
|
||||||
Then follow the `Jinja2 templating documentation for the I18N plugin <http://jinja.pocoo.org/docs/templates/#i18n>`_ to make your templates localizable. This usually means surrounding strings with the ``{% trans %}`` directive or using ``gettext()`` in expressions::
|
Then follow the `Jinja2 templating documentation for the I18N plugin <http://jinja.pocoo.org/docs/templates/#i18n>`_ to make your templates localizable. This usually means surrounding strings with the ``{% trans %}`` directive or using ``gettext()`` in expressions
|
||||||
|
|
||||||
|
.. code-block:: jinja
|
||||||
|
|
||||||
{% trans %}translatable content{% endtrans %}
|
{% trans %}translatable content{% endtrans %}
|
||||||
{{ gettext('a translatable string') }}
|
{{ gettext('a translatable string') }}
|
||||||
@ -33,7 +37,9 @@ The domain of the translations (the name of each translation file is ``domain.mo
|
|||||||
Example
|
Example
|
||||||
.......
|
.......
|
||||||
|
|
||||||
With the following in your Pelican settings file::
|
With the following in your Pelican settings file
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
I18N_GETTEXT_LOCALEDIR = 'some/path/'
|
I18N_GETTEXT_LOCALEDIR = 'some/path/'
|
||||||
I18N_GETTEXT_DOMAIN = 'my_domain'
|
I18N_GETTEXT_DOMAIN = 'my_domain'
|
||||||
@ -60,7 +66,9 @@ Let's assume that you are localizing a theme in ``themes/my_theme/`` and that yo
|
|||||||
|
|
||||||
It is up to you where to store babel mappings and translation files templates (``*.pot``), but a convenient place is to put them in ``themes/my_theme/`` and work in that directory. From now on let's assume that it will be our current working directory (CWD).
|
It is up to you where to store babel mappings and translation files templates (``*.pot``), but a convenient place is to put them in ``themes/my_theme/`` and work in that directory. From now on let's assume that it will be our current working directory (CWD).
|
||||||
|
|
||||||
To tell babel to extract translatable strings from the templates create a mapping file ``babel.cfg`` with the following line::
|
To tell babel to extract translatable strings from the templates create a mapping file ``babel.cfg`` with the following line
|
||||||
|
|
||||||
|
.. code-block:: cfg
|
||||||
|
|
||||||
[jinja2: ./templates/**.html]
|
[jinja2: ./templates/**.html]
|
||||||
|
|
||||||
@ -68,7 +76,9 @@ To tell babel to extract translatable strings from the templates create a mappin
|
|||||||
2. Extract translatable strings from templates
|
2. Extract translatable strings from templates
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Run the following command to create a ``messages.pot`` message catalog template file from extracted translatable strings::
|
Run the following command to create a ``messages.pot`` message catalog template file from extracted translatable strings
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
pybabel extract --mapping babel.cfg --output messages.pot ./
|
pybabel extract --mapping babel.cfg --output messages.pot ./
|
||||||
|
|
||||||
@ -77,7 +87,9 @@ Run the following command to create a ``messages.pot`` message catalog template
|
|||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
If you want to translate the template to language ``lang``, run the following command to create a message catalog
|
If you want to translate the template to language ``lang``, run the following command to create a message catalog
|
||||||
``translations/lang/LC_MESSAGES/messages.po`` using the template ``messages.pot``::
|
``translations/lang/LC_MESSAGES/messages.po`` using the template ``messages.pot``
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
pybabel init --input-file messages.pot --output-dir translations/ --locale lang --domain messages
|
pybabel init --input-file messages.pot --output-dir translations/ --locale lang --domain messages
|
||||||
|
|
||||||
@ -86,7 +98,10 @@ babel expects ``lang`` to be a valid locale identifier, so if e.g. you are trans
|
|||||||
4. Fill the message catalogs
|
4. Fill the message catalogs
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
The message catalog files format is quite intuitive, it is fully documented in the `GNU gettext manual <http://www.gnu.org/software/gettext/manual/gettext.html#PO-Files>`_. Essentially, you fill in the ``msgstr`` strings::
|
The message catalog files format is quite intuitive, it is fully documented in the `GNU gettext manual <http://www.gnu.org/software/gettext/manual/gettext.html#PO-Files>`_. Essentially, you fill in the ``msgstr`` strings
|
||||||
|
|
||||||
|
|
||||||
|
.. code-block:: po
|
||||||
|
|
||||||
msgid "just a simple string"
|
msgid "just a simple string"
|
||||||
msgstr "jenom jednoduchý řetězec"
|
msgstr "jenom jednoduchý řetězec"
|
||||||
@ -103,7 +118,9 @@ You might also want to remove ``#,fuzzy`` flags once the translation is complete
|
|||||||
5. Compile the message catalogs
|
5. Compile the message catalogs
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
The message catalogs must be compiled into binary format using this command::
|
The message catalogs must be compiled into binary format using this command
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
pybabel compile --directory translations/ --domain messages
|
pybabel compile --directory translations/ --domain messages
|
||||||
|
|
||||||
@ -113,7 +130,9 @@ This command might complain about "fuzzy" translations, which means you should r
|
|||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
If you add any translatable patterns into your templates, you have to update your message catalogs too.
|
If you add any translatable patterns into your templates, you have to update your message catalogs too.
|
||||||
First you extract a new message catalog template as described in the 2. step. Then you run the following command [#pybabel_error]_::
|
First you extract a new message catalog template as described in the 2. step. Then you run the following command [#pybabel_error]_
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
pybabel update --input-file messages.pot --output-dir translations/ --domain messages
|
pybabel update --input-file messages.pot --output-dir translations/ --domain messages
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user