from pyramid.interfaces import ILocaleNegotiator, ITranslationDirectories
|
|
from pyramid.exceptions import ConfigurationError
|
from pyramid.path import AssetResolver
|
|
from pyramid.config.actions import action_method
|
|
|
class I18NConfiguratorMixin(object):
|
@action_method
|
def set_locale_negotiator(self, negotiator):
|
"""
|
Set the :term:`locale negotiator` for this application. The
|
:term:`locale negotiator` is a callable which accepts a
|
:term:`request` object and which returns a :term:`locale
|
name`. The ``negotiator`` argument should be the locale
|
negotiator implementation or a :term:`dotted Python name`
|
which refers to such an implementation.
|
|
Later calls to this method override earlier calls; there can
|
be only one locale negotiator active at a time within an
|
application. See :ref:`activating_translation` for more
|
information.
|
|
.. note::
|
|
Using the ``locale_negotiator`` argument to the
|
:class:`pyramid.config.Configurator` constructor can be used to
|
achieve the same purpose.
|
"""
|
|
def register():
|
self._set_locale_negotiator(negotiator)
|
|
intr = self.introspectable(
|
'locale negotiator',
|
None,
|
self.object_description(negotiator),
|
'locale negotiator',
|
)
|
intr['negotiator'] = negotiator
|
self.action(ILocaleNegotiator, register, introspectables=(intr,))
|
|
def _set_locale_negotiator(self, negotiator):
|
locale_negotiator = self.maybe_dotted(negotiator)
|
self.registry.registerUtility(locale_negotiator, ILocaleNegotiator)
|
|
@action_method
|
def add_translation_dirs(self, *specs, **kw):
|
""" Add one or more :term:`translation directory` paths to the
|
current configuration state. The ``specs`` argument is a
|
sequence that may contain absolute directory paths
|
(e.g. ``/usr/share/locale``) or :term:`asset specification`
|
names naming a directory path (e.g. ``some.package:locale``)
|
or a combination of the two.
|
|
Example:
|
|
.. code-block:: python
|
|
config.add_translation_dirs('/usr/share/locale',
|
'some.package:locale')
|
|
The translation directories are defined as a list in which
|
translations defined later have precedence over translations defined
|
earlier.
|
|
By default, consecutive calls to ``add_translation_dirs`` will add
|
directories to the start of the list. This means later calls to
|
``add_translation_dirs`` will have their translations trumped by
|
earlier calls. If you explicitly need this call to trump an earlier
|
call then you may set ``override`` to ``True``.
|
|
If multiple specs are provided in a single call to
|
``add_translation_dirs``, the directories will be inserted in the
|
order they're provided (earlier items are trumped by later items).
|
|
.. versionchanged:: 1.8
|
|
The ``override`` parameter was added to allow a later call
|
to ``add_translation_dirs`` to override an earlier call, inserting
|
folders at the beginning of the translation directory list.
|
|
"""
|
introspectables = []
|
override = kw.pop('override', False)
|
if kw:
|
raise TypeError('invalid keyword arguments: %s', sorted(kw.keys()))
|
|
def register():
|
directories = []
|
resolver = AssetResolver(self.package_name)
|
|
# defer spec resolution until register to allow for asset
|
# overrides to take place in an earlier config phase
|
for spec in specs:
|
# the trailing slash helps match asset overrides for folders
|
if not spec.endswith('/'):
|
spec += '/'
|
asset = resolver.resolve(spec)
|
directory = asset.abspath()
|
if not asset.isdir():
|
raise ConfigurationError(
|
'"%s" is not a directory' % directory
|
)
|
intr = self.introspectable(
|
'translation directories',
|
directory,
|
spec,
|
'translation directory',
|
)
|
intr['directory'] = directory
|
intr['spec'] = spec
|
introspectables.append(intr)
|
directories.append(directory)
|
|
tdirs = self.registry.queryUtility(ITranslationDirectories)
|
if tdirs is None:
|
tdirs = []
|
self.registry.registerUtility(tdirs, ITranslationDirectories)
|
if override:
|
tdirs.extend(directories)
|
else:
|
for directory in reversed(directories):
|
tdirs.insert(0, directory)
|
|
self.action(None, register, introspectables=introspectables)
|