in lib/l10n_utils/__init__.py [0:0]
def render(request, template, context=None, ftl_files=None, activation_files=None, **kwargs):
"""
Same as django's render() shortcut, but with l10n template support.
If used like this::
return l10n_utils.render(request, 'myapp/mytemplate.html')
... this helper will render the following template::
l10n/LANG/myapp/mytemplate.html
if present, otherwise, it'll render the specified (en-US) template.
"""
# use copy() here to avoid modifying the dict in a view that will then
# be different on the next call to the view.
context = context.copy() if context else {}
l10n = None
ftl_files = ftl_files or context.get("ftl_files")
locale = get_locale(request)
# is this a non-locale page?
name_prefix = request.path_info.split("/", 2)[1]
non_locale_url = name_prefix in settings.SUPPORTED_NONLOCALES or request.path_info in settings.SUPPORTED_LOCALE_IGNORE
# is this a CMS page?
is_cms_page = hasattr(request, "is_cms_page") and request.is_cms_page
# Make sure we have a single template
if isinstance(template, list):
template = template[0]
if ftl_files:
if isinstance(ftl_files, str):
ftl_files = [ftl_files]
# do not use list.extend() or += here to avoid modifying
# the original list passed to the function
ftl_files = ftl_files + settings.FLUENT_DEFAULT_FILES
context["fluent_l10n"] = l10n = fluent_l10n([locale, "en"], ftl_files)
else:
context["fluent_l10n"] = fluent_l10n([locale, "en"], settings.FLUENT_DEFAULT_FILES)
context["fluent_files"] = ftl_files or settings.FLUENT_DEFAULT_FILES
context["template"] = template
context["template_source_url"] = template_source_url(template)
# if it's a CMS page, draw the active locales from the Page data.
# if `active_locales` is given use it as the full list of active translations
translations = []
if is_cms_page and request._locales_available_via_cms:
translations = request._locales_available_via_cms
elif "active_locales" in context:
translations = context["active_locales"]
del context["active_locales"]
else:
if activation_files:
translations = set()
for af in activation_files:
translations.update(ftl_active_locales(af))
translations = sorted(translations) # `sorted` returns a list.
elif l10n:
translations = l10n.active_locales
# if `add_active_locales` is given then add it to the translations for the template
if "add_active_locales" in context:
translations.extend(context["add_active_locales"])
del context["add_active_locales"]
if not translations:
translations = [settings.LANGUAGE_CODE]
context["translations"] = get_translations_native_names(translations)
# Ensure the path requires a locale prefix.
if not non_locale_url:
# If the requested path's locale is different from the best matching
# locale stored on the `request`, and that locale is one of the active
# translations, redirect to it. Otherwise we need to find the best
# matching locale.
# Does that path's locale match the request's locale?
# AND is it NOT for the root path with no discernable lang?
if locale in translations and not is_root_path_with_no_language_clues(request):
# Redirect to the locale if:
# - The URL is the root path but is missing the trailing slash OR
# - The locale isn't the current prefix in the URL
if request.path == f"/{locale}" or locale != request.path.lstrip("/").partition("/")[0]:
return redirect_to_locale(request, locale)
else:
return redirect_to_best_locale(request, translations)
# Look for locale-specific template in app/templates/
locale_tmpl = f".{locale}".join(splitext(template))
try:
return django_render(request, locale_tmpl, context, **kwargs)
except TemplateDoesNotExist:
pass
# Render originally requested/default template.
return django_render(request, template, context, **kwargs)