WordPress шаблон - Как добавить класс к тегу li при наличии подменю

16 февр. 2015 г., 13:38:33
Просмотры: 18.3K
Голосов: 0

Например, я хочу создать такое меню:

<div class="menu_wrap">
 <ul class="nav sf-menu">
  <li class="sub-menu"><a href="">Главное меню 1</a>
    <ul>
        <li><a href=""><span>-</span>Подменю 1</a></li>
        <li><a href=""><span>-</span>Подменю 2</a></li>
    </ul>
  </li>
  <li class="sub-menu"><a href="">Главное меню 2</a>
    <ul>
        <li><a href=""><span>-</span>Подменю 1</a></li>
        <li><a href=""><span>-</span>Подменю 2</a></li>
    </ul>
  </li>
  <li><a href="">Главное меню 3 без подменю</a></li>
</ul>

как добавить class="sub-menu" в тег li, если подменю существует:

<li class="sub-menu"><a href="">Главное меню 1</a>

если подменю нет, то вывести li без класса:

<li><a href="">Главное меню 3 без подменю</a></li>

У меня есть такой код в functions.php:

// Добавляем поддержку меню
    add_theme_support( 'menus' );
    register_nav_menus(
            array(
                'mainmenu' => 'Главное меню'
            )
        );
    function dtuts_main_nav() {
        // отображаем wp3 меню если доступно
        wp_nav_menu(array(
            'theme_location'  => 'mainmenu',
            'menu'            => 'mainmenu',
            'container'       => 'div',
            'container_class' => 'menu_wrap',
            'menu_class'      => 'nav sf-menu',
            'echo'            => true,
            'items_wrap'      => '<ul class="%2$s">%3$s</ul>',
            'depth'           => 1,
            'walker'          => new themeslug_walker_nav_menu
        ));
    } 

Я не могу написать класс themeslug_walker_nav_menu, помогите.

1
Комментарии

Вы можете использовать jQuery (javascript).

Mayeenul Islam Mayeenul Islam
16 февр. 2015 г. 13:43:05
Все ответы на вопрос 1
4

Вот код, который я использую. Это пользовательский навигационный Walker для Bootstrap, но вы можете легко адаптировать его под свои нужды. Кстати, вы можете просто скопировать и вставить мой Walker, только обязательно измените эту строку:

$class_names .= ' dropdown';

на

$class_names .= ' sub-menu';

Надеюсь, это поможет.

/**
 * Пользовательский Bootstrap Walker для навигационного меню
 */

class macho_bootstrap_walker extends Walker_Nav_Menu
{

/**
 * @see Walker::start_lvl()
 * @since 3.0.0
 *
 * @param string $output Передается по ссылке. Используется для добавления дополнительного контента.
 * @param int $depth Глубина страницы. Используется для отступов.
 */
public function start_lvl(&$output, $depth = 0, $args = array())
{
    $indent = str_repeat("\t", $depth);
    $output .= "\n$indent<ul role=\"menu\" class=\" dropdown-menu\">\n";
}

/**
 * @see Walker::start_el()
 * @since 3.0.0
 *
 * @param string $output Передается по ссылке. Используется для добавления дополнительного контента.
 * @param object $item Объект данных пункта меню.
 * @param int $depth Глубина пункта меню. Используется для отступов.
 * @param int $current_page ID пункта меню.
 * @param object $args
 */
public function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0)
{
    $indent = ($depth) ? str_repeat("\t", $depth) : '';

    /**
     * Разделители, заголовки или отключенные элементы
     * ==============================================
     * Определяем, является ли пункт разделителем, заголовком, отключенным или обычным
     * пунктом меню. Во избежание ошибок используем функцию strcasecmp() для
     * сравнения без учета регистра. Функция strcasecmp() возвращает
     * 0, если строки равны.
     */
    if (strcasecmp($item->attr_title, 'divider') == 0 && $depth === 1) {
        $output .= $indent . '<li role="presentation" class="divider">';
    } else if (strcasecmp($item->title, 'divider') == 0 && $depth === 1) {
        $output .= $indent . '<li role="presentation" class="divider">';
    } else if (strcasecmp($item->attr_title, 'dropdown-header') == 0 && $depth === 1) {
        $output .= $indent . '<li role="presentation" class="dropdown-header">' . esc_attr($item->title);
    } else if (strcasecmp($item->attr_title, 'disabled') == 0) {
        $output .= $indent . '<li role="presentation" class="disabled"><a href="#">' . esc_attr($item->title) . '</a>';
    } else {

        $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));

        if ($args->has_children)
            $class_names .= ' dropdown';

        if (in_array('current-menu-item', $classes))
            $class_names .= ' active';

        $class_names = $class_names ? ' class="' . esc_attr($class_names) . '"' : '';

        $id = apply_filters('nav_menu_item_id', 'menu-item-' . $item->ID, $item, $args);
        $id = $id ? ' id="' . esc_attr($id) . '"' : '';

        $output .= $indent . '<li' . $id . $value . $class_names . '>';

        $atts = array();
        $atts['title'] = !empty($item->title) ? $item->title : '';
        $atts['target'] = !empty($item->target) ? $item->target : '';
        $atts['rel'] = !empty($item->xfn) ? $item->xfn : '';


        $atts['custom'] = !empty($item->custom) ? $item->custom : '';

        // Если у элемента есть дочерние элементы, добавляем атрибуты к ссылке
        if ($args->has_children && $depth === 0) {
            $atts['href'] = '#';
            $atts['data-toggle'] = 'dropdown';
            $atts['class'] = 'dropdown-toggle';
            $atts['aria-haspopup'] = 'true';
        } else {
            $atts['href'] = !empty($item->url) ? $item->url : '';
        }

        $atts = apply_filters('nav_menu_link_attributes', $atts, $item, $args);


        $attributes = '';
        foreach ($atts as $attr => $value) {


            if (!empty($value)) {
                $value = ('href' === $attr) ? esc_url($value) : esc_attr($value);
                $attributes .= ' ' . $attr . '="' . $value . '"';
            }
        }

        $item_output = $args->before;

        /*
         * Иконки Glyphicons
         * ================
         * Так как пункт меню НЕ является разделителем или заголовком, проверяем
         * наличие значения в свойстве attr_title. Если attr_title
         * не пустое, применяем его как имя класса для glyphicon.
         */
        if (!empty($item->attr_title))
            $item_output .= '<a' . $attributes . '><span class="glyphicon ' . esc_attr($item->attr_title) . '"></span>&nbsp;';
        else
            $item_output .= '<a' . $attributes . '>';


        $item_output .= $args->link_before . apply_filters('the_title', $item->title, $item->ID) . $args->link_after;
        $item_output .= ($args->has_children && 0 === $depth) ? ' <span class="caret"></span></a>' : '</a>';
        $item_output .= $args->after;

        $output .= apply_filters('walker_nav_menu_start_el', $item_output, $item, $depth, $args);
    }
}

/**
 * Обход элементов для создания списка из элементов.
 *
 * Отображает один элемент, если у элемента нет дочерних элементов, в противном случае
 * отображает элемент и его дочерние элементы. Обрабатывает только до максимальной
 * глубины и игнорирует элементы глубже этой глубины.
 *
 * Этот метод не должен вызываться напрямую, используйте вместо него метод walk().
 *
 * @see Walker::start_el()
 * @since 2.5.0
 *
 * @param object $element Объект данных
 * @param array $children_elements Список элементов для продолжения обхода.
 * @param int $max_depth Максимальная глубина обхода.
 * @param int $depth Глубина текущего элемента.
 * @param array $args
 * @param string $output Передается по ссылке. Используется для добавления дополнительного контента.
 * @return null Возвращает null при ошибке без изменения параметров.
 */
public function display_element($element, &$children_elements, $max_depth, $depth, $args, &$output)
{
    if (!$element)
        return;

    $id_field = $this->db_fields['id'];

    // Отображаем этот элемент.
    if (is_object($args[0]))
        $args[0]->has_children = !empty($children_elements[$element->$id_field]);

    parent::display_element($element, $children_elements, $max_depth, $depth, $args, $output);
}

/**
 * Фолбэк для меню
 * ===============
 * Если эта функция назначена как fallback_cb для wp_nav_menu
 * и меню не назначено для данной локации в менеджере меню WordPress,
 * функция не будет отображать ничего для незалогиненного пользователя,
 * но добавит ссылку в менеджер меню WordPress для администратора.
 *
 * @param array $args Аргументы, переданные из функции wp_nav_menu.
 *
 */
public static function fallback($args)
{
    if (current_user_can('manage_options')) {

        extract($args);

        $fb_output = null;

        if ($container) {
            $fb_output = '<' . $container;

            if ($container_id)
                $fb_output .= ' id="' . $container_id . '"';

            if ($container_class)
                $fb_output .= ' class="' . $container_class . '"';

            $fb_output .= '>';
        }

        $fb_output .= '<ul';

        if ($menu_id)
            $fb_output .= ' id="' . $menu_id . '"';

        if ($menu_class)
            $fb_output .= ' class="' . $menu_class . '"';

        $fb_output .= '>';
        $fb_output .= '<li><a href="' . admin_url('nav-menus.php') . '">Добавить меню</a></li>';
        $fb_output .= '</ul>';

        if ($container)
            $fb_output .= '</' . $container . '>';

        echo $fb_output;
    }
}
}
16 февр. 2015 г. 13:47:21
Комментарии

Вот ваш голос "за".

kaiser kaiser
16 февр. 2015 г. 14:05:18

Код TanQ.It работает, но я хочу отключить другие классы. Этот код выводит несколько других классов для тега ul и тега li и т.д. Я хочу, чтобы выводился только class="sub-menu" для тега li. Как мне это сделать?

Shahin Ataei Shahin Ataei
16 февр. 2015 г. 19:56:52

Измените приведенный выше код в соответствии с вашими потребностями. Это была отправная точка.

cristian.raiber cristian.raiber
16 февр. 2015 г. 20:15:15

спасибо. будь честным и работай. Только у меня есть проблема. я хочу добавить префиксный символ, например "-". если элемент является дочерним, выведите "<span>-</span>" перед пунктом подменю для отступа. как я могу это сделать?

Shahin Ataei Shahin Ataei
17 февр. 2015 г. 14:12:16