0
votes

I'm trying to create a blogging website in Django. I'm pretty much a beginner so this question is probably silly but I don't know how to fix this.

I have a main navigation in my header. In the base.html template I created links in the menu for a couple of pages. In the same template I have a list of categories in the sidebar which are links to listing all posts within that category.

When I go to any other template (when I click any of those links), even though I extend the base.html template, the links disappear. How can I keep them in place regardless of the template? What's the common practice for things like this?

Thanks for reading! Cheers!

EDIT: The code:

<nav>
    <ul>
        <li><a href="{% url 'index' %}">HOME</a></li>
    {% for link in links %}
        <li><a href="{% url 'page' link.slug %}">{{ link.title }} </a></li>
    {% endfor %}
    </ul>
</nav>

This is in the base.html, but those links (except for the hardcoded Home link) disappear in other templates which just change the content block.

EDIT 2: Here's the view for the base:

def index(request):
    posts = Post.objects.all()
    links = Page.objects.filter(menu='Y')
    categories = Category.objects.all()
    return render(request, 'main/base.html', {'posts': posts,
                                              'links': links,
                                              'categories': categories,
                                              })

SOLUTION: Thanks everyone for your help. Here's the solution I used:

from django.template import RequestContext

def base_links(request):
    header_links = Page.objects.filter(menu='Y')
    sidebar_categories = Category.objects.all()
    return  {
        'links': header_links,
        'categories': sidebar_categories,
    }

And then I've added:

context_instance = RequestContext(request, processors=[base_links])

to all my views.

2
Could you please post your templates? Have you included {% extends 'myapp/base.html' %} in the other templates? - Wtower
I've posted a code of the links. All other templates extend the base.html template. - Vedran
How is links being passed to the context? - rnevius
I've added the code in the post. - Vedran
If you read the doc about context processors, you'll find out you DONT have to add anything to your views (except making sure they use a RequestContext) - just add your custom context processor to your settings.CONTEXT_PROCESSORS. - bruno desthuilliers

2 Answers

0
votes

Your templates are passed the current's view's context, so you cannot expect the index() views's context to become magically available everywhere.

The two common solutions to make such data available in other templates are

  1. a context processor:

https://docs.djangoproject.com/en/1.8/ref/templates/api/#subclassing-context-requestcontext https://docs.djangoproject.com/en/1.8/ref/templates/api/#writing-your-own-context-processors

It's a very easy solution, but it has a couple downsides too: - the context processor will be called even for templates that don't need it - it makes it hard to know what's really available in the context and where it comes from - you may end up with two conflicting processors trying to set the same keys in the context - you may end up with conflicts between processors and views (each trying to set the same keys in the context).

  1. custom template tags:

https://docs.djangoproject.com/en/1.8/howto/custom-template-tags/

In your case, if you plan on presenting the same data in the same way on each and every page of the site, an inclusion_tag() is the obvious choice.

As far as I'm concerned, I find custom tags to be much more maintainable than context processors, and with the inclusion_tag() shortcut they are as easy to setup as context processors.

-1
votes

In django each "page" is a view. Your index() function is the view for your homepage and i bet that you have a blog_post() or something like that that renders the posts

Each view must define the template to use and pass the context (variables) needed to render it's template. Your base template has a menu that needs the links variable, so every view that renders a template extending the base template must pass the links variable to the context.

In simple words :) you need to pass the links variable to the context in your post's view

Small advice: don't use functions as views. It's better to use Class Based Views

Hope this helps