commit | author | age
|
0c29cf
|
1 |
from pyramid.interfaces import ILocaleNegotiator, ITranslationDirectories |
5bf23f
|
2 |
|
CM |
3 |
from pyramid.exceptions import ConfigurationError |
0c1c58
|
4 |
from pyramid.path import AssetResolver |
52fde9
|
5 |
|
d579f2
|
6 |
from pyramid.config.actions import action_method |
0c29cf
|
7 |
|
5bf23f
|
8 |
|
CM |
9 |
class I18NConfiguratorMixin(object): |
|
10 |
@action_method |
|
11 |
def set_locale_negotiator(self, negotiator): |
|
12 |
""" |
|
13 |
Set the :term:`locale negotiator` for this application. The |
|
14 |
:term:`locale negotiator` is a callable which accepts a |
|
15 |
:term:`request` object and which returns a :term:`locale |
|
16 |
name`. The ``negotiator`` argument should be the locale |
|
17 |
negotiator implementation or a :term:`dotted Python name` |
|
18 |
which refers to such an implementation. |
|
19 |
|
|
20 |
Later calls to this method override earlier calls; there can |
|
21 |
be only one locale negotiator active at a time within an |
|
22 |
application. See :ref:`activating_translation` for more |
|
23 |
information. |
|
24 |
|
012b97
|
25 |
.. note:: |
M |
26 |
|
|
27 |
Using the ``locale_negotiator`` argument to the |
|
28 |
:class:`pyramid.config.Configurator` constructor can be used to |
|
29 |
achieve the same purpose. |
5bf23f
|
30 |
""" |
0c29cf
|
31 |
|
5bf23f
|
32 |
def register(): |
CM |
33 |
self._set_locale_negotiator(negotiator) |
0c29cf
|
34 |
|
MM |
35 |
intr = self.introspectable( |
|
36 |
'locale negotiator', |
|
37 |
None, |
|
38 |
self.object_description(negotiator), |
|
39 |
'locale negotiator', |
|
40 |
) |
3b5ccb
|
41 |
intr['negotiator'] = negotiator |
CM |
42 |
self.action(ILocaleNegotiator, register, introspectables=(intr,)) |
5bf23f
|
43 |
|
CM |
44 |
def _set_locale_negotiator(self, negotiator): |
|
45 |
locale_negotiator = self.maybe_dotted(negotiator) |
|
46 |
self.registry.registerUtility(locale_negotiator, ILocaleNegotiator) |
|
47 |
|
a78b58
|
48 |
@action_method |
d009c0
|
49 |
def add_translation_dirs(self, *specs, **kw): |
5bf23f
|
50 |
""" Add one or more :term:`translation directory` paths to the |
CM |
51 |
current configuration state. The ``specs`` argument is a |
|
52 |
sequence that may contain absolute directory paths |
|
53 |
(e.g. ``/usr/share/locale``) or :term:`asset specification` |
|
54 |
names naming a directory path (e.g. ``some.package:locale``) |
|
55 |
or a combination of the two. |
|
56 |
|
|
57 |
Example: |
|
58 |
|
|
59 |
.. code-block:: python |
|
60 |
|
|
61 |
config.add_translation_dirs('/usr/share/locale', |
|
62 |
'some.package:locale') |
|
63 |
|
c13745
|
64 |
The translation directories are defined as a list in which |
MM |
65 |
translations defined later have precedence over translations defined |
|
66 |
earlier. |
|
67 |
|
d009c0
|
68 |
By default, consecutive calls to ``add_translation_dirs`` will add |
MM |
69 |
directories to the start of the list. This means later calls to |
|
70 |
``add_translation_dirs`` will have their translations trumped by |
|
71 |
earlier calls. If you explicitly need this call to trump an earlier |
|
72 |
call then you may set ``override`` to ``True``. |
|
73 |
|
c13745
|
74 |
If multiple specs are provided in a single call to |
MM |
75 |
``add_translation_dirs``, the directories will be inserted in the |
|
76 |
order they're provided (earlier items are trumped by later items). |
|
77 |
|
d009c0
|
78 |
.. versionchanged:: 1.8 |
c13745
|
79 |
|
d009c0
|
80 |
The ``override`` parameter was added to allow a later call |
MM |
81 |
to ``add_translation_dirs`` to override an earlier call, inserting |
|
82 |
folders at the beginning of the translation directory list. |
0c1c58
|
83 |
|
5bf23f
|
84 |
""" |
3b5ccb
|
85 |
introspectables = [] |
d009c0
|
86 |
override = kw.pop('override', False) |
MM |
87 |
if kw: |
|
88 |
raise TypeError('invalid keyword arguments: %s', sorted(kw.keys())) |
5bf23f
|
89 |
|
3b5ccb
|
90 |
def register(): |
b24aeb
|
91 |
directories = [] |
MM |
92 |
resolver = AssetResolver(self.package_name) |
|
93 |
|
0c1c58
|
94 |
# defer spec resolution until register to allow for asset |
MM |
95 |
# overrides to take place in an earlier config phase |
d009c0
|
96 |
for spec in specs: |
0c1c58
|
97 |
# the trailing slash helps match asset overrides for folders |
MM |
98 |
if not spec.endswith('/'): |
|
99 |
spec += '/' |
|
100 |
asset = resolver.resolve(spec) |
|
101 |
directory = asset.abspath() |
|
102 |
if not asset.isdir(): |
0c29cf
|
103 |
raise ConfigurationError( |
MM |
104 |
'"%s" is not a directory' % directory |
|
105 |
) |
|
106 |
intr = self.introspectable( |
|
107 |
'translation directories', |
|
108 |
directory, |
|
109 |
spec, |
|
110 |
'translation directory', |
|
111 |
) |
0c1c58
|
112 |
intr['directory'] = directory |
MM |
113 |
intr['spec'] = spec |
|
114 |
introspectables.append(intr) |
|
115 |
directories.append(directory) |
5bf23f
|
116 |
|
b24aeb
|
117 |
tdirs = self.registry.queryUtility(ITranslationDirectories) |
MM |
118 |
if tdirs is None: |
|
119 |
tdirs = [] |
|
120 |
self.registry.registerUtility(tdirs, ITranslationDirectories) |
d009c0
|
121 |
if override: |
MM |
122 |
tdirs.extend(directories) |
|
123 |
else: |
|
124 |
for directory in reversed(directories): |
|
125 |
tdirs.insert(0, directory) |
5bf23f
|
126 |
|
3b5ccb
|
127 |
self.action(None, register, introspectables=introspectables) |