On 30 oct, 20:22, Joe Murphy <[EMAIL PROTECTED]> wrote:
> Hi,
>
> So I've got a bunch of views that I need to output in three forms:
> HTML with the site wrapper (header, footer etc.), HTML without the
> site wrapper, and JS. The templates are really, really similar.
>
> I'm thinking of using a url pattern like:
> r'^blog/blah(?P<filetype>[-\.\/\w]+)$'
> so that blog/blah/ would return the HTML with site wrapper, blog/
> blah.html would return the HTML without wrapper, and blog/blah.js
> would return the javascript.
>
> Doing this means I'm putting logic in all the views that need this
> functionality -- and, then, building slightly-different templates for
> each of the three outputs.
>
> There's something about this that seems wrong, but I can't imagine a
> cleaner solution. Any thoughts?
I've been thinking about this recently (going to have a working
solution for the same problem pretty soon...). The cleanest solution
I've came with so far is to make the view function only return a
context, then wrap the view function in a decorator that takes care of
rendering, based on request informations. The points I'm yet really
happy with are:
- how to tell the rendering decorator what we want to render
- how to avoid template duplication for 'full' rendering and 'partial'
rendering
wrt/ first point, the simplest solution IMHO is to pass a render=json
or render=partial argument in the query string (default being
rendering the 'full' page). My main problem is with second point. I
have a working scheme using two templates, the 'full' one doing an
include of the 'partial' one. This should work, but I still don't like
having two distinct templates.
I don't have the (prototype) code at hand here, but from memory it's
something like:
class render_with(object):
def __init__(self, partial, full):
self.partial_template_path=fragment
self.full_template_path = full
def __call__(self, view):
self.view = view
return self.render
def render_json(self, request, context):
# this is in djangosnippets IIRC
return JsonResponse(context)
def render_partial(self, request, context):
return render_to_response(
self.partial_template_path,
context,
context_instance=RequestContext(request)
)
def render_full(self, request, context):
context['partial_include'] = self.partial_template_path
return render_to_response(
self.full_template_path,
context,
context_instance=RequestContext(request)
)
def render(self, request, *args, **kw)
context = self.view(request, *args, **kw)
# the view can still return a response object
if isinstance(context, HttpResponse):
return context
# ok, it's really a context
render_mode = request.REQUEST.get('render', 'full')
render_method = getattr(self, 'render_%s' % render_mode)
return render_method(request, context)
Then you use it that way:
# myview.py
@render_with(partial='mypartial.html', full='myfull.html')
def myview(request, somearg):
return dict(yadda='yadda')
# mypartial.html
<p>
Yadda : {{ yadda }}
</p>
# myfull.html
{% extends 'base.html' %}
{% block stuff %}
{{ yadday }} stuff here
{% endblock %}
{% block main %}
{% include partial_include %}
{% endblock %}
{% block other %}
other {{ yadda }} stuff here
{% endblock %}
HTH
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---