WPmagus - magicy od WordPressa

Filtry, wtyczki, obiekty i inne czary

Krzysiek Dróżdż
krzysiek@wpmagus.pl
WPmagus.pl

Kto używa Timbera?

Dlaczego?

  • bo przyśpiesza development,
  • bo jest wygodny,
  • bo fronci nie muszą się uczyć PHP,
  • bo…

Kod motywu to spaghetti *

* jeśli developer jest leniwy lub zapomina, że WordPress nie zwalnia ze znajomości PHP

Prosty formularz wysyłany AJAXem

… czyli co można zrobić źle i jak zrobić to lepiej

Co tu jest nie tak?

<?php
    if ( $_POST... ) {
        ... (przetwarzanie formularza)
    }

    get_header();
?>
...
<form ...>
    ... (treść formularza)
</form>
<script type="text/javascript">
    $('form').submit(function (e) {
        $.post( '<?php echo get_permalink(); ?>', {...}, function () { ... } );
    });
</script>
...

page-form.php

No to zacznijmy sprzątać

Lepsza obsługa AJAXa

function my_action() {
    ... (przetwarzanie formularza)
}
add_action( 'wp_ajax_my_action', 'my_action' );
add_action( 'wp_ajax_nopriv_my_action', 'my_action' );

functions.php

Dołączmy plik JS

function my_enqueue() {
    wp_enqueue_script( 'ajax-script', ... );
    wp_localize_script( 'ajax-script', 'ajax_object',
        array( 'ajax_url' => admin_url( 'admin-ajax.php' ), ... ) );
}
add_action( 'admin_enqueue_scripts', 'my_enqueue' );

functions.php

jQuery(function ($) {
    $('form.my-form').submit(function (e) {
        $.post( ajax_object.ajax_url, {...}, function () { ... } );
    });    
});

my-script.js

A z formularza zróbmy shortcode

function my_form_shortcode_func( $atts ) {
    ob_start();
    ?>
    <form ...>
        ... (treść formularza)
    </form>
    <?php
    return ob_get_clean();
}
add_shortcode( 'my_form', 'my_form_shortcode_func' );

functions.php

Czy to nie powinna być wtyczka?

Przesłanki

  • implementuje funkcjonalność
  • jest niezależna od wyglądu strony
  • po zmianie motywu nadal będzie działać poprawnie
  • po zmianie motywu nadal będzie wykorzystywana

To całkiem proste

/*
Plugin Name: Moja wtyczka
Description: Opis mojej wtyczki
Version: 1.0.0
Author: Jakiś Ja
Author URI: http://moja-strona.pl
*/

function my_enqueue() {
    wp_enqueue_script( 'ajax-script', ... );
    wp_localize_script( 'ajax-script', 'ajax_object',
        array( 'ajax_url' => admin_url( 'admin-ajax.php' ), ... ) );
}
add_action( 'admin_enqueue_scripts', 'my_enqueue' );

function my_form_shortcode_func( $atts ) {
    ob_start();
    ?>
    <form ...>
        ... (treść formularza)
    </form>
    <?php
    return ob_get_clean();
}
add_shortcode( 'my_form', 'my_form_shortcode_func' );

function my_action() {
    ... (przetwarzanie formularza)
}
add_action( 'wp_ajax_my_action', 'my_action' );
add_action( 'wp_ajax_nopriv_my_action', 'my_action' );

my-plugin.php

Ale wtyczka to też utrudnienia

A jeśli ktoś aktywuje dwie kopie wtyczki?

Uwaga: Nie wolno wielokrotnie deklarować tej samej funkcji!

if ( ! function_exists( 'my_function' ) ) : 
    function my_function() { ... }
endif;

I to by było nawet OK

… jeśli zatrzymaliśmy się na programowaniu proceduralnym

Tyle, że w ten sposób dalej otrzymujemy śmietnik w postaci worka z funkcjami, zmiennymi globalnymi i prefiksowaniem funkcji.

Obiekty

Trochę klas(y)

class My_Plugin_Class {
    function __construct() {
        add_action( 'admin_enqueue_scripts', array($this, 'enqueue') );

        add_shortcode( 'my_form', array($this, 'form_shortcode_func') );

        add_action( 'wp_ajax_my_action', array($this, 'action') );
        add_action( 'wp_ajax_nopriv_my_action', array($this, 'action') );
    }

    function enqueue() { ... }
    function form_shortcode_func( $atts ) { ... }
    function action() { ... }
}

$my_plugin = new My_Plugin_Class();

my-plugin.php

Problematyczne kopie

Uwaga: Nie wolno wielokrotnie deklarować tej samej klasy!

if ( ! class_exists( 'My_Plugin_Class' ) ) : 
    class My_Plugin_Class { ... }
endif;

Uwaga: Ale ktoś może przypadkiem (lub nie) stworzyć wiele obiektów naszej klasy…

Singleton

class My_Plugin_Class {
    protected static $instance = null;

    public static function get_instance() {
        if ( ! isset(self::$instance) ) {
            self::$instance = new My_Plugin_Class();
        }
        return self::$instance;
    }

    protected function __construct() { ... }
    private function __clone() {}
    ...
}

My_Plugin_Class::get_instance();

A template tagi?

if ( ! function_exists( 'my_template_tag' ) ) : 
    function my_template_tag( $arg1, $arg2 ) {
        return apply_filter( 'my_template_tag', 'domyslna wartość', $arg1, $arg2 );
    }
endif;

A w klasie naszej wtyczki podpinamy się pod ten filtr.

Dzięki za uwagę!

Krzysiek Dróżdż
krzysiek@wpmagus.pl
WPmagus.pl