views:

196

answers:

3

Let's say you have a view called "View Story" which is just a web page rendered on the backend via Python/Django. On that page there's a list of comments at the bottom rendered as part of the "View Story" template using Django's templating system (in a loop). This page also allows you to add a comment to the list. This is done through AJAX and the page is updated with the new comment (without sending a new full page request).

Now, when adding the new comment to the end of the list I want the HTML that's generated for this new comment (something inside an <li>) to use the exact same code that was used to generate the original comments sent to the client via the original request.

There's multiple ways to do this:

  1. Have the initial rendering throw the comment data into a javascript variable and once the page is rendered add the content via javascript. Then when new comments are added that same javascript can be used to render the new one. The problem: from a search engine perspective I'm not sure google would be able to index the comments if they're generated after the page has been rendered - I'm guessing not

  2. Each time a new comment is added via AJAX, have the ajax request return the actual HTML to put on the page rather than just the JSON data of the new comment. The HTML can be generated using the same template snippet that was used to render the original page. The problem with this is that it ties that AJAX request to a particular view or a way of rendering it which I don't like.

  3. Similar to #2 except that a separate request is made to retrieve the HTML for the new comment or maybe all the comments and the list is just wiped and re-rendered. Don't like that cause it's deeply inefficient and unnecessarily time-consuming.

So, to summarize, I want a way to avoid duplicating Template/HTML code for a single view. And I would like some advice on what has worked for others because I'm pretty sure this is a common case irregardless of the technology on the back-end.

Thanks!

+2  A: 

I think option 2 is best. It's incremental (only renders one more comment when a comment is added), and re-uses the rendering. If you don't like returning just HTML from an Ajax request, then have the response be a JSON structure which includes the HTML as just one component. Then you can also carry status (or whatever) without an extra request to get the HTML.

Option 1 is wasteful: the server should render the page as it should first appear.

Option 3 is also wasteful: why make two requests to add a single comment?

Ned Batchelder
yeah, i agree. I just wanted to cover the possibilities for the sake of completeness.
Karim
+3  A: 

Here is what you should do:

view_story.html:

bla bla bla

Comments:
<ul id="comments">
{% for comment in comments %}
   <li>{% include "comment_item.html" %}</li>
{% endfor %}
</ul>
<from>Ajax form here</form>

than you need to create view for adding comments(ajax):

def add_comment(request):
    comment = Comment(...)
    return render_to_response('comment_item.html', {'comment': comment})

So after you submit your ajax query to add_comment view you will get the content of the comment(one comment).. after that just push it to list.. f.e. using jQuery like this:

$('ul#comments').append('<li>'+comment_content+'</li>')
Pydev UA
So option 2. That seems to be the consensus (if 3 is a consensus). Thanks!
Karim
This is what I do also. Seems the most DRY.
DrBloodmoney
+1  A: 

There is also option 4:

Copy an existing element in the list and change its values. This is of course less flexible than templates. You can copy a hidden element instead to handle the case where the list is empty.

You could also try option 2b:

Generate the HTML on the server like option 2, but instead of directly accessing the database, pass the generation routine the JSON (or an object that can easily be converted to JSON). This involves more work, but means that you are effectively writing an API at the same time you are writing your own website.

Option 1 is what any non-web application would use. Even though search engines are improving in their ability to handle AJAX, it is still strongly recommended to return all the content in HTML. I think Javascript is fast enough in all modern browsers that except for huge pages 1 would be quite reasonable except for the SEO issue.

There is also option 5 - use Javascript on the server to generate the page and use the same code on the client. This is probably the most complicated approach and I wouldn't recommend it unless you really have a good reason.

Casebash