Reputation: 19911
I would like to redirect the top menu items in a page I'm writing to point at their children if they have any. E.g. this site has a top level About, with several CMS pages underneath. When a user clicks on about, I want to show the first child page under the top-level about menu.
I can do it like the below, but it feels wrong. I know I can do a static redirect, but I don't want to do that, as the first child might change (it's a CMS system after all) and I don't want the people entering data into the CMS to have to manage a redirect. So I prefer the below to a configured redirect.
This is a pretty common requirement, is there a standard way of doing this? I think I might be able to do it with a navigation modifier, so I might try that route next.
<div style="display:none;">{% show_menu 0 1 1 %}</div>
<div id="topmenu">
<ul>
{% for child in children %}
<li>
{% if child.children %}
<a href="{{child.children.0.get_absolute_url}}">
{% else %}
<a href="{{child.get_absolute_url}}">
{% endif %}
{{ child.get_menu_title }}
</a>
</li>
{% endfor %}
</ul>
</div>
About the above, I need to have the show_menu in there otherwise the data isn't there for my custom menu. Is there any way for this not to be needed?
The thing I dislike the most about the above, is that the /about/ page is still active. It's not the worst thing in the world if someone browses there, they'll get an empty page, but I'd rather that not happen. I think if I wrote a navigation extension the same disadvantage would be there. I guess I need a programmatic redirect to redirect to the first child if that page is hit. Thoughts? I can probably do it in template logic, but that seems crazy.
Upvotes: 2
Views: 1711
Reputation: 1867
2018: updated version, that works in cms 3.4+ and new middleware style compatible available here. Once you added the /firstchild, you'll need to edit/publish the redirecting page in the cms pages's change list, as, you guess it, will redirect.
solution with middleware and custom redirect field value of "/firstchild", to trigger redirects.
from django.shortcuts import redirect
# redirect to first subpage if the "redirect" field is exactly "_subpage"
class RedirectSubpageMiddleware(object):
def process_view(self, request, view_func, view_args, view_kwargs):
if request.current_page:
page = request.current_page
if "slug" in view_kwargs and page.get_redirect() == "/firstchild":
subpages = request.current_page.children.all()
if subpages.count():
# can redirect! must make uri!
return redirect(subpages[0].get_absolute_url(), permanent=True)
return None
Upvotes: 3
Reputation: 189
You might consider setting the CMS_REDIRECTS = True in the settings.py file.
Then you can go into the /about/ page in the admin and add the redirect to /about/child-page
Note: I haven't actually tried this, I just happened to stumble across this information this morning.
Upvotes: 3