diff --git a/django/contrib/comments/templates/comments/list.html b/django/contrib/comments/templates/comments/list.html
new file mode 100644
index 0000000000..3d4ec1ed8f
--- /dev/null
+++ b/django/contrib/comments/templates/comments/list.html
@@ -0,0 +1,10 @@
+
diff --git a/django/contrib/comments/templatetags/comments.py b/django/contrib/comments/templatetags/comments.py
index 1ebc9dba34..8e62f91eed 100644
--- a/django/contrib/comments/templatetags/comments.py
+++ b/django/contrib/comments/templatetags/comments.py
@@ -81,10 +81,10 @@ class BaseCommentNode(template.Node):
object_pk = smart_unicode(object_pk),
site__pk = settings.SITE_ID,
)
-
+
# The is_public and is_removed fields are implementation details of the
# built-in comment model's spam filtering system, so they might not
- # be present on a custom comment model subclass. If they exist, we
+ # be present on a custom comment model subclass. If they exist, we
# should filter on them.
field_names = [f.name for f in self.comment_model._meta.fields]
if 'is_public' in field_names:
@@ -169,6 +169,46 @@ class RenderCommentFormNode(CommentFormNode):
else:
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
# the automagic docstrings-into-admin-docs tricks. So each node gets a cute
# 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)
+#@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
def get_comment_form(parser, token):
"""
@@ -271,4 +329,5 @@ register.tag(get_comment_list)
register.tag(get_comment_form)
register.tag(render_comment_form)
register.simple_tag(comment_form_target)
-register.simple_tag(get_comment_permalink)
\ No newline at end of file
+register.simple_tag(get_comment_permalink)
+register.tag(render_comment_list)
diff --git a/docs/ref/contrib/comments/example.txt b/docs/ref/contrib/comments/example.txt
index 626e8b4a95..e9445353ca 100644
--- a/docs/ref/contrib/comments/example.txt
+++ b/docs/ref/contrib/comments/example.txt
@@ -39,6 +39,18 @@ available in the context, then you can refer to it directly::
{% get_comment_count for entry as comment_count %}
{{ comment_count }} comments have been posted.
+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.
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
@@ -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 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 %}
@@ -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
`, :ttag:`comment_form_target` evaluates to
``/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
creating a context variable. One can iterate over the ``form`` object to
get individual fields. This gives you fine-grain control over the form::
diff --git a/docs/ref/contrib/comments/index.txt b/docs/ref/contrib/comments/index.txt
index f66d14d0c4..9f53f06299 100644
--- a/docs/ref/contrib/comments/index.txt
+++ b/docs/ref/contrib/comments/index.txt
@@ -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
name of the model class.
-.. templatetag:: get_comment_list
-
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`::
{% get_comment_list for [object] as [varname] %}
diff --git a/tests/regressiontests/comment_tests/tests/templatetag_tests.py b/tests/regressiontests/comment_tests/tests/templatetag_tests.py
index 7cb2148b54..669caff667 100644
--- a/tests/regressiontests/comment_tests/tests/templatetag_tests.py
+++ b/tests/regressiontests/comment_tests/tests/templatetag_tests.py
@@ -83,4 +83,15 @@ class CommentTemplateTagTests(CommentTestCase):
ctx, out = self.render(t, author=author)
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(""))
+
+ def testRenderCommentListFromLiteral(self):
+ self.testRenderCommentList("{% render_comment_list for comment_tests.article 1 %}")
+
+ def testRenderCommentListFromObject(self):
+ self.testRenderCommentList("{% render_comment_list for a %}")
{{ comment.comment }}
+