#17085: Deprecate "add_to_builtins" and turn builtins into a property of Engine
---------------------------------+------------------------------------
Reporter: carljm | Owner: nobody
Type: New feature | Status: new
Component: Template system | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
---------------------------------+------------------------------------
Changes (by aaugustin):
* stage: Unreviewed => Accepted
Comment:
When I worked on #17093 I treated template tag and filter libraries (i.e.
`myapp/templatetags/*.py`) like Python modules. Each Python module is
referenced in `sys.modules` and can be imported as needed. Likewise, each
library is referenced in `django.template.base.libraries` and can be
loaded in templates as needed.
----
To give some background on the issue, builtin libraries are simply added
to `django.template.base.builtins` as follows:
{{{
builtins = []
def add_to_builtins(module):
builtins.append(import_library(module))
add_to_builtins('django.template.defaulttags')
add_to_builtins('django.template.defaultfilters')
add_to_builtins('django.template.loader_tags')
}}}
If we want to discourage adding libraries to builtins, this code can be
simplified to:
{{{
builtins = [
import_library('django.template.defaulttags'),
import_library('django.template.defaultfilters'),
import_library('django.template.loader_tags'),
]
}}}
However it will still be trivial to add things to builtins by appending to
this list if you want to, so this breaks third-party code without
providing real advantages in terms of isolation. I'm against doing this.
----
Turning `builtins` into a property of the `Engine` class would be much
more interesting.
That's easy because builtins` is only used in `Parser.__init__` which is
only called from `Engine.compile_string`.
Then extra builtins could be configured like this:
{{{
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'APP_DIRS': True,
'OPTIONS': {
'extra_builtins': [
'foobar.templatetags',
],
},
},
]
}}}
With this solution, authors of pluggable apps will have the choice between
using `{% load ... %}` in their templates (and the only excuse for not
doing so is laziness) or documenting that their users must configure some
extra builtins in TEMPLATES. Developers of projects can easily add
builtins for use within the project.
----
I understand that adding builtins sounds horrific from the perspective of
a Python developer, but within a given project and in templates it seems
acceptable:
- templates have tons of builtins already and it isn't a problem because
the situation is more simple than with Python imports: you don't go read
the source of templatetags, unless it shows up in the debug page
- as long as the extra builtins are defined within the same project,
they're just a "Find-all" away (with the caveat that you can still shoot
yourself into the foot by adding third-party tags in extra builtins...)
--
Ticket URL: <https://code.djangoproject.com/ticket/17085#comment:6>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/064.49a45d0fb21915bb9158ffdfcb9b2f13%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.