summaryrefslogtreecommitdiff
path: root/src/jinja2/ext.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/jinja2/ext.py')
-rw-r--r--src/jinja2/ext.py63
1 files changed, 57 insertions, 6 deletions
diff --git a/src/jinja2/ext.py b/src/jinja2/ext.py
index 73a2e77..0b2b441 100644
--- a/src/jinja2/ext.py
+++ b/src/jinja2/ext.py
@@ -30,7 +30,7 @@ from .utils import import_string
# I18N functions available in Jinja templates. If the I18N library
# provides ugettext, it will be assigned to gettext.
-GETTEXT_FUNCTIONS = ("_", "gettext", "ngettext")
+GETTEXT_FUNCTIONS = ("_", "gettext", "ngettext", "pgettext", "npgettext")
_ws_re = re.compile(r"\s*\n\s*")
@@ -167,6 +167,37 @@ def _make_new_ngettext(func):
return ngettext
+def _make_new_pgettext(func):
+ @contextfunction
+ def pgettext(__context, __string_ctx, __string, **variables):
+ variables.setdefault("context", __string_ctx)
+ rv = __context.call(func, __string_ctx, __string)
+
+ if __context.eval_ctx.autoescape:
+ rv = Markup(rv)
+
+ # Always treat as a format string, see gettext comment above.
+ return rv % variables
+
+ return pgettext
+
+
+def _make_new_npgettext(func):
+ @contextfunction
+ def npgettext(__context, __string_ctx, __singular, __plural, __num, **variables):
+ variables.setdefault("context", __string_ctx)
+ variables.setdefault("num", __num)
+ rv = __context.call(func, __string_ctx, __singular, __plural, __num)
+
+ if __context.eval_ctx.autoescape:
+ rv = Markup(rv)
+
+ # Always treat as a format string, see gettext comment above.
+ return rv % variables
+
+ return npgettext
+
+
class InternationalizationExtension(Extension):
"""This extension adds gettext support to Jinja."""
@@ -200,23 +231,43 @@ class InternationalizationExtension(Extension):
ngettext = getattr(translations, "ungettext", None)
if ngettext is None:
ngettext = translations.ngettext
- self._install_callables(gettext, ngettext, newstyle)
+
+ pgettext = getattr(translations, "pgettext", None)
+ npgettext = getattr(translations, "npgettext", None)
+ self._install_callables(
+ gettext, ngettext, newstyle=newstyle, pgettext=pgettext, npgettext=npgettext
+ )
def _install_null(self, newstyle=None):
self._install_callables(
- lambda x: x, lambda s, p, n: s if n == 1 else p, newstyle
+ lambda s: s,
+ lambda s, p, n: s if n == 1 else p,
+ newstyle=newstyle,
+ pgettext=lambda c, s: s,
+ npgettext=lambda c, s, p, n: s if n == 1 else p,
)
- def _install_callables(self, gettext, ngettext, newstyle=None):
+ def _install_callables(
+ self, gettext, ngettext, newstyle=None, pgettext=None, npgettext=None
+ ):
if newstyle is not None:
self.environment.newstyle_gettext = newstyle
if self.environment.newstyle_gettext:
gettext = _make_new_gettext(gettext)
ngettext = _make_new_ngettext(ngettext)
- self.environment.globals.update(gettext=gettext, ngettext=ngettext)
+
+ if pgettext is not None:
+ pgettext = _make_new_pgettext(pgettext)
+
+ if npgettext is not None:
+ npgettext = _make_new_npgettext(npgettext)
+
+ self.environment.globals.update(
+ gettext=gettext, ngettext=ngettext, pgettext=pgettext, npgettext=npgettext
+ )
def _uninstall(self, translations):
- for key in "gettext", "ngettext":
+ for key in ("gettext", "ngettext", "pgettext", "npgettext"):
self.environment.globals.pop(key, None)
def _extract(self, source, gettext_functions=GETTEXT_FUNCTIONS):