Tyler Travers
Tyler Travers

Reputation: 13

Creating a "Recent Posts" list in a sidebar.

I'm working on a simple blog app in Django, and i'm having trouble figuring out how to dynamically generate the five most recent posts in a side bar. Each of my views are class based and they extend a generic template, each view maps to one template which I believe is the correct way to do it. I've looked for a way to do this using template tags, but it seems Django doesn't like you to put any logic inside of your templates.

The problem I believe is that I want this to exist within my base.html because I want the recent posts to be displayed site-wide, is a view even supposed to map to your base.html or does that cause problems, i'm pretty new with this. I don't know how to approach this, whether i'm supposed to create a new view for base.html or if I should use my template tags, or if I should extend an existing view(but if I do that it won't be site wide?).

I essentially want the following(they're ordered in reverse chronological order)

{% for post in post_list[:4] %}
<a href="{{ post.get_absolute_url }}"> {{ post.title }} </a>
{% endfor %}

Upvotes: 1

Views: 454

Answers (1)

Timmy O&#39;Mahony
Timmy O&#39;Mahony

Reputation: 53991

You can use a template tag. More specifically, an inclusion tag is what you need. This allows you to insert a rendered snippet anywhere inside your template via a small view-like piece of code.

For example, create a templatetags/blog_tags.py file (it's important that you create the templatetags folder within your app; Django searches for them here by default) in your blog app and add the following:

from django import template
register = template.Library() 

@register.inclusion_tag('blog/snippets/recent_posts.html')
def render_recent_blogposts():
    return {
        # This is just an example query, your actual models may vary
        'post_list': BlogPost.objects.all().order_by("published_on")[:4]
    }

now create a blog/snippets/recent_posts.html template (it can be anywhere as long as it mathecs the @register.inclusion_tag(...) above.):

<ul>
    {% for post in post_list %}
        <li><a href="{{ post.get_absolute_url }}"> {{ post.title }}</a></li>
        ...
    {% endfor %}
</ul>

finally, in your original template, you can now render your template tags:

<aside>
    {% load blog_tags %}
    {% render_recent_blogposts %}
</aside>

Upvotes: 4

Related Questions