Question

There's a feature in Twitter called hashtags that extracts tags from messages.
For example, in

"Hey #guys, I love #stackoverflow"

#guys and #stackoverflow are clickable and lead to their own queries.

I'm building a similar app for training, and I wonder where and when to actually inject links in the output?

I grab all recent tweets:

def index(request):
    latest_tweets = Tweet.objects.all().order_by('-pub_date')[:5]
    return render_to_response('index.html',
                              { 'tweets': latest_tweets },
                              context_instance=RequestContext(request)
                              )

And in a block I render:

{% for tweet in tweets %}
    <p>{{tweet.message}}</p>
{% endfor %}

But this of course only shows plain message, no links.
I want each #tag in message to be replaced with a link passing tag name in a query string to a view called by_tag.

Does inserting <a href="...">s belong to views.py? Then what if I later decided this to be an AJAX link? Okay, seems like this belongs to templates. But how do I do such a complex replacement with routing from a template? Should I write a custom template filter?

Just for the reference, a Tweet contains its Tags in a field called tags.

Was it helpful?

Solution

I did something similar last week and wrote a quick custom template filter to scan text looking for mentions and hashtags and wrap them in links.

https://gist.github.com/1023144

It makes sense to do this at the template level as you are performing HTML markup/replacement.

Generally, your views perform routing logic, i.e. taking the url, retrieving and aggregating the necessary data, and rendering the template.

If there is any associated logic you need to perform on a model (i.e. compare to tweets for example), it is a good idea to put this in Model functions, or Model Managers, as it is logic tied to you Models and Database.

Any logic in at the template level should generally address the structuring and displaying the data it has received from the view.

Sometimes though, you might want to perform some logic at the template level so that it can be reused across different views (like grabbing the top 10 most popular tags for example). This is a good time to create a template tag to perform the logic (and it's also nice and reuseable)

Anyway, place that code in:

yourapp/templatetags.py

and in the template:

{% for tweet in tweets %}
    <p>{{ tweet.message|twittify }}</p>
{% endfor %}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top