Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup, example and overall improvements to django-threadedcomments #39

Merged
merged 33 commits into from
Mar 1, 2013
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
5d0e93d
added: example app
yurtaev Jun 1, 2011
e6cedd4
replaced threadedcommentstags to threadedcomments_tags; closed Issue #23
yurtaev Jun 1, 2011
9448335
Adding the migrations back into threadedcomments
coleifer Aug 8, 2011
832fb6a
Add checking for the second arg being 'for' like Django's comments.
adamfast Oct 27, 2010
608a25d
Don't delete a comment's parent with it
fcurella Jan 24, 2012
f698cf6
Merge pull request #1 from worldcompany/bugfix/last_child_on_delete
fcurella Jan 24, 2012
b760a49
Add south migration for the initial model state.
vdboor May 31, 2012
1e0e0c2
Merge 'pahaz/master' in, cleans legacy_threadedcomments
vdboor May 31, 2012
87ff76c
Merge 'worldcompany/master' in, fixes deleted parents
vdboor May 31, 2012
bc9cada
Merge 'yurtaev/master' in, adds example app and doc fix.
vdboor May 31, 2012
76888f1
Include south migration for on_delete change.
vdboor May 31, 2012
025ee78
Reset last_child for parent on deleting a child
vdboor Jun 1, 2012
eab7d35
Fix example app to run in Django 1.4
vdboor Jun 1, 2012
10ca149
Remove all the fluff in the settings, clean by default.
vdboor Jun 1, 2012
43d99a0
Clean and brush up the example app.
vdboor Jun 3, 2012
af6ee8b
Set Site to 127.0.0.1:8000, so admin preview buttons work.
vdboor Jun 3, 2012
04c0029
Fix casing of title field in the form.
vdboor Jun 3, 2012
7159f2b
Get rid of that 80 column width thing
vdboor Jun 3, 2012
1fbb2c6
Drop support for Python 2.4
vdboor Jun 3, 2012
9472891
Comment that sample_tree.html is used by unit tests
vdboor Jun 3, 2012
9788b71
Improved clarity of threadedcomments/util
vdboor Jun 3, 2012
4602905
Clarify code of threadedcomments_tags
vdboor Jun 3, 2012
0a6cbbf
Include the missing `render_comment_list` and `get_comment_count` tags
vdboor Jun 3, 2012
903842f
Move flat/root_only logic to BaseThreadedCommentNode
vdboor Jun 3, 2012
0bd61f7
Fix support in `get_comment_form` for `app.name objectid` notation.
vdboor Jun 3, 2012
3e79504
Port example to use `render_comment_list` instead.
vdboor Jun 3, 2012
784a4bf
Update example to use c### as comment HTML ID
vdboor Jun 3, 2012
c818289
Include example configuration of django.contrib.comments
vdboor Jun 3, 2012
5c73219
Override comments/list.html to have a basic threading view.
vdboor Jun 3, 2012
65e93a3
Added README
vdboor Jun 3, 2012
77e2109
Using get_object_or_404 in the example
vdboor Jun 3, 2012
3fb2e3d
Remove sampledb.db in favour of fixtures
vdboor Jun 3, 2012
6ea6b25
Fix missing super() in ThreadedComment.delete()
vdboor Jun 3, 2012
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
.pydevproject
.settings
*.swp
.idea/
6 changes: 6 additions & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Version 0.9, dev.
-----------------

Rewrote application to use django.contrib.comments
Included example app

Version 0.5.1, 31st March 2009
------------------------------

Expand Down
159 changes: 159 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
django-threadedcomments
=======================

*threadedcomments* is a Django application which allows for the simple creation of a threaded commenting system.
Commenters can reply both to the original item, and reply to other comments as well.

The application is (as of 0.9) built on top of django.contrib.comments,
which allows it to be easily extended by other modules.


Installation
============

Download this Git repository, and install it::

cd django-threadedcomments
pip install .

It's preferred to install the module in a virtual environment.

Configuration
-------------

Add the following to ``settings.py``::

INSTALLED_APPS += (
'threadedcomments',
'django.contrib.comments',
)

COMMENTS_APP = 'threadedcomments'

By placing the ``threadedcomments`` app above the ``django.contrib.comments`` application,
the placeholder ``comments/list.html`` template will already be replaced by a threaded view.

Make sure django.contrib.comments_ is configured in ``urls.py``::

urlpatterns += patterns('',
url(r'^articles/comments/', include('django.contrib.comments.urls')),
)

Provide a template that displays the comments for the ``object`` (e.g. article or blog entry)::

{% load threadedcomments_tags %}

...

<h2>Comments for {{ object.title }}:</h2>

{% render_comment_list for object %}
{% render_comment_form for object %}


Template design
---------------

Naturally, it's desirable to write your own version of ``comments/list.html`` in your project,
or use one of the ``comments/app/list.html`` or ``comments/app/model/list.html`` overrides.

Make sure to override ``comments/base.html`` as well, so the other views of django.contrib.comments_
are displayed using your web site design. The other templates of django.contrib.comments_ are
very plain as well on purpose (for example ``comments/posted.html``),
since these pages depend on the custom design of the web site.

See the provided ``example`` app for a basic configuration,
including a JavaScript-based reply form that moves to the comment the visitor replies to.


Template tags
=============

The ``threadedcomments_tags`` library is a drop-in replacement for the ``comments`` library
that is required for the plain comments. The tags are forwards compatible;
they support the same syntax as django.contrib.comments_ provides,
and they add a few extra parameters.

Fething comment counts::

{% get_comment_count for [object] as [varname] %}
{% get_comment_count for [object] as [varname] root_only %}

{% get_comment_count for [app].[model] [id] as [varname] %}
{% get_comment_count for [app].[model] [id] as [varname] root_only %}

Fetching the comments list::

{% get_comment_list for [object] as [varname] %}
{% get_comment_list for [object] as [varname] flat %}
{% get_comment_list for [object] as [varname] root_only %}

Rendering the comments list::

{% render_comment_list for [object] %}
{% render_comment_list for [object] root_only %}

{% render_comment_list for [app].[model] [id] %}
{% render_comment_list for [app].[model] [id] root_only %}

Fetching the comment form::

{% get_comment_form for [object] as [varname] %}
{% get_comment_form for [object] as [varname] with [parent_id] %}
{% get_comment_form for [app].[model] [id] as [varname] %}
{% get_comment_form for [app].[model] [id] as [varname] with [parent_id] %}

Rendering the comment form::

{% render_comment_form for [object] %}
{% render_comment_form for [object] with [parent_id] %}
{% render_comment_form for [app].[model] [id] %}
{% render_comment_form for [app].[model] [id] with [parent_id] %}

Rendering the whole tree::

{% for comment in comment_list|fill_tree|annotate_tree %}
{% ifchanged comment.parent_id %}{% else %}</li>{% endifchanged %}
{% if not comment.open and not comment.close %}</li>{% endif %}
{% if comment.open %}<ul>{% endif %}

<li id="c{{ comment.id }}">
...
{% for close in comment.close %}</li></ul>{% endfor %}
{% endfor %}

The ``fill_tree`` filter is required for pagination, it ensures that the parents of the first comment are included as well.

The ``annotate_tree`` filter adds the ``open`` and ``close`` properties to the comment.


Extending the module
====================

The application is built on top of the standard django.contrib.comments_ framework,
which supports various signals, and template overrides to customize the comments.

To customize django-threadedcomments, override the proper templates, or include the apps that provide the missing features.
Front-end editing support for example, is left out on purpose. It belongs to the domain of moderation, and policies
to know "who can do what". That deserves to be in a separate application, it shouldn't be in this application as it focuses on threading.
The same applies to social media logins, comment subscriptions, spam protection and Ajax posting.

Note that the standard framework also supports moderation, flagging, and RSS feeds too. More documentation can be found at:

* `Django's comments framework <https://docs.djangoproject.com/en/dev/ref/contrib/comments/>`_
* `Customizing the comments framework <http://docs.djangoproject.com/en/dev/ref/contrib/comments/custom/>`_
* `Example of using the in-built comments app <http://docs.djangoproject.com/en/dev/ref/contrib/comments/example/>`_

Some of the modules worth looking at are:

* django-comments-spamfighter_
* django-myrecaptcha_
* django-fluent-comments_

These modules can enhance the comments system even further.


.. _django.contrib.comments: https://docs.djangoproject.com/en/dev/ref/contrib/comments/
.. _django-fluent-comments: https://github.com/edoburu/django-fluent-comments/
.. _django-myrecaptcha: https://bitbucket.org/pelletier/django-myrecaptcha/
.. _django-comments-spamfighter: https://github.com/bartTC/django-comments-spamfighter/
2 changes: 1 addition & 1 deletion docs/index.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Templates

To use ``threadedcomments`` in templates first initialize the tag library::

{% load threadedcommentstags %}
{% load threadedcomments_tags %}

Then you can use the template tags supplied by the application. The
templatetags have the same syntax and semantics as the built-in comments
Expand Down
Empty file added examples/example/__init__.py
Empty file.
Empty file.
8 changes: 8 additions & 0 deletions examples/example/core/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from django.contrib import admin
from core.models import Message


class MessageAdmin(admin.ModelAdmin):
list_display = ('title', 'text',)

admin.site.register(Message, MessageAdmin)
16 changes: 16 additions & 0 deletions examples/example/core/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from django.core.urlresolvers import reverse
from django.db import models

class Message(models.Model):
title = models.CharField(max_length=140)
text = models.TextField()

class Meta:
verbose_name = "message"
verbose_name_plural = "messages"

def __unicode__(self):
return self.title

def get_absolute_url(self):
return reverse('message_detail', args=(self.pk,))
19 changes: 19 additions & 0 deletions examples/example/core/templates/comments/base.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{% extends "core/base.html" %}{% load i18n %}
{% comment %}

To implement django.contrib.comments in your web site,
it is recommended to override the following templates in your app:

comments/base.html - map the blocks 'title' and 'contents' to your base template.
comments/posted.html - provide a decent redirect back to the article.

Other templates could also be overwritten off course, but these two are the basic ones.
Features such as editing posts, spam protection, recaptcha, twitter/facebook/openid login etc..
are all subject to different applications which can add those features.
They don't belong in django-threadedcomments, and hence are not demonstrated here.

{% endcomment %}

{% block head_title %}{% block title %}{% trans "Responses for page" %}{% endblock %}{% endblock %}

{# 'content' block is already defined in the base class, no need to redefine it here. #}
10 changes: 10 additions & 0 deletions examples/example/core/templates/comments/core/form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<div id="form-comment">
<form action="/comments/post/" method="post">{% csrf_token %}
{{ form.as_p }}{# just to keep the example simple. Consider using django-crispy-forms in real life #}

<p>
<input type="submit" value="Submit Comment"/>
<a href="#c0" id="cancel_reply">cancel reply</a>
</p>
</form>
</div>
26 changes: 26 additions & 0 deletions examples/example/core/templates/comments/core/list.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{% load threadedcomments_tags %}

<div class="comments_length">
<p>{{ comment_list|length }} Comments</p>
</div>

<div class="comments">
{% for comment in comment_list|fill_tree|annotate_tree %}{% ifchanged comment.parent_id %}{% else %}</li>{% endifchanged %}{% if not comment.open and not comment.close %}</li>{% endif %}{% if comment.open %}
<ul>{% endif %}
<li class="comment_li" id="c{{ comment.id }}">{# c## is used by the absolute URL of the Comment model, so keep that as it is. #}
<div class="comment">
<div class="comment_info">
<div class="comment_user">{{ comment.user_name }}</div>
<div class="comment_data">
{{ comment.submit_date|date:"d M Y, H:i" }}
| <a href="#c{{ comment.id }}" data-comment-id="{{ comment.id }}" class="comment_reply_link">Reply</a>
</div>
</div>
<div class="comment_text">
{{ comment.comment }}
</div>
</div>
{% for close in comment.close %}</li></ul>{% endfor %}

{% endfor %}
</div>
20 changes: 20 additions & 0 deletions examples/example/core/templates/comments/posted.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{% extends "comments/base.html" %}{% load i18n %}

{% block title %}{% trans "Thanks for commenting" %}{% endblock %}

{% block extrahead %}
{{ block.super }}
<meta http-equiv="Refresh" content="5; url={{ comment.content_object.get_absolute_url }}#c{{ comment.id }}" />
{% endblock %}

{% block content %}
<h2>{% trans "Thanks for posting your comment" %}</h2>
<p>
{% blocktrans %}
We have received your comment, and posted it on the web site.<br/>
You will be sent back to the article...
{% endblocktrans %}
</p>

<p><a href="{{ comment.content_object.get_absolute_url }}#c{{ comment.id }}">{% trans "Back to the article" %}</a></p>
{% endblock %}
Loading