Fixed #10285 - Added render_comment_list template tag to comments app. Thanks Kyle Fuller for the patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@12082 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Jannis Leidel 2010-01-04 02:29:12 +00:00
parent f6c519e2b9
commit b9d698e9f2
5 changed files with 122 additions and 6 deletions

View File

@ -0,0 +1,10 @@
<dl id="comments">
{% for comment in comment_list %}
<dt id="c{{ comment.id }}">
{{ comment.submit_date }} - {{ comment.name }}
</dt>
<dd>
<p>{{ comment.comment }}</p>
</dd>
{% endfor %}
</dl>

View File

@ -169,6 +169,46 @@ class RenderCommentFormNode(CommentFormNode):
else: else:
return '' return ''
class RenderCommentListNode(CommentListNode):
"""Render the comment list directly"""
#@classmethod
def handle_token(cls, parser, token):
"""Class method to parse render_comment_list and return a Node."""
tokens = token.contents.split()
if tokens[1] != 'for':
raise template.TemplateSyntaxError("Second argument in %r tag must be 'for'" % tokens[0])
# {% render_comment_list for obj %}
if len(tokens) == 3:
return cls(object_expr=parser.compile_filter(tokens[2]))
# {% render_comment_list for app.models pk %}
elif len(tokens) == 4:
return cls(
ctype = BaseCommentNode.lookup_content_type(tokens[2], tokens[0]),
object_pk_expr = parser.compile_filter(tokens[3])
)
handle_token = classmethod(handle_token)
def render(self, context):
ctype, object_pk = self.get_target_ctype_pk(context)
if object_pk:
template_search_list = [
"comments/%s/%s/list.html" % (ctype.app_label, ctype.model),
"comments/%s/list.html" % ctype.app_label,
"comments/list.html"
]
qs = self.get_query_set(context)
context.push()
liststr = render_to_string(template_search_list, {
"comment_list" : self.get_context_value_from_queryset(context, qs)
}, context)
context.pop()
return liststr
else:
return ''
# We could just register each classmethod directly, but then we'd lose out on # We could just register each classmethod directly, but then we'd lose out on
# the automagic docstrings-into-admin-docs tricks. So each node gets a cute # the automagic docstrings-into-admin-docs tricks. So each node gets a cute
# wrapper function that just exists to hold the docstring. # wrapper function that just exists to hold the docstring.
@ -216,6 +256,24 @@ def get_comment_list(parser, token):
""" """
return CommentListNode.handle_token(parser, token) return CommentListNode.handle_token(parser, token)
#@register.tag
def render_comment_list(parser, token):
"""
Render the comment list (as returned by ``{% get_comment_list %}``)
through the ``comments/list.html`` template
Syntax::
{% render_comment_list for [object] %}
{% render_comment_list for [app].[model] [object_id] %}
Example usage::
{% render_comment_list for event %}
"""
return RenderCommentListNode.handle_token(parser, token)
#@register.tag #@register.tag
def get_comment_form(parser, token): def get_comment_form(parser, token):
""" """
@ -272,3 +330,4 @@ register.tag(get_comment_form)
register.tag(render_comment_form) register.tag(render_comment_form)
register.simple_tag(comment_form_target) register.simple_tag(comment_form_target)
register.simple_tag(get_comment_permalink) register.simple_tag(get_comment_permalink)
register.tag(render_comment_list)

View File

@ -39,6 +39,18 @@ available in the context, then you can refer to it directly::
{% get_comment_count for entry as comment_count %} {% get_comment_count for entry as comment_count %}
<p>{{ comment_count }} comments have been posted.</p> <p>{{ comment_count }} comments have been posted.</p>
Next, we can use the :ttag:`render_comment_list` tag, to render all comments
to the given instance (``entry``) by using the ``comments/list.html`` template.
{% render_comment_list for entry %}
Django will will look for the ``list.html`` under the following directories
(for our example)::
comments/blog/post/list.html
comments/blog/list.html
comments/list.html
To get a list of comments, we make use of the :ttag:`get_comment_list` tag. To get a list of comments, we make use of the :ttag:`get_comment_list` tag.
This tag's usage is very similar to the :ttag:`get_comment_count` tag. We This tag's usage is very similar to the :ttag:`get_comment_count` tag. We
need to remember that the :ttag:`get_comment_list` returns a list of comments need to remember that the :ttag:`get_comment_list` returns a list of comments
@ -58,7 +70,7 @@ display the comments template available under your ``comments/form.html``.
The other method gives you a chance to customize the form. The other method gives you a chance to customize the form.
The first method makes use of the :ttag:`render_comment_form` tag. It's usage The first method makes use of the :ttag:`render_comment_form` tag. It's usage
too is similar to the other two tags we have discussed above:: too is similar to the other three tags we have discussed above::
{% render_comment_form for entry %} {% render_comment_form for entry %}
@ -74,6 +86,7 @@ tag called :ttag:`comment_form_target`. This tag on rendering gives the URL
where the comment form is posted. Without any :ref:`customization where the comment form is posted. Without any :ref:`customization
<ref-contrib-comments-custom>`, :ttag:`comment_form_target` evaluates to <ref-contrib-comments-custom>`, :ttag:`comment_form_target` evaluates to
``/comments/post/``. We use this tag in the form's ``action`` attribute. ``/comments/post/``. We use this tag in the form's ``action`` attribute.
The :ttag:`get_comment_form` tag renders a ``form`` for a model instance by The :ttag:`get_comment_form` tag renders a ``form`` for a model instance by
creating a context variable. One can iterate over the ``form`` object to creating a context variable. One can iterate over the ``form`` object to
get individual fields. This gives you fine-grain control over the form:: get individual fields. This gives you fine-grain control over the form::

View File

@ -84,11 +84,34 @@ different ways you can specify which object to attach to:
In the above, ``blog.entry`` is the app label and (lower-cased) model In the above, ``blog.entry`` is the app label and (lower-cased) model
name of the model class. name of the model class.
.. templatetag:: get_comment_list
Displaying comments Displaying comments
------------------- -------------------
To display a list of comments, you can use the template tags
:ttag:`render_comment_list` or :ttag:`get_comment_list`.
.. templatetag:: render_comment_list
Quickly rendering a comment list
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The easiest way to display a list of comments for some object is by using
:ttag:`render_comment_list`::
{% render_comment_list for [object] %}
For example::
{% render_comment_list for event %}
This will render comments using a template named ``comments/list.html``, a
default version of which is included with Django.
.. templatetag:: get_comment_list
Rendering a custom comment list
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To get the list of comments for some object, use :ttag:`get_comment_list`:: To get the list of comments for some object, use :ttag:`get_comment_list`::
{% get_comment_list for [object] as [varname] %} {% get_comment_list for [object] as [varname] %}

View File

@ -83,4 +83,15 @@ class CommentTemplateTagTests(CommentTestCase):
ctx, out = self.render(t, author=author) ctx, out = self.render(t, author=author)
self.assertEqual(out, "/cr/%s/%s/#c2-by-Joe Somebody" % (ct.id, author.id)) self.assertEqual(out, "/cr/%s/%s/#c2-by-Joe Somebody" % (ct.id, author.id))
def testRenderCommentList(self, tag=None):
t = "{% load comments %}" + (tag or "{% render_comment_list for comment_tests.article a.id %}")
ctx, out = self.render(t, a=Article.objects.get(pk=1))
self.assert_(out.strip().startswith("<dl id=\"comments\">"))
self.assert_(out.strip().endswith("</dl>"))
def testRenderCommentListFromLiteral(self):
self.testRenderCommentList("{% render_comment_list for comment_tests.article 1 %}")
def testRenderCommentListFromObject(self):
self.testRenderCommentList("{% render_comment_list for a %}")