Поддержка Проблемы и решения Вопрос по разработке виджета

  • Привет мастерам WP!

    Вопрос по виджетам. Во всех туториалах описаны виджеты в которых будет точно известно количество настроек, переменных и их имена (да, я их прочитал и английские варианты тоже, и до этого я писал простые виджеты). У меня количество чекбосков будет зависеть от количества страниц (ну задумка такая — страниц всего 5-6). В настройках — циклом вывожу названия страниц и возле каждой — чекбокс (показывать/не показывать). Как мне в таком случае хранить настройки? Как оформлять форму виджета и сохранение настроек? В функции «form()» виджета — «id» инпута и его «name» должны оформлятся по каким-то правилам?

    Если я непонятно описал суть проблемы — задайте уточняющий вопрос! Это упросит задачу и мне и Вам.

    Спасибо.

    З.Ы. И еще, если можно — подскажите кто и как дебажит данные при разработке виджетов, какие приемы используете — как оказалось это то еще занятие (Или я это неправильно делаю 🙂 ).

Просмотр 8 ответов — с 1 по 8 (всего 8)
  • Модератор Yuri

    (@yube)

    В настройках — циклом вывожу названия страниц и возле каждой — чекбокс (показывать/не показывать). Как мне в таком случае хранить настройки?

    foreach($pages as $page) {
     echo "<input type='checkbox' name='page[$page->ID]'> $page->post_title";
    }

    и хранить сериализованным массивом. Как вариант.

    кто и как дебажит данные при разработке виджетов

    В 90% случаев использую print_r().

    Так и сделано, как вы описали, но дамп при апдейте плагина показывает, что все тлен и ничего не пришло.

    При таких раскладах у $instance должен существовать ключ ‘page’, то есть сделав

    print_r($instance['page']);

    при сохранении я должен буду получить массив из айдишников?

    На wp.tutsplus.com есть очень хороший видео-курс по этому делу. Только он платный 🙁

    class HH_xxxxxx extends WP_Widget {
    
    		function __construct() {
    			$params = array(
    				'name' => 'HH xxxxxx',
    				'description' => 'Short description of this widget',
    			);
    
    			// Instantiate the parent object
    			parent::__construct( 'HH_xxxxxx' , '' , $params );
    		}
    
    		function widget( $args, $instance ) {
    
    			extract( $args );
    			extract( $instance );
    
    			echo PHP_EOL . $before_widget . PHP_EOL;
    			echo PHP_EOL . $before_title . $title . $after_title . PHP_EOL;
    
    //			echo do_shortcode( '[my_shortcode]' );
    
    			echo PHP_EOL . $after_widget . PHP_EOL;
    		}
    
    		function update( $new_instance, $old_instance ) {
    
    			$result = array();
    
    			$result['title'] = ( $new_instance['title'] ) ? $new_instance['title'] : 'Default title' ;
    
    			$result['is_exclude_hot_day_themes'] = ( isset( $new_instance['is_exclude_hot_day_themes'] ) && $new_instance['is_exclude_hot_day_themes'] === 'on' ) ? $new_instance['is_exclude_hot_day_themes'] : 'off' ;
    
    			if ( is_numeric( $new_instance['posts_number'] ) && $new_instance['posts_number'] > 0 && $new_instance['posts_number'] < 7 )  {
    				$result['posts_number'] = $new_instance['posts_number'];
    			} else {
    				$result['posts_number'] = 5;
    			}
    
    			return $result;
    		}
    
    		function form( $instance ) {
    			extract( $instance );
    			?>
    
    			<?php // Text field ?>
    			<p>
    				<label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title'); ?></label>
    				<input
    					class="widefat"
    					type="text"
    					name="<?php echo $this->get_field_name('title'); ?>"
    					id="<?php echo $this->get_field_id('title'); ?>"
    					value="<?php if ( isset( $title ) && $title ) { echo esc_attr( $title ); } ?>"
    					>
    			</p>
    
    			<?php // Checkbox ?>
    			<p>
    				<label for="<?php echo $this->get_field_id('is_exclude_hot_day_themes'); ?>">Показывать на главной странице?</label>
    				<input
    					type="checkbox"
    					name="<?php echo $this->get_field_name('is_exclude_hot_day_themes'); ?>"
    					id="<?php echo $this->get_field_id('is_exclude_hot_day_themes'); ?>"
    					value="on"
    					<?php if ( isset( $is_exclude_hot_day_themes ) && $is_exclude_hot_day_themes === 'on' ) { echo ' checked="checked" '; } ?>
    					>
    			</p>
    
    			<?php // Numeric ?>
    			<p>
    				<label for="<?php echo $this->get_field_id('posts_number'); ?>"><?php _e( 'Number of posts to show:' ) ?></label>
    				<input
    					class="widefat"
    					type="text"
    					name="<?php echo $this->get_field_name('posts_number'); ?>"
    					id="<?php echo $this->get_field_id('posts_number'); ?>"
    					value="<?php if ( isset( $posts_number ) && $posts_number ) { echo esc_attr( $posts_number ); } ?>"
    					>
    			</p>
    
    		<?php
    		}
    
    	}

    Поиграйтесь с этим сниппетом, я с него начинаю все свои виджеты. Сыровато конечно, но сойдёт.

    Ну и вот на гитхабе очень замороченный проект, но из него можно многое подсмотреть.
    https://github.com/tommcfarlin/WordPress-Widget-Boilerplate

    Ну и наш любимый Codex =)

    ну вот я вижу, например, что

    name="<?php echo $this->get_field_name('posts_number'); ?>"
    id="<?php echo $this->get_field_id('posts_number'); ?>"

    не произвольные, а определенным образом оформлены. Это принципиально? Если да, то нужно думать…

    как оказалось да, строгий порядок оформления в форме виджета атрибута «name» и «id» — обязателен! (Или, как вариант работать с массивом $_POST напрямую, что мне не очень нравится — не по Кодексу, да и небезопасно)

    Сделал так

    foreach ($posts as $post) {
                echo '<p><input type="checkbox" id="' .$this->get_field_id($post->ID) . '" name="'.$this->get_field_name($post->ID).'" value="1">
                        <a href="' . get_permalink($post->ID) . '">' . $post->post_title . '</a>
                      </p>';
            }

    и в дапме $instance виджета в функции сохранения получил ожидаемое — массив айдишников))

    Как говорил Дядь Федор — «Машина из сугроба выбралась, дальше я своим ходом».

    Всем спасибо 🙂

    Не за что 🙂

Просмотр 8 ответов — с 1 по 8 (всего 8)
  • Тема «Вопрос по разработке виджета» закрыта для новых ответов.