みなさんこんにちは、アジャストの山本と申します。

さて、このブログですが1~2週毎に担当が入れ替わるのですが
早いもので、もう私の番が来てしましました。

そこで何について書こうかと考えたのですが
ショッキングなネタや、ゲームネタは諸先輩方に取られてしまったので
どんなネタで書いたものかに、ここ最近頭を悩ませていました。

ちょうどWordPressの案件に携わっておりましたので
この辺りで何か書けないかと考えたところ、プラグインが良いのではと思い
そのプラグイン作成について解説させて頂こうと思います。

なぜプラグインを作るのか?

まず、始めになぜプラグインを作成するのかについてです。

  • 移植がしやすい
    WordPressでサイトを複数作成されたことがある方はご理解頂けるかと思いますが、大抵同じような処理を行います。
    (WordPressのバージョンを隠す、アップロードした画像のサイズを追加する、カテゴリにカスタムフィールドを追加する等)

    通常ですと、これらの処理を「function.php」に実装されるかと思います。
    このサイトでのみの使用でしたら良いのですが、問題は別のサイトでも使用する際です。

    方法として、該当の記述をコピーし、新しい環境の「function.php」にペーストする事で対応されているのではないでしょうか?

    毎回、必要箇所をコピーしての移植を行うことは、無駄が多く不毛です。
    何より、どれを移植すれば良いのかを忘れていたりといった事もあり、ミスの原因となりえます。

    それを、プラグインといった形式として分離する事でコピペをする必要もなくなり、再利用が行い易くなります。

  • 修正対応
    使い回している箇所に、バグ等の問題が発生した際です。
    「function.php」に実装している場合は、該当箇所の記述をそれぞれの環境で修正を行う必要があります。

    当然の事ながら、「function.php」には修正を行いたい箇所以外にも、別の実装が含まれているかと思います。
    その為、ファイルをアップロードして対応といったことは出来ません。

    ですが、プラグインといった形で纏めておけば、修正したプラグインをそのままアップロードすることで修正を行うことが出来ます。

  • テーマへの依存
    仕事ではあまり使用されないかもしれませんが「function.php」はテーマに含まれます。

    つまり、テーマを変更すると変更後のテーマの「function.php」に同じ処理を移植しなくてはいけません。
    これは、不便ですね。

さっそく作ってみる

まず初めてプラグインを作成するのですが、最小の構成で行います。

ディレクトリを設置する

「wp-content/plugins/」に、今回作成するプラグインのディレクトリを作成します。

ここでは「testPlugin」と名前を付けます。

プラグインの実行ファイルを作成する

先程作成した「testPlugin」に直下に、以下の内容で「testPlugin.php」を作成します。

<?php
/*
Plugin Name: testPlugin
Plugin URI: http://www.adjust.ne.jp
Description: プラグイン作成テスト
Author: ADjust Co.,Ltd.
Author URI: http://www.adjust.ne.jp
Version: 1.0
*/

確認する

管理画面から、プラグインの一覧画面を表示します。
plugin_001

先程、作成したプラグインが一覧に表示されているかと思います。

有効にしてもまだ何も出来ませんが、これがプラグインの最小構成となります。

機能を実装する

次に、何か機能を実装してみます。

簡単なものが良いので、ヘッダーに含まれるWordPressのバージョン情報等の不要データの除去を行います。

まずは、除去前のheadを確認します。

<head>
<title>test | Just another WordPress site</title>
<link rel="alternate" type="application/rss+xml" title="test &raquo; フィード" href="http://dev.wordpress.com/?feed=rss2" />
<link rel="alternate" type="application/rss+xml" title="test &raquo; コメントフィード" href="http://dev.wordpress.com/?feed=comments-rss2" />
<script type="text/javascript">
  window._wpemojiSettings = {"baseUrl":"http:\/\/s.w.org\/images\/core\/emoji\/72x72\/","ext":".png","source":{"concatemoji":"http:\/\/dev.wordpress.com\/wp-includes\/js\/wp-emoji-release.min.js?ver=4.2.2"}};
  !function(a,b,c){function d(a){var c=b.createElement("canvas"),d=c.getContext&&c.getContext("2d");return d&&d.fillText?(d.textBaseline="top",d.font="600 32px Arial","flag"===a?(d.fillText(String.fromCharCode(55356,56812,55356,56807),0,0),c.toDataURL().length>3e3):(d.fillText(String.fromCharCode(55357,56835),0,0),0!==d.getImageData(16,16,1,1).data[0])):!1}function e(a){var c=b.createElement("script");c.src=a,c.type="text/javascript",b.getElementsByTagName("head")[0].appendChild(c)}var f,g;c.supports={simple:d("simple"),flag:d("flag")},c.DOMReady=!1,c.readyCallback=function(){c.DOMReady=!0},c.supports.simple&&c.supports.flag||(g=function(){c.readyCallback()},b.addEventListener?(b.addEventListener("DOMContentLoaded",g,!1),a.addEventListener("load",g,!1)):(a.attachEvent("onload",g),b.attachEvent("onreadystatechange",function(){"complete"===b.readyState&&c.readyCallback()})),f=c.source||{},f.concatemoji?e(f.concatemoji):f.wpemoji&&f.twemoji&&(e(f.twemoji),e(f.wpemoji)))}(window,document,window._wpemojiSettings);
</script>
<style type="text/css">
img.wp-smiley,
img.emoji {
    display: inline !important;
    border: none !important;
    box-shadow: none !important;
    height: 1em !important;
    width: 1em !important;
    margin: 0 .07em !important;
    vertical-align: -0.1em !important;
    background: none !important;
    padding: 0 !important;
}
</style>
<link rel='stylesheet' id='twentyfifteen-fonts-css'  href='//fonts.googleapis.com/css?family=Noto+Sans%3A400italic%2C700italic%2C400%2C700%7CNoto+Serif%3A400italic%2C700italic%2C400%2C700%7CInconsolata%3A400%2C700&#038;subset=latin%2Clatin-ext' type='text/css' media='all' />
<link rel='stylesheet' id='genericons-css'  href='http://dev.wordpress.com/wp-content/themes/twentyfifteen/genericons/genericons.css?ver=3.2' type='text/css' media='all' />
<link rel='stylesheet' id='twentyfifteen-style-css'  href='http://dev.wordpress.com/wp-content/themes/twentyfifteen/style.css?ver=4.2.2' type='text/css' media='all' />
<!--[if lt IE 9]>
<link rel='stylesheet' id='twentyfifteen-ie-css'  href='http://dev.wordpress.com/wp-content/themes/twentyfifteen/css/ie.css?ver=20141010' type='text/css' media='all' />
<![endif]-->
<!--[if lt IE 8]>
<link rel='stylesheet' id='twentyfifteen-ie7-css'  href='http://dev.wordpress.com/wp-content/themes/twentyfifteen/css/ie7.css?ver=20141010' type='text/css' media='all' />
<![endif]-->
<script type='text/javascript' src='http://dev.wordpress.com/wp-includes/js/jquery/jquery.js?ver=1.11.2'></script>
<script type='text/javascript' src='http://dev.wordpress.com/wp-includes/js/jquery/jquery-migrate.min.js?ver=1.2.1'></script>
<link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://dev.wordpress.com/xmlrpc.php?rsd" />
<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="http://dev.wordpress.com/wp-includes/wlwmanifest.xml" /> 
<meta name="generator" content="WordPress 4.2.2" />
    <style type="text/css">.recentcomments a{display:inline !important;padding:0 !important;margin:0 !important;}</style>
</head>

「testPlugin.php」のコメントの下に、以下のコードを追加を行い、プラグインを有効にします。

remove_action('wp_head', 'rsd_link');
remove_action('wp_head', 'wlwmanifest_link');
remove_action('wp_head', 'wp_generator');
remove_action('wp_head', 'print_emoji_detection_script', 7);
remove_action('wp_print_styles', 'print_emoji_styles');

除去後のheadを確認します。

<head>
<title>test | Just another WordPress site</title>
</head>

有効にすることで、プラグイン内に実装した処理が動作し、不要なメタタグが除去されました。

機能を拡張する

さて、機能のあるプラグインを作成しましたが、メタタグ除去の制御を、プラグイン本体の有効、無効でしか制御が出来ません。

これでは、特定のメタタグは表示したい、他の機能もプラグインに含めたいといった要望には応えることが出来ません。
ですので、これを拡張します。

管理画面に設定画面を設ける

「testPlugin.php」のタグ除去の記述を消し、設定画面の追加を行います。

//testPlugin.php
<?php
/*
Plugin Name: testPlugin
Plugin URI: http://www.adjust.ne.jp
Description: プラグイン作成テスト
Author: ADjust Co.,Ltd.
Author URI: http://www.adjust.ne.jp
Version: 1.0
*/

$testPlugin = new testPlugin;
add_action('admin_menu', array($testPlugin, 'addPluginMenu'));

class testPlugin
{
  public function addPluginMenu()
  {
    add_options_page('testPlugin Config', 'テストプラグイン設定', 'manage_options', basename(plugin_basename(__FILE__), '.php'), function(){
      require 'settingTemplate.php';
    });
  }
}

次に、プラグインディレクトリに「settingTemplate.php」を作成します。

//settingTemplate.php
<div class="wrap">
<h2>テストプラグイン設定</h2>
</div>

管理画面への設定画面の追加と、その導線となるメニューが追加されました。

plugin_002

機能毎のon/offを出来るように改修する

機能毎の設定を定義します。
(説明簡略化の為、設定ファイルではなく配列で設定を定義しています)

//testPlugin.php
class testPlugin
{
  public function addPluginMenu()
  {
    add_options_page('testPlugin Config', 'テストプラグイン設定', 'manage_options', basename(plugin_basename(__FILE__), '.php'), function(){
      require 'settingTemplate.php';
    });
  }

  public function getConfigs()
  {
    return array(
      array(
        'tag'      => 'wp_head',
        'name'     => 'rsd_link',
      ),
      array(
        'tag'      => 'wp_head',
        'name'     => 'wlwmanifest_link',
      ),
      array(
        'tag'      => 'wp_head',
        'name'     => 'wp_generator',
      ),
      array(
        'tag'      => 'wp_head',
        'name'     => 'print_emoji_detection_script',
        'priority' => 7,
      ),
      array(
        'tag'      => 'wp_print_styles',
        'name'     => 'wp_generator',
      ),
    );
  }
}

設定画面で機能毎のon/off用のチェックボックスの用意と、設定保存機能を追加します。

//settingTemplate.php
<?php
  $testPlugin = new testPlugin;
  $configs    = $testPlugin->getConfigs();

  if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_REQUEST['submit']))
  {
    foreach ($configs as $value)
    {
      $name = $value['name'];
      update_option($name, !empty($_REQUEST[$name]));
    }
  }
?>
<div class="wrap">
<h2>テストプラグイン設定</h2>
<form method="post" action="<?php echo $_SERVER['REQUEST_URI']?>">
<?php foreach ($configs as $value): ?>
    <?php if (!empty($value['name'])):?>
      <?php $name = $value['name'];?>
      <p>
      <label>
      <input type="checkbox" name="<?php echo $name;?>" <?php if (get_option($name)):?> checked="checked"<?php endif;?>> <?php echo $name;?>
      </label>
      </p>
    <?php endif; ?>
<?php endforeach; ?>
  <p><input type="submit" name="submit" value="submit"></p>
</form>
</div>

設定画面にチェックボックスを用意しました。
plugin_004

最後に、チェックボックスがonになっていた場合、該当の項目をremoveするように調整します。

//testPlugin.php
<?php
/*
Plugin Name: testPlugin
Plugin URI: http://www.adjust.ne.jp
Description: プラグイン作成テスト
Author: ADjust Co.,Ltd.
Author URI: http://www.adjust.ne.jp
Version: 1.0
*/

$testPlugin = new testPlugin;
add_action('admin_menu', array($testPlugin, 'addPluginMenu'));
add_action('plugins_loaded', array($testPlugin, 'init'));

class testPlugin
{
  public function init()
  {
    foreach ($this->getConfigs() as $config)
    {
      if (get_option($config['name']))
      {
        remove_action($config['tag'], $config['name'], !empty($config['priority']) ? $config['priority'] : 10);
      }
    }
  }

  public function addPluginMenu()
  {
    add_options_page('testPlugin Config', 'テストプラグイン設定', 'manage_options', basename(plugin_basename(__FILE__), '.php'), function(){
      require 'settingTemplate.php';
    });
  }

  public function getConfigs()
  {
    return array(
      array(
        'tag'      => 'wp_head',
        'name'     => 'rsd_link',
      ),
      array(
        'tag'      => 'wp_head',
        'name'     => 'wlwmanifest_link',
      ),
      array(
        'tag'      => 'wp_head',
        'name'     => 'wp_generator',
      ),
      array(
        'tag'      => 'wp_head',
        'name'     => 'print_emoji_detection_script',
        'priority' => 7,
      ),
      array(
        'tag'      => 'wp_print_styles',
        'name'     => 'print_emoji_styles',
      ),
    );
  }
}

これで、個別にon/offが切り替えるようになりました。

まとめ

さて、ここまで纏めましたが如何だったでしょうか?

複雑なものでなければ、比較的簡単にプラグインが作成出来る事が伝わったのではないかと思います。

基本的にプラグインでの拡張は、WordPressのコアファイルを直接編集するわけにはいきませんので、フィルターを使用することで対応することになります。

今回は、あまりフィルターを操作することがありませんが
幸いにしてプラグインはインストール、アンイストール時に動作するフィルターがありますので
次回はそのフィルターと絡めた形で解説をしようかと思います。

今回作成したプラグイン:testPlugin