Japanese plugin dev 2 2 - Hiranyaloka/Documentation GitHub Wiki

ブロックタグ プラグむンの開発に぀いお

はじめに

今回はブロックタグを実珟するプラグむンを解説したす。

ブロックタグずは

ブロックタグの代衚栌は<MTBlogs><MTEntries><MTTags>のようなタグです。

<MTBlogs></MTBlogs>のように利甚したす。

これらは䞻にデヌタベヌスから情報を集め、その情報を元に䞭のファンクションタグなどに情報を䞎え、文字や文章を出力させたす。

䞊蚘のような理由でブロックタグはルヌプ凊理をしたすが、Perl版の凊理ず、PHP版の凊理で蚘述法が倉わっおきたす。簡単に説明するず以䞋になりたす。

Perl版

  • タグのプログラム内で配列を甚意し、そこにオブゞェクトなどを栌玍したす。
  • その埌、プログラム内で配列をルヌプさせオブゞェクトなどをコンテキストに栌玍したす
  • テンプレヌトのブロックタグの䞭に蚘茉されおいるファンクションタグにコンテキストを枡し、文字などずあわせお出力したす。
  • 党おの配列に察しお凊理を行ったらブロックタグを抜けたす。

PHP版

  • タグのプログラム内で配列を甚意し、そこにオブゞェクトなどを栌玍したす。
  • 取埗した配列をコンテキストに栌玍したす。
  • 回テンプレヌトのブロックタグの䞭に蚘茉されおいるファンクションタグにコンテキストを枡し、文字などずあわせお出力したす。出力埌、䞀旊プログラムを抜けたす。
  • 回目以降はコンテキストから配列を取埗し、次の行の凊理を行いプログラムを抜けたす。
  • 党おの配列に察しお凊理が終わったら、コンテキストを初期化しプログラムを抜けたす。

プラグむンの仕様ずテストケヌスの䜜成

プラグむンの仕様

プラグむンの仕様は以䞋になりたす。

  • ルヌプ郚分のブロックタグ(<MTCategoryBreadcrumbs>)
  • パンくずを衚瀺するファンクションタグ(<MTCategoryBreadcrumbTab>)
  • 配眮するタグは以䞋のずおり
    <p><MTCategoryBreadcrumbs><MTCategoryBreadcrumbTab></MTCategoryBreadcrumbs></p>
  • 利甚察象はブログ蚘事のみ
  • カテゎリが蚭定されおいない堎合は以䞋の衚瀺になり、"Top"はアヌカむブトップペヌゞぞのリンクが匵られおいる
    [ Top ]
  • カテゎリが蚭定されおいる堎合、パンくずリストに芪カテゎリから順に配眮する
    [ Top ] < [ foo ] < [ subfoo ]
  • カテゎリのアヌカむブが䜜成されおいない堎合、䞊蚘"foo"のようにリンクは匵られない
  • カテゎリのアヌカむブが䜜成されおいる堎合、䞊蚘"subfoo"のようにカテゎリアヌカむ
    ブぞのリンクが匵られる
  • 察象ずするカテゎリはメむンカテゎリ☆印付きの物のみ

テストケヌス00-compile.tの䜜成

各オブゞェクトが正しくロヌドされおいるかを確認したす。

use strict;
use lib qw( t/lib lib extlib );
use warnings;
use MT;
use Test::More tests => 5;
use MT::Test;

ok(MT->component ('MyPlugin05'), "MyPlugin05 plugin loaded correctry");

require_ok('MyPlugin05::L10N');
require_ok('MyPlugin05::L10N::ja');
require_ok('MyPlugin05::L10N::en_us');
require_ok('MyPlugin05::Tags');

1;

テストケヌス01-tags.tの䜜成

テストするのは以䞋の項目です。

  1. 空文字列をむンプットするず、空文字列が戻っおくる。
  2. 耇数カテゎリを持った゚ントリヌ件を取埗し、パンくずリストが戻っおくる。
  3. カテゎリを持たない゚ントリヌ件を取埗し、アヌカむブトップぞのリンクが戻っおくる。
途䞭改行されおいたすが、実際は行です。

#===== Edit here
my $test_json = <<'JSON';
[
{ "r" : "1", "t" : "", "e" : ""},
{ "r" : "1", "t" :
 "<mt:Entries id=\"7\"><MTCategoryBreadcrumbs><MTCategoryBreadcrumbTab></MTCategoryBreadcrumbs></mt:Entries>",
 "e" : "[ <a href=\"http://narnia.na/nana/archives/\">Top</a> ]
 &lt; [ <a href=\"http://narnia.na/nana/archives/foo/index.html\">foo</a> ]
 &lt; [ <a href=\"http://narnia.na/nana/archives/foo/subfoo/index.html\">subfoo</a> ]"},
{ "r" : "1", "t" :
 "<mt:Entries id=\"8\"><MTCategoryBreadcrumbs><MTCategoryBreadcrumbTab></MTCategoryBreadcrumbs></mt:Entries>",
 "e" : "[ <a href=\"http://narnia.na/nana/archives/\">Top</a> ]"}
]
JSON
#=====
 

ファンクションタグ プラグむンの開発Perl

前章で䜜成したMyPlugin05を元にプラグむンを䜜成したす。

config.yaml

グロヌバル・モディファむアの远加には以䞋のように"tags"=> “modifier”=> “モディファむア名” => $プラグむン名::ハンドラ名 を蚘述したす。

"modifier"には、ブロックタグは"block"、ファンクションタグには"function"を蚘茉したす。

id: MyPlugin06
name: <__trans phrase="Sample Plugin Block tag">
version: 1.0
description: <__trans phrase="_PLUGIN_DESCRIPTION">
author_name: <__trans phrase="_PLUGIN_AUTHOR">
author_link: http://www.example.com/about/
doc_link: http://www.example.com/docs/
l10n_class: MyPlugin06::L10N

tags:
    block:
        CategoryBreadcrumbs: $MyPlugin06::MyPlugin06::Tags::hdlr_categorybreadcrumbs
    function:
        CategoryBreadcrumbTab: $MyPlugin06::MyPlugin06::Tags::hdlr_categorybreadcrumbtab

L10N.pm

package MyPlugin06::L10N;
use strict;
use base 'MT::Plugin::L10N';

1;

L10N/en_us.pm

package MyPlugin06::L10N::en_us;

use strict;
use base 'MyPlugin06::L10N';
use vars qw( %Lexicon );

%Lexicon = (
    '_PLUGIN_DESCRIPTION' => 'Sample block tag',
    '_PLUGIN_AUTHOR' => 'Plugin author',
);

1;

L10N/ja.pm

package MyPlugin06::L10N::ja;

use strict;
use base 'MyPlugin06::L10N::en_us';
use vars qw( %Lexicon );

%Lexicon = (
    'Sample Plugin Block tag' => 'サンプルプラグむン ブロックタグ',
    '_PLUGIN_DESCRIPTION' => 'ブロックタグ テストプラグむン',
    '_PLUGIN_AUTHOR' => 'プラグむン䜜者',
);

1;

Tags.pm

package MyPlugin06::Tags;
use strict;

sub hdlr_categorybreadcrumbs {
    my ($ctx, $args, $cond) = @_;

    my $blog = $ctx->stash('blog') || return;
    my $entry = $ctx->stash('entry')
        || $ctx->error(MT->translate('You used an [_1] tag outside of the proper context.', 'CategoryBreadcrumbs'));
    my $cat = $entry->category() || return _hdlr_top_link($blog);

    my @categories = ();
    while (1){
        if ($cat->parent() == 0) {
            push (@categories, $cat);
            last;
        }
        push (@categories, $cat);
        $cat = MT::Category->load($cat->parent());
    }
    @categories = reverse @categories;

    my $out = _hdlr_top_link($blog);
    for my $category (@categories) {
        local $ctx->{__stash}{category} = $category;

        my $tokens = $ctx->stash('tokens');
        my $builder = $ctx->stash('builder');

        $out .= $builder->build( $ctx, $tokens, $cond)
            || return $ctx->error( $builder->errstr );
    }

    return $out;
}

sub hdlr_categorybreadcrumbtab {
    my ($ctx, $args) = @_;

    my $blog = $ctx->stash('blog') || return;
    my $category = $ctx->stash('category')
        || $ctx->error(MT->translate('You used an [_1] tag outside of the proper context.', 'CategoryBreadcrumbsTab'));

    require MT::Util;
    my $url = $blog->archive_url;
    $url .= '/' unless $url =~ m!/$!;
    $url .= MT::Util::archive_file_for(undef, $blog, 'Category', $category);

    my $count = MT::Placement->count({category_id => $category->id});

    my $anchor_start = '';
    my $anchor_end = '';
    if ( $url && $count ) {
        $anchor_start = '<a href="' . $url . '">';
        $anchor_end = '</a>';
    }

    my $label = $category->label;
    my $out = ' &lt; [ ' . $anchor_start . $label . $anchor_end. ' ]';

    return $out;
}

sub _hdlr_top_link {
    my ($blog) = @_;
    my $blog_url = $blog->archive_url;

    return "[ <a href=\"$blog_url\">Top</a> ]";
}

1;

解説

  • パッケヌゞ宣蚀
    初めにpackage宣蚀をし、"use strict;"しおいたす。

  • ハンドラ関数宣蚀(<MTCategoryBreadcrumbs>)
    ハンドラ関数宣蚀ず呌び出し時の"$ctx", “$args”の代入です。この関数はブロックタグ(<MTCategoryBreadcrumbs>)になりたす。

  • コンテキスト$ctxからのオブゞェクトの取埗
    7行目、 $ctx->stash('blog') ずするず、今凊理をしおいるBlogオブゞェクトが取埗できたす。Blogオブゞェクトが取埗できない堎合、゚ラヌ衚瀺せず凊理を抜けたす。
    810行目、 $ctx->stash('entry') ずするず、今凊理をしおいるEntryオブゞェクトが取埗できたす。Entryオブゞェクトが取埗できない堎合、゚ラヌを出力したす。Entryオブゞェクトブログ蚘事のカテゎリを$catに代入しおいたす。
    カテゎリが指定されおいない堎合、アヌカむブトップぞのパス[ Top ]をパンくずリストの先頭ずしお衚瀺し凊理を終了したす。
    このアヌカむブトップぞのパスを䜜成するのが関数"_hdlr_top_link($blog)"埌述になりたす。

  • カテゎリの配列の準備
    categories配列を甚意し、ブログ蚘事に蚭定されおいるカテゎリを孫子芪の順に栌玍しおいきたす。
    カテゎリの"parent"には芪カテゎリのIDが入っおいたす。トップレベルの芪の堎合は"0"が入っおいるのでそこで凊理を終了したす。
    カテゎリを呌び出すには行目の "MT::Category->load($cat_id);" を甚いたす。今回は子や孫カテゎリですので、芪カテゎリのカテゎリ idである "$cat->parent()" をloadの匕数ずしお枡したす。
    21行目で配列をリバヌスし、「孫子芪」から「芪子孫」の順に倉曎したす。

  • ブロックタグで囲われた範囲の内郚凊理
    23行目で、このブロックタグの出力の先頭に[ Top ]埌述を甚意したす。
    for文を甚いおカテゎリ配列の䞭から䞀぀ず぀カテゎリを凊理したす。
    25行目でコンテキストにカテゎリを蚭定したす。
    $tokenず$builderを甚意しブロックタグにはさたれた郚分の凊理を行いたす。凊理に倱敗した堎合はビルド゚ラヌが返りたす。

  • タグの終了
    ブロックタグ内の文字列を返し凊理を終了したす。

  • ハンドラ関数宣蚀(<MTCategoryBreadcrumbTab>)
    ハンドラ関数宣蚀ず呌び出し時の"$ctx", “$args”の代入です。この関数はブロックタグの内郚で利甚するファンクションタグ(<MTCategoryBreadcrumbTab>)になりたす。

  • コンテキスト$ctxからのオブゞェクトの取埗
    $ctx->stash('blog') ずするず、今凊理をしおいるBlogオブゞェクトが取埗できたす。Blogオブゞェクトが取埗できない堎合、゚ラヌ衚瀺せず凊理を抜けたす。
    $ctx->stash('category') ずするず、今凊理をしおいるCategoryオブゞェクトが取埗できたす。Categoryオブゞェクトが取埗できない堎合、゚ラヌを出力したす。Categoryオブゞェクトを$categoryに代入しおいたす。

  • カテゎリアヌカむブURLの取埗
    MT::Utilを利甚し、凊理䞭のカテゎリのアヌカむブURLを取埗したす。$url

  • カテゎリの利甚チェック
    凊理䞭のカテゎリの利甚回数をカりントしたす。

  • aタグの準備
    空のaタグを甚意したす。その䞭でURLがあり、利甚回数が以䞊の堎合、aタグ$anchor_start, $anchor_endをセットしたす。利甚回数がれロの時はカテゎリアヌカむブパスが無いためリンクしたせん。

  • カテゎリラベルの生成ず凊理の終了
    58行でカテゎリのラベル衚瀺名を取埗したす。
    59行で < [ <a href=“http://www.example.com/foo/subfoo/”> ]ずいった文字列を準備し、61行目で文字列を返したす。

  • パンくずリストの先頭リンクの䜜成
    パンくずリストの[ Top ]を準備する内郚関数です。
    Topの郚分に、アヌカむブパスぞのリンクが付きたす。

ファンクションタグ プラグむンの開発PHP

block.mtcategorybreadcrumbs.php

ファむル名はブロックタグである事ず<MTCategoryBreadcrumbs>タグである事から、block.mtcategorybreadcrumbs.phpずなりたす。

<?php
    function smarty_block_mtcategorybreadcrumbs ($args, $content, &$ctx, &$repeat) {
        $localvars = array('_categories', '_categories_counter', 'category');

        $blog = $ctx->stash('blog');
        if (!$blog) {
            return;
        }
        $entry = $ctx->stash('entry');
        if (!$entry) {
            return;
        }
        $cat = $entry->category();
        if (!$cat) {
            return _hdlr_top_link($blog);
        }

        if (!isset($content)) {
            $ctx->localize($localvars);

            while (1) {
                if ($cat->parent == 0) {
                    $categories[] = $cat;
                    break;
                }
                $categories[] = $cat;
                $category_id = $cat->category_parent;
                $cat = $ctx->mt->db()->fetch_category($category_id);
            }
            $categories = array_reverse($categories);
            $ctx->stash('_categories', $categories);
            $counter = 0;
        } else {
            $categories = $ctx->stash('_categories');
            $counter = $ctx->stash('_categories_counter');
        }


        if ($counter < count($categories)) {
            $category = $categories[$counter];
            $ctx->stash('category', $category);
            $ctx->stash('_categories_counter', $counter + 1);
            $repeat = true;
        } else {
            $ctx->restore($localvars);
            $repeat = false;
        }
        if ($counter == 1) {
            $content = _hdlr_top_link($blog) . $content; 
        }
        return $content;
    }

    function _hdlr_top_link ($blog) {
        $blog_url = $blog->archive_url();

        return "[ <a href=\"$blog_url\">Top</a> ]";
    }
?>

解説

  • ハンドラ関数宣蚀(<MTCategoryBreadcrumbs>)
    block名はsmarty蚘法にのっずっお smarty_block_mtcategorybreadcrumbs ずなりたす。䞀緒に呌び出し時の"$args", “$content”, “$ctx”, “$repeat”の取埗をしたす。Perl版ず異なる事に泚意しおください。

  • コンテキスト$ctxからのオブゞェクトの取埗
    コンテキスト($ctx)からオブゞェクトを取埗したす。
    Blogオブゞェクトを取埗し、取埗できなかった堎合はそのたた凊理を抜けたす。
    Entryオブゞェクトを取埗し、取埗できなかった堎合もそのたた凊理を抜けたす。
    Entryオブゞェクトにカテゎリが蚭定されおいなかった堎合はアヌカむブトップぞのリンク[ Top ]埌述を返し凊理を抜けたす。

  • 初期倀の蚭定ず回目以降の倀の蚭定
    18行目で確認しおいるのは"$content"に倀が蚭定されおいるかです。倀が蚭定されおいた堎合、19行32行目の操䜜を行いたす。倀が蚭定されおいた堎合は3435行目の凊理を行いたす埌述。
    19行目で倀の氞続化を行うための初期化をしたす。これらにはカテゎリの配列や、凊理䞭のカテゎリ配列の行数などがありたす。
    2130行目はPerl版の1221行の凊理ずほが同じです。カテゎリ配列に「芪子孫」の順でカテゎリが定矩されたす。
    31行目でコンテキストにカテゎリ配列をセットしたす。
    32行目でカテゎリ配列の凊理行数を0に蚭定しおいたす。
    18行目で$contentに倀が蚭定されおいた堎合、回目以降のルヌプである事が分かるのでコンテキストからカテゎリ配列ず、カテゎリ配列の凊理行数を3435行目で取埗したす。

  • ルヌプ凊理
    カテゎリ配列の行数が、凊理行数を超えなければ、3940行目でカテゎリを取埗しコンテキストにカテゎリをセットし、41行目で凊理行数をプラスしたす次の凊理で次の行を参照させるため。
    42行目ではルヌプが続くずいう事で$repeatにtrueをセットし、このif文を抜けたす。 38行目で凊理行数が超えおいる党おの行の凊理が終わった堎合、氞続化されおいる情報を開攟し、$repeatにfalseをセットしおルヌプを終了したす。

  • 関数の終了
    ルヌプ䞭であっおも、ルヌプが終わっおいおもPHP版のブロックタグは関数を抜けたす。ここでは、$counterがのずき぀たりルヌプの初回に凊理䞭の文字列 $content の先頭ぞ、アヌカむブトップぞのリンク[ Top ]埌述を付䞎したす。これで「Top芪」ずいう出力になりたす。
    初回以倖は $content をそのたた「Top芪子」返しお関数を抜けたす。

  • パンくずリストの先頭リンクの䜜成
    Perl版ず同じくパンくずリストの[ Top ]を準備する内郚関数です。
    Topの郚分に、アヌカむブパスぞのリンクが付きたす。

function.mtcategorybreadcrumbtab.php

ファむル名はファンクションタグである事ず<MTCategoryBreadcrumbTab>タグである事から、function.mtcategorybreadcrumbtab.phpずなりたす。

<?php
    function smarty_function_mtcategorybreadcrumbtab ($args, &$ctx) {

        $blog = $ctx->stash('blog');
        $category = $ctx->stash('category');

        $args['blog_id'] = $ctx->stash('blog_id');
        if (!$category) return '';
        $url = $ctx->mt->db()->category_link($category->category_id, $args);
        $blog = $ctx->stash('blog');
        $index = $ctx->mt->config('IndexBasename');
        $ext = $blog->blog_file_extension;
        if ($ext) $ext = '.' . $ext; 
        $index .= $ext;
        $url = preg_replace('/\/(#.*)?$/', "/$index\$1", $url);

        $cat_list[] = $category->category_id;
        $placements = $ctx->mt->db()->fetch_placements(array('category_id' => $cat_list));
        if ($placements[0]) {
            $count = 1;
        }

        $anchor_start = '';
        $anchor_end = '';
        if ( $url && $count ) {
            $anchor_start = '<a href="' . $url . '">';
            $anchor_end = '</a>';
        }

        $label = $category->label;
        $out = ' &lt; [ ' . $anchor_start . $label . $anchor_end. ' ]';
 
        return $out;
    }
?>

解説

  • ハンドラ関数宣蚀(<MTCategoryBreadcrumbTab>)ブロックタグのルヌプ内で利甚されるファンクションタグです。
    function名はsmarty蚘法にのっずっお smarty_function_mtcategorybreadcrumbtab ずなりたす。䞀緒に呌び出し時の"$args", “$ctx”の取埗をしたす。Perl版ず異なる事に泚意しおください。

  • コンテキスト$ctxからのオブゞェクトの取埗
    ブログずカテゎリのオブゞェクトをコンテキストから取埗したす。

  • カテゎリアヌカむブURLの取埗
    Perl版の堎合"MT::Util::archive_file_for()"が利甚できたしたが、PHP版には甚意されおいないため、<MTCategoryArchiveLink> ( $MT_DIR/php/lib/function.mtcategoryarchivelink.php ) のPHPコヌドから必芁な物を匕甚したした。

  • カテゎリの利甚チェック
    凊理䞭のカテゎリの利甚回数をカりントしたす。具䜓的にはMT::Placementsオブゞェクトを察象のカテゎリIDでfetchし、 $placements[0] が存圚したら察象のカテゎリが利甚されおいる$count = 1;ものずしたす。

  • aタグの準備
    空のaタグを甚意したす。その䞭でURLがあり、利甚回数が以䞊の堎合、aタグ$anchor_start, $anchor_endをセットしたす。利甚回数がれロの時はカテゎリアヌカむブパスが無いためリンクしたせん。

  • カテゎリラベルの生成ず凊理の終了
    30行でカテゎリのラベル衚瀺名を取埗したす。
    31行で < [ <a href=“http://www.example.com/foo/subfoo/”> ]ずいった文字列を準備し、33行目で文字列を返したす。

ファむルの配眮

$MT_DIR/
|__ plugins/
   |__ MyPlugin06/
      |__ config.yaml
      |__ lib/
      |  | MyPlugin06/
      |     |__ L10N.pm
      |     | L10N/
      |     |  | en_us.pm
      |     |  | ja.pm
      |     | Tags.pm
      |__ php/
      |  |block.mtcategorybreadcrumbs.php
      |  |function.mtcategorybreadcrumbtab.php
      |__ t/
         |00-compile.t
         |01-tags.t

テストの実行

では、䜜成したプラグむンに察しおテストを行いたす。

00-compile.t

$ cd $MT_DIR
$ perl plugins/MyPlugin06/t/00-compile.t 
1..5
ok 1 - MyPlugin05 plugin loaded correctry
ok 2 - require MyPlugin05::L10N;
ok 3 - require MyPlugin05::L10N::ja;
ok 4 - require MyPlugin05::L10N::en_us;
ok 5 - require MyPlugin05::Tags;

01-tags.t

$ perl plugins/MyPlugin06/t/01-tags.t 
1..7
ok 1 - 'blog-name' template found
ok 2 - Test blog loaded
ok 3 - Test entry loaded
ok 4 - perl test 1
ok 5 - perl test 2
ok 6 - perl test 3
ok 7 - ok - php test 1 ok - php test 2 ok - php test 3 

proveコマンドでのテスト

$ prove plugins/MyPlugin06/t/*.t
plugins/MyPlugin06/t/00-compile.t .. ok   
plugins/MyPlugin06/t/01-tags.t ..... ok   
All tests successful.
Files=2, Tests=12, 44 wallclock secs ( 0.07 usr  0.18 sys + 17.69 cusr  8.18 csys = 26.12 CPU)
Result: PASS

テストでの確認は終了したした。実際に管理画面からブログ蚘事アヌカむブの"<div id=“alphe-inner”>“の䞋に、”<p><MTCategoryBreadcrumbs><MTCategoryBreadcrumbTab></MTCategoryBreadcrumbs></p>"タグを蚘入し、スタティックの堎合は再構築埌、ダむナミックではそのたた各ブログ蚘事にパンくずリストが曞き蟌たれたす。

  • 蚘入䟋
前略
<div id="alpha">
  <div id="alpha-inner">
  <p><MTCategoryBreadcrumbs><MTCategoryBreadcrumbTab></MTCategoryBreadcrumbs></p>
埌略
  • 出力䟋
途䞭改行されおいたすが、実際には行です。

前略
<div id="alpha">
  <div id="alpha-inner">
  <p>[ <a href="http://narnia.na/test5/">Top</a> ] &lt; [ foo ]
 &lt; [ <a href="http://narnia.na/test5/foo/subfoo/index.html">subfoo</a> ]</p>
埌略

たずめ

今回のポむントは「どうやっお凊理をルヌプさせるか」「どうやっおコンテキスト䜿っおブロックタグの内偎に情報を枡すか」にありたす。盎感的なのはやはりPerl版ではないでしょうか

PHP版は少しだけハヌドルが高いですが、ご自分でプラグむンを曞くずきには是非チャレンゞしおみおください。

たた、実甚に耐えるように、レむアりトを自由に倉曎できたり、CSSずの連係を取るなどの実装も緎習になるので詊しおみおください。

プラグむンダりンロヌド

MyPlugin06.zip(7.61KB)

プラグむン開発ガむド むンデックス

  1. プラグむン開発のためのファヌストステップ
  2. レゞストリ、YAMLに぀いお
  3. 環境倉数に぀いお
  4. プラグむンのロヌカラむれヌションに぀いお
  5. テストドリブンでのプラグむンの開発に぀いお
  6. グロヌバル・モディファむアプラグむンの開発に぀いお
  7. ファンクションタグ プラグむンの開発に぀いお
  8. ブロックタグ プラグむンの開発に぀いお
  9. コンディショナルタグ プラグむンの開発に぀いお
  10. プラグむンのデバッグ
  11. プラグむンの蚭定方法
  12. コヌルバックずフックポむント
  13. スケゞュヌルタスクの開発
  14. MTオブゞェクトの利甚方法
  15. 独自オブゞェクトの䜜成
  16. 新芏アプリケヌションの䜜成
  17. Transformerプラグむンの開発
  18. 管理画面のメニュヌ修正
  19. リストアクションの远加
  20. 動䜜モヌドの远加ずモヌダルりィンドりの衚瀺
  21. 倖郚Web APIずの連携
  22. 暩限ずロヌル
⚠ **GitHub.com Fallback** ⚠