diff --git a/frappe/utils/jinja.py b/frappe/utils/jinja.py index 4e5a2b6a1a..63f48a9b9f 100644 --- a/frappe/utils/jinja.py +++ b/frappe/utils/jinja.py @@ -6,35 +6,39 @@ from frappe.utils.caching import site_cache def get_jenv(): import frappe + from frappe.utils.safe_exec import get_safe_globals - if not getattr(frappe.local, "jenv", None): - from jinja2 import DebugUndefined - from jinja2.sandbox import SandboxedEnvironment + jenv = _get_jenv() + jenv.globals.update(get_safe_globals()) # TODO: This isn't thread safe. + frappe.local.jenv = jenv + return jenv - from frappe.utils.safe_exec import UNSAFE_ATTRIBUTES, get_safe_globals - UNSAFE_ATTRIBUTES = UNSAFE_ATTRIBUTES - {"format", "format_map"} +@site_cache(ttl=10 * 60, maxsize=4) +def _get_jenv(): + from jinja2 import DebugUndefined + from jinja2.sandbox import SandboxedEnvironment - class FrappeSandboxedEnvironment(SandboxedEnvironment): - def is_safe_attribute(self, obj, attr, *args, **kwargs): - if attr in UNSAFE_ATTRIBUTES: - return False + from frappe.utils.safe_exec import UNSAFE_ATTRIBUTES, get_safe_globals - return super().is_safe_attribute(obj, attr, *args, **kwargs) + UNSAFE_ATTRIBUTES = UNSAFE_ATTRIBUTES - {"format", "format_map"} - # frappe will be loaded last, so app templates will get precedence - jenv = FrappeSandboxedEnvironment(loader=get_jloader(), undefined=DebugUndefined) - set_filters(jenv) + class FrappeSandboxedEnvironment(SandboxedEnvironment): + def is_safe_attribute(self, obj, attr, *args, **kwargs): + if attr in UNSAFE_ATTRIBUTES: + return False - jenv.globals.update(get_safe_globals()) + return super().is_safe_attribute(obj, attr, *args, **kwargs) - methods, filters = get_jinja_hooks() - jenv.globals.update(methods or {}) - jenv.filters.update(filters or {}) + # frappe will be loaded last, so app templates will get precedence + jenv = FrappeSandboxedEnvironment(loader=get_jloader(), undefined=DebugUndefined) + set_filters(jenv) - frappe.local.jenv = jenv + methods, filters = get_jinja_hooks() + jenv.globals.update(methods or {}) + jenv.filters.update(filters or {}) - return frappe.local.jenv + return jenv def get_template(path):