Changes between Version 6 and Version 7 of UsingFreeComment


Ignore:
Timestamp:
06/17/2006 09:30:59 PM (9 years ago)
Author:
tyson@…
Comment:

Completely rewritten for comprehensiveness. Surely I've missed a few things, though.

Legend:

Unmodified
Added
Removed
Modified
  • UsingFreeComment

    v6 v7  
    1 == Using the FreeComment application integrated to Django. ==
    2 
    3 If you are using your own views and not Django's built-in generic views, you'll need to import FreeComment in views.py:
    4 
    5 {{{
    6 #!python
    7 from django.contrib.comments.models import FreeComment
    8 }}}
    9 
    10 Edit your settings.py
     1= Using Django's Free Comments =
     2
     3Django includes some basic commenting functionality that can save you a ton of time if you want to allow users to add comments to objects such as blog entries or photos. Django's free comments are flexible enough that they can be used on pretty much anything.
     4
     5== Set Up ==
     6
     7The first thing you'll need to do is add Django's comment packages to your INSTALLED_APPS in "settings.py":
     8
    119{{{
    1210#!python
     
    1614)
    1715}}}
    18 In your html template you can use the comment system.
    19 Remember a comment is going to be link to an entry id , for any of your model, it could be a blog post or a recipe.
    20 Add this to your template file
    21 {{{
    22 {% load comments %}
    23 }}}
    24 
    25 to display the comments for the current entry wich is a recipe object '''r'''.
    26 '''recettes''' is the app name
    27 '''recipe''' the model in models.py
    28 {{{
    29 {% get_free_comment_list for recettes.recipe r.id as comment_list %}
    30 {% if comment_list %}
    31     {% for comment in comment_list %}
    32          {{ comment.person_name }}
    33          {{ comment.submit_date|date:"j F, Y" }}
    34          {{ comment.submit_date|date:"P" }}
    35          {{ comment.comment|escape|urlizetrunc:40|linebreaks }}
    36     {% endfor %}
     16
     17If you're using custom views and not generic views, you'll need to add the following to the top of the relevant "urls.py" file. Generic views already include FreeComment, so you don't have to import it yourself.
     18
     19{{{
     20#!python
     21from django.contrib.comments.models import FreeComment
     22}}}
     23
     24Add the following URL pattern to your site-wide "urls.py" file:
     25
     26{{{
     27#!python
     28urlpatterns = patterns('',
     29        [...]
     30        (r'^comments/', include('django.contrib.comments.urls.comments')),
     31}
     32}}}
     33
     34In any template file in which you want to access comments, you'll have to load the comments packages before you access them with:
     35
     36{{{
     37{% load comments.comments %}
     38}}}
     39
     40Below that, you're free to access the comments.
     41
     42== Adding Comment Counts to List and Archive Pages ==
     43
     44The only data you need to access an object's comments is that object's id. If you have that, you can get the comments themselves, comment count, and other info.
     45
     46=== django.views.generic.list_detail.object_list ===
     47
     48In an object_list template, you can do the following to add the comment count to each of the blog entry listings. The following example assumes you have an app named "blog" with a class called "entry", which has fields called "title", "summary", and has a method called "get_absolute_url" which returns an absolute path to that entry's detail page.
     49
     50{{{
     51<ul>
     52        {% for object in object_list %}
     53                {% get_free_comment_count for blog.entry object.id as comment_count %}
     54                <li>
     55                        <h2><a href="{{ object.url }}">{{ object.title }}</a></h2>
     56                        <p class="description">{{ object.summary}}</p>
     57                        <p class="details"><a href="{{ object.get_absolute_url }}">{{ comment_count }} Comments</a></p>
     58                </li>
     59        {% endfor %}
     60</ul>
     61}}}
     62
     63=== django.views.generic.date_based.archive_index ===
     64
     65An archive_index generic view works almost exactly the same, except you're iterating through objects from the "latest" collection instead of the "object_list" collection:
     66
     67{{{
     68<ul>
     69        {% for object in latest %}
     70                {% get_free_comment_count for blog.entry object.id as comment_count %}
     71                [...]
     72        {% endfor %}
     73</ul>
     74}}}
     75
     76In the date-based archives such as archive_year or archive_month, the collection you iterate through is called "object_list". archive_index is the only generic view with "latest".
     77
     78== Adding Comments to Detail Pages ==
     79
     80Typically, you'll allow users to add comments through the detail page for an object. It's possible to allow them to do it elsewhere, but for simplicity's sake, this example only shows how to do it on detail pages. For any of the "detail" generic views such as django.views.generic.list_detail.object_detail or django.views.generic.date_based.object_detail, you'll have the object's id as "object.id", so getting the comment count is the same:
     81
     82{{{
     83{% get_free_comment_count for Blog.entry object.id as comment_count %}
     84}}}
     85
     86To get the list of comments, you call the following, which puts the list of comments in "comment_list":
     87
     88{{{
     89{% get_free_comment_list for blog.entry object.id as comment_list %}
     90}}}
     91
     92Each comment object in comment_list has the following bits of data:
     93
     94 * '''comment.person_name''' - The comment poster's name.
     95 * '''comment.submit_date''' - The date and time the poster submitted the comment. You can pipe this through the "date" filter to format the date. (Shown in the example below)
     96 * '''comment.comment''' - The actual comment text. Don't forget to escape this to prevent code-injection attacks with the "escape" filter. (Shown in the example below)
     97 * '''comment.is_public''' - Whether or not the comment is public. (TODO: How do we set a comment's public or non-public status?)
     98 * '''comment.ip_address''' - The comment author's IP address.
     99 * '''comment.approved''' - Whether or not this comment has been approved by a staff member. (TODO: Where is this set or modified?)
     100
     101And the following built-in methods:
     102
     103 * '''comment.get_absolute_url''' - Returns an absolute URL to this comment by way of the content object's detail page. If a comment is attached to a blog entry located at "/blog/some-slug", this URL will look something like "/blog/some-slug/#c4", where "4" is the comments id number.
     104 * '''comment.get_content_object''' - Returns the object that this comment is a comment on.
     105
     106As of this writing, the free comments don't allow for you to specify other bits of data to be included, such as the comment poster's e-mail address or URL. This may be changed in the future.
     107
     108=== Example ===
     109
     110{{{
     111{% get_free_comment_count for blog.entry object.id as comment_count %}
     112
     113<h2><a href="{{ object.url }}">{{ object.title }}</a></h2>
     114
     115<em>{{ object.description }}</em>
     116
     117<div class="article_menu">
     118        <b>Added on {{ object.add_date|date:"F j, Y" }}</b>
     119        <a href="{{ object.get_absolute_url }}#comments">{{ comment_count }} Comment{{ comment_count|pluralize }}</a>
     120</div>
     121
     122{% get_free_comment_list for blog.entry object.id as comment_list %}
     123
     124<h2 id="comments">Comments</h2>
     125{% for comment in comment_list %}
     126        <div class="comment_{% cycle odd,even %}" id="c{{ comment.id }}">
     127                <span class="comnum"><a id="c{{ comment.id }}" href="#c{{ comment.id }}">#{{ forloop.counter }}</a></span>
     128                <p><b>{{ comment.person_name }}</b> commented, on {{ comment.submit_date|date:"F j, Y" }} at {{ comment.submit_date|date:"P" }}:</p>
     129                {{ comment.comment|escape|urlizetrunc:40|linebreaks }}
     130        </div>
     131{% endfor %}
     132
     133<h2>Post a comment</h2>
     134{% free_comment_form for blog.entry object.id %}
     135}}}
     136
     137== Free Comment Templates ==
     138
     139Django has internal default templates for the various bits of comments-related code. (NOTE: Actually, I lied. Once [http://code.djangoproject.com/ticket/2177 these patches] are applied, it will. Until then, you'll have to specify your own templates for "free_preview.html" and "posted.html".)
     140
     141You can override any of these built in templates by creating a "comments/" folder in your templates folder with any or all of the following files:
     142
     143=== Post Comment Form (freeform.html) ===
     144
     145This template holds the form code that is used by the user to post a comment. In the above example, this is included like so:
     146
     147{{{
     148<h2>Post a comment</h2>
     149{% free_comment_form for blog.entry object.id %}
     150}}}
     151
     152==== Example ====
     153
     154{{{
     155{% if display_form %}
     156        <form action="/comments/postfree/" method="post">
     157                <p>Your name: <input type="text" id="id_person_name" name="person_name" /></p>
     158                <p>Comment:<br /><textarea name="comment" id="id_comment" rows="10" cols="60"></textarea></p>
     159                <input type="hidden" name="options" value="{{ options }}" />
     160                <input type="hidden" name="target" value="{{ target }}" />
     161                <input type="hidden" name="gonzo" value="{{ hash }}" />
     162                <p><input type="submit" name="preview" value="Preview comment" /></p>
     163        </form>
    37164{% endif %}
    38165}}}
    39166
    40 Here is a larger example where you cycle throught 2 colors to display the comments.
    41 
    42 {{{
    43 {% get_free_comment_list for recettes.recipe r.id as comment_list %}
    44 {% get_free_comment_count for recettes.recipe r.id as comment_count %}
    45 {% if comment_list %}
    46         <h3>Comments ({{comment_count}})</h3>
    47         <br />
    48         {% for comment in comment_list %}
    49                 <div class="{% cycle comment_even,comment_odd %}"  id="c{{forloop.counter}}">
    50                 <div class="comment_content">
    51                         <span class="comnum"><a id="{{forloop.counter}}" href="#c{{forloop.counter}}">#{{forloop.counter}}</a></span>
    52                 <p>by<b> {{ comment.person_name }}</b>, the{{ comment.submit_date|date:"j F, Y" }} at {{ comment.submit_date|date:"P" }}</p>
    53                 {{ comment.comment|escape|urlizetrunc:40|linebreaks }}
    54         </div>
    55         </div></div>
    56         </div>
    57         {% endfor %}
     167=== Preview (free_preview.html) ===
     168
     169This template is called when an user previews their comment.
     170
     171==== Example ====
     172
     173{{{
     174<h1>Preview your comment</h1>
     175
     176<form action="../postfree/" method="post">
     177        {% if comment_form.has_errors %}
     178            <p><strong style="color: red;">Please correct the following errors.</strong></p>
     179        {% else %}
     180            <div class="comment">
     181            {{ comment.comment|escape|urlizetrunc:"40"|linebreaks }}
     182            <p class="date small">Posted by <strong>{{ comment.person_name }}</strong></p>
     183            </div>
     184
     185            <p><input type="submit" name="post" value="Post public comment" /></p>
     186
     187            <h1>Or edit it again</h1>
     188        {% endif %}
     189
     190        {% if comment_form.person_name.errors %}
     191            {{ comment_form.person_name.html_error_list }}
     192        {% endif %}
     193
     194        <p><label for="id_person_name">Your name:</label> {{ comment_form.person_name }}</p>
     195
     196        {% if comment_form.comment.errors %}
     197                {{ comment_form.comment.html_error_list }}
     198        {% endif %}
     199
     200        <p>
     201                <label for="id_person_name">Comment:</label>
     202                <br />
     203                {{ comment_form.comment }}
     204        </p>
     205       
     206        <input type="hidden" name="options" value="{{ options }}" />
     207        <input type="hidden" name="target" value="{{ target }}" />
     208        <input type="hidden" name="gonzo" value="{{ hash }}" />
     209       
     210        <p>
     211                <input type="submit" name="preview" value="Preview revised comment" />
     212        </p>
     213</form>
     214}}}
     215
     216=== Posted Message (posted.html) ===
     217
     218This template is shown after a user successfully posts a comment. You can access the comment object as "object".
     219
     220==== Example ====
     221
     222{{{
     223<h1>Comment posted successfully</h1>
     224
     225<p>Thanks for contributing.</p>
     226
     227{% if object %}
     228        <ul>
     229                <li><a href="{{ object.get_absolute_url }}">View your comment</a></li>
     230        </ul>
    58231{% endif %}
    59232}}}
    60233
    61 We have to append a submit comment form to this.
    62 
    63 {{{
    64 Add a comment
    65 {% free_comment_form for recettes.recipe r.id %}
    66 }}}
    67 
    68 
    69 To use our own comments template, create a comments folder into your template folder location.
    70 In my case /home/greg/projects/cefinban/templates/comments
    71 There you could  put your own '''freeform.html''', '''free_preview.html''', '''posted.html'''.
    72 freeform.html is located in /django/contrib/comments/template/comments
    73 
    74 freeform.html
    75 {{{
    76 {% load i18n %}
    77 {% if display_form %}
    78 <form action="/comments/postfree/" method="post">
    79 <p>{% trans "Your name:" %} <input type="text" id="id_person_name" name="person_name" /></p>
    80 <p>{% trans "Comment:" %}<br /><textarea name="comment" id="id_comment" rows="10" cols="60"></textarea></p>
    81 <input type="hidden" name="options" value="{{ options }}" />
    82 <input type="hidden" name="target" value="{{ target }}" />
    83 <input type="hidden" name="gonzo" value="{{ hash }}" />
    84 <p><input type="submit" name="preview" value="{% trans "Preview comment" %}" /><input type="submit" name="post" value="{% trans "Submit" %}" /></p>
    85 </form>
    86 {% endif %}
    87 }}}
    88 
    89 
    90 
    91 
    92 
    93 
    94 
    95 
    96 
    97 
    98 
     234== Other Examples ==
     235
     236=== List Recent Comments ===
     237
     238The following code lists all the recent comments on your site, regardless of app.
     239
     240{{{
     241<h1>Recent comments</h1>
     242
     243<p>
     244        {% if has_previous %}
     245                <a href="?page={{ previous }}">Previous</a> |
     246        {% endif %}
     247       
     248        Page {{ page }} of {{ pages }}
     249       
     250        {% if has_next %}
     251                | <a href="?page={{ next }}">Next</a>
     252        {% endif %}
     253</p>
     254
     255{% for comment in object_list %}
     256        <div class="comment" id="c{{ comment.id }}">
     257            <h3>
     258                        <a href="{{ comment.get_absolute_url }}">
     259                                {{ comment.person_name }}
     260                                <span class="small quiet">
     261                                        {{ comment.submit_date|date:"F j, Y" }} at {{ comment.submit_date|date:"P" }}
     262                                </span>
     263                        </a>
     264                </h3>
     265            {{ comment.comment|escape|urlizetrunc:"40"|linebreaks }}
     266        </div>
     267{% endfor %}
     268
     269<p>
     270        {% if has_previous %}
     271                <a href="?page={{ previous }}">Previous</a> |
     272        {% endif %}
     273       
     274        Page {{ page }} of {{ pages }}
     275       
     276        {% if has_next %}
     277                | <a href="?page={{ next }}">Next</a>
     278        {% endif %}
     279</p>
     280}}}
Back to Top