Code

Changes between Version 38 and Version 39 of UsingFreeComment


Ignore:
Timestamp:
11/20/12 10:23:47 (20 months ago)
Author:
timo
Comment:

Reverted to version 37 (spammer)

Legend:

Unmodified
Added
Removed
Modified
  • UsingFreeComment

    v38 v39  
    1 Earn Money from Home by Inviting Friends 
    2 1000$ Weekly, by just invite 10 friends daily 
    3 http://referraltask.com/ref.php?page=act%2Fref&invcod=62942 
     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 to add Django's comment packages to your INSTALLED_APPS in "settings.py": 
     8 
     9{{{ 
     10#!python 
     11INSTALLED_APPS = ( 
     12    [...] 
     13    'django.contrib.comments', 
     14) 
     15}}} 
     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')), 
     31) 
     32}}} 
     33 
     34You will need to update your database with the comments model.  Stop your webserver if it's running, then use the django admin tool with the syncdb command. 
     35 
     36In any template file in which you want to access comments, you'll have to load the comments packages before you access them with: 
     37 
     38{{{ 
     39{% load comments %} 
     40}}} 
     41 
     42Below that, you're free to access the comments. 
     43 
     44== Adding Comment Counts to List and Archive Pages == 
     45 
     46The 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. 
     47 
     48=== django.views.generic.list_detail.object_list === 
     49 
     50In 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.   
     51 
     52''Note: The class name should always be referred to in all lowercase.  For example, if the class contained inside the app named blog were actually named Entry, it would still be referred to as blog.entry.'' 
     53 
     54{{{ 
     55<ul> 
     56        {% for object in object_list %} 
     57                {% get_comment_count for blog.entry object.id as comment_count %} 
     58                <li> 
     59                        <h2><a href="{{ object.url }}">{{ object.title }}</a></h2> 
     60                        <p class="description">{{ object.summary}}</p> 
     61                        <p class="details"><a href="{{ object.get_absolute_url }}">{{ comment_count }} Comments</a></p> 
     62                </li> 
     63        {% endfor %} 
     64</ul> 
     65}}} 
     66 
     67=== django.views.generic.date_based.archive_index === 
     68 
     69An 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: 
     70 
     71{{{ 
     72<ul> 
     73        {% for object in latest %} 
     74                {% get_comment_count for blog.entry object.id as comment_count %} 
     75                [...] 
     76        {% endfor %} 
     77</ul> 
     78}}} 
     79 
     80In 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". 
     81 
     82== Adding Comments to Detail Pages == 
     83 
     84Typically, 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: 
     85 
     86{{{ 
     87{% get_comment_count for blog.entry object.id as comment_count %} 
     88}}} 
     89 
     90To get the list of comments, you call the following, which puts the list of comments in "comment_list": 
     91 
     92{{{ 
     93{% get_comment_list for blog.entry object.id as comment_list %} 
     94}}} 
     95 
     96Each comment object in comment_list has the following bits of data: 
     97 
     98 * '''comment.person_name''' - The comment poster's name. 
     99 * '''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) 
     100 * '''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) 
     101 * '''comment.is_public''' - Whether or not the comment is public. (TODO: How do we set a comment's public or non-public status?) 
     102 * '''comment.ip_address''' - The comment author's IP address. 
     103 * '''comment.approved''' - Whether or not this comment has been approved by a staff member. (TODO: Where is this set or modified?) 
     104 
     105And the following built-in methods: 
     106 
     107 * '''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. 
     108 * '''comment.get_content_object''' - Returns the object that this comment is a comment on. 
     109 
     110As 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. 
     111 
     112=== Example === 
     113 
     114{{{ 
     115{% get_comment_count for blog.entry object.id as comment_count %} 
     116 
     117<h2><a href="{{ object.url }}">{{ object.title }}</a></h2> 
     118 
     119<em>{{ object.description }}</em> 
     120 
     121<div class="article_menu"> 
     122        <b>Added on {{ object.add_date|date:"F j, Y" }}</b>  
     123        <a href="{{ object.get_absolute_url }}#comments">{{ comment_count }} Comment{{ comment_count|pluralize }}</a> 
     124</div> 
     125 
     126{% get_comment_list for blog.entry object.id as comment_list %} 
     127 
     128<h2 id="comments">Comments</h2> 
     129{% for comment in comment_list %} 
     130        <div class="comment_{% cycle odd,even %}" id="c{{ comment.id }}"> 
     131                <span class="comnum"><a id="c{{ comment.id }}" href="#c{{ comment.id }}">#{{ forloop.counter }}</a></span> 
     132                <p><b>{{ comment.person_name|escape }}</b> commented, on {{ comment.submit_date|date:"F j, Y" }} at {{ comment.submit_date|date:"P" }}:</p> 
     133                {{ comment.comment|escape|urlizetrunc:40|linebreaks }} 
     134        </div> 
     135{% endfor %} 
     136 
     137<h2>Post a comment</h2> 
     138{% render_comment_form for blog.entry object.id %} 
     139}}} 
     140 
     141== Free Comment Templates == 
     142 
     143Django 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".) 
     144 
     145You 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: 
     146 
     147=== Post Comment Form (freeform.html) === 
     148 
     149This template holds the form code that is used by the user to post a comment. In the above example, this is included like so: 
     150 
     151{{{ 
     152<h2>Post a comment</h2> 
     153{% render_comment_form for blog.entry object.id %} 
     154}}} 
     155 
     156==== Example ==== 
     157 
     158{{{ 
     159{% if display_form %} 
     160        <form action="/comments/postfree/" method="post"> 
     161                <p>Your name: <input type="text" id="id_person_name" name="person_name" /></p> 
     162                <p>Comment:<br /><textarea name="comment" id="id_comment" rows="10" cols="60"></textarea></p> 
     163                <input type="hidden" name="options" value="{{ options }}" /> 
     164                <input type="hidden" name="target" value="{{ target }}" /> 
     165                <input type="hidden" name="gonzo" value="{{ hash }}" /> 
     166                <p><input type="submit" name="preview" value="Preview comment" /></p> 
     167        </form> 
     168{% endif %} 
     169}}} 
     170 
     171In this Example change name="preview" to name="post" if you dont want to be redirected to a preview page 
     172 
     173=== Preview (free_preview.html) === 
     174 
     175This template is called when a user previews their comment. 
     176 
     177==== Example ==== 
     178 
     179{{{ 
     180<h1>Preview your comment</h1> 
     181 
     182<form action="/comments/postfree/" method="post"> 
     183        {% if comment_form.has_errors %} 
     184            <p><strong style="color: red;">Please correct the following errors.</strong></p> 
     185        {% else %} 
     186            <div class="comment"> 
     187            {{ comment.comment|escape|urlizetrunc:"40"|linebreaks }} 
     188            <p class="date small">Posted by <strong>{{ comment.person_name|escape }}</strong></p> 
     189            </div> 
     190 
     191            <p><input type="submit" name="post" value="Post public comment" /></p> 
     192 
     193            <h1>Or edit it again</h1> 
     194        {% endif %} 
     195 
     196        {% if comment_form.person_name.errors %} 
     197            {{ comment_form.person_name.html_error_list }} 
     198        {% endif %} 
     199 
     200        <p><label for="id_person_name">Your name:</label> {{ comment_form.person_name }}</p> 
     201 
     202        {% if comment_form.comment.errors %} 
     203                {{ comment_form.comment.html_error_list }} 
     204        {% endif %} 
     205 
     206        <p> 
     207                <label for="id_comment">Comment:</label> 
     208                <br /> 
     209                {{ comment_form.comment }} 
     210        </p> 
     211         
     212        <input type="hidden" name="options" value="{{ options }}" /> 
     213        <input type="hidden" name="target" value="{{ target }}" /> 
     214        <input type="hidden" name="gonzo" value="{{ hash }}" /> 
     215 
     216        <p> 
     217                <input type="submit" name="preview" value="Preview revised comment" /> 
     218        </p> 
     219</form> 
     220}}} 
     221 
     222=== Posted Message (posted.html) === 
     223 
     224This template is shown after a user successfully posts a comment. You can access the object that the comment was posted to as the context variable "object". 
     225 
     226==== Example ==== 
     227 
     228{{{ 
     229<h1>Comment posted successfully</h1> 
     230 
     231<p>Thanks for contributing.</p> 
     232 
     233{% if object %} 
     234        <ul> 
     235                <li><a href="{{ object.get_absolute_url }}">View your comment</a></li> 
     236        </ul> 
     237{% endif %} 
     238}}} 
     239 
     240== Wrapping post_free_comment to change the redirect url == 
     241At this time django.contrib.comments.views.comments has hard-coded, on its post_free_comment method, a redirection address to ''posted.html''. If you want your comments to redirect to the original page that the comment was posted from, you can wrap the post_free_comment method and add a redirect to another after the comment creation. The URL can be passed as a hidden parameter in freeform.html 
     242To do this you first need to create a wrapper in views.py 
     243{{{ 
     244#!python 
     245from django.contrib.comments.views.comments import post_free_comment 
     246from django.http import HttpResponseRedirect 
     247 
     248def my_post_free_comment(request): 
     249        if 'url' in request.REQUEST and 'preview' not in request.REQUEST: 
     250                response = post_free_comment(request) 
     251                 
     252                # Check there's a url to redirect to, and that post_free_comment worked 
     253                if len(request.REQUEST['url'].strip()) > 0 and isinstance(response, HttpResponseRedirect): 
     254                        return HttpResponseRedirect(request.REQUEST['url']) 
     255                 
     256                # Fall back on the default post_free_comment response 
     257                return response 
     258         
     259        return post_free_comment(request) 
     260}}} 
     261 
     262After you have your view you need to point the requests to that view instead of the default comments view 
     263To do this, '''before''' this line 
     264{{{ 
     265#!python 
     266(r'^comments/', include('django.contrib.comments.urls.comments')), 
     267}}} 
     268add this line: 
     269{{{ 
     270#!python 
     271(r'^comments/postfree/', 'views.my_post_free_comment'), 
     272}}} 
     273 
     274And change the form to include the URL as a hidden field. The problem is: How do I get the current url in a template variable?. To do this you need to activate the template context processor called ''request'' adding the following code to settings.py 
     275{{{ 
     276#!python 
     277from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS 
     278TEMPLATE_CONTEXT_PROCESSORS += ( 
     279     'django.core.context_processors.request', 
     280)  
     281}}} 
     282Once your request context processor is activated you will have the variable request available in your templates. With it you can get request.get_full_path to print the current URL. Make your freeform.html look like this: 
     283{{{ 
     284{% load i18n %} 
     285{% if display_form %} 
     286        <form action="/comments/postfree/" method="post"> 
     287                <p> 
     288                        <label for="id_person_name">{% trans "Your name:" %}</label> <input type="text" id="id_person_name" name="person_name" /> 
     289                </p> 
     290                <p> 
     291                        <label for="id_comment">{% trans "Comment:" %}</label><br /> 
     292                        <textarea name="comment" id="id_comment" rows="10" cols="60"></textarea> 
     293                </p> 
     294                <p> 
     295                        <input type="hidden" name="options" value="{{ options }}" /> 
     296                        <input type="hidden" name="target" value="{{ target }}" /> 
     297                        <input type="hidden" name="gonzo" value="{{ hash }}" /> 
     298                        <input type="hidden" name="url" value="{{ request.get_full_path }}" /> 
     299                        <input type="submit" name="preview" value="{% trans "Preview comment" %}" /> 
     300                </p> 
     301        </form> 
     302{% endif %} 
     303}}} 
     304 
     305In free_preview.html, add: 
     306{{{ 
     307        <input type="hidden" name="url" value="{{ request.REQUEST.url }}" /> 
     308}}} 
     309before 
     310{{{ 
     311        <p><input type="submit" name="preview" value="Preview revised comment" /></p> 
     312}}} 
     313 
     314This should be it. Enjoy 
     315  --NL 
     316 
     317== Other Examples == 
     318 
     319=== List Recent Comments === 
     320 
     321The following code lists all the recent comments on your site, regardless of app. 
     322 
     323{{{ 
     324<h1>Recent comments</h1> 
     325 
     326<p> 
     327        {% if has_previous %} 
     328                <a href="?page={{ previous }}">Previous</a> |  
     329        {% endif %} 
     330         
     331        Page {{ page }} of {{ pages }}  
     332         
     333        {% if has_next %} 
     334                | <a href="?page={{ next }}">Next</a> 
     335        {% endif %} 
     336</p> 
     337 
     338{% for comment in object_list %} 
     339        <div class="comment" id="c{{ comment.id }}"> 
     340            <h3> 
     341                        <a href="{{ comment.get_absolute_url }}"> 
     342                                {{ comment.person_name|escape }}  
     343                                <span class="small quiet"> 
     344                                        {{ comment.submit_date|date:"F j, Y" }} at {{ comment.submit_date|date:"P" }} 
     345                                </span> 
     346                        </a> 
     347                </h3> 
     348            {{ comment.comment|escape|urlizetrunc:"40"|linebreaks }} 
     349        </div> 
     350{% endfor %} 
     351 
     352<p> 
     353        {% if has_previous %} 
     354                <a href="?page={{ previous }}">Previous</a> |  
     355        {% endif %} 
     356         
     357        Page {{ page }} of {{ pages }}  
     358         
     359        {% if has_next %} 
     360                | <a href="?page={{ next }}">Next</a> 
     361        {% endif %} 
     362</p> 
     363}}}