LoginSignup
1
1

More than 5 years have passed since last update.

Picoのプラグインを作る

Last updated at Posted at 2015-06-04

Picoのプラグインは、pluginsというディレクトリの中に、所定のメソッドを実装したPHPクラスを配置するだけ。メソッドはそれぞれページレンダリングの特定のタイミングで呼び出されており、それを処理することで、Picoに機能を追加したり、編集機能を設けたりすることが出来るようです。既存のプラグインは、PicoCMSのWikiページにあります(…が、2015/06/04現在はプラグインの仕様が固まる前に作られたものも多く、「これを使ってなんか作る」というより「これを参考にしたりフォークして新規に自分で作る」ほうが早いかもしれません)。

プラグインをとりあえず作ってみる

プラグインを作るにあたり気をつけるべきことは3つ

  • pluginsディレクトリにファイルを配置すること(サブディレクトリの下でも良い)
  • phpファイルと、中で定義するクラス名は、同じとすること(大文字小文字は区別しない)
  • プラグインフックメソッドに渡される引数が、値渡しか参照渡しかよく見る(これを間違えると、せっかく加工した処理が反映されない なんてことになる)

pluginsディレクトリには、最初から「pico_plugins.php」というファイルが置いてあるので、それをコピーして好きなように作り替えて使うと良いです。

プラグインのメソッド呼び出しタイミング

ここからが厄介なところ。このプラグインのメソッド呼び出しタイミングですが、見たところ公式のドキュメントには載っていません。ソースコードは前述の通り一つですのでそんなに追いづらくはないのですが、以下にまとめてみました(記載は呼び出し順)

  1. plugins_loaded
  2. config_loaded
  3. request_url
  4. before_load_content
    1. before_404_load_content(読み込もうとしたファイルが存在したときには、呼び出されない
    2. after_404_content(同上)
  5. after_load_content(以降、コンテンツがあってもなくても呼び出される)
  6. before_read_file_meta(一回のアクセスにつきコンテンツファイルの数(contents/ディレクトリにあるmdファイルの数)ぶん呼び出される)
  7. file_meta
  8. before_parse_content
  9. after_parse_content
  10. content_parsed(非推奨)
  11. get_page_data(before_read_file_metaと同様、コンテンツファイル数ぶん呼び出される)
  12. get_pages
  13. before_twig_register
  14. before_render
  15. after_render

とくに上でも括弧書きしたとおり、before_read_file_metaget_page_dataは、一回のアクセスごとに、コンテンツファイル数ぶん呼び出されます。全てのコンテンツに追加のメタデータを定義したり、そのメタデータに何らかの加工を施したい場合は、これらを使うといいです。

なお、公式ページのサンプルにあるとおり、before_read_file_metaではメタデータフィールドの追加のみが行えます(メタデータの加工は行えません)。before_read_file_metaでメタデータのフィールド名を追加して、get_page_dataでメタデータを参考に処理を追加していく という感じがベストっぽいです。

お勧めの使い方?

いちおういくつかプラグインを作ってみた感じのメモ

config_loaded

config.phpの設定が読める唯一のフックメソッドです。設定値を使う場合はここでデータを取得し、クラスのフィールドに格納しておきましょう。

また、インターネットのコンテンツを受信し、それをページとして追加するようなプラグインを書く場合は、ここで処理をすませておくと良いです。

plugin_demo.php
class Plugin_Demo{

  private $base_url;

  public function config_loaded(&$settings) {
    $this->base_url = $settings['base_url'];
    $this->content_dir = $settings['content_dir'];
  }

  // ・・・
}

request_url

実際にアクセスするURLが確定したタイミングで呼び出されます。タグページなど実際には存在しないページを存在すると見せかける必要があるときに呼び出されています。

before_read_file_meta

メタデータのヘッダを追加できるメソッドです。それ以外のことは出来ません。

plugin_demo.php
class Plugin_Demo{

  // ・・・

  public function before_read_file_meta(&$headers)
  {
    $headers['image'] = 'Image';
  }

  // ・・・
}

after_parse_content

パースした直後のファイル(マークダウンから変換した後のHTMLデータ)にアクセスできます。
たとえばヘッダタグの番号を書き換えるなど、HTMLに関する加工を行う場合はここで行います。

plugin_demo.php
class Plugin_Demo{

    public function after_parse_content(&$content)
    {
    $content = preg_replace_callback('/(<\/?h)(\d)([^>]*>)/', function($m){
        return $m[2] + 3 <= 6 ? $m[1] . ($m[2] + 3) . $m[3] : "";
      }, $content);
    }

}

get_page_data

メタデータとページデータにアクセスできます。メタデータの加工を行う場合はここでやっておくと良いです。

plugin_demo.php
class Plugin_Demo{

  // ・・・

    public function get_page_data(&$data, $page_meta)
    {
    $file_url = substr($data["url"], strlen($this->base_url));
    if($file_url[strlen($file_url) - 1] == "/") $file_url .= 'index';
    if (strlen($page_meta['image']) > 0 && preg_match('/^(.+\/)[\w\.-]+?$/', $file_url, $m)) {
      if($page_meta['image'][0] == '.'){
        $data['image'] = $this->base_url . "/" . $this->content_dir . "$m[0]$page_meta[image]";
      }else{
        $data['image'] = $this->base_url . "/" . $this->content_dir . "$m[1]$page_meta[image]";
      }
    } else {
      $data['image'] = NULL;
    }

  // ・・・
}

get_pages

全てのページ情報にアクセスできるメソッドです。処理が重くなりがちなので、なるべく使わない方が良さそうです。

なお、古いプラグイン仕様ではこのメソッドで「ファイルが存在すれば処理を、しなければそのエントリをpagesリストから消す」という処理をやっているものがあります。

plugin_demo.php
class Plugin_Demo{

  // ・・・

    public function get_pages(&$pages, &$current_page, &$prev_page, &$next_page) {
        $new_pages = array();

        foreach ($pages as $page) {
            // ・・・
        }

        $pages = $new_pages;
    }


  // ・・・
}

before_render

ほぼ最後に呼び出される処理です。Twig変数に直接アクセスできるので、ページの並び替えや、グループ化して別の変数を作るなどの処理を行う場合はここが良いです。

plugin_demo.php
class Plugin_Demo{

  // ・・・

    public function before_render(&$twig_vars, &$twig, &$template) {
        $pages = $twig_vars["pages"];
        $curdir = array();
        // ・・・
        $twig_vars["dir_pages"] = $curdir;
    }

  // ・・・
}

プラグインの呼び出し順は?

変更出来ません。pico.phpのget_filesメソッドを見た感じ、PHPのディレクトリ処理関数におまかせのようです。

よって、○○のプラグイン処理の後に△△のプラグインの処理を実行して・・・ というようなことは出来ないっぽいです。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1