WordPress как на ладони

Разные виджеты в разных разделах сайта

Подскажите как можно реализовать такое.

я использую тему gambit, так вот у неё есть с права и лева виджеты по переходе по разделам сайта она повторяет все то что на главной.нужно сделать так что по переходе в другой раздел виджеты отображали тематику раздела,к примеру( раздел боевик в виджетах отображаются все с раздела а в разделе мультики все о мультиках)

Или это не возможно? или можно как то с помощью functions.php организовать?

0
Хаид
6 лет назад
  • 1

    Добрый вечер. Как раз реализовывал нечто подобное. У меня задача была следующая: мне нужно было на разных страницах и постах в сайдбарах выводить нужные мне виджеты. Я нашёл два способа.

    1 способ. плагин JP Widget Visibility. Добавялет к виджету кнопку "Visibility", при нажатии на которую даётся выбор где показывать/или не показывать данный виджет. Т.е. есть у тебя левый сайдбар (он отображается допустим на страницах и постах), ты в него запихиваешь кучу виджетов (меню, ещё меню, ещё меню, календари там всякие и прочее), а дальше у каждого виджета выставляешь где он должен быть показан/или скрыт.

    2 способ муторный, но именно тот который я хотел осуществить. Этот способ даёт возможность создавать сколько угодно сайдбаров, добавлять в них виджеты, а при создании/редактировании страницы/поста даётся выбор какой сайдбар отображать.

    1 шаг. Создаём 4 файла: theme-options.php, theme-options.css, sidebar-init.php и theme-function.php.

    В functions.php подрубаем:

    include_once (get_template_directory() . '/inc/theme-options.php');
    include_once (get_template_directory() . '/inc/sidebar-init.php');
    include_once (get_template_directory() . '/inc/theme-function.php');

    Далее создаём первый файл theme-options.php(за основу был взят файл темы TwentyEleven) и сразу же вместе с ним theme-options.css.

    Код файла theme-options.php:

    <?php
    function YourTheme_admin_enqueue_scripts( $hook_suffix ) {
    	wp_enqueue_style( 'YourTheme-theme-options', get_template_directory_uri() . '/css/theme-options.css', false, '1' );
    }
    add_action( 'admin_print_styles-appearance_page_theme_options', 'YourTheme_admin_enqueue_scripts' );
    
    function YourTheme_theme_options_init() {
    
    	register_setting(
    		'YourTheme_options',       // Options group, see settings_fields() call in YourTheme_theme_options_render_page()
    		'YourTheme_theme_options', // Database option, see YourTheme_get_theme_options()
    		'YourTheme_theme_options_validate' // The sanitization callback, see YourTheme_theme_options_validate()
    	);
    
    	// Register our settings field group
    	add_settings_section(
    		'general', // Unique identifier for the settings section
    		'', // Section title (we don't want one)
    		'__return_false', // Section callback (we don't want anything)
    		'theme_options' // Menu slug, used to uniquely identify the page; see YourTheme_theme_options_add_page()
    	);
    
    	// Register our individual settings fields
    	add_settings_field(
    		'custom_sidebar_left',                             // Unique identifier for the field for this section
    		__( 'Здесь можно добавлять и удалять области для виджетов (так называемые сайдбары). Далее, для того чтобы добавить необходимые виджеты в созданные области, нужно перейти во вкладку "Внешний вид" -> "Виджеты" и перетащить нужный виджет в нужную область. Далее при создании/редактировании страницы или поста справа в колонке "Выбрать сайдбар" выбрать из списка необходимый для отображения на данной странице сайдбар.', 'YourTheme' ),       // Setting field label
    		'YourTheme_settings_field_custom_sidebar_left', // Function that renders the settings field
    		'theme_options',                            // Menu slug, used to uniquely identify the page; see YourTheme_theme_options_add_page()
    		'general'                                  // Settings section. Same as the first argument in the add_settings_section() above
    	);
    
    	add_settings_field(
    		'custom_sidebar_right',                             // Unique identifier for the field for this section
    		'',       // Setting field label
    		'YourTheme_settings_field_custom_sidebar_right', // Function that renders the settings field
    		'theme_options',                            // Menu slug, used to uniquely identify the page; see YourTheme_theme_options_add_page()
    		'general'                                  // Settings section. Same as the first argument in the add_settings_section() above
    	);
    
    }
    add_action( 'admin_init', 'YourTheme_theme_options_init' );
    
    function YourTheme_option_page_capability( $capability ) {
    	return 'edit_theme_options';
    }
    add_filter( 'option_page_capability_YourTheme_options', 'YourTheme_option_page_capability' );
    
    function YourTheme_theme_options_add_page() {
    	$theme_page = add_theme_page(
    		__( 'Настройка сайдбаров', 'YourTheme' ),   // Name of page
    		__( 'Настройка сайдбаров', 'YourTheme' ),   // Label in menu
    		'edit_theme_options',                    // Capability required
    		'theme_options',                         // Menu slug, used to uniquely identify the page
    		'YourTheme_theme_options_render_page' // Function that renders the options page
    	);
    
    	if ( ! $theme_page )
    		return;
    
    	add_action( "load-$theme_page", 'YourTheme_theme_options_help' );
    }
    add_action( 'admin_menu', 'YourTheme_theme_options_add_page' );
    
    function YourTheme_theme_options_help() {
    
    	$help = '<p>' . __( 'Some themes provide customization options that are grouped together on a Theme Options screen. If you change themes, options may change or disappear, as they are theme-specific. Your current theme, YourTheme, provides the following Theme Options:', 'YourTheme' ) . '</p>' .
    			'<ol>' .
    				'<li>' . __( '<strong>Custom Sidebars</strong>: You can add and remove custom sidebars to use them on different pages and posts.', 'YourTheme' ) . '</li>' .
    			'</ol>' .
    			'<p>' . __( 'Remember to click "Save Changes" to save any changes you have made to the theme options.', 'YourTheme' ) . '</p>';
    
    	$sidebar = '<p><strong>' . __( 'For more information:', 'YourTheme' ) . '</strong></p>' .
    		'<p>' . __( '<a href="https://codex.wordpress.org/Appearance_Theme_Options_Screen" target="_blank">Documentation on Theme Options</a>', 'YourTheme' ) . '</p>' .
    		'<p>' . __( '<a href="https://wordpress.org/support/" target="_blank">Support Forums</a>', 'YourTheme' ) . '</p>';
    
    	$screen = get_current_screen();
    
    	if ( method_exists( $screen, 'add_help_tab' ) ) {
    		// WordPress 3.3.0
    		$screen->add_help_tab( array(
    			'title' => __( 'Overview', 'YourTheme' ),
    			'id' => 'theme-options-help',
    			'content' => $help,
    			)
    		);
    
    		$screen->set_help_sidebar( $sidebar );
    	} else {
    		// WordPress 3.2.0
    		add_contextual_help( $screen, $help . $sidebar );
    	}
    }
    
    /**
     * Возвращает дефолтные настройки.
     */
    function YourTheme_get_default_theme_options() {
    $default_theme_options = array(
    	'custom_sidebar_left' => array(),
    	'custom_sidebar_right' => array()
    );
    	if ( is_rtl() )
    		$default_theme_options['theme_layout'] = 'sidebar-content';
    	return apply_filters( 'YourTheme_default_theme_options', $default_theme_options );
    }
    
    /**
    * Sidebar handler. Добавление и удаление сайдюаров
    */
    function YourTheme_settings_field_custom_sidebar_left() { 
    	$themename = getCurrentTheme();
    
    	$opts = YourTheme_get_theme_options();
    
    	$output= "<script type='text/javascript'>";
    	$output .= '
    	var $ = jQuery;
    	$(document).ready(function(){
    		$(".sidebar_management.left").on("click", ".delete", function(){
    			$(this).parent().remove();
    		});
    		$("#add_sidebar_left").click(function(){
    			$(".sidebar_management.left ul").append("<li><strong>"+$("#new_sidebar_left_name").val()+"</strong><input class='.__("button-primary", $themename).' type='.__("button", $themename).' id='.__("delete_sidebar_left", $themename).' value='.__("Удалить", $themename).' /> <input type='.__("hidden", $themename).' name='.__("YourTheme_theme_options[custom_sidebar_left][]", $themename).' value="+$("#new_sidebar_left_name").val()+" /></li>");
    			$("#new_sidebar_left_name").val("");
    		})
    	 })';
    
    	$output .= "</script>";
    
    	$output .= "<div class='sidebar_management left'>";
    	$output .= "<label for='sidebar_left_generator'>Добавить сайдбар слева:</label><br><br><p>Введите название сайдбара</p>";
    	$output .= "<input type='text' id='new_sidebar_left_name' class='text' /><br><br><input class='button-primary' type='button' id='add_sidebar_left' value='".__("Добавить", $themename)."' /><br><br>";
    	$output .= "<ul class='created-sidebars left'><label for='created-sidebars-left'>Созданные сайдбары:</label><br><br>";
    
    	// Вывод на экран
    	if(isset($opts['custom_sidebar_left']))
    	{
    		$i = 0;
    		foreach($opts['custom_sidebar_left'] as $sidebar_left)
    		{
    			$output .= "<li><strong>".$sidebar_left."</strong><input class='delete button-primary' type='button' id='delete_sidebar_left' value='".__("Удалить", $themename)."' /> <input type='hidden' name='YourTheme_theme_options[custom_sidebar_left][]' value='".$sidebar_left."' /></li>";
    			$i++;
    		}
    	}
    	$output .= "</ul>";
    	$output .= "</div>";
    	echo $output;
    }
    
    function YourTheme_settings_field_custom_sidebar_right() { 
    	$themename = getCurrentTheme();
    
    	$opts = YourTheme_get_theme_options();
    
    	$output= "<script type='text/javascript'>";
    	$output .= '
    	var $ = jQuery;
    	$(document).ready(function(){
    		$(".sidebar_management.right").on("click", ".delete", function(){
    			$(this).parent().remove();
    		});
    		$("#add_sidebar_right").click(function(){
    			$(".sidebar_management.right ul").append("<li><strong>"+$("#new_sidebar_right_name").val()+"</strong><input class='.__("button-primary", $themename).' type='.__("button", $themename).' id='.__("delete_sidebar_right", $themename).' value='.__("Удалить", $themename).' /> <input type='.__("hidden", $themename).' name='.__("YourTheme_theme_options[custom_sidebar_right][]", $themename).' value="+$("#new_sidebar_right_name").val()+" /></li>");
    			$("#new_sidebar_right_name").val("");
    		})
    	 })';
    
    	$output .= "</script>";
    
    	$output .= "<div class='sidebar_management right'>";
    	$output .= "<label for='sidebar_right_generator'>Добавить сайдбар справа:</label><br><br><p>Введите название сайдбара</p>";
    	$output .= "<input type='text' id='new_sidebar_right_name' class='text' /><br><br><input class='button-primary' type='button' id='add_sidebar_right' value='".__("Добавить", $themename)."' /><br><br>";
    	$output .= "<ul class='created-sidebars right'><label for='created-sidebars-right'>Созданные сайдбары:</label><br><br>";
    
    	if(isset($opts['custom_sidebar_right']))
    	{
    		$i = 0;
    		foreach($opts['custom_sidebar_right'] as $sidebar_right)
    		{
    			$output .= "<li><strong>".$sidebar_right."</strong><input class='delete button-primary' type='button' id='delete_sidebar_right' value='".__("Удалить", $themename)."' /> <input type='hidden' name='YourTheme_theme_options[custom_sidebar_right][]' value='".$sidebar_right."' /></li>";
    			$i++;
    		}
    	}
    	$output .= "</ul>";
    	$output .= "</div>";
    	echo $output;
    }
    
    function YourTheme_get_theme_options() {
    	return get_option( 'YourTheme_theme_options', YourTheme_get_default_theme_options() );
    }
    
    /**
     * Render the theme options page for .
     */
    function YourTheme_theme_options_render_page() {
    	?>
    	<div class="wrap">
    		<?php $theme_name = function_exists( 'wp_get_theme' ) ? wp_get_theme() : get_current_theme(); ?>
    		<h2><?php printf( __( '%s: настройка сайдбаров', 'YourTheme' ), $theme_name ); ?></h2>
    		<?php settings_errors(); ?>
    
    		<form method="post" action="options.php">
    			<?php
    				settings_fields( 'YourTheme_options' );
    				// do_settings_sections( 'theme_options' );
    				do_settings_fields( 'theme_options', 'general' );
    				submit_button();
    			?>
    		</form>
    	</div>
    	<?php
    }
    
    function YourTheme_theme_options_validate( $input ) {
    	$output = $defaults = YourTheme_get_default_theme_options();
    
    	if ( isset( $input['custom_sidebar_left'] ) ) {
    		$output['custom_sidebar_left'] = $input['custom_sidebar_left'];
    	}
    	if ( isset( $input['custom_sidebar_right'] ) ) {
    		$output['custom_sidebar_right'] = $input['custom_sidebar_right'];
    	}   
    
    	return apply_filters( 'YourTheme_theme_options_validate', $output, $input, $defaults );
    }

    Если в двух словах, файл theme-options.php добавляет в админку во внешний вид филд "Настройка сайдбаров", где мы теперь можем добавлять и удалять сайдбары и сохранять изменения.

    Код файла theme-options.css:

    #wpcontent select option {
    	padding-right: 5px;
    }
    .sidebar_management {
    	max-width: 433px;
    	padding: 0;
    	position: relative;
    	margin-top: 30px;
    }
    .sidebar_management>ul>li {
    	border: 1px solid #dadada;
    	padding: 20px;
    }
    .sidebar_management ul li {
    	position: relative;
    	overflow: hidden;
    }
    .sidebar_management label {
    	color: #464646;
    	font-family: Arial, Helvetica, "Trebuchet MS", sans-serif;
    	font-size: 1.5em;
    	display: block;
    	float: left;
    	margin-bottom: 10px;
    }
    input.text {
    	width: 433px;
    }
    .sidebar_management .created-sidebars li {
    	background: #fff;
    	line-height: 25px;
    	line-height: 2em;
    }
    .sidebar_management .created-sidebars li strong, .ml_admin_page .sidebars li input {
    	float: left;
    	margin-right: 10px;
    }
    
    .sidebar_management .created-sidebars li strong {
    	display: block;
    	width: 300px;
    }

    2 шаг. Теперь надо чтобы эти добавленные/удалённые сайдбары были зарегистрированы и отображались в администрировании виджетов. С этим нам поможет файл sidebar-init.php:

    <?php
    function YourTheme_widgets_init() {
    	$options = YourTheme_get_theme_options();
    	if(isset($options['custom_sidebar_left']) && sizeof($options['custom_sidebar_left']) > 0) {
    		foreach($options['custom_sidebar_left'] as $sidebar_left)
    		{
    		register_sidebar( array(
    			'name' => __( $sidebar_left, 'YourTheme' ),
    			'id' => generateSlug($sidebar_left, 512),
    			'before_widget' => '<div id="%1$s">',
    			'after_widget' => '</div>',
    			'before_title' => '<h3>',
    			'after_title' => '</h3>',
    		) );
    		}
    	}
    	if(isset($options['custom_sidebar_right']) && sizeof($options['custom_sidebar_right']) > 0) {
    		foreach($options['custom_sidebar_right'] as $sidebar_right)
    		{
    		register_sidebar( array(
    			'name' => __( $sidebar_right, 'YourTheme' ),
    			'id' => generateSlug($sidebar_right, 512),
    			'before_widget' => '<div id="%1$s">',
    			'after_widget' => '</div>',
    			'before_title' => '<h3>',
    			'after_title' => '</h3>',
    		) );
    		}
    	}
    }
    
    add_action( 'widgets_init', 'YourTheme_widgets_init' );
    
    function generateSlug($phrase, $maxLength) {
    	$result = strtolower($phrase);
    	$result = preg_replace("/[^a-z0-9s-]/", "", $result);
    	$result = trim(substr($result, 0, $maxLength));
    
    	return $result;
    }

    Здесь мы получаем настройки темы, проверяем, есть ли хотя бы один собственный сайдбар и регистрируем его. Используем быструю функцию для генерации метки из названия сайдбара, который будет использоваться как ID сайдбара.
    Теперь во вкладке "Внешний вид" -> "Виджеты" мы можем увидеть созданные сайдбары.

    3 шаг. Теперь нужно добавить мета блоки на страницы редактирования страниц/постов, где мы и будем выбирать какие сайдбары отображать. Файл theme-function.php:

    <?php
    /** 
     * Define the custom box for sidebars
     */
    add_action( 'add_meta_boxes', 'add_sidebar_metabox' );
    
    /* Adds a box to the side column on the Post and Page edit screens */
    function add_sidebar_metabox()
    {
    	add_meta_box(
    		'custom_sidebar_left',
    		__( 'Выбрать сайдбар слева', 'techacademy' ),
    		'custom_sidebar_left_callback',
    		'post',
    		'side'
    	);
    	add_meta_box(
    		'custom_sidebar_left',
    		__( 'Выбрать сайдбар слева', 'techacademy' ),
    		'custom_sidebar_left_callback',
    		'page',
    		'side'
    	);
    	add_meta_box(
    		'custom_sidebar_right',
    		__( 'Выбрать сайдбар справа', 'techacademy' ),
    		'custom_sidebar_right_callback',
    		'post',
    		'side'
    	);
    	add_meta_box(
    		'custom_sidebar_right',
    		__( 'Выбрать сайдбар справа', 'techacademy' ),
    		'custom_sidebar_right_callback',
    		'page',
    		'side'
    	);
    }
    
    /* Prints the box content */
    function custom_sidebar_left_callback( $post )
    {
    	global $wp_registered_sidebars;
    	$themename = getCurrentTheme();
    
    	$custom = get_post_custom($post->ID);
    
    	if(isset($custom['custom_sidebar_left']))
    		$val = $custom['custom_sidebar_left'][0];
    	else
    		$val = "default";
    
    	// Use nonce for verification
    	wp_nonce_field( basename( __FILE__ ), 'custom_sidebar_left_nonce' );
    
    	// The actual fields for data entry
    	$output = '<p><label for="myplugin_new_field">'.__("Выбрать сайдбар для отображения", 'Выбрать сайдбар' ).'</label></p>';
    	$output .= "<select name='custom_sidebar_left'>";
    
    	// Add a default option
    	$output .= "<option";
    	if($val == "default")
    		$output .= " selected='selected'";
    	$output .= " value='default'>".__('default', $themename)."</option>";
    
    	// Fill the select element with all registered sidebars
    	foreach($wp_registered_sidebars as $sidebar_id => $sidebar_left)
    	{
    		$output .= "<option";
    		if($sidebar_id == $val)
    			$output .= " selected='selected'";
    		$output .= " value='".$sidebar_id."'>".$sidebar_left['name']."</option>";
    	}
    
    	$output .= "</select>";
    
    	echo $output;
    
    }
    
    function custom_sidebar_right_callback( $post )
    {
    	global $wp_registered_sidebars;
    	$themename = getCurrentTheme();
    
    	$custom = get_post_custom($post->ID);
    
    	if(isset($custom['custom_sidebar_right']))
    		$val = $custom['custom_sidebar_right'][0];
    	else
    		$val = "default";
    
    	// Use nonce for verification
    	wp_nonce_field( basename( __FILE__ ), 'custom_sidebar_right_nonce' );
    
    	// The actual fields for data entry
    	$output = '<p><label for="myplugin_new_field">'.__("Выбрать сайдбар для отображения", 'Выбрать сайдбар' ).'</label></p>';
    	$output .= "<select name='custom_sidebar_right'>";
    
    	// Add a default option
    	$output .= "<option";
    	if($val == "default")
    		$output .= " selected='selected'";
    	$output .= " value='default'>".__('default', $themename)."</option>";
    
    	// Fill the select element with all registered sidebars
    	foreach($wp_registered_sidebars as $sidebar_id => $sidebar_right)
    	{
    		$output .= "<option";
    		if($sidebar_id == $val)
    			$output .= " selected='selected'";
    		$output .= " value='".$sidebar_id."'>".$sidebar_right['name']."</option>";
    	}
    
    	$output .= "</select>";
    
    	echo $output;
    
    }
    
    /* When the post is saved, saves our custom data */
    function save_sidebar_postdata( $post_id ) {
    	// verify if this is an auto save routine.
    	// If it is our form has not been submitted, so we dont want to do anything
    	if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
    	  return $post_id;
    
    	// verify this came from our screen and with proper authorization,
    	// because save_post can be triggered at other times
    	if ( !isset( $_POST['custom_sidebar_left_nonce'] ) || !wp_verify_nonce( $_POST['custom_sidebar_left_nonce'], basename( __FILE__ ) ) )
    	  return $post_id;
    	if ( !isset( $_POST['custom_sidebar_right_nonce'] ) || !wp_verify_nonce( $_POST['custom_sidebar_right_nonce'], basename( __FILE__ ) ) )
    	  return $post_id;
    
    	if ( !current_user_can( 'edit_page', $post_id ) )
    		return $post_id;
    	// теперь также проверим тип записи
    
    	$data_left = $_POST['custom_sidebar_left'];
    	$data_right = $_POST['custom_sidebar_right'];
    	update_post_meta($post_id, "custom_sidebar_left", $data_left);
    	update_post_meta($post_id, "custom_sidebar_right", $data_right);
    
    	return $post_id;
    }
    add_action('save_post', 'save_sidebar_postdata');

    Тут мы сначала добавялем наши мета блоки. Далее создаём функции обратного вызова, которые выводят разметку мета блоков, а также получают все зарегистрированные сайдбары (включая стандартный сайдбар темы) через глобальную переменную $wp_registered_sidebars; получают meta записи; создают временную защиту; добавляют выбранный элемент со всеми сайдбарами плюс стандартный, который определен напрямую в файле шаблона. И затем функция save_sidebar_postdata сохраняет meta описание нашей записи в несколько шагов (проверка наличия автосохранения WordPress; проверка защиты и авторизации; сохранение post_meta).

    4 шаг. Осталось лишь подправить файлы шаблонов, где у нас выводятся сайдбары (допустим page.php и single.php). Для этого создаём два файла sidebar-left.php и sidebar-custom-left.php и тоже самое для правого сайдбара.

    Файл sidebar-custom-left.php

    <?php
    /**
    * Sidebar Name: Dynamic Custom Sidebar Left
    */
    $options = get_post_custom($post->ID);
    $sidebar_choice = $options['custom_sidebar_left'][0];
    ?>
    <?php if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar() ) : ?>
    	<?php dynamic_sidebar($sidebar_choice); ?>
    <?php else : ?>
    	<!-- No widget -->
    <?php endif; ?>

    Файл sidebar-left.php

    <?php /* Static Name: Sidebar Left */
    $options = get_post_custom(get_the_ID());
    if(isset($options['custom_sidebar_left'])) {
    	$sidebar_choice = $options['custom_sidebar_left'][0];
    } else {
    	$sidebar_choice = "default";
    }
    if($sidebar_choice && $sidebar_choice != "default") {
    	get_sidebar("custom-left");
    } else {
    	get_sidebar();
    }
    ?>

    А в файлах page.php и single.php выводим сайдбары через

    <?php get_template_part('sidebar-left'); ?>
    <?php get_template_part('sidebar-right'); ?>

    Стандартный sidebar.php(который будет отображаться по дефолту) можно настроить заранее, или вообще сделать пустым.

    Вот и всё. Теперь мы можем выводить на страницах/в постах нужные нам сайдбары с нужными нам виджетами слева, или справа, или сразу оба.

    В принципе всё это можно запихнуть сразу в functions.php, но мне не нравится когда он захламлён.

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