Как правильно создать виджет с помощью ООП


Я работаю над простым виджетом формы поиска со встроенной функцией автозаполнения (вы можете скачать текущую версию здесь ). Плагин работает, но в настоящее время я переписываю весь код с помощью ООП. Одна из проблем, с которой я столкнулся, заключалась в том, что виджет Wordpress уже является частью класса WP_Widget. Я могу разделить код на 2 класса. Первый загружает все скрипты и css и инициализирует виджет. Вот наброски код:

class wdSearchForm {

        public function __construct() {
            // Action hook to load widget
            // Register and enqueue styles
            // Register and enqueue scripts
        }

        // register widget in WordPress so that it is available under the widgets section
        public function wd_searchform() {
            register_widget( 'wd_searchform' );
        }
}

А вот схема класса виджетов:

class wd_searchform extends WP_Widget {

    // Constructor
    function wd_searchform() {

    }

    // The widget itself
    function widget( $args, $instance ) {
        // The widget code
    }

    //Update the widget 
    function update( $new_instance, $old_instance ) {
        // Update code
    }

    function form( $instance ) {
        //Set up widget settings.
    }
}

Я хотел бы объединить их, чтобы использовать wp_localize_script и загрузить скрипт с параметрами виджета. Как мне это сделать? Любые предложения приветствуются, даже если вы скажете мне, что я совершенно не в том направлении...

Author: Yoav Kadosh, 2013-01-13

2 answers

Вы можете просто поместить свой код инициализации в конструктор класса. Например:

class myWidget extends WP_Widget{

    function myWidget(){
       // Init code here
    }

    function widget( $args, $instance ) {
       // The widget code
       wp_enqueue_script(...);
       wp_enqueue_style(...);

   }

   // Over methods...

}

register_widget('myWidget');

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

 9
Author: Steve, 2013-01-13 19:10:43

Ваш код выполнен в стиле PHP4. Код в стиле PHP4 больше не следует использовать. И просто поместить некоторые функции в конструкцию класса - это не ООП. Если вы хотите написать повторно используемый код, разделите свой код.

Например:

class Widget_Setup
{
    public $widget_class  = '';
    public $admin_styles  = array();
    public $admin_scripts = array();
    public $front_styles  = array();
    public $front_scripts = array();

    public $script_defaults = array(
        'handle'    => '',
        'src'       => '',
        'deps'      => array(),
        'version'   => false,
        'in_footer' => false
    );

    public $style_defaults = array(
        'handle'   => '',
        'src'      => '',
        'deps'     => array(),
        'version'  => false,
        'media'    => 'all'
    );

    public function __construct( $widget_class = '', $admin_styles = array(), $admin_scripts = array(), $front_styles = array(), $front_scripts = array() ) {

        $this->widget_class  = $widget_class;
        $this->admin_styles  = $admin_styles;
        $this->admin_scripts = $admin_scripts;
        $this->front_styles  = $front_styles;
        $this->front_scripts = $front_scripts;

        add_action( 'admin_print_styles',    array( $this, 'add_styles' ) );
        add_action( 'admin_enqueue_scripts', array( $this, 'add_scripts' ) );
        add_action( 'wp_enqueue_scripts',    array( $this, 'add_styles' ) );
        add_action( 'wp_enqueue_scripts',    array( $this, 'add_scripts' ) );

        if( ! empty( $this->widget_class ) )
            add_action( 'widgets_init', array( $this, 'register_widget' ) );

    }

    public function register_widget() {

        register_widget( $this->widget_class );

        return true;

    }

    public function add_styles() {

        $styles = ( is_admin() ) ?
            $this->admin_styles : $this->front_styles;

        if( empty( $styles ) )
            return false;

        foreach( $styles as $style ) {

            $style = wp_parse_args( $style, $this->style_defaults );

            wp_enqueue_style(
                $style['handle'],
                $style['src'],
                $style['deps'],
                $style['version'],
                $style['media']
            );

        }

        return true;
    }

    public function add_scripts() {

        $scripts = ( is_admin() ) ?
            $this->admin_scripts : $this->front_scripts;

        if( empty( $scripts ) )
            return false;

        foreach( $scripts as $script ) {

            $script = wp_parse_args( $script, $this->script_defaults );

            wp_enqueue_script(
                $script['handle'],
                $script['src'],
                $script['deps'],
                $script['version'],
                $script['media']
            );

        }

        return true;
    }

}

Этот класс можно повторно использовать для каждого виджета. Идея, лежащая в основе ООП, заключается в повторном использовании вашего кода путем написания конструкций данных с дополнительной функцией. Не использовать конструкции классов, потому что кто-то сказал, что это хороший стиль.

Класс может быть использован как это:

class MyAwesomeWidget extends WP_Widget
{

    const TEXTDOMAIN = 'widget_textdomain';

    public function __construct() {

        parent::__construct(

            'widget-name-id',
            __( 'Widget Name', self::TEXTDOMAIN ),
            array(
                'classname'   =>    __CLASS__,
                'description' =>    __( 'Short description.', self::TEXTDOMAIN )
            )
        );

        $admin_style = array(
            array( 'handle' => 'somehandle', 'src' => 'path/to/source' ),
            array( 'handle' => 'someotherhandle', 'src' => 'path/to/source' ),
        );

        $admin_scripts = array(
            array( 'handle' => 'scrpthandle', 'src' => 'path/to/source', 'deps' => array( 'jquery') ),
        );

        $front_styles = array(
            array( 'handle' => 'frontstyle', 'src' => 'path/to/src' ),
        );

        new Widget_Setup( __CLASS__, $admin_style, $admin_scripts, $front_styles );
    }

    public function widget( $instance, $args ) {}

    public function update( $new_instance, $old_instance ) {}

    public function form( $instance ) {}

}
 5
Author: Ralf912, 2013-01-13 21:16:28