hiromasa.zone : o)

2005/11/13 Sunday 投稿時の月齢:11.9  月名:十二日月  潮汐:中潮 Moon:11.9[十二日月]今日の心技体 : 好調期低調前不安定期好調期

WordPress プラグイン作成時のノウハウ – 後編 – このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加

日記 - ひろまさ @ 23:00

WordPress プラグイン作成時のノウハウ – 後編 – です。

前回はこちら、

WordPress プラグイン作成のノウハウ – 中編 –

いろいろ書いてしまいましたが、実は「中編」の知識だけで WP プラグインは書くことは可能です。 あとは hook のドキュメントを見て、”おお、こんなところに割り込めるのか。これを使えば、、ふふふ。” と思う気持ちが芽生えればもうプラグインマスターです。

たとえば、the_content というフィルター hook はエントリの本文を全て渡してきてくれるので、渡された本文の文字列の単語や語尾を置換し、札幌弁や岡山弁や博多弁(地域の選択に深い意味はございません(?)…)に変換してしまうプラグインの機構なんてのは、すぐつくれることでしょう。 😛

機構ができれば、あとはこの “置換する” といった部分を hook に登録した関数に、”機械の言葉” = ソースコードで書けば OK です。なにやら難しそうな雰囲気ですが、そこはそこ我らが PHP。これ以上ないくらい便利な関数が沢山用意されていますので、たとえば Google で “PHP 置換” なんてやりたいことを検索すれば参考になるサンプルソースがたくさん出てくることでしょう。あとは、プラグインとして機能するようにそのソースをあてはめれば良く、もしかすると PHP 知らなくてもプラグインかけちゃうかもしれません。 🙂

とりあえず前回の、「投稿時間に “☆” を無意味に付けるプラグイン」を有効化して 登録する hook や関数の中を書き換えていけば自然と概略が分かってくると思いますので、興味のある方は是非どうぞ!

さてさて、このようにして作っていったプラグイン。実はソース(機能)が大きくなっていくとちょっとした壁にあたります。

  • 作成した関数”名”が WordPress 本体や他のプラグインとかぶるんじゃないかと不安になってくる
  • 関数間で使い回したい変数や定数があるときに、グローバル変数や define を使わなくてはならず、これまた名前の重複が不安になる
  • 上記理由でグローバル変数を使いたくないから関数内で定数を定義すると、hook で呼ばれるたびに初期化しなくてはいけなくて何か釈然としない

ふまえて前回作った「投稿時間に “☆” を無意味に付けるプラグイン」をみてみます。

  1.  <?php
  2.  /*
  3.  Plugin Name: Star Time
  4.  Plugin URI: http://zone.maple4ever.net/blog/
  5.  Description: 投稿時間に "☆" を無意味に付けるプラグイン
  6.  Author: hiromasa
  7.  Version: 1.0
  8.  Author URI: http://zone.maple4ever.net/blog/
  9.  */
  10.  
  11.  /****************************************************
  12.   * WP の the_time hook に startime 関数を追加します。
  13.   ***************************************************/
  14.  add_filter('the_time', 'startime');
  15.  
  16.  /****************************************************
  17.   * startime 関数を定義します。
  18.   ***************************************************/
  19.  function startime($time) {
  20.     
  21.      $hosi = "";
  22.      $newtime = $hosi . $time . $hosi;
  23.     
  24.      return $newtime;
  25.     
  26.  }
  27.  ?>

この場合、

  • 関数名 startime が他と重複してはいけない
  • $hosi 変数(定数)を hook が呼ばれるたびに再定義している

ということになります。(え、$hosi は強引じゃないかって・・・、その通りです。orz サンプルということでお許しを…)

これを解決するのに PHP で用意されているオブジェクト指向用の記述(class)を使ってみます。

ソースを見たほうが早いので、同プラグインを class 化したソースをまず書きます。

  1.  <?php
  2.  /*
  3.  Plugin Name: Star Time Class 版
  4.  Plugin URI: http://zone.maple4ever.net/blog/
  5.  Description: 投稿時間に "☆" を無意味に付けるプラグイン
  6.  Author: hiromasa
  7.  Version: 1.0
  8.  Author URI: http://zone.maple4ever.net/blog/
  9.  */
  10.  
  11.  /****************************************************
  12.   * WP の the_time hook に StarTime オブを追加します。
  13.   ***************************************************/
  14.  /* StarTime のオブジェクト作成 */
  15.  $startime = & new StarTime();
  16.  /* hook にオブジェクトと関数を登録 */
  17.  add_filter('the_time', array(&$startime, 'addStar'));
  18.  
  19.  /****************************************************
  20.   * StarTime クラスを定義します。
  21.   ***************************************************/
  22.  class StarTime {
  23.     
  24.      var $hosi;
  25.     
  26.      function StarTime() {
  27.         
  28.          $this->hosi = "";
  29.         
  30.      }
  31.     
  32.      function addStar($time) {
  33.       
  34.        $newtime = $this->hosi . $time . $this->hosi;
  35.       
  36.        return $newtime;
  37.       
  38.      }
  39.  }
  40.  ?>

☆を出力する関数の定義部分(addStar)が class StarTime の中に入ったのが分かります。また、class の StarTime() 関数が新設され $hosi の “初期化” を行っています。

ではソースを上から見ていきます。とりあえずコメントはいいとして、hook の登録の部分が変りました。

  1.  /* StarTime のオブジェクト作成 */
  2.  $startime = & new StarTime();
  3.  /* hook にオブジェクトと関数を登録 */
  4.  add_filter('the_time', array(&$startime, 'addStar'));

まず、class StarTime のオブジェクトの作成(15行目)をしているのが分かります。次に、add_filter でそのインスタンスと hook したときに呼ばれる関数名(addStar)を登録しています(17行目)。インスタンスの関数を hook に登録するときはこのように array 形式で記述を使います。(なお $startime 変数の前に “&” を付けているのは PHP 4系互換のためです。5系ではデフォルト参照で渡るので必要ありません。)

記述方法が変っただけでやっていることは同じですね!

次に class の定義部分をみていきます。

  1.  class StarTime {
  2.     
  3.      var $hosi;
  4.     
  5.      function StarTime() {
  6.         
  7.          $this->hosi = "";
  8.         
  9.      }

24行目でメンバ変数として(ここでは)定数となる変数 $hosi を定義しています。

そして、26行目からの StarTime() がこのオブジェクトのコンストラクタです。 class 名と同じ名称の関数がコンストラクタになります。コンストラクタが呼び出されるタイミングは、オブジェクトが作成された時・・・ 15行目で「$startime = & new StarTime();」された時になります。 つまり、プラグイン内で一度だけでいい “初期設定”を行うタイミングをつくることができました。 ここでは、$hosi を “☆” に設定することでプラグインの生存期間は自由にこの変数を使えるということになります。

このように class 化することでまずは、

関数間で使い回したい変数や定数があるときに、グローバル変数や define を使わなくてはならず、これまた名前の重複が不安になる

上記理由でグローバル変数を使いたくないから関数内で定数を定義すると、hook で呼ばれるたびに初期化しなくてはいけなくて何か釈然としない

という問題点が解決できるわけです。

コードを再び追っていきます。

  1.  function addStar($time) {
  2.       
  3.        $newtime = $this->hosi . $time . $this->hosi;
  4.       
  5.        return $newtime;
  6.       
  7.      }
  8.  }
  9.  ?>

addStar 関数が hook から呼ばれる関数です。この関数”名”は StarTime クラス内でしか通用しない名前になります。 class 内であればいくつでも関数をつくって大丈夫です。 class 内でのみ有効な名前です。

ということで、

作成した関数”名”が WordPress 本体や他のプラグインとかぶるんじゃないかと不安になってくる

この問題も class 化することで解決することが出来ます。

もちろん WP とインターフェースしている以上、この “名称かぶり” の問題は依然として残っていて、気をつけなければならないのは、

  1.  $startime = & new StarTime();

の、class 名(StarTime) とインスタンス変数($startime) 名がかぶってはいけない名前です。まぁこればかりは WP とプラグインが繋がっている以上しょうがない部分ですので気をつけて名称を決めましょう。 🙂

以上まとめますと、大きめのプラグインは class 化すると、

  • コンストラクタ部分にプラグインの初期化コードを設けることが出来る
  • class を名前空間として使い他のプログラムとの関数/変数名の重複を考えなくて済むようになる

ということが出来るようになり、大分プログラムが書きやすくなります。

お気づきの方も多いと思いますが、今回サンプルにした Class 版とClass 版じゃない StarTime、実は名称のかぶりを気をつけるという観点だと、Class 版 “じゃないほう”が気をつける個数的に勝っています・・・、これを改悪と呼ぶ。。 サンプルは関数一個の小さいものですので、こういった場合には無理に class 化する必要はないということですね。 また、変数の初期化も強引なものでした。

では最後に、本当は今回のサンプルにするはずだった「wp-hatena」のソースのメイン部分を class 化したプラグインの例として記載します。 プログラム中、未完成でコメントアウトしている部分があるのですが、とりあえずあるものとしてみてください。

  1.  /******************************************************************************
  2.   * WpHatena function define.
  3.   *****************************************************************************/
  4.  if(class_exists('WpHatena')) {
  5.     
  6.      $wph = & new WpHatena();
  7.      // add_filter('wp_head', array(&$wph, 'addScript'));
  8.     
  9.  }
  10.  
  11.  /******************************************************************************
  12.   * WpHatena
  13.   *
  14.   * @author      hiromasa
  15.   * @version    1.0
  16.   *
  17.   *****************************************************************************/
  18.  class WpHatena {
  19.     
  20.      var $plugin_path;
  21.      var $hatena_url;
  22.      var $hatena_gifname;
  23.      var $popup_jsname;
  24.     
  25.      /**
  26.      * The Constructor
  27.      *
  28.      * @param none
  29.      * @return Object reference
  30.      */
  31.      function WpHatena() {
  32.         
  33.          $this->plugin_path  = get_settings('siteurl');
  34.          $this->plugin_path .= '/wp-content/plugins/wp-hatena/';
  35.          $this->hatena_gifname = 'append.gif';
  36.          $this->popup_jsname = 'popup.js';
  37.          $this->haneta_url = 'http://b.hatena.ne.jp/append?';
  38.         
  39.      }
  40.     
  41.      /**
  42.      * WP interface.
  43.      *
  44.      * @param none
  45.      * @return none (はてなブックマーク用のタグを echo)
  46.      */
  47.      function addHatena() {
  48.         
  49.          $title  = '<a';
  50.          $title .= ' href="' . $this->haneta_url . get_permalink() . '"';
  51.          $title .= ' target="_blank"';
  52.          $title .= '">';
  53.          $title .= '<img ';
  54.          $title .= ' src="' . $this->plugin_path . $this->hatena_gifname . '"';
  55.          $title .= ' alt="このエントリをはてなブックマークに追加"';
  56.          $title .= ' title="このエントリをはてなブックマークに追加"';
  57.          $title .= ' width="16" height="12"';
  58.          $title .= ' style="border: 0;margin: 0;padding: 0;vertical-align: baseline;"';
  59.          //$title .= ' onmouseover="wpHatenaPopup()"';
  60.          $title .= '>';
  61.          $title .= '</a>';
  62.         
  63.          echo $title;
  64.         
  65.      }
  66.     
  67.      /**
  68.      * WP filter interface.(wp_head)
  69.      *
  70.      * @param none
  71.      * @return none (リンクタグ用のポップアップ JavaScript を echo)
  72.      */
  73.      function addScript($content) {
  74.         
  75.          echo '<script type="text/javascript"';
  76.          echo ' src="'. $this->plugin_path . $this->popup_jsname . '"';
  77.          echo '>';
  78.          echo '</script>';
  79.         
  80.      }
  81.     
  82.  }
  83.  ?>

次回はようやく wp-hatena を使ったソースの細かい説明と、「del.icio.us」対応、そして Masayan さんからいただいた不具合報告(!)の対応をしてみたいと思います。

・・・え、後編なのにまだ続くのって・・・。 はい。。 続編に続く・・・。

[続き..]

wp-hatena にみるプラグインの作成方 – 第1章 –

7 Comments

Trackback

  1. From: WordPress Plugins Database » Plugin Details » Private Status - 2007/12/14 Friday Nighttime (Pingback)

    […] : aニ停€蚤ニ団a窶堋、aニ停┐aニ陳シaニ塚・ツ?aaナ黴€窶「c¨ツソaツ?≪aヒ怐窶噤fe!¨cツ、oaツ?邃「a窶壺€ケaニ停€蚤ニ団a窶噤蟻窶堋、aニ驤€3a竄ャ窶啾窶噤疎ニ槌誕ニ停€蚤ニ驤€-aニ陳シaニ秩ツシ窶ケaナ刀ナ黴€1aナ停€殿ツ?邃「a窶壺€ケaツ?ツ黴€aツ?‘aツ?§aツスツソaツ?ヒ・ツ?ツセaツ?邃「a竄ャ窶喇iromasaaツ?窶「a窶噤gaツ?Ra竄ャナ誕ナ黴€窶「c¨ツソa邃「窶啼窶刀gaツ?≪a竄ャナ殿ヒ怐竄ャツ?a窶噤fc窶鮑€!a窶楪?a‘3aツ?≪a≫ヒ彗ツ…a竄ャツ?a窶噤fa窶?1e竄ャツ黴€aツ?窶蚤ツ?|aツ?窶杪ツ?ツセaツ?邃「a竄ャ窶鬨€ […]

  2. From: Ximo ephedra. - 2008/8/20 Wednesday Daytime (Trackback)

    Ximo ephedra….

    Ximo ephedra….

  3. From: Blog BBTUNE » Blog Archive » WordPress Plugin Class化する。 - 2009/11/3 Tuesday Daytime (Pingback)

    […] 参考 : hiromasa.zone )さん。 […]

Comment

  1. From: yutaka - 2005/11/14 Monday Nighttime (Comment)

    いかん、いきなり中編、後編と進みすぎた。
    取り敢えず、前編に戻ろっ:oops:

    プラグイン開発なんて大それたことは考えてないけど
    うまく動かないプラグインを動かせるようにはなりたいなぁ~

  2. From: ひろまさ - 2005/11/14 Monday Nighttime (Comment)

    いやいや、すいません:oops:。 だんだん何を書いていいのか分からなく手探りで書いているうちにこのような形に・・・。

    実は人がつくられたプラグインを見るときは、全部のソース読んでいるわけではないんですよね。 トラブルがあったときはおおざっぱな流れだけみて、なんであっちでうごいてこっちでうごかないんだろう・・・、という観点で見ています。

    長いプログラムだと流れを追うのも結構大変ですが、基本は hook から動くのが多いので、このへんが手がかりになるかもしれません。 もしなにかあったら、見てみてください!。

    あ、困ったら全然連絡下さい。 ソースって一人でみると結構はまっちゃうことあるので。:grin:

  3. From: yutaka - 2005/11/14 Monday Nighttime (Comment)

    プラグインをダウンロードしてブログの説明の英語をほとんど想像で理解して?Readmeファイをを参考に設置するんですが、使っているテーマによって全然違うんですよね、そこで何日も行き詰まるんですよね。 WordPressってPHP、CSSがすべてですね。両方ともかなり手強いです:cry: プラグインの作成方は前編からエディターにコピペしてプリントアウトしました。じっくり読ませてもらいます。どうもモニター画面からだと頭に入らないっす:oops:

  4. From: ひろまさ - 2005/11/15 Tuesday Nighttime (Comment)

    そうですよねー。 テーマの PHP/CSS をそのまま修正できて自由度が高い分、難易度は高いですよね。いや、でも yutaka さんとこハッキリとすごいと思うんですが・・・。:eek:

    プリントアウトまでして頂いてどうもありがとうございます。 実はぼくもソースみるときはプリンタアウト派だったりします。 やっぱり文章とかって一度に見えないと厳しいところありますよね!

    稚拙な文章ですので、なにかご不明点などありましたら是非ご連絡下さい。:razz:


このサイトはコンテンツをフリーズしました。トラックバック・コメントは閉じられています。

新しいサイトは、

hiromasa.another :o)

です。 :-)

このサイトについて

このブログは引っ越しを行いコンテンツはフリーズしています。hiromasa.anotherへどうぞ。

Powerd By WordPress

We (Heart) WordPress

WordPressME Logo
WordPress Plugins

ブログ内検索

Todays Popular

WordPress Ring

はてなリング - WordPress -

情報

31 queries. 1.321 seconds.

このページの先頭へ