プラグイン作成の基礎

PowerCMS XはPHPによるプラグインでさまざまな機能を拡張することができます。このページでは、サンプル・プラグインを元にプラグイン作成の基礎について紹介します。

PowerCMS との違い

  • プラグインはPerlではなく、PHPで記述します。
  • 定義ファイルはこれまでの YAML形式ではなく、JSON形式で記述します。

サンプル「MyFirstPlugin」のファイル構成

このプラグインが提供するのは、下記の機能です。

  • ダッシュボードをカスタマイズして、管理者からのメッセージを表示する
  • 「My First Menu」メニューを追加して、カスタムメソッド「myfirstplugin_mode(__mode=myfirstplugin_mode)」を追加する
  • 条件タグ「ifmyfirstplugin」ファンクションタグ「myfirstpluginfunction」を追加する

プラグインは下記のようなファイル構成となります。最低限必要なのは、config.json(定義ファイル)と、プラグイン本体のPHPファイルです。

plugins/
 └ MyFirstPlugin/ (root)
   ├ config.json (定義ファイル)
   ├ MyFirstPlugin.php (プラグイン・クラス)
   ├ tmpl (テンプレート・ファイル)
   │  ├ cfg_template.tmpl (プラグイン設定画面)
   │  ├ myfirstplugin_mode.tmpl (カスタム・メソッド用)
   │  └ widgets/
   │    └ myfirstplugin_widget.tmpl (カスタム・ダッシュボードウィジェット)
   └ locale/
      └ ja.json (翻訳ファイル)

config.json

プラグインの有効化・無効化、プラグインの設定は「システムメニュー」→「ツール」→「プラグイン」から行えます。画面と設定ファイル「config.json」の関係は以下のようになります。

プラグイン設定画面

{
    "label"       : "MyFirstPlugin", // ラベル 
    "id"          : "myfirstplugin",
    "component"   : "MyFirstPlugin", // PHPクラス名
    "version"     : "1.0", // バージョン 
    "author"      : "Alfasado Inc.", // 作成者 
    "author_link" : "https://alfasado.net/", // 作成者のURL
    "description" : "My First PowerCMS X's Plugin.", // 概要 
    "cfg_template": "cfg_template.tmpl", // プラグイン設定のテンプレート
    "cfg_system"  : 1, // システムで設定を表示する 
    "cfg_space"   : 1, // スペースで設定を表示する
    "settings"    : {
        "myfirstplugin_test" : "Default value." // プラグイン設定と初期値 
    }
}

config.jsonで指定可能な処理、機能の書き方

    "menus": {
        // カスタム・メニューの定義
    },
    "widgets": {
        // カスタム・ダッシュボードウィジェット
    },
    "tasks": {
        // 定期実行処理(worker.phpで実行)
    },
    "hooks": {
        // フック(割り込み処理)
    },
    "callbacks": {
        // コールバック(何らかのオブジェクトに対する処理の追加やオーバーライド)
    },
    "tags": {
        // テンプレート・タグの定義
    },
    "methods": {
        // カスタム・メソッドの追加
    },
    "list_actions": {
        // 一覧画面に対するカスタム・アクションの追加
    },
    "import_format": {
        // カスタム・インポート(記事)
    },
    "export_format": {
        // カスタム・エクスポートフォーマット(記事)
    }
キー説明参考情報
menusシステムまたはスペースの「メニュー」→「 ツール」にメニュー項目を追加します。EntryImporter / LivePreviewプラグインを参照
widgetsカスタム・ダッシュボード・ウィジェットを追加します。サンプルMyFirstPlugin / SiteMapプラグインを参照
tasks定期実行タスク(worker.php)の実行時に追加する処理を定義します。
hooksアプリケーションの各処理フェイズに、処理を割り込ませる時に指定します。 初期化直後
  • post_init
runメソッドの冒頭
  • pre_run
__destructがコールされた時
  • post_run
callbacksコールバック(何らかのオブジェクトに対する処理の追加やオーバーライド)を定義します。

オブジェクトの保存と削除

  • save_filter
  • pre_save
  • post_save
  • delete_filter
  • post_delete

一覧画面や公開側テンプレートでの一覧表示

  • start_listing
  • pre_listing
  • post_load_objects
  • pre_archive_list
  • pre_archive_count

管理画面のテンプレート処理

  • template_source
  • template_output

インポート

  • pre_import
  • post_import

時限公開・非公開処理

  • scheduled_published
  • scheduled_replacement

日付ベースアーカイブの再構築時

  • publish_date_based
tagsテンプレート・タグを追加します。block, conditional, functionまたはmodifier(サンプル / Minifierプラグインを参照)
methodsカスタムメソッド「__mode=method_name」を追加します。サンプルプラグインを参照
list_actions一覧画面に追加するカスタム・アクションを定義します。EntryImporterプラグインを参照
import_format記事のカスタム・インポートフォーマットを追加します。EntryImporterプラグインを参照
export_format記事のカスタム・エクスポートフォーマットを追加します。EntryImporterプラグインを参照

コード・サンプル

プラグインは、lib/Prototype/PTPluginファイルをrequireし、extends を使ってPTPluginクラスを継承したクラスとして作成します。

<?php
require_once( LIB_DIR . 'Prototype' . DS . 'class.PTPlugin.php' );
class MyFirstPlugin extends PTPlugin {
    function __construct () {
        parent::__construct();
    }
}

カスタム・ダッシュボードウィジェット

サンプル・プラグインでは、プラグイン設定で指定したメッセージをダッシュボードに表示するダッシュボードカスタマイズ例を追加しています。

サンプルのダッシュボードウィジェット

config.jsonに、1.システム内で一意のキーを指定し、2.component(プラグインクラス名)、label(ウィジェット名)、scope(system、space)を定義します。

    "widgets": {
        "myfirstplugin_widget": {
            "component"   : "MyFirstPlugin",
            "label"       : "Information from MyFirstPlugin",
            "scope"       : ["system"]
        }
    },
    "callbacks": {
        "myfirstplugin_template_source_dashboard": {
            "dashboard" : {
                "template_source" : {
                    "component" : "MyFirstPlugin",
                    "priority"  : 10,
                    "method" : "template_source_dashboard"
                }
            }
        },
    },

カスタム・ダッシュボード・ウィジェットは、プラグイン配下の tmpl/widgets/{一意のキー}.tmplを設置するだけで実装できます。コードは特段書く必要はありませんが、このサンプルでは、ダッシュボードを表示した際にページのタイトルを変更する処理を必要としているため、dashboardテンプレートに対するcallbacks「template_source」を定義しています。

tmpl/widgets/myfirstplugin_widget.tmpl
<div class="card dashboard-widget" id="widget-myfirstplugin_widget">
  <h2 class="card-header text-white bg-primary text-center">
  <strong><mt:trans phrase="Information from MyFirstPlugin" component="MyFirstPlugin"></strong>
    <button  type="button" class="detatch-widget" aria-label="<mt:trans phrase="Detach">" data-name="widget-myfirstplugin_widget">
      <span aria-hidden="true">&times;</span>
    </button>
  </h2>
  <div class="card-block text-center">
  <mt:pluginsetting workspace_id="$workspace_id" component="MyFirstPlugin" name="myfirstplugin_test" setvar="myfirstplugin_information">
  <mt:if name="myfirstplugin_information">
    <mt:var name="myfirstplugin_information" escape nl2br>
  <mt:else>
    <mt:trans phrase="There are no news now." component="MyFirstPlugin">
  </mt:if>
  </div>
</div>
<script>
$('.view-external').hide();
</script>
MyFirstPlugin.php
    function template_source_dashboard ( $cb, $app, $tmpl ) {
        $ctx = $app->ctx;
        $ctx->vars['dashboard_widgets'] = ['myfirstplugin_widget'];
        $ctx->vars['disabled_widgets'] = [];
        $app->ctx->vars['page_title'] = $this->translate( "Hello %s!", 
                                        htmlspecialchars( $app->user()->nickname ) );
    }

カスタム・メニューとカスタム・メソッド

menusにカスタムメニューを追加し、メニューを選択された時にカスタム・メソッド(__mode=myfirstplugin_menu)を実行するコードです。

カスタム・メニュー
config.json
    "menus": {
        "myfirstplugin_menu": {
            "display_system" : 1,
            "display_space" : 1,
            "component"  : "MyFirstPlugin",
            "mode"       : "myfirstplugin_mode",
            "label"      : "My First Menu",
            "permission" : "superuser",
            "order"      : 10
        }
    },
    "methods": {
        "myfirstplugin_mode": {
            "display_system" : 1,
            "component"  : "MyFirstPlugin",
            "permission" : "superuser",
            "method"     : "myfirstplugin_mode"
        }
    }
MyFirstPlugin.php
    function myfirstplugin_mode ( $app ) {
        $app->ctx->vars['page_title'] = $this->translate( "Hello %s!", 
                                        htmlspecialchars( $app->user()->nickname ) );
        $app->build_page( 'myfirstplugin_mode.tmpl' );
    }
tmpl/myfirstplugin_mode.tmpl
<mt:include file="include/header.tmpl">
<mt:include file="include/footer.tmpl">
locale/ja.json

日本語環境用の翻訳フレーズをJSON形式で記述したファイルを localeディレクトリ配下に設置します。

{
    "My First PowerCMS X's Plugin." : "はじめてのPowerCMS Xプラグインですよ。",
    "My First Menu" : "はじめてのメニュー",
    "My First Setting" : "はじめての設定",
    "Please specify my first plugin setting." : "はじめての設定を指定してね!",
    "Information from MyFirstPlugin" : "はじめてのお知らせ",
    "There are no news now." : "現在お知らせはありません。",
    "Hello %s!" : "やぁ! %s さん"
}

※ テンプレート・タグプラグインのコードについては、別途まとめてご紹介します。