Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

menus empty if generate_menu not called within same block. #79

Open
nerdoc opened this issue Apr 12, 2022 · 3 comments
Open

menus empty if generate_menu not called within same block. #79

nerdoc opened this issue Apr 12, 2022 · 3 comments
Assignees
Labels
docs Issue with the project's documantation

Comments

@nerdoc
Copy link
Contributor

nerdoc commented Apr 12, 2022

the docs say that {% generate_menu %} needs to be called within a block. I think this is not correct, as it seems to need to be called within the same block you are using the menu.
Using a simple pattern to demonstrate this:

# base.html template
<html>
<head>
</head>
<body>
  {% block generate_menu %}
    {% generate_menu %}
  {% endblock %}

  {% block content %}
  Empty page.
  {% endblock %}
</body>
</html>

Now use a template that inherits this:

# application.html
{% extends 'base.html' %}

{% block content %}
Now you should see menus, but you don't.
{{ menus }}
{% endblock %}

Here you just override the content block. The generate_menu block should be inherited by extend and be untouched, so generate_menu should be called - which I can confirm by debugging.

The problem seems to be that the context which is passed to MenuNode.render() does't seem to get passed through to the correct template in application.html.

If I add {% generate_menu %} within the content block in application.html, everything is ok. Even if I add {% generate_menu %} in a new generate_menu block in application.html (which is "a block", like the docs say), it does NOT work.

Is this intended behaviour? Or a bug?

@nerdoc
Copy link
Contributor Author

nerdoc commented Oct 27, 2022

I know a bit more now. See in an example here with a base.html:

{% load menu %}
<html>
<head></head>
<body>
{% block menu_wrapper %}
  {% generate_menu %}
{% endblock %}

{% block body %}{% endblock %}
</body>
</html>

...and here a template that extends it:

{% extends 'base.html' %}
{% load menu %}

{% block body %}
{{ menus }} <!-- do something with the menus here -->
{% endblock %}

This does not work, as stated earlier. BUT, if you put the block containing the generate_menu as wrapper around a block that is extended in a sub template, it works:

{% load menu %}
<html>
<head></head>
<body>
{% block menu_wrapper %}
  {% generate_menu %}
  {% block body %}{% endblock %}
{% endblock %}
</body>
</html>

You might ask, why the heck do you need a separate block for generate_menu? Because I had used django_hosts in a complicated, dynamic setup, and wanted to let the sub template decide if it needs menus at all. If not, it would eventually override the menu_wrapper with empty content, so suppressing menu generation.

I ditched django_hosts later, but the separate block remained in my base html - so the bug stayed with me.

I think I could live with seeing this as not a bug, but a "certain behaviour". But it should be stated in the docs as the sentence there is a bit misleading:

Note that generate_menu must be called inside of a block.

I would change that. it's even not good practice, as suggested there, to run generate_menu within a sub template. It is sufficient to run once, in the base (most root) template: BUT, it must be within a block, that's true. So the only way I can think of is like in my second example above: to put a menu_wrapper block around everything else. - And just don't override this block...

@nerdoc
Copy link
Contributor Author

nerdoc commented Oct 27, 2022

AAARGH. Sorry for the spam. It's much easier...

{% load menu %}
<html>
<head></head>
<body>
  {% generate_menu %}
  {% block body %}{% endblock %}
</body>
</html>

I was blinded by the docs because they say it has to be within a block. It hasn't in fact. Or only, if using in a sub template that extends another.

So: best practice is: put it into the main, root template, just anywhere. No block needed. Exactly said, DON'T put it in a block in your root template, as this will most certainly be overridden.

@kytta
Copy link
Member

kytta commented Oct 28, 2022

I was blinded by the docs because they say it has to be within a block. It hasn't in fact. Or only, if using in a sub template that extends another.

Incredible! I didn't know this, either! Thank you a lot!

So: best practice is: put it into the main, root template, just anywhere. No block needed. Exactly said, DON'T put it in a block in your root template, as this will most certainly be overridden.

I will make sure to update the docs

@kytta kytta self-assigned this Oct 28, 2022
@kytta kytta added the docs Issue with the project's documantation label Oct 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Issue with the project's documantation
Projects
None yet
Development

No branches or pull requests

2 participants