WordPress как на ладони
Недорогой хостинг для сайтов на WordPress: wordpress.jino.ru Купить персональные IPV4 и IPV6 прокси

Показать подпункты меню, если находишься на странице выбранного пункта

Здравствуйте. Нужно, чтобы меню раскрывалось, если находишься на определенной странице. Уже 4 день бьюсь.

Сделал левое меню такого плана. Знак минус напротив пунктов - можно закрыть меню, знак плюс - открыть подпункты.

Сам пример:

Главная
Наши работы -
   -работы №1
   -работы №2
   -работы №3
Фото объектов +
О нас

Вопрос в следующем. К примеру пользователь нажал на "Наши работы", перешёл на эту страницу и все подпункты "Наши работы" автоматически раскрылись. И, если пользователь, к примеру, перейдет с главной страницы сайта, на которой есть ссылка на подпункт "-работы №1" его перекинет на -работы №1 и меню полностью раскроется. Как такое можно реализовать в wordpress?

Самое меню формирую и вывожу виджетом:

class Foo_Widgettwo extends WP_Widget {

	// Регистрация виджета используя основной класс
	function __construct() {
		// вызов конструктора выглядит так:
		// __construct( $id_base, $name, $widget_options = array(), $control_options = array() )
		parent::__construct(
			'foo_widgettwo', // ID виджета, если не указать (оставить ''), то ID будет равен названию класса в нижнем регистре: foo_widget
			'Заголовок виджета',
			array( 'description' => 'Описание виджета', /*'classname' => 'my_widget',*/ )
		);

		// скрипты/стили виджета, только если он активен
		if ( is_active_widget( false, false, $this->id_base ) || is_customize_preview() ) {
			add_action('wp_enqueue_scripts', array( $this, 'add_my_widget_scripts' ));
			add_action('wp_head', array( $this, 'add_my_widget_style' ) );
		}
	}

	/**
	 * Вывод виджета во Фронт-энде
	 *
	 * @param array $args     аргументы виджета.
	 * @param array $instance сохраненные данные из настроек
	 */
	function widget( $args, $instance ) {
		$title = apply_filters( 'widget_title', $instance['title'] );

		echo $args['before_widget'];
		if ( ! empty( $title ) ) {
			echo $args['before_title'] . $title . $args['after_title'];
		}
			echo __('<ul class="sidemenu">');

	wp_nav_menu( array(
	'theme_location'  => 'leftmenu',
	'menu'            => 'leftmenu', 
	'container'       => '', 
	'container_class' => '', 
	'container_id'    => '',
	'menu_class'      => '', 
	'menu_id'         => '',
	'echo'            => true,
	'fallback_cb'     => 'wp_page_menu',
	'before'          => '',
	'after'           => '',
	'link_before'     => '',
	'link_after'      => '',
	'items_wrap'      => '%3$s',
	'depth'           => 0,
	'walker'          => new My_Walker_Nav_Menuleft(),
) );
	echo __('</ul>');

		echo $args['after_widget'];
	}

	/**
	 * Админ-часть виджета
	 *
	 * @param array $instance сохраненные данные из настроек
	 */
	function form( $instance ) {
		$title = @ $instance['title'] ?: 'Заголовок по умолчанию';

		?>
		<p>
			<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label> 
			<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>">
		</p>
		<?php 
	}

	/**
	 * Сохранение настроек виджета. Здесь данные должны быть очищены и возвращены для сохранения их в базу данных.
	 *
	 * @see WP_Widget::update()
	 *
	 * @param array $new_instance новые настройки
	 * @param array $old_instance предыдущие настройки
	 *
	 * @return array данные которые будут сохранены
	 */
	function update( $new_instance, $old_instance ) {
		$instance = array();
		$instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';

		return $instance;
	}

	// скрипт виджета
	function add_my_widget_scripts() {
		// фильтр чтобы можно было отключить скрипты
		if( ! apply_filters( 'show_my_widget_script', true, $this->id_base ) )
			return;

		$theme_url = get_stylesheet_directory_uri();

		wp_enqueue_script('my_widget_script', $theme_url .'/my_widget_script.js' );
	}

	// стили виджета
	function add_my_widget_style() {
		// фильтр чтобы можно было отключить стили
		if( ! apply_filters( 'show_my_widget_style', true, $this->id_base ) )
			return;
		?>
		<style type="text/css">
			.my_widget a{ display:inline; }
		</style>
		<?php
	}

} 
// конец класса Foo_Widgetwo

// регистрация Foo_Widget в WordPress
function register_foo_widget() {
	register_widget( 'Foo_Widgettwo' );
}
add_action( 'widgets_init', 'register_foo_widget' );

Параметр walker:

class My_Walker_Nav_Menuleft extends Walker_Nav_Menu {
 /*
	 * Позволяет перезаписать <ul class="sub-menu">
	 */
	function start_lvl(&$output, $depth) {
		/*
		 * $depth – уровень вложенности, например 2,3 и т д
		 */ 
		$output .= '<span class="ddBtn"></span><ul class="dropdown">';
	}

	/**
	 * @see Walker::start_el()
	 * @since 3.0.0
	 *
	 * @param string $output
	 * @param object $item Объект элемента меню, подробнее ниже.
	 * @param int $depth Уровень вложенности элемента меню.
	 * @param object $args Параметры функции wp_nav_menu
	 */
	function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0 ) {
		global $wp_query;           
		/*
		 * Некоторые из параметров объекта $item
		 * ID - ID самого элемента меню, а не объекта на который он ссылается
		 * menu_item_parent - ID родительского элемента меню
		 * classes - массив классов элемента меню
		 * post_date - дата добавления
		 * post_modified - дата последнего изменения
		 * post_author - ID пользователя, добавившего этот элемент меню
		 * title - заголовок элемента меню
		 * url - ссылка
		 * attr_title - HTML-атрибут title ссылки
		 * xfn - атрибут rel
		 * target - атрибут target
		 * current - равен 1, если является текущим элементом
		 * current_item_ancestor - равен 1, если текущим (открытым на сайте) является вложенный элемент данного
		 * current_item_parent - равен 1, если текущим (открытым на сайте) является родительский элемент данного
		 * menu_order - порядок в меню
		 * object_id - ID объекта меню
		 * type - тип объекта меню (таксономия, пост, произвольно)
		 * object - какая это таксономия / какой тип поста (page /category / post_tag и т д)
		 * type_label - название данного типа с локализацией (Рубрика, Страница)
		 * post_parent - ID родительского поста / категории
		 * post_title - заголовок, который был у поста, когда он был добавлен в меню
		 * post_name - ярлык, который был у поста при его добавлении в меню
		 */

		$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

		/*
		 * Генерируем строку с CSS-классами элемента меню
		 */
		$class_names = $value = '';
		$classes = empty( $item->classes ) ? array() : (array) $item->classes;
		$classes[] = 'menu-item-' . $item->ID;

		// функция join превращает массив в строку
		$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );
		$class_names = ' class="' . esc_attr( $class_names ) . '"';

		/*
		 * Генерируем ID элемента
		 */
		$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 .'>';

		// атрибуты элемента, title="", rel="", target="" и href=""
		$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        ) .'"' : '';

		// ссылка и околоссылочный текст

		$item_output = $args->before;
		$item_output .= '<a'. $attributes .'>';
		$item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
		$item_output .= '</a>';
		$item_output .= $args->after;

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

}

}

HTML код меню:

<ul class="sidemenu">
  <li>
	<a href="#">Menu item</a>
		<span class="ddBtn"></span>
	<ul class="dropdown">
	  <li>
		<a href="#">Sub level item 1</a>
	  </li>
	  <li>
		<a href="#">Sub level item 2</a>
	  </li>
	  <li>
		<a href="#">Sub level item 3</a>
	  </li>
	</ul>

</ul>

Скрипт открытия меню:

$(".sidemenu ul").hide();
$(".ddBtn").click(function() {
  //e.preventDefault();
  // hide submenu
  var $this = $(this).parent().find('ul');
  $(".sidemenu ul").not($this).slideUp(200);
  $(".ddBtn").not(this).removeClass("ddBtnActive");
  // toggle class & dd list
  $this.slideToggle(200);
  $(this).toggleClass("ddBtnActive");
});

Как я понимаю, логика должна быть такой: если мы находимся на странице "Наши работы", мы ищем <span class="ddBtn"></span> и автоматически кликаем по нему, если мы находимся на странице "-работы №1", то опять ищем наш плюсик - <span class="ddBtn"></span> и меню раскрывается.

Только не хватает знаний, как это реализовать. Скорее всего через JS. Помогите, кто чем может..

Заметки к вопросу:
Glum 5 мес назад

Проверяй по активному пункту меню, если память не подводит он есть по умолчанию, если конечно ты его не затер в валкере.. при загрузке страницы проверяй через js этот класс и раскрывай меню

ivanpan 5 мес назад

Спасибо за ответ. Активный пункт принимает класс current-menu-item, это стандарт, его не затирал. К сожалению, у меня знаний не хватает, чтобы это реализовать, хоть и читаю документацию. Если вам не сложно, то напишите, как должно быть.

0
ivanpan
5 месяцев назад

Нет ответов на этот вопрос.

    На вопросы могут отвечать только зарегистрированные пользователи. Вход . Регистрация