MovableType-プラグイン開発からの抜粋

MovableTypeはわが国ではあまり人気がありませんが、ブログシステムを見る価値はあります。 箱から出して、それは多くのブログをサポートします、5番目のバージョンからそれはまた、完全なサイトを管理します。 大量の静的htmlファイルを生成することにより、perlで動作します。そのため、大きな負荷にも十分耐えることができます。

OpenSourceとProの2つのバージョンで配布されています。 それのためのプラグインは、セミフリーモードで配布されます:watch、watch、pay、use。

一般的に、システムはOOPの精神で書かれており、ほとんどすべてのくしゃみにフックがあり、ORMがあり、すべてがほとんど問題ありません...

プラグインのインストール


だから、最初のポイント:プラグインをインストールします。 プラグインのインストールは以下で構成されます:

プラグインの機能と複雑さに応じて、最後の2つのポイントが重要なタスクになる場合があります。 一部のプラグインメーカーは、mt-hacks.comのTemplateInstallerなど、これらのタスクを簡素化するカスタムプラグインを開発しました
したがって、MT用のプラグインを作成する場合は、ユーザーができるだけ動きを少なくするように慎重に検討してください。

MTのプラグインの説明


そこで、プラグインを作成することにしました。 フォルダー構造を作成しました:
plugins/coolplugin/
plugins/coolplugin/lib/
plugins/coolplugin/tmpl/
mt-static/plugins/coolplugin/

そして、彼らは考えました:何について書くべきか?

まず、config.yamlを記述します。 プラグインの説明は、いくつか(4.xxタイプ)から始まり、config.yamlファイルを介して簡単でアクセス可能な形式で作成できます。プラグインのメインファイルに多数のコードを追加することはできません。 それでは、config.yamlを含めることができるものと含めるべきものは何ですか?
しかし、 誰も知りません 。 そこに何があるのか​​を知りたい場合は、 $mt/lib/MT/Plugin.pmと他のプラグインを$mt/lib/MT/Plugin.pm

最も有用なものは次のとおりです。
 name:プラグインの名前。 収まるように短い線をお勧めします。
 id:プラグイン名OneWord
 author_link:プラグインの作者へのリンク
 author_name:プラグイン作成者名
 description:<__ trans phrase = "プラグインの説明。プラグインメニューでプラ​​グイン名をクリックすると表示されます">
バージョン:プラグインのバージョン
 schema_version:プラグインデータスキーマバージョン
 plugin_link:プラグインをマージできるページへのリンク
 doc_link:プラグインの説明があるページへのリンク
 blog_config_template:template_name with_configuration_page.tpl
 l10n_class:プラグイン::国際化クラス
アイコン:プラグイン画像{gif / png / jpg / itd}
設定:
    どの設定:
        デフォルト:「デフォルト値」
        スコープ:ブログ
    グローバル設定:
        デフォルト:「より重要」

 init:$プラグイン::モジュール::初期化関数

コールバック:
    いくつかのハック:$プラグイン::モジュール::ハック関数

タグ:
    機能:
         TagName:$プラグイン::モジュール:: tag_function
    ブロック:
         BlockTagName:$プラグイン::モジュール:: block_function_function

 object_types:
    オブジェクト:
         field:type#このフィールドはデータベースのオブジェクトに追加されます
         field:type meta#このフィールドはメタデータテーブルに保存され、データベース構造を更新する必要はありません

アプリケーション:
     #忘れてしまった後


一度にすべてのセクションが必要になることはほとんどありませんが、ここに何があるかについての説明が不足していると、さらに多くの問題が発生します。
上記では、私自身が出くわしたすべてを説明しました。 icon:などの些細なことでさえ、ドキュメントではなくMT自体のコードで発見されました。

プラグイン構成


設定については多くのことが書かれています。 MTは選択肢を提供します。設定ページを自分で作成するか、自動ジェネレータを使用します。 プラグインが2-3-4の単純な行/チェックボックス/などで構成されている場合、もちろん、自動生成プログラムを使用する方がはるかに簡単で高速です。 一般的に、基本はAdept MT Byrne Reeseの記事「 HOWTO:Own plugin settings page 」で役立ちます(ByrneはMTについて多くのことを知っています。彼の投稿を読むことをお勧めします)。

構成に関連するいくつかのポイントを説明したいと思いますが、その説明はどこにも見つかりませんでした。

プラグイン構成中のデータの検証

MT自体は、データを実際にどこでも検証しません。 目的の型にキャストされた後も最大値を保持するため、検証の方法を見つけるのはそれほど簡単ではないことがわかりました。

そのため、ここには、initフックで設定されたプラグインクラスがあります(上記のconfig.yamlを参照)。 メソッド自体(たとえば、plugins / OurPlugin / lib / Plugin.pmにあります)は、最も単純な場合は次のようになります。
 package OurPlugin::Plugin use base 'MT::Plugin'; sub cb_init { my $p = shift; return bless $p, 'OurPlugin::Plugin'; } 

config.yamlには次のように記述されています。
init: $OurPlugin::Plugin::cb_init

そのため、保存時にOurPlugin :: Plugin:save_configが呼び出され、オブジェクト、ハッシュ内のフォームデータ、スコープエリアの3つの引数が与えられます。

すでにベースMT ::プラグインがあるため、何もしなければ、ユーザーが入力を求めたものはすべてそのまま保存されます。 検証を行うには、次のものが必要です。
 sub save_config { my ($plugin, $args, $scope) = @_; my @errors; #           if (@errors) { return $plugin->error("<br />\n".join("<br />\n", @errors)); } return $plugin->SUPER::save_config($args, $scope); } ## end sub save_config 


これにより、保存時に不気味なエラーページが生成され、戻るボタンが表示されます。 なんで? 別の方法で行くことができます:別の関数load_configを追加します:
 sub load_config { my ($plugin, $args, $scope) = @_; $plugin->SUPER::load_config($args, $scope); #   -   ,   $plugin->error()   if($plugin->errstr) { # Set $args->{error} to display error banner right before plugin settings $args->{error} = $plugin->errstr; } } ## end sub load_config 

そして、構成テンプレートにピースを挿入します
  <mt:if name="error"> <mtapp:statusmsg id="generic-error" class="error"> <mt:var name="error"> </mtapp:statusmsg> </mt:if> 


したがって、任意のデータが保存されますが、設定ウィンドウを開くと、ユーザーには何が間違っているのかがわかります。 どちらの方法を選択するかはあなた次第です。両方の方法をさまざまな場面で使用できます。 多くの標準タグはプラグイン構成テンプレート内では機能しないことに注意してください。 つまり、それらは使用可能ですが、テンプレートは個別の独立したコンテキストでコンパイルされるため、設定が生成されるブログIDもありません-そして、ここでload_config$args->{...} load_config $args->{...}に設定するためにload_config助けにload_config $args->{...}必要な変数$args->{...}これを使用しないと、通常どおりユーザーにプロンプ​​トを出すことができません。

プラグインを構成するためのJQuery接続

とても面白い瞬間。 MT5はjQを完全に使用しますが、MT4ではそうではありません。 同時に、MT4の一部のプラグインはすでにjQをロードしているため、常にjQをロードするだけでは、ヘッドで競合が発生します。
私自身は、blog_config.tmplのこのような部分でこれを決定しました。
 <mt:If tag="Version" lt="5"> <script type="text/javascript"> // prevent double-load of jQuery, save if jQ already loaded its state if(window.jQuery) { window.__PLUG_jQ = window.jQuery; window.__PLUGB = window.$; } </script> <script type="text/javascript" src="<$mt:StaticWebPath$>jquery/jquery.js"></script> <script type="text/javascript"> // Restore there jQ state, if it was loaded before if(window.__PLUG_jQ) { window.jQuery = window.__PLUG_jQ; window.$ = window.__PLUGB; window.__PLUG_jQ = undefined; window.__PLUGB = undefined; } </script> </mt:If> 

このメソッドはあまり美しくありませんが、jQが正確にロードされ、$ / jQueryが悪くならないことを確認できます。

タグマジック


ここでタグを考えてみましょう:関数とブロック。

タグ関数は、現在のコンテキスト、引数、条件を受け取り、使用される文字列を返す特定の関数です。 テンプレートでは、タグは<$mt:$>介して参照されます。

古典的な質問:


ブロックタグは、ループ、条件、またはテンプレートで「内部」が定義されているが、ブロック自体がそれらのコンパイル方法を決定する何かです。 それらはconfig.yamlのタグ/ブロックで説明されています(上記参照)。 配列の古典的なタグループは次のようになります。
 sub tag_myloop { my($ctx, $args, $cond) = @_; my $builder = $ctx->stash('builder'); #       . #   ,     -  my $tokens = $ctx->stash('tokens'); #   ,     my $res = ''; my $vars = $ctx->{__stash}{vars} ||= {}; for my $i (0..$#looparray) { my $item = $looparray[$i]; #    ,        local $vars->{__item__} = $item; #     local $vars->{__first__} = $i == 0; local $vars->{__last__} = ($i==($#looparray-1)); local $vars->{__odd__} = ($i % 2) == 0; local $vars->{__even__} = ($i % 2) == 1; local $vars->{__counter__} = $i+1; defined(my $out = $builder->build($ctx, $tokens, $cond)) or return $ctx->error($builder->errstr); $res .= $out; } return $res; } 

したがって、本体は必要な回数だけコンパイルされ、連結されて発行されます。 もちろん、必要に応じて別のロジックを作成することもできますが、これはそれほど明白ではないことです。したがって、一般的なルールに従うことをお勧めします。タグブロックは、必要なデータへのアクセスを提供します。

コールバック:カーネルハック


一般に、MTには、ほとんどすべての場合にハンドラーを固定する機能が含まれています。 利用可能な場所の詳細については、ドキュメントを参照してください。ただし、ここでもすべてがリストされているわけではなく、主なもののみがリストされています。 たとえば、管理パネルでページのテンプレートを設定する必要がある場合は、 MT::App::CMS::template_param.フックを定義する必要があります。 また、ページの出力を変更する必要がある場合は、template_outputが使用されます。 これらのフックは、管理パネルで独自のページを作成したい場合に非常に役立ちます(要求があれば、次の投稿で)。 どのような種類のフックが発生するかを見つける必要がある場合、 run_callbacksのMTコードをgrepして、対応するモジュールのPODを分析してください。

コールバックのトピックはあらゆる場合に長い間噛むことができるため、投稿内のtwitterへのリンクを自動的に展開するなど、最も単純な例を紹介します。
config.yamlで定義
 コールバック:
     MT ::エントリ:: pre_save:$ OurPlugin ::プラグイン:: cb_entry_pre_save
     #cms_pre_save.entry:$ OurPlugin ::プラグイン:: cb_cms_pre_save_entry
     #api_pre_save.entry:$ OurPlugin ::プラグイン:: cb_api_pre_save_entry 

保存する前にレコードのテキストを処理し続けることができる3つのポイントがあります。


Entry_pre_saveは、正規表現でテキストを処理するだけなので、タスクに最適です。 だから、私たちは書く:
 sub cb_entry_pre_save { my ($cb, $entry, $original) = @_; my $txt = $entry->text; if ($txt ne $original->text) { my $newtxt = $txt; # regexp from twitter-blackbird-pie plugin $newtxt =~ s/([^a-zA-Z0-9_]|^)([@\xef\xbc\xa0]+)([a-zA-Z0-9_]{1,20})(\/[a-zA-Z][a-zA-Z0-9\x80-\xff-]{0,79})?/$1@<a href="http://twitter.com/intent/user?screen_name=$3" class="twitter-action">$3</a>/ug; $entry->text($newtxt) if ($newtxt ne $txt); } return 1; } ## end sub cb_entry_pre_save 


アプリケーション:管理者設定


MT自体はいくつかの「別個の」部分に分割され、各部分は開始点から起動されます。 これは:


config.yamlアプリケーションセクションの各部分について、プラグインが展開/置換する独自のパラメーターと設定を設定できます。 セクション全体の文書化は非常に不十分です(PODでのみ使用方法を確認してください)。
このセクションの主な用途は、必要なajax呼び出しを宣言することです。 たとえば、公開サイトで利用できるajaxメソッド:
  applitcations:
    コメント:
        メソッド:
             record_some_info:$ OurPlugin ::プラグイン:: ajax_record_some_info 

プラグインでの機能:
 sub ajax_record_some_info { my ($app) = @_; my $blog = $app->blog; my $result = "{'error': 'No information supplied'}"; my $user_name = $app->param('user_name'); my $info = $app->param('info'); if ($user_name && $info) { $result = do_store_info($user_name, $info); #     } $app->send_http_header(""); $app->print($result); return $app->{no_print_body} = 1; } ## end sub ajax_record_some_info 

タイプの何かをインターフェースに追加します(コードを生成するか、パスを生成する必要があります):
 var u = mtGetUser(); if(u && !u.is_anonymous) { jQuery.post({ url: '<mt:CGIPath encode_js='1'><mt:CommentScript encode_js='1'>', '__mode': 'record_some_info', 'user_name': u.name, 'info': 'he he' }); 

投稿のURLは<mt:CGIPath encode_js = '1'> <mt:CommentScript encode_js = '1'>バンドルから取得する必要があります。場所によって異なる場合があります。 従来の解決策は、MT自身が行うように.jsファイルを生成するか、このようなものをヘッダーテンプレートに入力することです。
 <script>COMMENTS_URL = '<mt:CGIPath encode_js='1'><mt:CommentScript encode_js='1'>';</script> 

必要に応じてCOMMENTS_URLを使用します。

逃した瞬間


データベースの操作、既存のオブジェクトの拡張方法、新しいオブジェクトの作成方法、および管理パネルとi18nの質問で自分のページを作成する方法については説明しませんでした。 これについては次の号で読んでください。

便利なリンク


Source: https://habr.com/ru/post/J119939/


All Articles