これで案件が捗る!オレオレWordPressプラグインの作り方がわかる実例

2016/07/02

Simon Codrington

0

Articles in this issue reproduced from SitePoint
Copyright © 2016, All rights reserved. SitePoint Pty Ltd. www.sitepoint.com. Translation copyright © 2016, KADOKAWA CorporationJapanese syndication rights arranged with SitePoint Pty Ltd, Collingwood, Victoria,Australia through Tuttle-Mori Agency, Inc., Tokyo

探せば大抵のものある、と言われるWordPressのプラグイン。でも、ちょっと自分がほしいものとは違うんだけど…なんてことも多いはず。自分専用のプラグインを作っておけば、いろんな案件で使いまわせて便利。長いので2回に分けてどうぞ。

この記事を最大限に活用するには、actionsfiltersshortcodeswidgetsobject orientated designなどの基本的な理解が必要です。

基本から復習したい人は、私が以前書いた記事『An Introduction to WordPress Plugin Development』を読んでください。この後の記事にある概念やアイデアの理解を深めるのに役立ちます。

1464795300wordpress-plugin

事業拠点リストのプラグインを作る

プラグインがどのような場面で使われ、Webサイトにどのような機能を追加できるのか。さっそく実例を紹介します。

コーポーレートサイトなどでは、企業はさまざまな事業拠点やオフィスを紹介したいと考えるでしょう。拠点情報の紹介はWordPressの固定ページで作成できますが、固有の情報として一元管理し、担当者が簡単に更新できるインターフェイスを提供する方がよいかもしれません。

ご存知のとおり、こうした機能は子テーマでも構築できますが、プラグインを使えば、ほかのWebサイトでもシンプルかつ簡単に実装できます。

2回に分けて紹介する実例は、拠点情報を処理して出力するプラグインについてです。拠点情報は、拠点の特定のデータを保存する補完的なメタ情報を伴うカスタムコンテンツタイプになります。プラグインを使って情報を出力するさまざまな方法(個別の拠点紹介ページ、拠点をリスト化するウィジェット、拠点をリスト化するショートコードなど)についても説明します。

初期設定をする

必要なものをすべてセットアップして、プラグインディレクトリで、以下のようにフォルダ/ファイルを作成します。

  • wp_simple_location_plugin
    • css
      • wp_location_public_styles.css
      • wp_location_admin_styles.css
    • inc
      • wp_location_widget.php
      • wp_location_shortcode.php
    • wp_simple_location_plugin.php

最上層のファイル「wp_simple_location_plugin.php」がメインファイルです。CSSディレクトリからスタイルをロードしたり、インクルードディレクトリから追加のPHPファイルをロードするときのロード先となるファイルです。

拠点のメインクラス

wp_simple_location_plugin.phpファイルに、プラグインの中心となる機能を記述します。またウィジェットとショートコードの機能に必要な追加ファイルも記述します。

ダイレクトアクセスを拒否する

ABSPATH変数が定義されている場合、ABSPATH変数を参照してPHPファイルにダイレクトアクセスしないように、ブロックすることをおすすめします(もし実行中で定義されていたら終了します)。PHPタグを開いた後に、以下のコードを直接加えてください。

defined( 'ABSPATH' ) or die( 'Nope, not accessing this' );

プラグイン宣言

プラグインを動かすには、定義したプラグイン宣言が必要になります。プラグイン宣言はWordPressが探して参照する1組のコメントで、プラグイン情報が含まれています。プ宣言がないプラグインはプラグインマネジャーに表示されないので、必ず必要です。

<?php
/*
Plugin Name: WordPress Simple Location Plugin
Plugin URI:  https://github.com/simonrcodrington/Introduction-to-WordPress-Plugins---Location-Plugin
Description: Creates an interfaces to manage store / business locations on your website. Useful for showing location based information quickly. Includes both a widget and shortcode for ease of use.
Version:     1.0.0
Author:      Simon Codrington
Author URI:  http://www.simoncodrington.com.au
License:     GPL2
License URI: https://www.gnu.org/licenses/gpl-2.0.html
*/

プラグイン名、説明、バージョン、その他の情報をここで定義します。定義した情報のほとんどは、ユーザーがプラグインを有効にしたときに、プラグイン管理ページに表示されます。

wp_simple_locationクラス

wp_simple_locationクラスのシェルを作成します。このクラスには、作成するプラグインの機能のほとんどが含まれていて、クラスを使ってプロパティとメソッドを保持します。

class wp_simple_location{

}

ショートコードファイルとウィジェットファイルを組み込む

ウィジェットとショートコードの両方を使う予定なので、ウィジェットとショートコードの機能が自身のファイルに分かれて入っています。

wp_simple_locationクラスの最後で、以下を追加します。

//include shortcodes
include(plugin_dir_path(__FILE__) . 'inc/wp_location_shortcode.php');
//include widgets
include(plugin_dir_path(__FILE__) . 'inc/wp_location_widget.php');

組み込んだら、あとで説明するウィジェットとショートコードのファイルを読み込みます。

クラスのプロパティ

クラスのプロパティはクラス内で関数がアクセスする変数です。

プロパティ宣言をすると、よく使われる要素にアクセスしやすくなります。

この関数内のプロパティは、拠点の営業時間に使用する「日(days)」の配列だけです。あとで値を入れるので、今は空の配列で定義しておきます。

//properties
private $wp_location_trading_hour_days = array();

__construct(コンストラクタ)関数

__construct関数は、プラグインの重要部分で、ほかの関数を実行する際にマスターとして使われます。

この関数はマジック関数です。マジック関数はPHP5から導入された、ある条件で自動的に起動する関数です。クラスがインスタンス化されたとき(クラスが作成されて変数が割り当てられたとき)に実行されます。

プラグインでは、この関数を使って、すべてのアクション、フィルター、関数の呼び出しを追加します。クラスの外にフックを追加できますが、そのまま残しておいても問題ありません。

以下のコードをコピーします。要素を1つずつ見ながら、何をしているのか理解していきます。

//magic function (triggered on initialization)
public function __construct(){

    add_action('init', array($this,'set_location_trading_hour_days')); //sets the default trading hour days (used by the content type)
    add_action('init', array($this,'register_location_content_type')); //register location content type
    add_action('add_meta_boxes', array($this,'add_location_meta_boxes')); //add meta boxes
    add_action('save_post_wp_locations', array($this,'save_location')); //save location
    add_action('admin_enqueue_scripts', array($this,'enqueue_admin_scripts_and_styles')); //admin scripts and styles
    add_action('wp_enqueue_scripts', array($this,'enqueue_public_scripts_and_styles')); //public scripts and styles
    add_filter('the_content', array($this,'prepend_location_meta_to_content')); //gets our meta data and dispayed it before the content

    register_activation_hook(__FILE__, array($this,'plugin_activate')); //activate hook
    register_deactivation_hook(__FILE__, array($this,'plugin_deactivate')); //deactivate hook

}

register_activation_hookregister_deactivation_hookは、プラグインが有効、または無効のときに、フックする関数です。こうしたフックを使って、コンテンツタイプ(拠点)が正しく追加されるようにし、パーマリンクをフラッシュします(多くののパーマリンクを使用できます)。

拠点の営業時間・営業日を設定する

このプラグインを使うと、管理者は拠点ごとに異なる始業、終業時間を定義できます。

詳細の入力先であるバックエンドでは「日(days)」の配列を含むプロパティ$wp_location_trading_hour_daysを参照します。set_location_trading_hour_days関数を呼び出して、拠点の営業時間を表示したい日を設定します。

//set the default trading hour days (used in our admin backend)
public function set_location_trading_hour_days(){

    //set the default days to use for the trading hours
    $this->wp_location_trading_hour_days = apply_filters('wp_location_trading_hours_days', 
        array('monday' => 'Monday',
              'tuesday' => 'Tuesday',
              'wednesday' => 'Wednesday',
              'thursday' => 'Thursday',
              'friday' => 'Friday',
              'saturday' => 'Saturday',
              'sunday' => 'Sunday',
        )
    );      
}

配列の値を割り当てる際、wp_location_trading_hours_daysフィルターも呼び出します。呼び出すことでテーマやもう1つのプラグインが、拠点の営業日を再定義できます(配列をフィルターして、たとえば配列に「休日」を追加したいときにはその日の営業時間を入力できます)。

拠点の営業時間・営業日を設定する

プラグインで使用する、拠点の新しいコンテンツタイプを定義します。

コンテンツタイプのラベルと引数を定義し、引数をregister_post_type関数に渡します。

カスタムコンテンツタイプについてWordPressのCodexページに、指定できるすべてのオプションの説明があります。コンテンツタイプにはタイトル、エディタとアイキャッチ画像のための基本的なサポートが必要です。

//register the location content type
public function register_location_content_type(){
     //Labels for post type
     $labels = array(
           'name'               => 'Location',
           'singular_name'      => 'Location',
           'menu_name'          => 'Locations',
           'name_admin_bar'     => 'Location',
           'add_new'            => 'Add New', 
           'add_new_item'       => 'Add New Location',
           'new_item'           => 'New Location', 
           'edit_item'          => 'Edit Location',
           'view_item'          => 'View Location',
           'all_items'          => 'All Locations',
           'search_items'       => 'Search Locations',
           'parent_item_colon'  => 'Parent Location:', 
           'not_found'          => 'No Locations found.', 
           'not_found_in_trash' => 'No Locations found in Trash.',
       );
       //arguments for post type
       $args = array(
           'labels'            => $labels,
           'public'            => true,
           'publicly_queryable'=> true,
           'show_ui'           => true,
           'show_in_nav'       => true,
           'query_var'         => true,
           'hierarchical'      => false,
           'supports'          => array('title','thumbnail','editor'),
           'has_archive'       => true,
           'menu_position'     => 20,
           'show_in_admin_bar' => true,
           'menu_icon'         => 'dashicons-location-alt',
           'rewrite'            => array('slug' => 'locations', 'with_front' => 'true')
       );
       //register post type
       register_post_type('wp_locations', $args);
}

サポートされている場合は、投稿タイプの新しいメニューが表示されるはずです。

拠点のコンテンツタイプにメタボックスを追加する

拠点ページに表示されるカスタムのメタボックスを定義します。このボックスはメタデータとして保存したいフィールド(電話番号、Eメールアドレスなど)をすべて追加できます。

関数の内部でadd_meta_box()関数を呼び出し、引数を渡します。

//adding meta boxes for the location content type*/
public function add_location_meta_boxes(){

    add_meta_box(
        'wp_location_meta_box', //id
        'Location Information', //name
        array($this,'location_meta_box_display'), //display function
        'wp_locations', //post type
        'normal', //location
        'default' //priority
    );
}

add_meta_boxの3番目の値は、ボックスの出力を表示する関数です。クラスに追加する次で説明する関数location_meta_box_displayを呼び出しています。

location_meta_box_display関数

location_meta_box_display関数は拠点のメタボックスから呼び出される関数で、管理者が拠点情報を保存するために使える追加フィールドを表示します。

//display function used for our custom location meta box*/
public function location_meta_box_display($post){

    //set nonce field
    wp_nonce_field('wp_location_nonce', 'wp_location_nonce_field');

    //collect variables
    $wp_location_phone = get_post_meta($post->ID,'wp_location_phone',true);
    $wp_location_email = get_post_meta($post->ID,'wp_location_email',true);
    $wp_location_address = get_post_meta($post->ID,'wp_location_address',true);

    ?>
    <p>Enter additional information about your location </p>
    <div class="field-container">
        <?php 
        //before main form elementst hook
        do_action('wp_location_admin_form_start'); 
        ?>
        <div class="field">
            <label for="wp_location_phone">Contact Phone</label>
            <small>main contact number</small>
            <input type="tel" name="wp_location_phone" id="wp_location_phone" value="<?php echo $wp_location_phone;?>"/>
        </div>
        <div class="field">
            <label for="wp_location_email">Contact Email</label>
            <small>Email contact</small>
            <input type="email" name="wp_location_email" id="wp_location_email" value="<?php echo $wp_location_email;?>"/>
        </div>
        <div class="field">
            <label for="wp_location_address">Address</label>
            <small>Physical address of your location</small>
            <textarea name="wp_location_address" id="wp_location_address"><?php echo $wp_location_address;?></textarea>
        </div>
        <?php
        //trading hours
        if(!empty($this->wp_location_trading_hour_days)){
            echo '<div class="field">';
                echo '<label>Trading Hours </label>';
                echo '<small> Trading hours for the location (e.g 9am - 5pm) </small>';
                //go through all of our registered trading hour days
                foreach($this->wp_location_trading_hour_days as $day_key => $day_value){
                    //collect trading hour meta data
                    $wp_location_trading_hour_value =  get_post_meta($post->ID,'wp_location_trading_hours_' . $day_key, true);
                    //dsiplay label and input
                    echo '<label for="wp_location_trading_hours_' . $day_key . '">' . $day_key . '</label>';
                    echo '<input type="text" name="wp_location_trading_hours_' . $day_key . '" id="wp_location_trading_hours_' . $day_key . '" value="' . $wp_location_trading_hour_value . '"/>';
                }
            echo '</div>';
        }       
        ?>
    <?php 
    //after main form elementst hook
    do_action('wp_location_admin_form_end'); 
    ?>
    </div>
    <?php

}

location_meta_box_display関数について説明します。

  • 最初に、メタボックスに保護されたnonceフィールドを作成します(nonceを使って実行するアクションが正しい配置から来たことを認証します
  • 電話番号、Eメール、住所のメタ情報(もしある場合)を収集します
  • フォームの直前にアクションフックwp_location_admin_form_startを追加します。ほかのプラグインやテーマを拠点にフックして、追加フィールドや情報を表示します
  • 電話番号、Eメール、住所のフィールドを表示します(前の値がある場合には自動入力します)
  • 拠点の営業日のリストを表示します。管理者は日ごとに営業時間を定義できます。日ごとの情報はwp_location_trading_hours_daysフィルターにアタッチされるので、動的に変更できます
  • フォームが終わる直前にアクションフックwp_location_admin_form_endを追加します。ほかのプラグインやテーマを拠点にフックして、追加フィールドや情報を表示します

拠点に表示されたメタボックスを確認します。次のように表示されます。

コンテンツタイプの登録とリライトルールを有効にしてフラッシュする

プラグインをはじめに起動する際、1回だけアクションを実行する関数を呼び出せます。plugin_activateです。

もしInitフックを経由してコンテンツタイプを登録しても、register_location_content_typeを(コンテンツタイプが正しく追加されていることを保証するために)内部から呼び出す必要があります。

拠点にかなりの数のパーマリンクを使えるのでリライトルールもフラッシュします(example.com/?p=144ではなくexample.com/location/mylocationのようなリンクにできます)。

//triggered on activation of the plugin (called only once)
public function plugin_activate(){  
    //call our custom content type function
    $this->register_location_content_type();
    //flush permalinks
    flush_rewrite_rules();
}

リライトルールを無効にしてフラッシュする

プラグインを無効に設定すると、プラグインが無効になります。プラグインが無効の状態で、プラグインがカスタムコンテンツタイプを定義したので、この機会に、整合性を保つためにリライトルールをフラッシュします。

//trigered on deactivation of the plugin (called only once)
public function plugin_deactivate(){
    //flush permalinks
    flush_rewrite_rules();
}

拠点ごとにメタ情報を表示する

各拠点の補完的なメタ情報を定義しているので、各拠点ページを閲覧するときに、追加情報を表示する関数を作成します。

prepend_location_meta_to_content関数はthe_contentフィルターでフックされます。この動きによって、ページのメインコンテンツの前に追加情報を加えます。

public function prepend_location_meta_to_content($content){

    global $post, $post_type;

    //display meta only on our locations (and if its a single location)
    if($post_type == 'wp_locations' && is_singular('wp_locations')){

        //collect variables
        $wp_location_id = $post->ID;
        $wp_location_phone = get_post_meta($post->ID,'wp_location_phone',true);
        $wp_location_email = get_post_meta($post->ID,'wp_location_email',true);
        $wp_location_address = get_post_meta($post->ID,'wp_location_address',true);

        //display
        $html = '';

        $html .= '<section class="meta-data">';

        //hook for outputting additional meta data (at the start of the form)
        do_action('wp_location_meta_data_output_start',$wp_location_id);

        $html .= '<p>';
        //phone
        if(!empty($wp_location_phone)){
            $html .= '<b>Location Phone</b> ' . $wp_location_phone . '</br>';
        }
        //email
        if(!empty($wp_location_email)){
            $html .= '<b>Location Email</b> ' . $wp_location_email . '</br>';
        }
        //address
        if(!empty($wp_location_address)){
            $html .= '<b>Location Address</b> ' . $wp_location_address . '</br>';
        }
        $html .= '</p>';

        //location
        if(!empty($this->wp_location_trading_hour_days)){
            $html .= '<p>';
            $html .= '<b>Location Trading Hours </b></br>';
            foreach($this->wp_location_trading_hour_days as $day_key => $day_value){
                $trading_hours = get_post_meta($post->ID, 'wp_location_trading_hours_' . $day_key , true);
                $html .= '<span class="day">' . $day_key . '</span><span class="hours">' . $trading_hours . '</span></br>';
            }
            $html .= '</p>';
        }

        //hook for outputting additional meta data (at the end of the form)
        do_action('wp_location_meta_data_output_end',$wp_location_id);

        $html .= '</section>';
        $html .= $content;

        return $html;  


    }else{
        return $content;
    }

}

prepend_location_meta_to_content関数がどのように動くのかを説明します。

  • the_contentフックに追加されるので、ページがロードされるたびに動きます。グローバル変数の$post$post_typeを使って、1つの拠点ページにだけを表示します
  • Eメール、電話番号、住所など基本的な拠点情報を収集します
  • ちょうどメタ情報を表示するところで、アクションフックwp_location_meta_data_output_startを呼び出します。このアクションはほかのプラグインやテーマに、メタ情報の出力開始をフックします(もし拠点に新しいフィールドが追加されると、このフックを使って保存された情報を表示します)
  • Eメール、電話番号、住所情報を出力します
  • wp_location_trading_hour_days変数を渡して、定義された「日(days)」があるかを確認します。確認できたらすべてをループし、営業時間を収集して表示します
  • すべての出力が終わる直前に、wp_location_meta_data_output_endアクションを呼び出します。このアクションで、拠点のメタ情報終了前に追加情報を出力します

get_locations_output関数

拠点をリスト化するためにHTMLを構築する関数を作成します。

get_locations_output関数は拠点のショートコードと、マークアップされている拠点のウィジェットの両方で使われます。

複数の目的で使用されるので、この関数にはいくつか重要なアクションをともないます。順番に見ていきます。

//main function for displaying locations (used for our shortcodes and widgets)
public function get_locations_output($arguments = ""){

    //default args
    $default_args = array(
        'location_id'   => '',
        'number_of_locations'   => -1
    );

    //update default args if we passed in new args
    if(!empty($arguments) && is_array($arguments)){
        //go through each supplied argument
        foreach($arguments as $arg_key => $arg_val){
            //if this argument exists in our default argument, update its value
            if(array_key_exists($arg_key, $default_args)){
                $default_args[$arg_key] = $arg_val;
            }
        }
    }

    //find locations
    $location_args = array(
        'post_type'     => 'wp_locations',
        'posts_per_page'=> $default_args['number_of_locations'],
        'post_status'   => 'publish'
    );
    //if we passed in a single location to display
    if(!empty($default_args['location_id'])){
        $location_args['include'] = $default_args['location_id'];
    }

    //output
    $html = '';
    $locations = get_posts($location_args);
    //if we have locations 
    if($locations){
        $html .= '<article class="location_list cf">';
        //foreach location
        foreach($locations as $location){
            $html .= '<section class="location">';
                //collect location data
                $wp_location_id = $location->ID;
                $wp_location_title = get_the_title($wp_location_id);
                $wp_location_thumbnail = get_the_post_thumbnail($wp_location_id,'thumbnail');
                $wp_location_content = apply_filters('the_content', $location->post_content);
                if(!empty($wp_location_content)){
                    $wp_location_content = strip_shortcodes(wp_trim_words($wp_location_content, 40, '...'));
                }
                $wp_location_permalink = get_permalink($wp_location_id);
                $wp_location_phone = get_post_meta($wp_location_id,'wp_location_phone',true);
                $wp_location_email = get_post_meta($wp_location_id,'wp_location_email',true);

                //apply the filter before our main content starts 
                //(lets third parties hook into the HTML output to output data)
                $html = apply_filters('wp_location_before_main_content', $html);

                //title
                $html .= '<h2 class="title">';
                    $html .= '<a href="' . $wp_location_permalink . '" title="view location">';
                        $html .= $wp_location_title;
                    $html .= '</a>';
                $html .= '</h2>';


                //image & content
                if(!empty($wp_location_thumbnail) || !empty($wp_location_content)){

                    $html .= '<p class="image_content">';
                    if(!empty($wp_location_thumbnail)){
                        $html .= $wp_location_thumbnail;
                    }
                    if(!empty($wp_location_content)){
                        $html .=  $wp_location_content;
                    }

                    $html .= '</p>';
                }

                //phone & email output
                if(!empty($wp_location_phone) || !empty($wp_location_email)){
                    $html .= '<p class="phone_email">';
                    if(!empty($wp_location_phone)){
                        $html .= '<b>Phone: </b>' . $wp_location_phone . '</br>';
                    }
                    if(!empty($wp_location_email)){
                        $html .= '<b>Email: </b>' . $wp_location_email;
                    }
                    $html .= '</p>';
                }

                //apply the filter after the main content, before it ends 
                //(lets third parties hook into the HTML output to output data)
                $html = apply_filters('wp_location_after_main_content', $html);

                //readmore
                $html .= '<a class="link" href="' . $wp_location_permalink . '" title="view location">View Location</a>';
            $html .= '</section>';
        }
        $html .= '</article>';
        $html .= '<div class="cf"></div>';
    }

    return $html;
}

get_locations_output関数がどのように動くのかを説明します。

  • argumentsという省略可能な引数を持っています。ショートコードとウィジェットの両方が(返されたものを確実にカスタマイズするために)ディスプレイにオプションを渡すときに使われます
  • 1組のデフォルト引数を$default_args配列に定義します。基本的には拠点の数を-1(すべての拠点)に設定し、拠点IDには記入せずに設定します(デフォルトで1か所だけでなく、拠点のリストを表示したいためです)
  • 渡された$arguments変数が空になっていないか、また配列であるかを確認します(変数の配列を渡しています)。配列キーのうちのいくつかが$default_argsで何かとマッチしているかを確認するために、$arguments配列とチェック中の要素のすべてを確かめます。もしマッチしているものがあれば、$default_args配列を更新します
  • default_args配列を使って拠点すべてを見つけ出すget_posts()で検索します(1つの拠点を指定した場合はそれを検索します)
  • $html変数を定義してHTML出力を始めます
  • 拠点のすべての情報(店名、コンテンツ、画像、リンクなど)を収集し、出力に備えます
  • 出力の収集を続ける前に、$html変数を入れたwp_location_before_main_contentでフィルターします。これによってサードパーティーに拠点名の前に特別なコンテンツを追加してもらいます。これはあたかも出力できるように、管理環境で特別なフィールドが定義されたみたいで、とても便利です
  • 店名、画像、コンテンツ、電話番号、Eメールを出力に追加します(もしある場合は条件付きで確認)
  • 「read more」ボタンを出力する前に、2番目のフィルターであるwp_location_after_main_contentを呼び出します。このフィルターはサードパーティーにボタンの直前でコンテンツを追加します。
  • 「read more」ボタンを出力に追加してから、$html変数を返します。

拠点の追加メタ情報を保存する

1つの拠点を保存するときは、追加のメタ情報(Eメール、電話番号、住所など)の収集と更新をする関数を実行すると良いです。

save_location関数を使います。

//triggered when adding or editing a location
public function save_location($post_id){

    //check for nonce
    if(!isset($_POST['wp_location_nonce_field'])){
        return $post_id;
    }   
    //verify nonce
    if(!wp_verify_nonce($_POST['wp_location_nonce_field'], 'wp_location_nonce')){
        return $post_id;
    }
    //check for autosave
    if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE){
        return $post_id;
    }

    //get our phone, email and address fields
    $wp_location_phone = isset($_POST['wp_location_phone']) ? sanitize_text_field($_POST['wp_location_phone']) : '';
    $wp_location_email = isset($_POST['wp_location_email']) ? sanitize_text_field($_POST['wp_location_email']) : '';
    $wp_location_address = isset($_POST['wp_location_address']) ? sanitize_text_field($_POST['wp_location_address']) : '';

    //update phone, memil and address fields
    update_post_meta($post_id, 'wp_location_phone', $wp_location_phone);
    update_post_meta($post_id, 'wp_location_email', $wp_location_email);
    update_post_meta($post_id, 'wp_location_address', $wp_location_address);

    //search for our trading hour data and update
    foreach($_POST as $key => $value){
        //if we found our trading hour data, update it
        if(preg_match('/^wp_location_trading_hours_/', $key)){
            update_post_meta($post_id, $key, $value);
        }
    }

    //location save hook 
    //used so you can hook here and save additional post fields added via 'wp_location_meta_data_output_end' or 'wp_location_meta_data_output_end'
    do_action('wp_location_admin_save',$post_id, $_POST);

}

save_location関数が何をしているのかを分析します。

  • 最初に、nonceを確認し、(メタボックスから渡されて)nonceがあることを確かめます。自動保存していないことも確認します。すべて確認できたら先に進みます
  • 電話番号、Eメール、住所の情報を収集し、sanitize_text_field()関数でサニタイズします。変数が割り当てられたあとにupdate_post_meta()関数で使用され、拠点に情報が保存されます
  • 営業時間は動的なので、少し変更して収集、保存する必要があります。どのぐらいの数になるか分からないので、名前で$_POST配列から営業時間を抽出できません。すべての$_POST変数を見て、wp_location_trading_hours_で始まるものがないか確認します。もし見つけたら、値を更新し、メタ情報として保存します
  • 最後に、終わる直前にwp_location_admin_saveアクションを呼び出します。このアクションは拠点の現在のIDを$post_idとし、サードパーティーの関数に、グローバルの$_POSTから追加情報を収集して、拠点に保存します

管理者、公開スクリプト、スタイルを読み込む

Webサイトのフロントエンドとバックエンドの両方で、補完的なCSSファイルを読み込む必要があります。必要なスクリプトやスタイルを読み込む2つの関数を作成します。

これらのCSSファイルの内部には、メタボックス内の管理者フィールドの基本的なスタイルと、フロントエンドのスタイルが少し入っています。

プラグインはCSSがなくても問題なく動くので、もし興味がなければ、安全に削除すれば問題ありません(もし追加したくない場合は、コンストラクタ関数から該当のアクションコールを削除することも覚えておいてください)。

//enqueus scripts and stles on the back end
public function enqueue_admin_scripts_and_styles(){
    wp_enqueue_style('wp_location_admin_styles', plugin_dir_url(__FILE__) . '/css/wp_location_admin_styles.css');
}

//enqueues scripts and styled on the front end
public function enqueue_public_scripts_and_styles(){
    wp_enqueue_style('wp_location_public_styles', plugin_dir_url(__FILE__). '/css/wp_location_public_styles.css');

}

次回に続きます。

(原文:A Real World Example of WordPress Plugin Development

[翻訳:和田麻紀子
[編集:Livit

Copyright © 2016, Simon Codrington All Rights Reserved.

Simon Codrington

Simon Codrington

デザイナー、開発者で、Webが大好き。Webやデザインに関することは何でも興味があります。驚くべきWebサイトをクライアントに作ることに情熱を注いでいます。WorPressにフォーカスして、テーマ、プラグイン、Web Bird Digitalのチームと解決策を探っていきます。

Loading...