Я пытался искать информацию о том, как исключить/удалить военно-морские пункты меню из пользовательских меню, и единственный поток, который я нашел, не имел никаких ответов, которые были полезны для меня.
1. Фон:
Я соединил меню Dock с помощью пользовательских меню WP (wp_nav_menu) и jqDock на моем сайте. Так как jqDock нужны непрерывные изображения, или изображение связывает с работой свое волшебство, я' использование пользовательского Уокера, таким образом, военно-морской вывод HTML меню смотрит что-то как это:
<div id="menu-first" class="nav">
<a><img src="http://path/to/image-1.png"/></a>
<a><img src="http://path/to/image-2.png"/></a>
<a><img src="http://path/to/image-3.png"/></a>
etc...
</div>
Код для моего пользовательского Уокера:
class custom_nav_walker extends Walker_Nav_Menu
{
var $tree_type = array( 'post_type', 'taxonomy', 'custom' );
var $db_fields = array( 'parent' => 'menu_item_parent', 'id' => 'db_id' );
function start_lvl(&$output, $depth) {
$indent = str_repeat("\t", $depth);
$output .= "\n$indent<ul class=\"sub-menu\">\n";
}
function end_lvl(&$output, $depth) {
$indent = str_repeat("\t", $depth);
$output .= "$indent</ul>\n";
}
function start_el(&$output, $item, $depth, $args) {
global $wp_query;
$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
$class_names = $value = '';
$classes = empty( $item->classes ) ? array() : (array) $item->classes;
$classes[] = 'menu-item-' . $item->ID;
$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );
$class_names = ' class="' . esc_attr( $class_names ) . '"';
$id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
$id = strlen( $id ) ? ' id="' . esc_attr( $id ) . '"' : '';
//$output .= $indent . '<li' . $id . $value . $class_names .'>';
$attributes = ! empty( $item->attr_title ) ? ' title="' . esc_attr( $item->attr_title ) .'"' : '';
$attributes .= ! empty( $item->target ) ? ' target="' . esc_attr( $item->target ) .'"' : '';
$attributes .= ! empty( $item->xfn ) ? ' rel="' . esc_attr( $item->xfn ) .'"' : '';
$attributes .= ! empty( $item->url ) ? ' href="' . esc_attr( $item->url ) .'"' : '';
$description = ! empty( $item->description ) ? esc_attr( strtolower( $item->description )) : '';
$item_title = ! empty( $item->attr_title ) ? esc_attr( $item->attr_title ) : '';
if ( strpos($description, ';') !== false ) {
$description_array = explode (';', $description);
$image_name = $description_array[0];
$image_alt = $description_array[1];
} else {
$image_name = $description;
$image_alt = $item_title;
}
$item_output = $args->before;
$item_output .= '<a'. $attributes .'>';
$item_output .= $args->link_before .'<img src="'.get_bloginfo('template_url').'/images/skin1/'.$image_name.'" alt="'.$image_alt.'" title="'.$item_title.'" />'.$args->link_after;
$item_output .= '</a>';
$item_output .= $args->after;
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
}
function end_el(&$output, $item, $depth) {
$output .= "";
}
}
jqDock сценарий затем ловит меню ID ('меню сначала') и заменяет вывод wp_nav_menu меню Dock. Изменения вывода HTML меню Dock на основе опций указали при загрузке jqDock.
2. Вопрос:
Я хотел бы не отобразить (т.е. исключить) определенные пункты меню согласно тому, где пользователь находится на сайте. Например, я хотел бы только показать Домашний объект, когда пользователь не дома, и Случайный объект сообщения только, когда он.
3. Отброшенные решения:
a. Меню Muliple: Регистрация и создание нескольких меню и затем вызов их условно могли работать; однако, я не думаю, что это - идеал, ни чистое решение вообще по многим причинам. Кроме того, несколько меню не легко поддержать или обновить.
b. Поиск Regex и Замена: Это могло бы вынудить меня изменить параметр иглы каждый раз, когда я изменяю jqDock опции, потому что вывод HTML изменяется.
c. Свойство 'дисплея' CSS: Сокрытие объектов через CSS отображает работы свойства, но так как это должно быть применено к jqDock выводу меню, это влияет на визуальный рендеринг меню.
4. Неудавшиеся решения:
a. Фильтр к wp_nav_menu_items: Я пытался ловить переменную '$items' (строка) и присвоить ей различные значения через условные теги со следующим кодом:
function userf_dynamic_nav_menu ($items) {
$items_array_home = explode('<a', $items);
$items_array_nothome = $items_array_home;
unset($items_array_home[1]);
unset($items_array_nothome[2]);
$items_home = implode('<a', $items_array_home);
$items_nothome = implode('<a', $items_array_nothome);
if ( is_home() ) {
$items = $items_home;
} else {
$items = $items_nothome;
}
return $items;
}
add_filter('wp_nav_menu_first_items', 'userf_dynamic_nav_menu');
Это работает только частично, потому что пункты меню действительно изменяются, но условные теги проигнорированы. Я предполагаю, что это имеет смысл из-за момента, в который применяется фильтр.
b. Пользовательская военно-морская функция меню: Я пытался создать свою собственную военно-морскую функцию меню, чтобы смочь добавить исключить аргумент массиву $defaults и использовать этот немного измененный код от wp_list_pages
заполнить дополнительный аргумент:
$exclude_array = ( $args->exclude ) ? explode(',', $args->exclude) : array();
$args->exclude = implode( ',', apply_filters('wp_nav_menu_excludes', $exclude_array) );
Какие-либо идеи?
Можно добавить конструктора к пользовательскому Walker для хранения некоторых дополнительных аргументов исключения, как:
class custom_nav_walker extends Walker_Nav_Menu {
function __construct( $exclude = null ) {
$this->exclude = $exclude;
}
function skip( $item ) {
return in_array($item->ID, (array)$this->exclude);
// or
return in_array($item->title, (array)$this->exclude);
// etc.
}
// ...inside start_el, end_el
if ( $this->skip( $item ) ) return;
}
Или отбросьте конструктора и установите $exclude
свойство прежде, чем передать его в как Уокер к wp_nav_menu()
как так:
$my_custom_nav_walker = new custom_nav_walker;
$my_custom_nav_walker->exclude = array( ... );
В зависимости от того, чем Вы исключаете, предоставьте правильную форму к исключению.
Это - то, как Вы пошли бы о выполнении этого путем сцепления в wp_get_nav_menu_items
фильтр.
function wpse31748_exclude_menu_items( $items, $menu, $args ) {
// Iterate over the items to search and destroy
foreach ( $items as $key => $item ) {
if ( $item->object_id == 168 ) unset( $items[$key] );
}
return $items;
}
add_filter( 'wp_get_nav_menu_items', 'wpse31748_exclude_menu_items', null, 3 );
Примечание: object_id
объект, на который меню указывает на, в то время как ID
меню ID, они отличаются.
Сообщите мне свои мысли.
делает эту справку
$exclude_array = ( $args->exclude ) ? explode(',', $args->exclude) : array();
$args->exclude = implode( ',', apply_filters('wp_nav_menu_excludes', $exclude_array) );
как пример
< ?php wp_nav_menu( array( 'container_class' => 'menu-header', 'theme_location' => 'primary', 'exclude' => '66' ) ); ?>
wp_nav_menu
не имеет "исключить" аргумента, но я мог быть неправым.
– Marventus
22.10.2011, 04:35
wp_get_nav_menu_items
не получит изображения, потому что теги img не хранятся в фактическом пользовательском меню (только их имена файлов находятся в поле описания, например, "image1.png"). Пользовательский Уокер - то, что позволяет мне вставлять теги img в вывод меню.
– Marventus
22.10.2011, 14:53
in_array
функция. Я делаю что-то не так? – Marventus 21.10.2011, 21:41$exclude
свойство должно быть массивом. Поэтому удостоверьтесь, что Вы передаете массив в конструктора или смотрите обновленный код в моем ответе. Конкретно преобразование типа для$this->exclude
, на всякий случай массив не передается. – soulseekah 21.10.2011, 21:43$exclude = array ('4', '7');
и с помощью кратких заголовков также, но это не имеет никаких эффектов на вывод Уокера. Я попробую второй подход и сообщу. – Marventus 22.10.2011, 02:20