~ubuntu-branches/ubuntu/utopic/python-django-threadedcomments/utopic

« back to all changes in this revision

Viewing changes to docs/tutorial.txt

  • Committer: Package Import Robot
  • Author(s): Bernhard Reiter, Bernhard Reiter, Jakub Wilk
  • Date: 2013-08-09 19:12:14 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20130809191214-p8482p4e1ctekffq
Tags: 0.9.0-1
[ Bernhard Reiter ]
* New upstream release
* debian/compat: Bump to 9.
* debian/control, debian/copyright: Update upstream links. (Closes: #713930)
* debian/control: 
  - Remove python-textile, python-markdown, python-docutils from
    Build-Depends: and Suggests:
  - Bump debhelper Build-Depends to >= 9.
  - Bump Standards-Version to 3.9.4.
  - Add Suggests: python-django-south
* debian/copyright: s/BSD-new/BSD-3-clause/
* debian/docs, debian/doc-base: Update/remove to correspond with
  upstream sources.
* debian/patches/series, debian/patches/add_markup_deps_to_install,
  debian/patches/gravatar_default_url, debian/patches/django14:
  Remove patches, as obsolete.
* debian/rules: Add a SECRET_KEY for tests during building. (Closes: #711369)
* debian/NEWS.Debian: Add.

[ Jakub Wilk ]
* Use canonical URIs for Vcs-* fields.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
=============================================
2
 
Tutorial 1
3
 
=============================================
4
 
Creating a Threaded Comment System for a Blog
5
 
---------------------------------------------
6
 
 
7
 
Overview
8
 
========
9
 
 
10
 
Many modern websites have the need for a threaded commenting system.  Places 
11
 
like Digg_ and Reddit_ have great systems for responding not only to an item on
12
 
the site, but also for responding to comments on that item as well.
13
 
 
14
 
.. _Digg: http://www.digg.com/
15
 
.. _Reddit: http://www.reddit.com/
16
 
 
17
 
*threadedcomments* is a Django application which allows for the simple creation 
18
 
of a threaded commenting system.  It is flexible as well, partly due to its use 
19
 
of the same facilities that any other Django application would use.  For 
20
 
instance, it would be trivial to integrate django-voting_ to rank each comment.  
21
 
That, however, is a tutorial for another day.
22
 
 
23
 
This tutorial will get you up and running with a threaded comment system for the
24
 
typical case: a blog.
25
 
 
26
 
.. _django-voting: http://code.google.com/p/django-voting/
27
 
 
28
 
Goals of This Tutorial
29
 
======================
30
 
 
31
 
There are three main goals that this tutorial sets out to meet.  After having
32
 
completed this tutorial, you should:
33
 
 
34
 
1. Know how to use *threadedcomments* to implement a basic threaded comment 
35
 
   system.
36
 
2. Have a very good idea on how to integrate this comment system with your blog.
37
 
 
38
 
3. Be able to simply and easily migrate an existing ``django.contrib.comments`` 
39
 
   installation to use *django_threadedcomments* instead.
40
 
 
41
 
Step 1: Defining our Blog Model
42
 
===============================
43
 
 
44
 
Before we can even begin to use *django_threadedcomments*, we must first create 
45
 
a simplistic "blog" model.  This should be very familiar to anyone who has ever 
46
 
written a basic blog model in Django before.
47
 
 
48
 
We'll define our simplistic blog model as follows::
49
 
 
50
 
    from django.db import models
51
 
    from datetime import datetime
52
 
 
53
 
    class BlogPost(models.Model):
54
 
        title = models.CharField(max_length=128)
55
 
        slug = models.SlugField(prepopulate_from=('title',))
56
 
        body = models.TextField()
57
 
        published = models.BooleanField(default=True)
58
 
        date_posted = models.DateTimeField(default=datetime.now)
59
 
 
60
 
        def __unicode__(self):
61
 
            return self.title
62
 
 
63
 
        class Admin:
64
 
            pass
65
 
 
66
 
There shouldn't be anything that's too tricky so far in this ``BlogPost`` model.  
67
 
If you're having a hard time understanding what's going on here, you may want to
68
 
first check out the `django tutorial`_ or the `django book`_.
69
 
 
70
 
If you do understand how this model works, go ahead and use the admin or shell
71
 
to create some sample blog posts.  We'll be needing them in the following steps 
72
 
of the tutorial.
73
 
 
74
 
.. _`django tutorial`: http://www.djangoproject.com/documentation/tutorial01/
75
 
.. _`django book`: http://www.djangobook.com/en/1.0/
76
 
 
77
 
Step 2: Creating a View for the Sample Blog
78
 
===========================================
79
 
 
80
 
There are many different choices when it comes to displaying and creating
81
 
comments.  Some people choose to show comments in a separate window.  Others
82
 
choose to display them on the same page as the content object.  Others still
83
 
require users to go to a special comments page to view and create comments.
84
 
 
85
 
Our approach here is going to be to display the comments directly below the blog
86
 
post, and directly below the comments will be a form for submitting a new 
87
 
comment.
88
 
 
89
 
Our example will be for the "latest" blog post.  The view is as follows::
90
 
 
91
 
    from models import BlogPost
92
 
    from django.template import RequestContext
93
 
    from django.shortcuts import render_to_response
94
 
    from django.http import Http404
95
 
 
96
 
    def latest_post(request):
97
 
        try:
98
 
            post = BlogPost.objects.latest('date_posted')
99
 
        except BlogPost.DoesNotExist:
100
 
            raise Http404
101
 
        return render_to_response(
102
 
            'blog/latest_post.html', {'post' : post},
103
 
            context_instance = RequestContext(request)
104
 
        )
105
 
 
106
 
Step 3: Configuration
107
 
=====================
108
 
 
109
 
First, make sure that django_threadedcomments is installed and is located
110
 
somewhere on your pythonpath.  Then, in your ``settings.py`` file, append
111
 
the string ``'threadedcomments'`` to the end of your ``INSTALLED_APPS`` tuple.
112
 
 
113
 
In the end, your ``INSTALLED_APPS`` should look something like this::
114
 
 
115
 
    INSTALLED_APPS = (
116
 
        'django.contrib.sessions',
117
 
        'django.contrib.auth',
118
 
        'django.contrib.contenttypes',
119
 
        'django.contrib.sites',
120
 
        'django.contrib.admin',
121
 
        'blog',
122
 
        'threadedcomments',
123
 
    )
124
 
 
125
 
Next, make sure that in one of your included url configuration files (preferably
126
 
your ``ROOT_URLCONF``) you include 'threadedcomments.urls'.
127
 
 
128
 
In the end, your ``urls.py`` file may look something like this::
129
 
 
130
 
    from django.conf.urls.defaults import *
131
 
 
132
 
    urlpatterns = patterns('',
133
 
        (r'^blog/', include('blog.urls')),
134
 
        (r'^admin/', include('django.contrib.admin.urls')),
135
 
        (r'^threadedcomments/', include('threadedcomments.urls')),
136
 
    )
137
 
 
138
 
Make sure to run ``python manage.py syncdb`` to finish off this step.
139
 
 
140
 
Step 4: Template Creation
141
 
=========================
142
 
 
143
 
Believe it or not, in this step we're going to not only create a template with
144
 
which we can view our latest post, but we're also going to completely integrate
145
 
*django_threadedcomments*.  Note also that in our sample template, we are not 
146
 
using any of the extremely advisable feature of template inheritance.  The only 
147
 
reason that we are not doing so is to simplify the tutorial itself.  In 
148
 
practice, please take advantage of this feature.
149
 
 
150
 
Now with that said, let's begin to create our template.  We'll start like so::
151
 
 
152
 
    {% load threadedcommentstags %}
153
 
 
154
 
    <html>
155
 
    <head><title>{{ post.title }}</title></head>
156
 
    <body>
157
 
        <div id="blogpost">
158
 
            <h1>{{ post.title }}</h1>
159
 
            <h3>Posted On: {{ post.date_posted|date }}</h3>
160
 
            {{ post.body|linebreaks }}
161
 
        </div>
162
 
        <h3>Comments on This Post:</h3>
163
 
        {% get_free_threaded_comment_tree for post as tree %}
164
 
        {% for comment in tree %}
165
 
            <div style="margin-left: {{ comment.depth }}em;" class="comment">
166
 
                <a href="{{ comment.website }}">{{ comment.name }}</a> said:<br/>
167
 
                {% auto_transform_markup comment %}
168
 
            </div>
169
 
        {% endfor %}
170
 
        <p>Reply to Original:</p>
171
 
        <form method="POST" action="{% get_free_comment_url post %}">
172
 
            <ul>
173
 
                {% get_free_threaded_comment_form as form %}
174
 
                {{ form.as_ul }}
175
 
                <li><input type="submit" value="Submit Comment" /></li>
176
 
            </ul>
177
 
        </form>
178
 
    </body>
179
 
    </html>
180
 
 
181
 
There are three main parts to this template:
182
 
 
183
 
1. **Displaying the blog post.**
184
 
 
185
 
   This part is nothing tricky: the title, date, and body are displayed.
186
 
 
187
 
2. **Getting and displaying the comment tree.**
188
 
 
189
 
   This part is much more interesting.  A new template tag,
190
 
   ``get_free_threaded_comment_tree`` is called on the ``post`` object, and 
191
 
   then the results are stored in a context variable called ``tree``.  We 
192
 
   iterate over that tree using a simple ``for`` tag and for each comment we 
193
 
   provide a link to the commenter's website and display their name.  
194
 
 
195
 
   We then call a tag named ``auto_transform_markup`` on the comment.  This  tag
196
 
   looks at the markup type and calls the appropriate filter on the body of the 
197
 
   post before displaying it.
198
 
 
199
 
4. **Providing a form with which the user can reply to the original post.**
200
 
 
201
 
   We use ``get_free_threaded_comment_form`` to provide an unbound form to 
202
 
   display to the user.  Because of that, we can simply call write 
203
 
   ``{{ form.as_ul }}`` and we've got a beautiful, accessible form displayed.
204
 
 
205
 
   The ``get_free_comment_url`` template tag gets the appropriate URL to post
206
 
   to, given an object.  All appropriate form submissions to that URL will then
207
 
   be attached to that given object.  In this case, we want to attach the
208
 
   comments to the blog post, so that's the argument that we provide.
209
 
 
210
 
There's still a **crucial** piece missing: the ability to reply to other 
211
 
people's comments!  This is where some javascript will help us out a lot.
212
 
 
213
 
Let's decide on some Javascript functions which will do the trick:
214
 
 
215
 
``function show_reply_form(comment_id, url, person_name){ ... }``
216
 
    This takes in the ID of the comment for which to add a reply form, the URL 
217
 
    to POST to, and the person's name to whom you are replying.
218
 
    
219
 
    It dynamically inserts into the HTML DOM a FORM element which will POST to 
220
 
    the specified URL.
221
 
 
222
 
``function hide_reply_form(comment_id, url, person_name){ ... }``
223
 
    This takes in the same parameters and instead of dynamically creating a FORM
224
 
    element, it dynamically removes the element.
225
 
 
226
 
.. note::
227
 
    Unfortunately there was not enough space here to display the full Javascript
228
 
    functions, but you can view `the full template here`_ to see how one might 
229
 
    implement this functionality.
230
 
 
231
 
.. _`the full template here`: http://django-threadedcomments.googlecode.com/svn/trunk/examples/tut1/blog/templates/blog/latest_post.html
232
 
 
233
 
Now that we've decided on some Javascript functions to create our response 
234
 
forms, we'll have to call those functions from our HTML.  We'll do so by adding 
235
 
a link directly underneath ``{% auto_transform_markup comment %}``.  It'll look 
236
 
like this::
237
 
 
238
 
    <a id="c{{ comment.id }}" href="javascript:show_reply_form('c{{ comment.id }}','{% get_free_comment_url post comment %}','{{ comment.name }}')">Reply</a>
239
 
 
240
 
That's one long link right there!  What we're doing here is dynamically 
241
 
creating a Javascript function call to ``show_reply_form`` using Django's 
242
 
context variables as parameters for ``show_reply_form``.  Note that 
243
 
``get_free_comment_url`` takes a second argument--the parent comment.  In this
244
 
case, we're creating a response form, so the parent comment to the reply will
245
 
be the comment that we're currently displaying.  Once Django has processed this 
246
 
template, the result will look something like this::
247
 
 
248
 
    <a id="c1" href="javascript:show_reply_form('c1','/threadedcomments/freecomment/12/1/1/','Tony Hauber')">Reply</a>
249
 
 
250
 
In this case, we're calling ``show_reply_form`` for comment ``c1``, the URL to
251
 
POST to is ``/threadedcomments/freecomment/12/1/1/``, and the person's name
252
 
that we'd like to respond to is ``Tony Hauber``.
253
 
 
254
 
Step 5: Upgrading from ``django.contrib.comments``
255
 
==================================================
256
 
 
257
 
*django_threadedcomments* provides a simple management command to allow for
258
 
the simple upgrading of the built-in ``django.contrib.comments``.  To use it,
259
 
simply open a console, navigate to your project directory, and type::
260
 
 
261
 
    python manage.py migratecomments
262
 
 
263
 
Running this will convert all ``django.contrib.comments.models.Comment`` 
264
 
comments to ``threadedcomments.models.ThreadedComment`` comments, and all
265
 
``django.contrib.comments.models.FreeComment`` comments to 
266
 
``threadedcomments.models.FreeThreadedComment`` comments.
267
 
 
268
 
Obviously, there can be no hierarchy data associated with those legacy comments,
269
 
but future commenters can reply to those legacy comments just fine.
270
 
 
271
 
Wrapping Up
272
 
===========
273
 
 
274
 
We've finished!  Now it's up to you to style the page according to your wishes,
275
 
or even better, apply the techniques from this tutorial on your own blog or web 
276
 
application.  For a live example of this, `visit this link`_.  Try it out for 
277
 
yourself and even leave comments on that page, if you wish.
278
 
 
279
 
.. _`visit this link`: http://www.eflorenzano.com/threadedcomments/example/
 
 
b'\\ No newline at end of file'