Was ist der richtige Weg, um ein Widget mit OOP zu erstellen?

7

Ich arbeite an einem einfachen Suchformular-Widget mit integrierter Autovervollständigungsfunktion (Sie können die aktuelle Version hier herunterladen ). Das Plugin funktioniert, aber ich schreibe gerade den gesamten Code mit OOP neu. Eines der Probleme, auf die ich gestoßen bin, war die Tatsache, dass ein Wordpress-Widget bereits Teil der WP_Widget-Klasse ist. Ich kann den Code in 2 Klassen unterteilen. Der erste lädt alle Skripte und CSS und initialisiert das Widget. Hier ist der Umriss des Codes:

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' );
        }
}

Und hier ist der Überblick über die Widget-Klasse:

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.
    }
}

Ich möchte beide kombinieren, um wp_localize_scriptdas Skript mit den Widget-Optionen zu verwenden und zu laden. Wie soll ich das machen Vorschläge sind willkommen, auch wenn Sie mir sagen, dass ich völlig in die falsche Richtung gehe ...

Yoav Kadosh
quelle
3
Sie sollten hier das Widget Boilerplate verwenden .
Mr2P

Antworten:

9

Sie können Ihren Init-Code einfach in den Konstruktor der Klasse einfügen. Zum Beispiel:

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');

Ich bevorzuge es, die Enqueue-Aufrufe tatsächlich in die Shortcode-Bearbeitungsfunktion zu integrieren, um den Overhead und mögliche Konflikte beim Laden von JavaScript und Stylesheets zu vermeiden, die auf einer bestimmten Seite nicht verwendet werden.

Steve
quelle
Danke @Stephen. Können Sie näher erläutern, wie Enqueue-Aufrufe in die Shortcode-Bearbeitungsfunktion eingefügt werden?
Yoav Kadosh
3
Platzieren Sie Ihre wp_enqueue_-Aufrufe in der Methode, die die Shortcode- / Widget-Verarbeitung tatsächlich übernimmt. Auf diese Weise werden JS und Stile nur dann in die Warteschlange gestellt, wenn der Shortcode / das Widget tatsächlich auf einer bestimmten Seite verwendet wird. Siehe Änderungen oben.
Steve
5

Ihr Code ist im PHP4-Stil. PHP4-Code sollte nicht mehr verwendet werden. Und nur einige Funktionen in ein Klassenkonstrukt einzufügen, ist kein OOP. Wenn Sie wiederverwendbaren Code schreiben möchten, trennen Sie Ihren Code.

Zum Beispiel:

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;
    }

}

Diese Klasse kann für jedes Widget wiederverwendet werden. Die Idee hinter OOP ist die Wiederverwendung Ihres Codes durch Schreiben von Datenkonstrukten mit zusätzlicher Funktion. Keine Klassenkonstrukte verwenden, weil jemand sagt, dass es ein guter Stil ist.

Die Klasse könnte folgendermaßen verwendet werden:

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 ) {}

}
Ralf912
quelle