Code

Opened 9 years ago

Closed 9 years ago

Last modified 8 years ago

#582 closed (fixed)

[patch] Load templates from application eggs

Reported by: sune.kirkeby@… Owned by: adrian
Component: Template system Version:
Severity: normal Keywords: apps eggs templates
Cc: Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

The attached patch changes django.core.template_loader to try several different template-source-loaders; first it tries the vanilla django.core.template_file loader; then it tries the new django.core.template_eggs loader. The new loader tries to load the named template from 'templates/%s' % name for each installed app. So one can package an app as a python egg and distribute it as one file with default templates included, and installation is as simple as dropping it somewhere in sys.path :)

Attachments (6)

template_eggs.patch (1.8 KB) - added by sune.kirkeby@… 9 years ago.
template_eggs-newfiles.tar (10.0 KB) - added by sune.kirkeby@… 9 years ago.
New unittests and testapp egg
template_eggs-runtests.patch (1.3 KB) - added by sune.kirkeby@… 9 years ago.
Add app-egg to test environment
template_eggs-2.patch (2.6 KB) - added by sune.kirkeby@… 9 years ago.
TEMPLATE_SOURCE_LOADERS moved into global_settings
template_eggs-3.patch (3.1 KB) - added by sune.kirkeby@… 9 years ago.
template_eggs-4.patch (3.1 KB) - added by sune.kirkeby@… 9 years ago.
Python 2.3 safe patch

Download all attachments as: .zip

Change History (16)

Changed 9 years ago by sune.kirkeby@…

Changed 9 years ago by sune.kirkeby@…

New unittests and testapp egg

Changed 9 years ago by sune.kirkeby@…

Add app-egg to test environment

comment:1 Changed 9 years ago by adrian

This is an interesting idea! However, I suspect most people aren't going to use eggs to store their templates, so I think this should be an opt-in thing. I don't want the extra "look for templates in eggs" overhead to affect people who don't use eggs. As in #583, a good compromise might be to introduce an opt-in setting: ALLOW_TEMPLATES_IN_EGGS, perhaps? Or we could move the template_source_loaders into settings, so that people have the flexibility to define their own template loaders.

comment:2 Changed 9 years ago by anonymous

However, I suspect most people aren't going to use eggs to store their templates, so I think this should be an opt-in thing. I don't want the extra "look for templates in eggs" overhead to affect people who don't use eggs.

I'm not sure there is any noticable performance penalty here, after all the template_eggs loader is only invoked if the template is not found in any of TEMPLATE_DIRS. So, for people who do not use eggs, it will only execute if they try to load a non-existing template.

But, I will attach a new patch, which moves TEMPLATE_SOURCE_LOADERS into global_settings.

Changed 9 years ago by sune.kirkeby@…

TEMPLATE_SOURCE_LOADERS moved into global_settings

comment:3 Changed 9 years ago by sune.kirkeby@…

Mental note to self: I should not touch code before the third cup of coffee. Please ignore the -2.patch, it's broken in several dumb ways. The -3.patch works for me, and passes the unittests.

Changed 9 years ago by sune.kirkeby@…

Changed 9 years ago by sune.kirkeby@…

Python 2.3 safe patch

comment:4 Changed 9 years ago by adrian

  • Status changed from new to assigned

Another question: As the patch stands, template_eggs.load_template_source() will fail silently (raising TemplateDoesNotExist) if resource_string() isn't available. Should it instead raise ImproperlyConfigured to tell the Django admin to remove django.core.template_eggs.load_template_source from the TEMPLATE_SOURCE_LOADERS setting?

comment:5 Changed 9 years ago by adrian

A follow-up to my previous comment. If indeed we changed template_eggs.load_template_source() to raise ImproperlyConfigured, we'd have to remove template_eggs.load_template_source from TEMPLATE_SOURCE_LOADERS in global_settings. Which would mean people would have to manually activate it.

comment:6 Changed 9 years ago by Sune Kirkeby <sune.kirkeby@…>

Silent failure are nasty critters; on the other hand, I like the all batteries included'ness of having it in global_settings. Maybe we could issue a warning if importing pkg_resources fails?

comment:7 Changed 9 years ago by hugo

couldn't django.conf.settings fix the TEMPLATE_SOURCE_LOADERS if resource_string isn't available? It could issue a warning that it is about to remove incompatible loader stuff and then go on. Or make the template source loaders "intelligent" with a "is_useable" hook - the init stuff of django tries to load the TEMPLATE_SOURCE_LOADERS and check their is_useable() hook and if that returns False, doesn't load it. That way template loaders could be added for stuff that's optional in the python environment but could still be listed in the global settings to give the "batteries included" feeling.

comment:8 Changed 9 years ago by adrian

The is_usable() hook idea is a good one, combined with the concept of throwing a warning at the init stage.

How's this for an algorithm:

  • For each loader in TEMPLATE_SOURCE_LOADERS:
    • If loader.is_usable()
      • Register the loader
    • Else
      • Throw a warning "Loader isn't available. You might as well remove it from TEMPLATE_SOURCE_LOADERS if you're not using it."

I've made some of these changes to my local copy of Sune's patch, so there's no need to add another patch. I'll probably be checking it in later today.

comment:9 Changed 9 years ago by adrian

  • Resolution set to fixed
  • Status changed from assigned to closed

(In [870]) Fixed #582 -- Added support for loading templates from Python eggs, and a TEMPLATE_LOADERS setting, which defines which loaders to use. Thanks, Sune

comment:10 Changed 8 years ago by Here

  • Type enhancement deleted

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.