コンテンツデータでMTEntriesWithSubCategoriesの代替テンプレートタグ

January 17,2022 11:55 PM
Category:[テンプレートタグ]
Tag:[MovableType]
Permalink

コンテンツデータでMTEntriesWithSubCategoriesの代替テンプレートタグを紹介します。

1.問題点

コンテンツデータでMTEntriesWithSubCategoriesと同等のタグ(MTContentsWithSubCategories)はありません。

ということで、コンテンツデータでMTEntriesWithSubCategoriesの代替テンプレートタグを紹介します。

2.前提条件

  • コンテンツタイプ名:products
  • コンテンツタイプに設定しているコンテンツフィールドのカテゴリセット名:field_category
  • カテゴリセット名:category
  • カテゴリセットの構造:下記(2階層まで)
cat1
  cat1-1
  cat1-2
  cat1-3

3.代替テンプレートタグ(親カテゴリが1つの場合)

赤字の部分は自由に書き換えてください。

<mt:CategorySets name="category">
  <mt:TopLevelCategories>
    <mt:HasParentCategory>
      <mt:setvarblock name="all"><mt:var name="all"> OR <mt:var name="top">/<mt:CategoryLabel></mt:setvarblock>
    </mt:HasParentCategory>
    <mt:HasNoParentCategory>
      <mt:CategoryLabel setvar="top">
      <mt:setvarblock name="all"><mt:var name="top"></mt:setvarblock>
    </mt:HasNoParentCategory>
    <mt:SubCatsRecurse>
  </mt:TopLevelCategories>
</mt:CategorySets>
 
<mt:Contents content_type="products" field:field_category="$all">
    <mt:ContentLabel><br />
</mt:Contents>

4.3の解説

テンプレートタグの前半で次のようなカテゴリ名の一覧を取得します。

cat1 OR cat1/cat1-1 OR cat1/cat1-2 OR cat1/cat1-3

この文字列を、後半のmt:Contentsタグの"field:field_category"オプションの値に設定します。

5.代替テンプレートタグ(親カテゴリが2つの場合)

赤字の部分は自由に書き換えてください。

<mt:setvar name="counter" value="0">
 
<mt:CategorySets name="category">
  <mt:TopLevelCategories>
    <mt:HasParentCategory>
      <mt:setvarblock name="all[$counter]"><mt:var name="all[$counter]"> OR <mt:var name="top">/<mt:CategoryLabel></mt:setvarblock>
    </mt:HasParentCategory>
    <mt:HasNoParentCategory>
      <mt:setvar name="counter" op="++">
      <mt:CategoryLabel setvar="top">
      <mt:setvarblock name="all[$counter]"><mt:var name="top"></mt:setvarblock>
    </mt:HasNoParentCategory>
    <mt:SubCatsRecurse>
  </mt:TopLevelCategories>
</mt:CategorySets>
 
<mt:setvarblock name="filter"><mt:Var name="all" index="1"> OR <mt:Var name="all" index="2"></mt:setvarblock>
 
<mt:Contents content_type="products" field:field_category="$filter">
  <mt:ContentField content_field="BookTitle"><mt:ContentFieldValue></mt:ContentField>
</mt:Contents>

6.5の解説

CategorySetsタグの中で、次のようなカテゴリ名の一覧を、親カテゴリ単位に配列の変数に取得します。

cat1 OR cat1/cat1-1 OR cat1/cat1-2 OR cat1/cat1-3

取得した配列変数をORで連結して、さきほどと同様、後半のmt:Contentsタグの"field:field_category"オプションの値に設定します。

親カテゴリが3つ以上の場合は、

<mt:setvarblock name="filter"><mt:Var name="all" index="1"> OR <mt:Var name="all" index="2"></mt:setvarblock>

の部分について、赤字で示す、

<mt:setvarblock name="filter"><mt:Var name="all" index="1"> OR <mt:Var name="all" index="2"> OR <mt:Var name="all" index="3"></mt:setvarblock>

のように増やしてください(もうちょっとエレガントな方法はあると思いますが)。

Comments [0] | Trackbacks [0]

XML::Simpleのインストールでエラーになる場合の対処

January 11,2022 11:55 PM
Category:[Perl]
Tag:[Perl]
Permalink

PerlのXML::Simpleのインストールでエラーになる場合の対処方法を紹介します。

モジュールはyum等ではなく、makeでインストールしています。

1.問題点

XML::Simpleをインストールしましたが、エラーになります。

下記のスクリプトを実行します。

#!/usr/bin/perl
 
use XML::Simple;
 
$file = './test.xml';
my $data = XMLin($file);

実行結果

# ./test.pl
XMLin() requires either XML::SAX or XML::Parser at ./test.pl line 6
XML::Simple called at ./test.pl line 6

ということで、PerlのXML::Simpleのインストールでエラーになる場合の対処方法を紹介します。

2.対処

エラーの内容より、XML::SAXまたはXML::Parserが必要みたいなのでインストールします。

なおXML::Parserはexpat-develのインストールが必要なようです。ここではXML::SAXをインストールします。

https://metacpan.org/pod/XML::Parser

からtar.gzファイルをダウンロードして展開し、

# perl Makefile.PL

でMakefileを生成します。

# make
cp lib/XML/SAX/PurePerl/EncodingDetect.pm blib/lib/XML/SAX/PurePerl/EncodingDetect.pm
cp lib/XML/SAX/PurePerl/Reader/UnicodeExt.pm blib/lib/XML/SAX/PurePerl/Reader/UnicodeExt.pm
cp lib/XML/SAX/PurePerl/Reader/Stream.pm blib/lib/XML/SAX/PurePerl/Reader/Stream.pm
  :
Manifying blib/man3/XML::SAX::PurePerl.3pm
Manifying blib/man3/XML::SAX::DocumentLocator.3pm
# make install
Installing /usr/local/share/perl5/XML/SAX.pm
Installing /usr/local/share/perl5/XML/SAX/Intro.pod
Installing /usr/local/share/perl5/XML/SAX/ParserFactory.pm
  :
Can't locate XML/SAX/Exception.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /usr/local/share/perl5/XML/SAX/ParserFactory.pm line 12.
BEGIN failed--compilation aborted at /usr/local/share/perl5/XML/SAX/ParserFactory.pm line 12.
Compilation failed in require at /usr/local/share/perl5/XML/SAX.pm line 18.
BEGIN failed--compilation aborted at /usr/local/share/perl5/XML/SAX.pm line 18.
Compilation failed in require.
BEGIN failed--compilation aborted.
make: *** [install_sax_pureperl] エラー 2

エラーが発生したので、さらにXML/SAX/Exception.pm(XML-SAX-Base-1.09)をインストールします。

https://metacpan.org/pod/XML::SAX::Exception

からtar.gzファイルをダウンロードして展開し、

# perl Makefile.PL

でMakefileを生成します。

# perl Makefile.PL
Checking if your kit is complete...
Looks good
Writing Makefile for XML::SAX::Base
# make
cp BuildSAXBase.pl blib/lib/XML/SAX/BuildSAXBase.pl
cp lib/XML/SAX/Base.pm blib/lib/XML/SAX/Base.pm
cp lib/XML/SAX/Exception.pm blib/lib/XML/SAX/Exception.pm
Manifying blib/man3/XML::SAX::Base.3pm
Manifying blib/man3/XML::SAX::BuildSAXBase.3pm
Manifying blib/man3/XML::SAX::Exception.3pm
# make test
PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/00basic.t ............. ok
t/01exception.t ......... ok
t/01simpledriver.t ...... ok
  :
t/16gethandlers.t ....... ok
t/release-pod-syntax.t .. skipped: these tests are for release candidate testing
All tests successful.
Files=19, Tests=137,  1 wallclock secs ( 0.09 usr  0.03 sys +  0.50 cusr  0.09 csys =  0.71 CPU)
Result: PASS
# make install
Installing /usr/local/share/perl5/XML/SAX/Exception.pm
Installing /usr/local/share/perl5/XML/SAX/Base.pm
Installing /usr/local/share/perl5/XML/SAX/BuildSAXBase.pl
Installing /usr/local/share/man/man3/XML::SAX::BuildSAXBase.3pm
Installing /usr/local/share/man/man3/XML::SAX::Base.3pm
Installing /usr/local/share/man/man3/XML::SAX::Exception.3pm
Appending installation info to /usr/lib64/perl5/perllocal.pod

XML-SAX-Baseインストール後に再度XML-SAXのmake testを実施します。

# make test
PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/00basic.t ....... Can't locate XML/NamespaceSupport.pm in @INC (@INC contains: /root/hoge/XML-SAX-1.02/blib/lib /root/hoge/XML-SAX-1.02/blib/arch /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /root/hoge/XML-SAX-1.02/blib/lib/XML/SAX/PurePerl.pm line 20.

エラーが発生したので、さらにXML/NamespaceSupport.pmをインストールします。

https://metacpan.org/pod/XML::NamespaceSupport

からtar.gzファイルをダウンロードして展開し、

# perl Makefile.PL

でMakefileを生成します。

# perl Makefile.PL
Checking if your kit is complete...
Looks good
Writing Makefile for XML::NamespaceSupport
# make
cp lib/XML/NamespaceSupport.pm blib/lib/XML/NamespaceSupport.pm
Manifying blib/man3/XML::NamespaceSupport.3pm
# make test
PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/00base.t .. ok
All tests successful.
Files=1, Tests=49,  0 wallclock secs ( 0.03 usr  0.01 sys +  0.02 cusr  0.00 csys =  0.06 CPU)
Result: PASS
# make install
Installing /usr/local/share/perl5/XML/NamespaceSupport.pm
Installing /usr/local/share/man/man3/XML::NamespaceSupport.3pm
Appending installation info to /usr/lib64/perl5/perllocal.pod

XML-NamespaceSupportインストール後に再度XML-SAXのmake testを実施します。

# make test
PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/00basic.t ....... ok
t/01known.t ....... ok
t/10xmldecl1.t .... ok
  :
t/42entities.t .... ok
t/99cleanup.t ..... ok
All tests successful.
Files=16, Tests=113,  2 wallclock secs ( 0.08 usr  0.03 sys +  1.60 cusr  0.18 csys =  1.89 CPU)
Result: PASS
# make install
Appending installation info to /usr/lib64/perl5/perllocal.pod
could not find ParserDetails.ini in /usr/local/share/perl5/XML/SAX

これでインストールでき、冒頭のスクリプトも正常に動作しました。

Comments [0] | Trackbacks [0]

Workflowプラグイン(コンテンツタイプ別の権限設定対応・その他)

December 27,2021 11:55 PM
Category:[ワークフロー]
Tag:[MovableType, Plugin, Workflow]
Permalink

現在販売中のWorkflowプラグイン(MT7版すべてのグレード)について、コンテンツタイプ別の権限設定に対応しました。

1.追加機能

ロール編集画面に「コンテンツデータの作成(承認つき)」および「コンテンツデータの承認」権限を追加しました。

ロール編集画面

この権限を選択した場合、すべてのサイトに適用されます(注:他のユーザーのコンテンツデータも一覧に表示)

また、ロール編集画面のコンテンツタイプ別の権限設定欄にも、「コンテンツデータの作成(承認つき)」および「コンテンツデータの承認」権限を追加しました。

ロール編集画面のコンテンツタイプ別の権限設定欄

この権限を利用した場合、適用したコンテンツタイプのみがユーザーの左メニューに表示されます。

また、「コンテンツデータの作成(承認つき)」を適用したロールのユーザーは、コンテンツデータ一覧には自分のコンテンツデータしか表示されなくなります。

今回の変更により、コンテンツタイプ処理の権限チェックを大幅に見直しました。

たとえば、コンテンツタイプAとコンテンツタイプBがあり、

  1. 承認者ロールX:コンテンツタイプAの承認権限
  2. 承認者ロールY:コンテンツタイプBの承認権限
  3. 承認者ロールZ:コンテンツタイプA・Bの承認権限

という紐づけを行っている場合、ライターがコンテンツデータAの作成を行い、承認依頼を行えるのは、承認者ロールX・Zのユーザーのみに制限されます。

もう少し複雑な設定で、多段階承認で同順位の承認者に上記のように異なる権限の承認者が混在していても、該当のコンテンツタイプに権限のない承認者に承認依頼メールは送信しないようにすることも可能です(=承認依頼時のチェックボックスが非表示になります)。ただし承認・差し戻し時のCcメールは送信されます。

2.その他の追加機能

ライターの編集画面で削除ボタン表示・非表示をプラグイン設定画面で選択可能にしました(お客様によって要望が異なるため)。

ロール作成で、ライター・承認者のロール名を自由に設定できるようにしました。

「多段階+グループ複数承認版」で、承認者が他グループの記事・コンテンツデータを開いた場合、「グループの承認者に属していません。」という警告を表示します。

承認者を設定する前に「ライター(承認つき)」のユーザーが記事を作成しようとした場合、「承認者が設定されていません。」という警告を表示します。

今回の機能追加に伴い、マニュアルも一部見直しました。

3.評価版ダウンロード・購入

評価版ダウンロード・ご購入はWorkflowプラグインのページにアクセスしてください。

Comments [0] | Trackbacks [0]

MTContentNextタグ、MTContentPreviousタグを出力ファイル名(ベースネーム)でソートする方法

December 14,2021 11:55 PM
Category:[コンテンツタイプ]
Tag:[MovableType]
Permalink

MT7のMTContentNextタグ、MTContentPreviousタグを出力ファイル名(ベースネーム)でソートする方法を紹介します。

1.問題点

MTContentNextタグ、MTContentPreviousタグは、デフォルトの機能では「出力ファイル名」でソートすることができないようです。

公式ページでは、MTContentNextタグ、MTContentPreviousタグに設定できるdate_fieldモディファイアの説明として次のようになっています。

'modified_on', 'authored_on', 'created_on' または 日付/時刻型のフィールドの ID, ユニークID, または名前を指定すると、指定されたフィールドの日時よりも新しいコンテンツデータを呼び出します。指定がない場合は、authored_onが利用されます。

ということで、別の手段を使って出力ファイル名でソートする方法を紹介します。

2.出力ファイル名でソートする

ここではMTContentNextタグ、MTContentPreviousタグの代わりに、テンプレートタグを使ってソートする方法を紹介します。

テンプレートは下記になります。このテンプレートをコンテンツタイプアーカイブの任意の位置に設定してください。赤字の「コンテンツタイプ名」には自コンテンツタイプ名を設定してください。

<mt:ContentIdentifier setvar="identifier">
<mt:setvar name="flag" value="0">
<mt:Contents content_type="コンテンツタイプ名" lastn="0" sort_by="identifier" sort_order="ascend">
  <mt:if name="flag" eq="1">
    <mt:setvarblock name="prev_page"><a href="<mt:ContentPermalink>">前のページ</a></mt:setvarblock>
    <mt:setvar name="flag" value="2">
  <mt:elseif name="flag" eq="0">
    <mt:if tag="ContentIdentifier" eq="$identifier">
      <mt:setvar name="flag" value="1">
    <mt:else>
      <mt:setvarblock name="next_page"><a href="<mt:ContentPermalink>">次のページ</a></mt:setvarblock>
    </mt:if>
  </mt:if>
</mt:Contents>
<mt:var name="next_page"> | <mt:var name="prev_page">

3.解説

まず、コンテンツアーカイブページの出力ファイル名をsetvarモディファイアで変数identifierに保持します。

<mt:ContentIdentifier setvar="identifier">

フラグとして使う変数flagに0を設定します。

<mt:setvar name="flag" value="0">

コンテンツデータの情報を取得するブロックタグを実行します。「sort_by="identifier"」を設定しているので、出力ファイル名でソートされます。

<mt:Contents content_type="コンテンツタイプ名" lastn="0" sort_by="identifier" sort_order="ascend">
    :
</mt:Contents>

ブロックタグ内部でMTIfタグを実行します。フラグはまだ0なのでブロック内は実行されません。

  <mt:if name="flag" eq="1">

次にMTElseIfタグを実行します。

  <mt:elseif name="flag" eq="0">

フラグは0なので、MTElseIfブロック内部を実行します。

MTElseIfブロック内部はさらにMTIf文になっています。

    <mt:if tag="ContentIdentifier" eq="$identifier">
      <mt:setvar name="flag" value="1">
    <mt:else>
      <mt:setvarblock name="next_page"><a href="<mt:ContentPermalink>">次のページ</a></mt:setvarblock>
    </mt:if>

MTContentsブロックタグ内で実行している出力ファイル名(tag="ContentIdentifier"の部分)が、現在再構築中のページの出力ファイル名(変数identifier)と等しいか判定します。

    <mt:if tag="ContentIdentifier" eq="$identifier">

等しくなければ、MTElseタグのブロックを実行し、MTContentsブロックタグ内で実行している出力ファイル名を使ったリンクを変数next_pageに保持します。この処理はMTIfタグの出力ファイル名がマッチするまで毎回実施します。つまりマッチする直前のリンクを取得している訳です。

    <mt:else>
      <mt:setvarblock name="next_page"><a href="<mt:ContentPermalink>">次のページ</a></mt:setvarblock>

出力ファイル名がマッチすると、変数flagに1を設定します。

    <mt:if tag="ContentIdentifier" eq="$identifier">
      <mt:setvar name="flag" value="1">

このMTIf文は変数flagが0の場合しか実行されないので、これでMTIf文の処理を終了します。

変数flagが1となったので、外側のMTIfタグブロックが実行され、MTContentsブロックタグ内で実行している出力ファイル名をリンクとして変数prev_pageに保持します。このリンクはつまり、マッチした直後のリンクとなります。さらに変数flagに2を設定します。

  <mt:if name="flag" eq="1">
    <mt:setvarblock name="prev_page"><a href="<mt:ContentPermalink>">前のページ</a></mt:setvarblock>
    <mt:setvar name="flag" value="2">

これでMTContentsブロックタグ内の処理は行われなくなります。

MTContentsブロックタグを抜け、最後に、変数next_pageと変数prev_pageの内容(前後ページのリンク)を出力します。

<mt:var name="next_page"> | <mt:var name="prev_page">

前後ページのリンクはMTContentsブロック内部で表示する方法もあると思いますが、出力ファイル名が最後にマッチした場合など制御が複雑になりそうなので、MTContentsブロック終了後に表示するようにしました。

Comments [0] | Trackbacks [0]

Movable Typeの本文フィールドの表示オプションを有効にしたりドラッグできるようにする「BodyFieldCustomizerプラグイン」(MT7版)

December 8,2021 11:55 PM
Category:[記事投稿・編集]
Tag:[]
Permalink

Movable Typeで本文・追記フィールドの動作をカスタマイズする「BodyFieldCustomizerプラグイン」を公開します。

このプラグインは以前公開した「BodyFieldCustomizerプラグイン」のMT7版です。

1.機能

ブログ記事またはウェブページの本文・追記フィールドの表示オプションを有効にします。

プラグイン適用前
プラグイン適用前

プラグイン適用後
プラグイン適用前

また、本文・追記フィールドをドラッグできるようにします。

プラグイン適用前(クリックで拡大)
プラグイン適用前

プラグイン適用後(クリックで拡大)
プラグイン適用前

それぞれの機能は独立して選択できます。両方を同時に利用することも可能です。

2.価格

価格:\5,000-(税別)/1インストールMT(購入前に必ず動作確認してください)

上記リンクよりご購入後、プラグイン製品版のダウンロードURLをメールにてご連絡致します。

3.ダウンロード・インストール

展開した中にあるBodyFieldCustomizerフォルダをpluginsディレクトリにアップロードしてください。

システム管理画面の「ツール」→「プラグイン」で「BodyFieldCustomizer~」が表示されればインストール完了です。

プラグイン設定画面

4.プラグインの設定

プラグインを適用したいウェブサイト・ブログの「ツール」→「プラグイン」をクリックし、「BodyFieldCustomizer」→「設定」をクリックして、利用したい機能を選択し、「変更を保存」をクリックします。

プラグイン設定画面

Comments [0] | Trackbacks [0]

MT7のTinyMCE5にボタンを追加する方法

December 7,2021 12:03 AM
Category:[TinyMCE]
Tag:[TinyMCE]
Permalink

これは「Movable Type Advent Calendar 2021」7日目の記事です。

MT7のTinyMCE5にボタンを追加する方法を紹介します。

注:プラグインではなく、ファイルを直接編集しています。

ここでは、wysiwygモードではなく、HTML編集モードに切り替えた場合のh2要素および、h3要素用のボタンを追加してみます。

変更前
変更前

変更後
変更後

たまにはこういうエレガントでない、ゴリゴリのカスタマイズもいいんじゃないかと(笑)。

カスタマイズの前提として、TinyMCE5のプラグインを有効にしておいてください。

1.ボタン表示の設定

まず、ボタンを表示する設定です。

mt-static/plugins/TinyMCE5/lib/js/adapter.js

に"plugin_mt_source_buttons2"を追加します。

       :
            // Buttons using in source mode.
            plugin_mt_source_buttons1:'mt_source_bold mt_source_italic mt_source_blockquote mt_source_unordered_list mt_source_ordered_list mt_source_list_item | mt_source_link mt_insert_file mt_insert_image | mt_fullscreen',
            plugin_mt_source_buttons2:'mt_source_h2 mt_source_h3',
            // Buttons using in wysiwyg mode.
            plugin_mt_wysiwyg_buttons1:'bold italic underline strikethrough | blockquote bullist numlist hr | link unlink | mt_insert_html mt_insert_file mt_insert_image | table',
       :

追加する名前(mt_source_h2、mt_source_h3)は任意の名称でOKです。

複数のボタンを追加する場合、半角スペースで区切ります。区切り線を入れたい場合は、パイプ"|"を記述します(こちらも半角スペース区切り)。

また、同じファイルの変数suffixへの代入をコメントアウトします。

    var suffix = '';
    if(jQuery('script[src*="tinymce.min"]').length){
        // min
//        suffix = '.min';
    }

この設定をしておかないと、次項で設定するファイルのファイル名がplugin.min.jsになってしまいます。

2.ボタン定義の追加

1項で追加しようとしているボタンの定義を追加します。具体的には、

mt-static/plugins/TinyMCE5/lib/js/tinymce/plugins/mt/plugin.js

の"ed.addMTButton"が並んでいる一番最後に、下記の赤色部分を追加します。

       :
          ed.addMTButton('mt_source_h2', {
              tooltip : 'source_h2',
              text : '&lt;h2&gt;',
              mtButtonClass: 'text',
              toggle: true,
              onclickFunctions : {
                  source: 'h2'
              }
          });
 
          ed.addMTButton('mt_source_h3', {
              tooltip : 'source_h3',
              text : '&lt;h3&gt;',
              mtButtonClass: 'text',
              toggle: true,
              onclickFunctions : {
                  source: 'h3'
              }
          });
 
/*
          var filterd_attrs = [];
          var regexp = new RegExp(/^on|action/);
       :

addMTButton()の第1パラメータには1項で設定した名称を指定します。

第2パラメータのハッシュの意味は次の通りです。

  • tooltip:ツールチップ(指定した名称を使って、さらに3項のファイルで表示内容を定義)
  • text:表示するボタン
  • mtButtonClass:ボタンのクラス。ここでは"text"固定
  • toggle:"true"にすると、終了タグを挿入するまでボタン色が反転
  • onclickFunctions:クリックしたときの動作。指定した名称で別ファイルに定義

3.ツールチップの設定

mt-static/plugins/TinyMCE5/lib/js/tinymce/plugins/mt/langs/plugin.js

に、下記の赤色部分を追加します。

       :
    // HTML mode
    "source_bold": trans('Strong Emphasis'),
    "source_italic": trans('Emphasis'),
    "source_blockquote": trans('Block Quotation'),
    "source_unordered_list": trans('Unordered List'),
    "source_ordered_list": trans('Ordered List'),
    "source_list_item": trans('List Item'),
    "source_h2": 'h2要素',
    "source_h3": 'h3要素',
       :

キーは2項の"tooltip"の内容を設定し、値には表示させたい文字列を設定します。

値の部分は、本来、

trans('...')

と記述してローカライズに対応すべきですが、ここでは表示させたい文字列を直接記述しています。

4.クリック時の動作を追加

準備が少し面倒です。

編集するファイルは、

mt-static/js/editor.js

なのですが、改行やスペース文字が除去されていて、編集がやや難しいです。

ということで、私は、editor.jの内容を

https://beautifier.io/

で一旦整形し、editor.jsに上書きしてから作業しました(元の内容はバックアップしておいてください)。

ここではその前提で話を進めます。

mt-static/js/editor.js

に、下記の赤色部分を追加します。追加位置は"MT.EditorCommand.Source.prototype.commands['default']"がある行の直後です。

       :
    MT.EditorCommand.Source.prototype.commands['default'] = {
        h2: function(command, userInterface, argument, text) {
            this.execEnclosingCommand(command, '<h2>', '</h2>', text);
        },
        h3: function(command, userInterface, argument, text) {
            this.execEnclosingCommand(command, '<h3>', '</h3>', text);
        },
        fontSizeSmaller: function(command, userInterface, argument, text) {
            this.execEnclosingCommand(command, '<small>', '</small>', text);
        },
       :

ハッシュのキー"h2"や"h3"は、2項の"onclickFunctions"のハッシュキー"source"の値と対応させてください。

"function(command, userInterface, argument, text)"の部分は何も考えずにそのまま使ってください。編集が必要なのはexecEnclosingCommand()の第2、第3パラメータの開始タグ名と終了タグ名のみです。

execEnclosingCommand()は、選択文字列がある場合は自動的にタグで括り、選択文字列がない場合は開始タグを挿入(ボタンが反転)、文字を入力してもう一度ボタンをクリックすれば終了タグを挿入してくれるという、便利関数です。

この関数は、

mt-static/js/editor.js

に実装されています。

クリック時の挙動を変更したい場合は、独自関数をここに書いてもいいでしょう。

これでブラウザをリロードしてHTML編集モードに切り替えれば、冒頭のボタンが表示されると思います。

5.その他

TinyMCEをカスタマイズするときはブラウザの開発者モード(F12)を有効にしておくと、typo等はコンソールにエラーが表示されるので便利です。

Comments [0] | Trackbacks [0]

MTの記事一覧をタイトル順に並び替える「SortByTitle」プラグイン

November 30,2021 11:55 PM
Category:[記事一覧]
Tag:[MovableType, Plugin, SortByTitle]
Permalink

MTの記事一覧をタイトル順に並び替える「SortByTitle」プラグインを公開します。

1.機能

MTの記事一覧はデフォルト「公開日」でソートされます。

「公開日」でソート

本プラグインを適用することでデフォルトのソートを「タイトル」に変更できます。

「タイトル」でソート

2.プラグインのダウンロード・インストール

下記のリンクをクリックして、SortByTitleのプラグインアーカイブをダウンロードします。

SortByTitle_0_01.zip

プラグインアーカイブを展開し、pluginsフォルダにあるSortByTitleフォルダをMovable Typeのアプリケーションディレクトリのpluginsディレクトリにアップロードします。

システム管理画面のプラグイン設定画面で「SortByTitle~」が表示されればインストール完了です。

プラグイン設定画面

Comments [0] | Trackbacks [0]

スマホのPDFファイルなどをセブンイレブンのネットプリントで出力する方法

November 12,2021 11:55 PM
Category:[スマートフォン]
Tag:[netprint]
Permalink

スマホに保存したPDFファイル等を、セブンイレブンのネットプリントで出力する方法を紹介します。

「かんたんnetprint」アプリをインストール

「かんたんnetprint」アプリ

インストール後、アプリを起動。「次へ」をタップ。

アプリを起動

「次へ」をタップ。

STEP1

「始める」をタップ。

STEP2

利用規約に「同意する」をタップ。

利用規約

右下の「+」アイコンをタップ。

「+」アイコンをタップ

「文書ファイルから選ぶ」をタップ。

文書ファイルから選ぶ

文書ファイルが表示されるのでプリントしたい文書をタップ。ここでは「Acrobat」アプリに保存していたPDFを選択します。

PDFを選択

用紙サイズ・カラーモード等を設定して、右上の「登録」をタップ

登録

これで登録されました。

登録完了

「アップロード完了」を閉じると予約番号の取得に切り替わります。

予約番号の取得

これで予約番号が取得できました。

予約番号取得

前の画面にある「プリント手順」をタップすると、コピー機でのプリント手順が表示されます。

コピー機でのプリント手順

これでますますPCが不要になりそうです。

Comments [0] | Trackbacks [0]

CSVDataImExporterプラグイン(ブロックエディタ対応)

October 19,2021 11:55 PM
Category:[インポート・エクスポート]
Tag:[]
Permalink

現在販売中のCSVDataImExporterプラグイン(MT7コンテンツデータ対応版)について、ブロックエディタに対応しました。

1.追加機能

コンテンツタイプ(コンテンツデータ)の「テキスト(複数行)」で「入力フォーマット」が「ブロックエディタ」の場合のエクスポート・インポートが可能となりました。

CSVDataImExporterプラグイン(ブロックエディタ対応)

ブロックエディタはYAML形式でエクスポートされます。

CSVDataImExporterプラグイン(ブロックエディタ対応)

YAMLのフォーマットについては販売ページのマニュアルに記載予定です。

2.対応グレード

ブロックエディタ対応は、MT7コンテンツデータ対応(通常版および機能拡張版)で提供致します。

価格は据え置きです。

3.評価版ダウンロード・購入

評価版のダウンロード・ご購入はCSVDataImExporterプラグインのページにアクセスしてください。

「CSVDataImExporterプラグイン」のページ
「CSVDataImExporterプラグイン」のページ

Comments [0] | Trackbacks [0]

YAML::Tinyで「YAML::Tiny found bad indenting in line~」というエラーになる場合の対処

October 12,2021 11:55 PM
Category:[Perl]
Tag:[YAML]
Permalink

PerlのYAML::Tinyで「YAML::Tiny found bad indenting in line~」というエラーになる場合の対処方法を紹介します。

1.問題点

YAML::Tinyを使って下記のYAMLを読み込ませました。

test:
    type: text
    order: 1
    value: |
hello

が、読み込ませたところ、「YAML::Tiny found bad indenting in line 'hello' at」というエラーが発生しました。

エラーの内容的にインデントが間違っているようですが、YAMLのお作法的には間違っていないと思われます。

ということで、YAML::Tinyで「YAML::Tiny found bad indenting in line~」というエラーになる場合の対処方法を紹介します。

2.対処方法

YAML::Tinyで複数行を記述する場合、インデントをつけて、

test:
    type: text
    order: 1
    value: |
        hello

とする必要があります。

複数行も場合も、

test:
    type: text
    order: 1
    value: |
        hello1
        hello2
        hello3

とする必要があるようです。

Comments [0] | Trackbacks [0]

bashでPostgreSQLのselect結果を出力する方法

September 28,2021 11:55 PM
Category:[bash]
Tag:[bash, PostgreSQL]
Permalink

bashでPostgreSQLのselect結果を出力する方法を紹介します。

1.問題点

PostgreSQLで次のようなデータベース・テーブルを作成し、3件のデータをinsertしました。

$ psql -q -U postgres
postgres=# create database testdb;
postgres=# \q
$ psql -q -U postgres -d testdb
testdb=# create table sample (data1 text, data2 text);
testdb=# insert into sample values ('aaa', 'xxx');
testdb=# insert into sample values ('bbb', 'yyy');
testdb=# insert into sample values ('ccc', 'zzz');
testdb=# select * from sample;
 data1 | data2
-------+-------
 aaa   | xxx
 bbb   | yyy
 ccc   | zzz
(3 行)

が、このデータをbashで出力する方法が分かりません。

ということで、bashでPostgreSQLのselect結果を出力する方法を紹介します。

2.bashでPostgreSQLのselect結果を出力する

bashでPostgreSQLのselect結果を出力するには次のようにします。

#!/bin/bash
 
psql="psql -q -U postgres -d testdb --no-align -t --field-separator"
sql="select data1, data2 from sample"
 
while IFS='|' read data1 data2 ; do
    echo $data1 $data2
done < <(echo ${sql} | ${psql} '|' -q 2>/dev/null)

実行結果

# ./test.sh
aaa xxx
bbb yyy
ccc zzz
Comments [0] | Trackbacks [0]

Movable TypeのDataAPIで記事を投稿するサンプル

September 8,2021 11:55 PM
Category:[DataAPI]
Tag:[DataAPI, MovableType]
Permalink

DataAPIで記事を投稿するサンプルを紹介します。

1.はじめに

ネットにDataAPIで記事を投稿するサンプルがないのと、サンプルがあってもログイン・ログアウトといった処理が盛り込まれていて、コードが複雑になって理解が難しいので、シンプルなものを自作してみました。

2.サンプル

下記にサンプル(ほぼほぼそのまま利用可能)を示します。ご利用前に3項と4項には必ず目を通してください。

また、コードにコメントを記載しているので、解説は省略します。

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="<$mt:StaticWebPath$>data-api/v4/js/mt-data-api.min.js"></script>
<script type="text/javascript">
function post() {
 
    // DataAPIオブジェクト生成
    var api = new MT.DataAPI({
        baseUrl: '<$mt:CGIPath$>mt-data-api.cgi',
        clientId: 'post-entry',
        sessionPath: '/',
    });
 
    // ユーザー情報
    var credential = {
        username: "ユーザー名",
        password: "パスワード",
        remember: true
    };
 
    // 認証
    api.authenticate(credential, function(response) {
        if (!response.error) {
 
            // 記事データ
            var entry = {};
            entry['title']  = $('#title').val();
            entry['body']   = $('#text_body').val();
            entry['status'] = 'Publish';
 
            // 記事投稿
            api.createEntry(<$mt:BlogID$>, entry, function(response) {
                if (response.error) {
                    alert("Error:" + response.error.code + ':' + response.error.message);
                    return;
                }
                alert("Success:" + response.title);
            });
        }
    });
}
</script>
 
<div id="entry-post">
    <form name="CreateEntry" id="CreateEntry" method="post">
        <p><input type="text" name="title" id="title" placeholder="タイトル"></p>
        <p><textarea name="text_body" id="text_body" placeholder="本文"></textarea></p>
        <p><input type="submit" onclick="post(); return false;" value="投稿"></p>
    </form>
</div>

3.使い方

上記のコードをインデックステンプレートにペーストして、下記の赤色部分について、任意のユーザー・パスワードに書き換えてください。

    // ユーザー情報
    var credential = {
        username: "ユーザー名",
        password: "パスワード",
        remember: true
    };

テンプレートを再構築してページにアクセスすればフォームが表示されるので、タイトルと本文を入力して「投稿」をクリックすれば投稿できます。

投稿結果はJavaScriptのalertで表示します。

4.注意事項

パスワードは、ウェブサービスのパスワードを設定してください。ユーザー編集画面の「Webサービスパスワード」が該当します。

また、DataAPIを有効にするには、サイトの「設定」→「Webサービス」→「Data API」を有効にしてください。無効のまま投稿すると403エラーが発生します。

ただいシステム管理者はこの設定と無関係に投稿できるようです。

Comments [0] | Trackbacks [0]

WordPressの記事データをCSV形式でエクスポート・インポートできる「wp-csv-data-imexporterプラグイン」

September 1,2021 11:55 PM
Category:[自作プラグイン]
Tag:[Plugin, WordPress, wp-csv-data-imexporter]
Permalink

WordPressの記事データをCSV形式でエクスポート・インポートできる「wp-csv-data-imexporterプラグイン」を公開します。

1.主な機能

CSV形式で記事・固定ページ・カスタム投稿タイプのエクスポートおよびインポートが可能です。

インポートでは記事・固定ページ・カスタム投稿タイプの新規作成、あるいはID指定による上書きが可能です。

CSVデータは、カテゴリ・カスタムタクソノミー・カスタムフィールドにも対応しています。

カスタムフィールドはAdvanced Custom Fields/Smart Custom Fields/Custom Field Suiteのフィールドに対応しています。

2.CSVデータのエクスポート

左メニューの「ツール」→「CSVのエクスポート」をクリック。

CSVのエクスポート

エクスポート画面が表示されるので、投稿タイプ・CSVファイルの文字コード・ステータ等を選択して「エクスポート」をクリック。カスタム投稿タイプを利用している場合は「投稿タイプ」に表示します。

(クリックで拡大)
エクスポート画面

3.CSVデータのインポート

左メニューの「ツール」→「インポート」をクリック。

インポート

「インポーターの実行」をクリック。

インポート

アップロードファイルを選択し、「ファイルをアップロードしてインポート」をクリック。

(クリックで拡大)
エクスポート画面

これでインポートが実行されます。インポート状況は枠内に表示されます。

(クリックで拡大)
エクスポート画面

4.wp-csv-data-imexporterプラグインについて

wp-csv-data-imexporterプラグインの詳細は、下記のリンク先をご確認ください。

wp-csv-data-imexporterプラグイン
wp-csv-data-imexporterプラグイン

Comments [0] | Trackbacks [0]

Movable Typeのコンテンツデータで公開日を比較する方法

August 30,2021 11:55 PM
Category:[テンプレート]
Tag:[]
Permalink

Movable Typeのコンテンツデータで公開日を比較する方法を紹介します。

1.はじめに

この記事で紹介するテンプレートは次のとおりです。

コンテンツデータの公開日(年月日)と再構築日(年月日)を比較し、

  • 公開日より再構築日の方が古い場合:「この記事は未来のものです」を表示
  • 公開日より再構築日の方が古い場合:「この記事は過去のものです」を表示
  • 公開日と再構築日が同じ場合:「この記事は現在のものです」を表示

をそれぞれ出力します。

2.テンプレート

コンテンツデータ公開日のタイムスタンプを比較するテンプレートは下記になります。

<$mt:ContentDate format="%Y%m%d" setvar="content_date"$>
<$mt:Date format="%Y%m%d" setvar="publish_date"$>
 
<mt:If name="content_date" gt="$publish_date">
この記事は未来のものです
<mt:ElseIf name="content_date" lt="$publish_date">
この記事は過去のものです
<mt:Else eq="Date">
この記事は現在のものです
</mt:If>

このテンプレートはコンテンツタイプアーカイブに張り付けてください。

3.テンプレートの解説

まず、コンテンツデータの公開日(年月日)を、MTContentDateタグとsetvarモディファイアを使って、変数content_dateに保存します。年月日は数値として比較できるよう、formatモディファイアに"%Y%m%d"を設定し、"20210827"という風にに出力されるようにします。

<$mt:ContentDate format="%Y%m%d" setvar="content_date"$>

次に再構築された年月日を、MTDateタグとsetvarモディファイアを使って、変数publish_dateに保存します。その他は上の設定と同じです。

<$mt:Date format="%Y%m%d" setvar="publish_date"$>

保存した2つの変数を比較します。最初のMTIfタグには次のように設定します。

<mt:If name="content_date" gt="$publish_date">

MTIfタグのnameモディファイアに変数content_date、gtモディファイアに変数publish_dateを設定します。

nameモディファイアに変数を記述するときはそのままでいいですが、gtモディファイアに変数を設定する場合は変数名の前に"$"を付与してください。

これで「変数content_dateの値が変数publish_dateの値より大きいか?」という判定になります。大きい場合はMTIfタグの中の処理を実行し、

この記事は未来のものです

を出力します。

次のMTElseIfタグには次のように設定します。

<mt:ElseIf name="content_date" lt="$publish_date">

MTElseIfタグにはMTIfタグと同じように条件を設定することができます。ltモディファイアにはgtモディファイアと同じように変数の先頭んに"$"を付与します。

これで「変数content_dateの値が変数publish_dateの値より小さいか?」という判定になります。小さい場合はMTIfタグの中の処理を実行し、

この記事は過去のものです

を出力します。

最後のMTElseタグは、上記の2つの判定条件のいずれにもマッチしなかった場合(=2つの変数の値が等しい場合)に実行されます。

<mt:Else eq="Date">

この条件が実行されると、

この記事は現在のものです

を出力します。

4.注意事項

スタティックパブリッシングの場合、MTDateタグの情報を更新させるため、日毎の再構築が必要です。

Comments [0] | Trackbacks [0]

Advanced Custom FieldsでGoogleマップが表示されない場合の対処

August 17,2021 11:55 PM
Category:[トラブルシューティング]
Tag:[AdvancedCustomFields, WordPress]
Permalink

WordPressのプラグイン「Advanced Custom Fields」でGoogleマップが表示されない場合の対処方法を紹介します。

1.問題点

「Advanced Custom Fields」でGoogleマップをカスタムフィールドとして表示するよう設定しました。

(クリックで拡大)

が、投稿画面では「このページでは Google マップが正しく読み込まれませんでした。」と表示されます。

(クリックで拡大)

ということで、WordPressのプラグイン「Advanced Custom Fields」でGoogleマップが表示されない場合の対処方法を紹介します。

2.対処方法

まず、Googleのサービスを利用するためのAPIキーを作成します。

Google Cloud Platform」にアクセスし、左上のナビゲーションメニューをクリックして、「APIとサービス」→「認証情報」をクリック。

「認証情報を作成」→「APIキー」を選択(私はすでにAPIキーを作成してしまっているので、文章のみ)。

これでAPIキーが作成されるので、キー名をクリックした先にあるAPIキーをコピーしてください。

このままの状態ではAPIキーを誰でも使えてしまうので、作成されたAPIキーのリンクをクリックし、遷移したページで使用制限の設定を適宜行ってください(ここでの説明は省略します)。

次に、Google Cloud PlatformのAPIライブラリの、

  • Maps JavaScript API
  • Places API
  • Geocoding API

を有効化します。

有効化するには、先ほどの「Google Cloud Platform」にアクセスし、左上のナビゲーションメニューをクリックして、「APIとサービス」→「ライブラリ」をクリック。

「Maps JavaScript API」をクリック。

「有効にする」をクリック。これで有効化されます。

他のAPIも同様の手順で有効化してください。「Geocoding API」はAPI一覧画面右側の「すべて表示」をクリックするか。「Maps JavaScript API」を有効化したあとに表示されたAPI一覧から選択できます。

最後に、取得したキーをWordPressのfunctions.phpに設定します。

WordPressの「外観」→「テーマエディター」をクリック。

「テーマのための関数(functions.php)」をクリック。

テキストエリアの最後に下記の内容をペースト。

function my_acf_google_map_api( $api ){
    $api['key'] = 'ここにAPIキーをペースト';
    return $api;
}
 add_filter('acf/fields/google_map/api', 'my_acf_google_map_api');

これでGoogle Mapが表示されます。

(クリックで拡大)

Comments [0] | Trackbacks [0]
 1  |  2  |  3  |  4  |  5  | All pages