• Здравствуйте всем! Подскажите пожалуйста, как связать между собой два меню так, чтобы когда в верхнем(горизонтальном) выбираю пункт, в сайбаре появлялось меню для этого пункта, например:
    география история химия астрономия — верхнее меню
    выбираю «география» и в сайдбаре появляется меню с пунктами:

    материки
    страны
    города

    для «История»

    древняя история
    среднияе века
    новая история ну и т.д.

    В wp набил несколько записей. Создал рубрики для главного(верхнего) меню(2 штуки получилось), поставил им в соответствие подрубрики, которые, в свою очередь, подключил к записям. Вот так в шаблоне прописал меню

    <nav id="wrap-menu">
    	<?php wp_nav_menu( array( 'menu' => 'main-menu') ); ?>
    </nav>

    вот сайдбар

    <div id="left-sidebar">
    	<nav id="left-menu">
    	<?php if(!function_exists('dynamic_sidebar') || !dynamic_sidebar('sidebar')) : ?>
    	<?php endif; ?>
    	</nav>
    </div><

    файл functions.php

    if ( function_exists( 'register_nav_menu' ) ) // регистрация меню
    {
        register_nav_menu( 'main-menu', 'Main Menu' );
     }
    
    if ( function_exists( 'register_sidebar' ) ) // Регистрация сайдбара(виджетов)
    {
        register_sidebar(array('name' => 'sidebar'));
     }

    При создании меню в wp подключил две главные рубрики, они в меню выводятся, дальше полный ступор.
    Даже записи не выводятся. Что не так?

Просмотр 12 ответов — с 1 по 12 (всего 12)
  • Как вариант для решения этой задачи можно использовать вложенные категории. Категория верхнего уровня будет называться ‘География’, а ‘Материки’, ‘Cтраны’, ‘Города’ — ее подкатегории. В верхнее меню добавить основные категории, а в сайдбаре выводить дочерние категории текущей категории. Для этого можно использовать функцию wp_list_categories.

    Да работает, но коряво получилось.

    <div id="left-sidebar">
    	<nav id="left-menu">
    		<ul>
    			<?php if (is_category(10))
    			{
    			wp_list_categories('include=2,3,4,5&orderby=ID&title_li=');
    			}
    			if (is_category(11))
    			{
    			wp_list_categories('include=6,7,8,9&orderby=ID&title_li=');
    			}
    			?>
    		</ul>
    	</nav>
    </div>

    10 и 11 это пункты главного меню, т.е. главные категории. 2,3,4,5 и 6,7,8,9 — те самые второстепенные, которые связаны с главными посредством wp-admin и которые выводятся в сайдбаре. Если щёлкаешь по главным пункам, в сайдбаре всё выводится норм. А если щелкнуть по сайдбарскому пункту, то оные пропадают. Это и понятно, потому что так у меня в коде прописано. А как сделать так(какое условие), чтобы они не исчезали?

    У функции wp_list_categories есть параметр child_of, который можно использовать для вывода дочерних категорий. Насколько я понимаю, вы хотите, чтобы на странице записей отображался список категорий, у которых один родитель. Вывод зависит от структуры данных, используемой на вашем сайте.

    Скажем, если вы задаете для записи как главную категорию, так и дочернюю, тогда вы можете получить функцией wp_get_post_categories() список всех категорий, взять из него категорию верхнего уровня и вывести для нее все дочерние категории. Причем известно, что это происходит в файле шаблона записи, а в первом случае, о котором вы пишите, все происходило в файле шаблона архива категорий. Таким образом можно написать условный вывод.

    В справке есть целый массив функций для работы с категориями, для категорий также можно использовать все функции для работы с таксономиями. Например, чтобы получить массив всех категорий верхнего уровня можно использовать следующую функцию
    $categories = get_terms( 'category', 'parent=0' );

    а чтобы получить массив категорий для текущей записи

    $taxonomy = 'category';
    
    // get the term IDs assigned to post.
    $post_terms = wp_get_object_terms( $post->ID, $taxonomy, array( 'fields' => 'ids' ) );

    Если на страницах записей вывести дочерние категории для той категории, которая есть в обоих массивах, то получится то, что надо. В справке много примеров как это сделать

    A Basic Example
    Used to get an array of children taxonomies and write them out with links in an unordered list.
    
    <?php
    $term_id = 10;
    $taxonomy_name = 'products';
    $termchildren = get_term_children( $term_id, $taxonomy_name );
    
    echo '<ul>';
    foreach ( $termchildren as $child ) {
    	$term = get_term_by( 'id', $child, $taxonomy_name );
    	echo '<li><a href="' . get_term_link( $child, $taxonomy_name ) . '">' . $term->name . '</a></li>';
    }
    echo '</ul>';
    ?>

    Вот так у меня получилось:
    в sidebar

    <div id="left-sidebar">
    	<nav id="left-menu">
    		<ul class="menu">
    			<?	$cat_ID = get_query_var('cat');
                             // Обработка нажатия пунктов главного меню и вывод соответствуйющего подменю в сайдбаре
    				switch($cat_ID) {
    				case 10:	wp_list_categories('child_of=10&orderby=ID&title_li=');break;	// Механика
    				case 11:	wp_list_categories('child_of=11&orderby=ID&title_li=');break;	// Термодинамика
    				case 13:	wp_list_categories('child_of=13&orderby=ID&title_li=');break;	// Электричество
    				case 17:	wp_list_categories('child_of=17&orderby=ID&title_li=');break;	// Колебания и волны
    				case 21:	wp_list_categories('child_of=21&orderby=ID&title_li=');break;	// Оптика
    				case 25:	wp_list_categories('child_of=25&orderby=ID&title_li=');break;	// Ядерная физика
    				};
                             // обработка нажатия пунков подменю в сайдбаре
    				if (is_category(array(2,3,4,5)))	// Механика
    				{
    					wp_list_categories('child_of=10&orderby=ID&title_li=');
    				}
    				if (is_category(array(6,7,8,9))) 	// Термодинамика
    				{
    					wp_list_categories('child_of=11&orderby=ID&title_li=');
    				}
    				if (is_category(array(14,15,16)))	// Электричество
    				{
    					wp_list_categories('child_of=13&orderby=ID&title_li=');
    				}
    				if (is_category(array(18,19,20)))	// Колебания и волны
    				{
    					wp_list_categories('child_of=17&orderby=ID&title_li=');
    				}
    				if (is_category(array(22,23,24)))	// Оптика
    				{
    					wp_list_categories('child_of=21&orderby=ID&title_li=');
    				}
    				if (is_category(array(26,27,28,29,30)))	// Ядерная физика
    				{
    					wp_list_categories('child_of=25&orderby=ID&title_li=');
    				}
    			?>
    		</ul>
    	</nav>
    </div>

    и так в index.php

    <div id="main">
    	<div id="content">
    		<?
                    // вывод одиночной(промо-поста) страницы при нажатии на пунко главного меню
    		if (is_category(10))		// Механика
    			{ query_posts('p=26'); }
    		if (is_category(11))		// Термодинамика
    			{ query_posts('p=61'); }
    		if (is_category(13))		// Электричество
    			{ query_posts('p=27'); }
    		if (is_category(17))		// Колебания и волны
    			{ query_posts('p=62'); }
    		if (is_category(21))		// Оптика
    			{ query_posts('p=63'); }
    		if (is_category(25))		// Ядерная физика
    			{ query_posts('p=64'); }
    		if ((is_category(10)) || (is_category(11)) || (is_category(13)) || (is_category(17)) || (is_category(21)) || (is_category(25)))
    			{?>
    			<article>
    				<?the_content(); ?>
    			</article>
    			<? wp_reset_query();
    			}
    			else
    			{
                            // Вывод постов для каждого пунка подменю из сайдбара
    				if(have_posts()):
    				while(have_posts()) : the_post() ;?>
    					<h1><?php the_title(); ?></h1>
    					<article>
    						<? the_content();?>
    					</article>
    				<? endwhile;
    			endif;
    		} ?>
    	</div><!-- content -->
    </div>

    не лучший вариант, наверное, но вроде работает. Спасибо cats_465

    Извините, я вам этого не советовала.. Когда я смотрю как у вас <хардкодед> в сайдбар айдишники записей, это вызывает холодную дрожь и ужас, как будто я возвращаюсь в прошлое, где я впервые открываю WordPress и пользуясь советами из интернета прописываю что-то в сайдбар. Понимаете, сайдбары они не для этого, в них нужно вставлять виджеты, а не этот ужасный код. И не приписывайте мне то, что я вам советую делать нечто подобное!

    Сначала надо понять, что вам нужно. У вас сейчас выходит, что пункты верхнего меню указывают на категории, а по этим ссылкам открываются записи. Уже с этого момента все становится кривовато. Сначала сделайте структуру, а потом отображайте все в соответствии с логикой WordPress, можете добавить дополнительные поля в форму таксономии, если надо. Но только без этих ужасных айдишников в исходном коде, пожалуйста!

    Я вам советую забыть о возможности прописывать какие-либо id в исходный код раз и навсегда, как бы просто это не казалось, но это плохая практика.

    Я не приписываю, просто спасибо за поддержку. Вот только исходя из всего последнего, я теперь вообще не знаю, что делать. Ладно, время покажет. Спасибо, теперь уже, за критику.

    Приношу свои глубокие извинения за то, что ввела вас в такое состояние. Сформулируйте задачу, чего вы хотите получить в итоге. Цель какую-то.

    Цель? Сделать сайт с задачами по физике и с их решениями по возможности. Думал структура очень простая и сложностей не вызовет.
    Исходя из этого сформировал простое главное меню с названиями разделов физики, а в сайдбаре располагаются подразделы, которые, естественно, разные у каждого главного раздела. Ну а в блоке main отображаются задачи на эти самые подтемы(подразделы) с решениями. Это всё.
    Да, кстати, не переживайте так за меня, я в норме, холодный душ иногда тоже нужен.

    Вы меня поймите правильно, я вас лично ни в коей мере не критикую, мое сообщение адресовано даже не к вашему коду, а к этим id-шникам, которые в него встроены. Дело в том, что принято данные и код разделять, а тут получается, что они смешиваются, да еще как. Чтобы добавить новую категорию придется лезть в шаблоны, да и чтобы удалить старую. Лазить там по админке, по базам данных, искать id. Представляете, какой это неприятный процесс? А что, если после вас в сайт залезет кто-то другой и увидит там id. Нет, это хорошо, что они снабжены комментириями, но вдруг это будет иностранец?
    И второе, это то, что у файлов WordPress тоже есть своя логика и по ссылке на категорию все ожидают, что откроется категория, а не единичная запись. Как потом разобраться во всем этом и добавить нечто новое, если понадобится?
    Выходит я переживаю-то не за вас, а за WordPress.
    А третье, этот код просто создан для появления неожиданных багов, потому что в нем много информации, с которой должна была работать база данных, а получается, что имеет дело человек и тут включается человеческий фактор на полную.

    К вам лично у меня нет никаких претензий либо критики, напротив, я за вас очень рада, ведь вы программируете WordPress, а это так весело.

    У вас получается, что верхнее меню указывает на отдельную запись, а не на категорию, поэтому логично делать его из ссылок на записи. А далее у вас на отдельных записях отображаются разные меню, то есть, меню привязаны к записи, а запись к родительской категории. В сайдбаре надо вывести дочерние категории категории текущей записи, если они есть, а если нет, то дочерние категории родительской категории текущей записи. В сайдбаре на страницах списков записей показывать дочерние категории родительской категории текущей категории, если они ест, а если нет, то… Так? Сначала надо понять, что делать.

    1. Пункты главного меню, это ссылки на родительские рубрики.
    2. У каждой из родительской рубрики есть дочерние рубрики, которые являются пунктами меню в сайдбаре(списками). Это всё сделано в wp.
    Каждая родительская рубрика(пункт главного меню) связана с одной записью информативного характера, которая появляется в блоке <main> при выборе к-л. пункта главного меню.
    3. К каждому пункту меню в сайдбаре(дочерней рубрике) привязаны какое-то количество записей(постов), т.е. задачи.

    Я больше не знаю, что ещё написать про структуру. Здесь я попробовал выразить в картинках логику своих размышлений:

    1. http://joxi.ru/4AkGyqGiMYqbAq

    2. http://joxi.ru/82359o5f6gxQrO

    3. http://joxi.ru/gmv78W7Hxw4L2a

    4. http://joxi.ru/4AkGyqGiMYzPAq

    Согласен, что данные и код в одной корзине и если данными, в моём случае, являются номера ID и постов, то как от них избавиться? Я пока не представляю. Сидел думал, ходил из угла в угол, чего-то пробовал … Не знаю.
    Не верится, чтобы wp мог решить мою задачу без вмешательства в шаблон. Понимаю, решение где-то рядом. Вопрос — где.

    Сотрите все это и сделайте обычные шаблоны. Вверху добавьте стандартное меню с категориями, в файл functions.php функции, которые показывают дочернее меню:

    /**
     * Print child terms for given term
     *
     * @param int $terms_id parent term id.
     * @param string $taxonomy_name taxonomy slug.
     */
    function my_theme_print_terms($terms_id, $taxonomy_name = 'category') {
    	$terms = get_term_children($terms_id, $taxonomy_name);
    	if ( !empty($terms) && !is_wp_error($terms) ) {
    		echo '<ul>';
    		foreach ( $terms as $child ) {
    			$term = get_term_by( 'id', $child, $taxonomy_name );
    			echo '<li><a href="' . get_term_link( $child, $taxonomy_name ) . '">' . $term->name . '</a></li>';
    		}
    		echo '</ul>';
    	}
    }
    
    if ( ! function_exists( 'my_theme_show_sidebar_menu' ) ) :
    
    /* Print menu */
    function my_theme_show_sidebar_menu() {
    	global $post;
    	$taxonomy_name = 'category';
    
    	if( is_single() ) {
    
    		$term_list = wp_get_post_terms($post->ID, $taxonomy_name);
    
    		if ( !empty($term_list) && !is_wp_error($term_list) ) {
    
    			foreach ($term_list as $term) {
    
    				if( !$term->parent ) { //top level term
    					my_theme_print_terms($term->term_id);
    				}
    
    				else { //child term
    					my_theme_print_terms($term->parent);
    				}
    			}
    
    		}
    	}
    	elseif( is_category() ) {
    		$cat_id = get_query_var('cat');
    		$term = get_term( $cat_id, 'category' );
    
    		if ( !empty($term) && !is_wp_error($term) ) {
    
    			if( !$term->parent ) { //top level term
    				my_theme_print_terms($term->term_id);
    			}
    
    			else {//child term
    				my_theme_print_terms($term->parent);
    			}
    		}
    
    	}
    }
    endif;

    В сайдбаре пропишите <?php my_theme_show_sidebar_menu(); ?>

    А еще лучше сделайте виджет и добавляйте его из меню виджетов.

    Вчера весь день не было инета, поэтому не отписался. sidebar работает, огромное спасибо. index.php пришлось оставить как есть, иначе, при выборе пунка меню, выводится вся ветка для данной категории. Ну да ладно, по ходу пьесы разберусь, не всё сразу, главное теперь знаю, что значит код и данные в одном месте.
    cats_456, ещё раз спасибо. Тема закрыта.

Просмотр 12 ответов — с 1 по 12 (всего 12)
  • Тема «Как связать между собой два меню» закрыта для новых ответов.