Как создать виджет, который позволяет добавлять только один экземпляр виджета через интерфейс WordPress?
Поведение виджета по умолчанию позволяет добавлять несколько экземпляров.
Я использую код примера из http://codex.wordpress.org/Widgets_API
Я видел аналогичный вопрос, когда ответ заключался в использовании старого кода виджетов, но я хотел бы продолжать использовать этот более современный код, если это возможно.
Я видел плагины, такие как Twitter для WordPress, которые дают точный контроль над количеством разрешенных экземпляров.
Благодаря,
матовый
В следующем примере вы можете найти static
переменную, которая не задана в первом экземпляре. Если виджет вызывается в первый раз, мы устанавливаем его в true. Во втором запуске мы прерываем и просто return
фактически ничего не обслуживая пользователя.
class My_Widget extends WP_Widget { // You static instance switch static $instance; function My_Widget() { // We set the static class var to true on the first run if ( ! $this->instance ) { $this->instance = true; } // abort silently for the second instance of the widget else { return; } // widget actual processes } function form($instance) { // outputs the options form on admin } function update($new_instance, $old_instance) { // processes widget options to be saved } function widget($args, $instance) { // outputs the content of the widget } } register_widget('My_Widget');
Код, взятый из соответствующей статьи Codex Code Widgets
Другим вариантом может быть проверка глобального массива, содержащего все зарегистрированные виджеты:
function wpse32103_show_widgets() { $dump = '<pre>'; $dump .= var_export( $GLOBALS['wp_registered_widgets'], false ); $dump .= '</pre>'; return print $dump; } add_action( 'shutdown', 'wpse32103_show_widgets' );
Результат ассоциативного массива содержит имя в качестве ключа, добавленное -2
(число увеличивается). Вы можете выполнить поиск по массиву на крючке init
или admin_init
и просто отменить, если вы нашли второй экземпляр. Может быть, что-то вроде следующего:
function wpse32103_show_widgets() { global $wp_registered_widgets; // Go and search for your widgets name with the above written function $target = 'FILL IN YOUR FOUND ARRAY KEY HERE. Without -2 (or any other appending number)'; // Container for your targeted widget(s) $unsets = array(); foreach ( array_keys( $wp_registered_widgets ) as $widget ) { // remove dashes $widget_check = str_replace( '-', '', $widget ); // remove numbers $widget_check = preg_replace( '/[^0-9]/', '', $widget ); // if we match, do it in our container if ( $widget_check === $target ) $unsets[] = $widget; } // less than one element in the container: abort if ( ! count ( $unsets ) > 1 ) return; // preserve first element array_shift( array_values( $unsets ) ); // unset all left instances from the global array foreach ( $unsets as $unset ) unset ( $wp_registered_widgets[ $unset ] ); return; } add_action( 'init', 'wpse32103_show_widgets' );
Edit: Doh, просто увидел, что вы не хотите использовать старый код. Хорошо, я оставлю это на всякий случай, если это поможет кому-то.
WP добавил несколько виджетов в 2.8 . Итак, я просмотрел учебник, в котором рассказывается, как сделать виджет в WP 2.7. Вот код:
add_action("widgets_init", array('Widget_name', 'register')); register_activation_hook( __FILE__, array('Widget_name', 'activate')); register_deactivation_hook( __FILE__, array('Widget_name', 'deactivate')); class Widget_name { function activate(){ $data = array( 'option1' => 'Default value' ,'option2' => 55); if ( ! get_option('widget_name')){ add_option('widget_name' , $data); } else { update_option('widget_name' , $data); } } function deactivate(){ delete_option('widget_name'); } function control(){ $data = get_option('widget_name'); ?> <p><label>Option 1<input name="widget_name_option1" type="text" value="<?php echo $data['option1']; ?>" /></label></p> <p><label>Option 2<input name="widget_name_option2" type="text" value="<?php echo $data['option2']; ?>" /></label></p> <?php if (isset($_POST['widget_name_option1'])){ $data['option1'] = attribute_escape($_POST['widget_name_option1']); $data['option2'] = attribute_escape($_POST['widget_name_option2']); update_option('widget_name', $data); } } function widget($args){ echo $args['before_widget']; echo $args['before_title'] . 'Your widget title' . $args['after_title']; echo 'I am your widget'; echo $args['after_widget']; } function register(){ wp_register_sidebar_widget( 'my_widget_id', 'Widget name', array('Widget_name', 'widget')); wp_register_widget_control( 'my_widget_id', 'Widget name', array('Widget_name', 'control')); } }
Я заменил вызовы register_sidebar_widget
и register_widget_control
на wp_register_sidebar_widget
и wp_register_widget_control
соответственно, чтобы исправить предупреждения об использовании устаревших функций. В противном случае это прямая копия / вставка из учебника, с которым я связан.
Вот доказательство концепции одноразового виджета, полученного из этого ответа :
https://github.com/glueckpress/single-use-widget
Ограничение: работает только в Настройщике, а не на странице администратора Widget.
Вы этого не сделаете. Слишком сложно это стоить. Это то, как работает редактор JS.
НО : Создайте виджет без настроек и разрешите его настройку на другой странице. Как это:
// In your Widget use this form() method public function form($instance){ $settings_url = admin_url('options-general.php?page=SettingsPage'); echo '<p>'; echo 'To setup this <strong>Widget</strong> go to:<br />'; echo '<a href="', $settings_url, '" target="_blank">'; echo '<strong>Settings » Settings Page</strong>'; echo '</a>'; echo '</p>'; return 'noform'; }
Используйте страницу add_options_page для создания страницы SettingsPage для управления Widget . И используйте get_option (), чтобы получить настройки для вывода Widget .
С уважением.
PS : Если вам нужен полный пример, дайте мне знать.