fantomas42 / django-app-namespace-template-loader Goto Github PK
View Code? Open in Web Editor NEWTemplate loader allowing you to both extend and override a template at the same time.
License: BSD 3-Clause "New" or "Revised" License
Template loader allowing you to both extend and override a template at the same time.
License: BSD 3-Clause "New" or "Revised" License
With:
TEMPLATES_DJANGO = {
...
'OPTIONS': {
...
'loaders': [
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
'app_namespace.Loader',
],
},
}
I get the following on second and subsequent request for a page that is extended with a namespace:
Traceback (most recent call last):
File "/Users/tailee/.pyenv/versions/2.7.10/lib/python2.7/wsgiref/handlers.py", line 85, in run
self.result = application(self.environ, self.start_response)
File "/Users/tailee/.virtualenvs/icekit-sprint/lib/python2.7/site-packages/django/contrib/staticfiles/handlers.py", line 63, in __call__
return self.application(environ, start_response)
File "/Users/tailee/.virtualenvs/icekit-sprint/lib/python2.7/site-packages/django/core/handlers/wsgi.py", line 189, in __call__
response = self.get_response(request)
File "/Users/tailee/.virtualenvs/icekit-sprint/lib/python2.7/site-packages/django/core/handlers/base.py", line 218, in get_response
response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
File "/Users/tailee/.virtualenvs/icekit-sprint/lib/python2.7/site-packages/django/core/handlers/base.py", line 261, in handle_uncaught_exception
return debug.technical_500_response(request, *exc_info)
File "/Users/tailee/.virtualenvs/icekit-sprint/lib/python2.7/site-packages/django/views/debug.py", line 97, in technical_500_response
html = reporter.get_traceback_html()
File "/Users/tailee/.virtualenvs/icekit-sprint/lib/python2.7/site-packages/django/views/debug.py", line 383, in get_traceback_html
c = Context(self.get_traceback_data(), use_l10n=False)
File "/Users/tailee/.virtualenvs/icekit-sprint/lib/python2.7/site-packages/django/views/debug.py", line 313, in get_traceback_data
} for t in source_list_func(str(self.exc_value))]
File "/Users/tailee/.virtualenvs/icekit-sprint/lib/python2.7/site-packages/django/views/debug.py", line 270, in format_path_status
if not os.path.exists(path):
File "/Users/tailee/.virtualenvs/icekit-sprint/lib/python2.7/genericpath.py", line 26, in exists
os.stat(path)
TypeError: coercing to Unicode: need string or buffer, NamespaceOrigin found
This shows up in stdout for manage.py runserver
and the browser just says A server error occurred. Please contact the administrator.
even thought DEBUG
is True
.
I assume this error is because on the first request, the template is found by app_namespace.Loader
which creates a NamespaceOrigin
which is somehow cached across requests. On second request, the NamespaceOrigin
is being passed to Django's loaders which expect a simple string.
If it is required that app_namespace.Loader
be first, this should be documented. Although it seems like this should not be a requirement. Perhaps NamespaceOrigin
objects need a __unicode__()
method or something, so they can be passed to other loaders, even if the unicode value is something that will never match another loader. Or perhaps the NamespaceOrigin
object shouldn't be cached across requests?
On Django 1.9, it seems django.template.base.TemplateDoesNotExist
as been removed, which cause template rendering to fail with the following stack trace :
"""Template loader for app-namespace"""
import os
import sys
from importlib import import_module
from collections import OrderedDict
import six
from django.conf import settings
from django.utils._os import safe_join
from django.utils.functional import cached_property
> from django.template.base import TemplateDoesNotExist
E ImportError: cannot import name 'TemplateDoesNotExist'
.tox/py34/lib/python3.4/site-packages/app_namespace/loader.py:12: ImportError
I'll make a pull request to solve this.
I assume to reproduce the error, one would override a template that extends from a template in a different app namespace.
The error can't be rendered by the technical 500 view (see stacktrace below), and shows up as a TemplateDoesNotExist: icekit_plugins_file:icekit/plugins/contact_person/default.html
in an error log.
A more friendly error than 'TemplateDoesNotExist' would be helpful, but I'm not sure enough about what's going on to be able to suggest one.
File "/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/wsgiref/handlers.py", line 85, in run
self.result = application(self.environ, self.start_response)
File "/Users/gturner/Sites/acmi/var/go.sh-venv/lib/python2.7/site-packages/django/contrib/staticfiles/handlers.py", line 63, in __call__
return self.application(environ, start_response)
File "/Users/gturner/Sites/acmi/var/go.sh-venv/lib/python2.7/site-packages/django/core/handlers/wsgi.py", line 189, in __call__
response = self.get_response(request)
File "/Users/gturner/Sites/acmi/var/go.sh-venv/lib/python2.7/site-packages/django/core/handlers/base.py", line 218, in get_response
response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
File "/Users/gturner/Sites/acmi/var/go.sh-venv/lib/python2.7/site-packages/django/core/handlers/base.py", line 261, in handle_uncaught_exception
return debug.technical_500_response(request, *exc_info)
File "/Users/gturner/Sites/acmi/var/go.sh-venv/lib/python2.7/site-packages/django/views/debug.py", line 97, in technical_500_response
html = reporter.get_traceback_html()
File "/Users/gturner/Sites/acmi/var/go.sh-venv/lib/python2.7/site-packages/django/views/debug.py", line 383, in get_traceback_html
c = Context(self.get_traceback_data(), use_l10n=False)
File "/Users/gturner/Sites/acmi/var/go.sh-venv/lib/python2.7/site-packages/django/views/debug.py", line 313, in get_traceback_data
} for t in source_list_func(str(self.exc_value))]
File "/Users/gturner/Sites/acmi/var/go.sh-venv/lib/python2.7/site-packages/django/views/debug.py", line 270, in format_path_status
if not os.path.exists(path):
File "/Users/gturner/Sites/acmi/var/go.sh-venv/bin/../lib/python2.7/genericpath.py", line 18, in exists
os.stat(path)
TypeError: coercing to Unicode: need string or buffer, NamespaceOrigin found```
I installed django-blog-zinnia. in the Djang Web project folder.
$tree -L 1
├── app_namespace
├── blog
├── db.sqlite3
├── manage.py
├── __pycache__
├── six.py
├── zinnia
├── zinnia_bootstrap
then $python3 manage.py runserver
open localhost:8000/weblog, there is this infomation
AttributeError at /weblog/
'module' object has no attribute '__file__'
Request Method: GET
Request URL: http://localhost:8000/weblog/
Django Version: 1.8.4
Exception Type: AttributeError
Exception Value:
'module' object has no attribute '__file__'
Exception Location: /tmp/zinnia/blog/app_namespace/loader.py in app_templates_dirs, line 59
Python Executable: /usr/bin/python3
Python Version: 3.4.3
Python Path:
['/tmp/zinnia/blog',
'/usr/local/lib/python3.4/dist-packages/Pillow-2.9.0-py3.4-linux-x86_64.egg',
'/usr/lib/python3.4',
'/usr/lib/python3.4/plat-x86_64-linux-gnu',
'/usr/lib/python3.4/lib-dynload',
'/usr/local/lib/python3.4/dist-packages',
'/usr/lib/python3/dist-packages']
Server time: Wed, 21 Oct 2015 16:11:46 +0000
But I installed django-blog-zinnia. in /usr/local/lib/python3/dist-packages/
,
then I test it, it is normal.
Could you fix it?
I am often switching between admin
and grappelli
for admin templates when debugging some template related issues (to see if it is caused by grappelli).
Then I have to change e.g. {% extends "grappelli:admin/index.html" %}
to {% extends "admin:admin/change_form.html" %}
.
Since django-app-namespace-template-loader appears to skip any templates which do not contain a :
, I wonder if a special syntax like :admin/change_form.html
could be used to extend the default template, which means to use the first one which is not the current template itself?
This would allow me to only remove/comment grappelli
in INSTALLED_APPS
, without modifying any templates.
Applications in Django>=1.7 can be added to the INSTALLED APPS
by using the dotted path to their AppConfig
, e.g. 'app_name.apps.AppConfig'.
This leads to an import error right here: https://github.com/Fantomas42/django-app-namespace-template-loader/blob/develop/app_namespace/loader.py#L55
Any ideas?
After I had to upgrade my django version to 1.8.3, I ran into this issue with zinnia: http://dpaste.com/0DPVTA5
I opened this issue here because I figured this is a problem of the Loader
class of this project, and not a problem of zinnia. I tried to update all the dependencies of zinnia and django-app-namespace-template-loader with pip to the newest version, but the problem persisted.
This looks like a newer version of django expects something differently of that template loader class. I'm not really into those django internals, can you have a look at this?
Hi @Fantomas42
I just stumbled upon your implementation and was wondering if you have considered leaving it to these Bitbucket using people?
https://pypi.python.org/pypi/django-apptemplates/
They already have Django 1.9 support and are pretty quick at updating stuff.
https://docs.djangoproject.com/en/1.8/ref/settings/#template-loaders
"Set the 'loaders' option in the OPTIONS of a DjangoTemplates backend instead."
I had a template icekit/integration/reversion/templates/admin/fluent_pages/page/change_list.html
that had {% extends "icekit:admin/fluent_pages/page/change_list.html" %}
at the top and which defined {% block object-tools-items %}
to add a "Recover deleted pages" button.
At some point, the icekit/templates/admin/fluent_pages/page/change_list.html
file was removed, because its overrides were no longer needed.
Surprisingly, the pages change list still rendered the reversion integration template, but it duplicated the contents of the object-tools-items
block, so there were two "Recover deleted pages" buttons.
I tried {% extends "icekit:admin/fluent_pages/page/change_list.html" %}
and even {% extends "foo:admin/fluent_pages/page/change_list.html" %}
(foo
being an invalid app namespace) and {% extends "admin:admin/fluent_pages/page/change_list.html" %}
(admin
being a valid app namespace, but not one that contained the specified template). All these exhibited the same behaviour.
Only specifying a different valid app namespace (where the template exists) worked: {% extends "fluent_pages:admin/fluent_pages/page/change_list.html" %}
.
I would expect an invalid app namespace to either raise an exception (if DEBUG=True
) or fail to match any templates. I would expect a valid namespace that doesn't contain the specified template to fail to match. I would expect an empty namespace to match the first app namespace that contains the template according to INSTALLED_APPS
order.
I write these to code to cover the default tempate:
{% extends "zinnia_bootstrap:zinnia/skeleton.html" %}
{% load staticfiles %}
{% block link %}
<link rel="stylesheet" href="{% static "test.css" %}" />
{% endblock%}
but things doesn't work, <link rel="stylesheet" href="{% static "test.css" %}" /> doesn't populate on the link block. Nothing happened.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.