Reputation: 674
So I want to add a extra link in the Wagtail admin. I am following the docs (Register Admin Menu Item Hook) and using this hook to contruct a new menu item.
They use this hook for adding menu items:
@hooks.register('register_admin_menu_item')
def register_edit_menu_item():
return MenuItem('Edit profile', 'edit_link', classnames='icon icon-folder-inverse', order=10000)
This should become a link which starts editing a page that is owned by the current logged in user. In a template I use this code to create a direct link to edit the profile of a user:
{% with request.user.owned_pages.all as pages %}
{% if pages.exists %}
{% for p in pages %}
{% if p.get_parent.id == 17 %}
<a class="list-group-item" href="/dashboard/pages/{{ p.id }}/edit/"><i class="fe-icon-edit mr-1 text-muted"></i>Edit profile</a>
{% endif %}
{% endfor %}
{% endif %}
{% endwith %}
This is working just fine, it links directly to the page that it is supposed to link to. However how do I implement a condition like this where I generate the menu link based on the current logged in user?
I would think something like:
if request.user.owned_pages.exists():
for p in request.user.owned_pages.all():
if p.get_parent.id == 17:
edit_link = "/dashboard/pages/" + p.id + "/edit/"
But how can I implement something like this into the Wagtail menu hook?
Upvotes: 1
Views: 1015
Reputation: 25227
The default implementation of MenuItem
assumes that the URL will be constant over all page requests, meaning that we can pass that fixed URL to the MenuItem
constructor inside the register_admin_menu_item
hook (that runs on server startup).
In your case, this isn't true, so you'll need to define a custom subclass of MenuItem
. If you look at the code for MenuItem
, you'll see that it implements a get_context(self, request)
method to gather all the template variables it needs to render the menu item, including url
. You can override this method to set a dynamic URL in place of the fixed one:
class EditProfileMenuItem(MenuItem):
def get_context(self, request):
context = super().get_context(request)
edit_link = None
if request.user.owned_pages.exists():
for p in request.user.owned_pages.all():
if p.get_parent().id == 17:
edit_link = "/dashboard/pages/" + p.id + "/edit/"
if edit_link:
context['url'] = edit_link
return context
You can then use this subclass in the register_admin_menu_item
hook, in place of MenuItem
:
@hooks.register('register_admin_menu_item')
def register_edit_menu_item():
return EditProfileMenuItem('Edit profile', 'edit_link', classnames='icon icon-folder-inverse', order=10000)
(Depending on your requirements you may want to override the is_shown
method too, so that the menu item is hidden from those users who don't have a profile.)
Upvotes: 2