#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.

Reply via email to