У меня есть одна «ветвь» дерева навигации моего основного сайта, которая должна быть доступна только для набора зарегистрированных, вошедших в систему пользователей. Я понимаю, как запросить роль и возможности пользователя. Этот вопрос касается именно того, как лучше всего использовать встроенное навигационное меню, но просто условно скрыть элемент.
Нужно ли мне перегружать встроенную навигацию по умолчанию, писать собственный запрос и создавать структуру навигации вручную? Я хотел бы избежать этого, если это возможно.
Мне не нужны полные примеры кода, только ваши идеи и общая структура/подход.
Зацените совет!
Т
Я написал сообщение в блоге, связанное с этой проблемой. Конкретный вариант использования сокрытия пунктов меню от пользователей, не имеющих доступа, см. в этом подробном посте.
Абсолютно блестящий. Спасибо за это — хотя я удивлен, что это так сложно. Как вы сказали, возможно, оплошность?
Таким образом, ходок хорош для того, чтобы убедиться, что пункт меню, помеченный как «защищенный», не появляется. Но как создать элемент меню, помеченный как «защищенный» или, что еще лучше, относящийся к определенной роли или возможности? Похоже, мы расширяем элементы меню и добавляем еще несколько настраиваемых пользователем параметров в форму элемента меню…?
@TomAuger Добавьте соответствующие метаданные в связанный объект записи, например пользовательскую таксономию или метаполе публикации. Проверьте значение поля в ходунке.
Спасибо за разъяснения. Абсолютно индивидуальная таксономия или настраиваемое поле были бы правильным выбором. Другой вариант, который я придумал, основан на шаблоне. Мне не так нравится мое решение, потому что вы не должны связывать шаблон со встроенной функциональностью, как это, но есть логическая связь между шаблоном (который должен проверять, есть ли у пользователя доступ для просмотра содержимого) и меню. Я собираюсь опубликовать свой код в ответе ниже для других пользователей с тем же вопросом.
Теперь вам нужно управлять одним меню для каждой роли. Я бы предпочел добавить флажки к пунктам меню в редакторе. К сожалению, для этого нет
do_action()
встроенногоclass Walker_Nav_Menu_Edit
API. Похоже на оплошность.Я согласен, и я сам предпочел бы добавить флажок или простое поле ввода для хранения нужного имени роли, но снова я опубликовал этот ответ в качестве альтернативы вашему. Существует возможность использовать поле описания для каждого элемента, и на основе этого вы можете проверить роль, но тогда вы потеряете возможность описания. это новый API, дайте ему немного времени и откройте много билетов на треки, сколько сможете, чтобы он заработал 🙂
Спасибо за этот более простой подход. Я лично содрогаюсь от необходимости определять свои меню через код — для меня это полностью подрывает одну из основных функций wp_admin, но, возможно, нет более простой альтернативы.
Я добавил этот ответ, хотя с тех пор, как этот вопрос был активен, прошло некоторое время, потому что я подумал, что он может быть полезен другим.
+1 Спасибо, что нашли время добавить свое решение! Это всегда ценят другие, которые натыкаются на вопрос в поиске Google или SE. Ваше здоровье!
Используйте свой собственный ходун и проверьте возможности, прежде чем создавать предмет.
Кто-то сделал блестящий плагин, чтобы сделать это без кодирования. Даже имеет флажки в интерфейсе редактора меню для выбора утвержденных ролей для каждого пункта меню.
http://wordpress.org/extend/plugins/nav-menu-roles/
Опубликованный ответ toscho правильный, но для немногих людей, которые знают, что они делают и как это делать. 🙂 Я добавляю это для остального мира как более простое решение для менее продвинутых пользователей. Идея заключалась бы в том, чтобы иметь разные меню и просто отображать их в зависимости от роли пользователя.
Итак, скажем, у вас есть 3 меню с именами редактор, автор и по умолчанию:
Проблема с переопределением start_el и end_el заключается в том, что это управляет только отображением рассматриваемого пункта меню — это не влияет на отображение дочерних элементов. Я думаю, вам нужно переопределить display_element, чтобы скрыть дочерние элементы.
Кроме того, можно использовать поле описания пункта меню для хранения информации для каждого пункта меню о том, отображать его или нет.
Этот код ищет в описании каждого пункта меню список возможностей, разделенных запятыми, таких как [capability: this_one, next_one], и если текущий пользователь не имеет ни одной из возможностей, он не будет отображать элемент (или любой из его дочерних элементов). Довольно легко удалить строки из описания, если вы действительно хотите использовать описание по назначению.
Я попробовал свои силы в использовании поля описания, чтобы определить, какие роли могут получить доступ к каким пунктам меню, и основывал свои модификации на коде, который я получил отсюда — Прокачай мое меню WP.
Моя модифицированная версия:
Это еще не самая чистая версия, но она работает. Я надеюсь, что кто-то еще может использовать его с пользой.
Я собираюсь опубликовать свое решение для других, которые могут встретиться в этой теме. Я не на 100% доволен этим, потому что вы не должны сочетать шаблон с функциональностью меню (подход Toscho с использованием метаданных или пользовательской таксономии, вероятно, более правильный). Однако это быстро и грязно. Я попытался смягчить тесную связь, предоставив некоторые константы в верхней части functions.php, чтобы помочь будущим разработчикам поддерживать код:
Таким образом, шаблон защищенной страницы — это просто вариант single.php, но он будет проверять, может ли current_user_can(ZG_PROTECTED_PAGE_CAPABILITY) перед отображением любого контента по соображениям безопасности.
Затем я реализую собственный ходок, как предложил Тошо. Ходок в данном случае предельно прост — мы переопределяем публичные методы start_el и end_el у Walker_Nav_Menu, просто перехватывая их достаточно долго, чтобы задать вопрос: есть ли у нас доступ для просмотра пункта меню?
Правило простое: если страница не является «приватной» страницей (что в данном случае определяется этой страницей с использованием определенного шаблона страницы), она видна. Если это ЯВЛЯЕТСЯ «частной» страницей, и пользователь аутентифицирован в роли, которая имеет настраиваемую возможность, которую мы ищем, тогда она видна. В противном случае его не видно.
Если у нас есть доступ, то нам просто нужно использовать встроенные методы Walker_Nav_Menu без изменений, поэтому мы вызываем метод parent:: с тем же именем.