PostgreSQLでSQLをファイルから読み込む方法
PostgreSQLでSQLをファイルから読み込む方法を紹介します。
1.問題点
下記のようなSQLを用意しました。
select * from hoge_20220520;
select * from hoge_20220519;
:
select * from hoge_20220101;
手で投入するのは時間がかかるため、SQLをファイルに設定して、そのファイルを読み込ませたいのですが、方法が分かりません。
ということで、PostgreSQLでSQLをファイルから読み込む方法を紹介します。
2.PostgreSQLでSQLをファイルから読み込む
PostgreSQLでSQLをファイルから読み込むには、psqlのメタコマンド"\i"または"\include"で実現可能です。
具体的には下記の手順で実施します。
まず、1項のSQLをtest.sqlに設定します。
作成したtest.sqlを、SQLを実行させたいユーザーがアクセス可能なディレクトリに配置します。
たとえばpostgresユーザーでSQLを読み込ませる場合、ファイルを/var/lib/pgsqlに配置します。/rootに配置するとpostgresユーザーでは読み込めないので注意してください。
準備ができたら下記の手順でSQLファイルを読み込ませます(postgresユーザーでの実施手順で示します)。
# su - postgres
$ psql -U <ユーザ名> -d <データベース名>
$ postgres=> \i test.sql
または
$ postgres=> \include test.sql
なお、SQLの経過情報はデフォルトでは表示されません。読み取った行を画面に表示させる場合は、下記のようにECHO変数をallに設定する必要があります。
$ psql -a -U <ユーザ名> -d <データベース名>
または
$ psql --echo-all -U <ユーザ名> -d <データベース名>
lessで検索文字列だけを表示する方法
lessで検索文字列だけを表示する方法を紹介します。
例えば、大量に表示されるログの中から特定の文字列を含む行だけを確認したい場合に威力を発揮します。
1.はじめに
lessはファイルの内容を表示するコマンドです。
ファイルを開いたあと、スラッシュ+検索文字列で特定の文字列を検索することはできます。
"Failed"で検索した例
が、検索した文字列の行だけを表示する方法が分かりません。
ということで、lessで検索文字列だけを表示する方法を紹介します。
2.lessで検索文字列だけを表示する
lessで検索文字列だけを表示するには、次の手順を実施します。
まず"less ファイル名"でファイルの中身を表示します。
次に、"&"を入力します。一番下に"&/"が表示されます。
検索文字列(ここではFailed)を入力してリターンを押下します。
これで検索文字列にマッチした行のみが表示されます。
3.lessでログを表示しながら指定した文字列以外を検索する
2項の"&"の代わりに"&!"を入力します。一番下に"Non-match &/"が表示されます。
検索したくない文字列を入力してリターンを押下します。
これで文字列にマッチしない行のみ表示します。
4.追加されたデータを表示する
tail -fのように追加されたデータを表示するには、2項または3項の設定を行った後、"Shift+f"を入力します。
5.検索の解除
&または&!の解除は、"&"を入力してリターンします。
4項を実施している場合は、Ctrl-cで追加データ表示を停止して、そのあとに"&"を入力してリターンしてください。
iPhoneの文字変換で変換候補を表示する裏ワザ
iPhoneの文字変換で変換候補を表示する裏ワザを紹介します。
1.はじめに
iPhoneの文字変換で変換候補を表示する場合、右側のアイコンをタップしていると思います。
実は変換候補を表示するもうひとつの方法があります。
労力はこれと大して変わりませんが、知っているとちょっと自慢できるかもしれません。
2.変換候補を表示する
まず任意の文字を入力して変換候補を表示します。
変換候補の任意の部分を長押しします。
長押した状態で、そのまま下にスライドすると変換候補が表示されます。
あとはこれまでと同様、スクロールで変換候補を探します。
画像を下揃えにしてテキストを回り込ませる方法
画像を下揃えにしてテキストを回り込ませる方法を紹介します。
1.問題点
画像にテキストを回り込ませる方法はありますが、回り込ませたテキストの一番下の行に画像を揃える方法が分かりません。
ということで、画像を下揃えにしてテキストを回り込ませる方法を紹介します。
2.画像を下揃えにしてテキストを回り込ませる
画像を下揃えにしてテキストを回り込ませるには、HTMLとCSSを次のように設定します。
HTML
<div id="box">
<div class="fix"></div>
<div class="img"><img src="[画像のURL]" width="[画像の幅]" />/div>
~(テキスト)~
</div>
CSS
#box {
width: 600px;
}
#box .fix {
float: right;
height: 12em; /* 画像上部の余白 */
}
#box .img {
float: right;
clear: both;
margin: 10px 0 0 10px;
}
要するに、class属性fixの高さ分だけ画像を下にずらしています。
Movable Typeのデータ更新を抑止する「DataUpdateSuppressorプラグイン」
Movable Typeのデータ更新を抑止する「DataUpdateSuppressorプラグイン」を公開します。
1.機能
プラグインの設定で、下記の機能を抑止します。
- 記事の作成・更新・削除
- ウェブページ作成・更新・削除
- コンテンツデータ作成・更新・削除
- カテゴリ追加・削除
- カテゴリセット作成・追加・削除
- フォルダ追加・削除
- コンテンツタイプ作成・更新・削除
- テンプレート(グローバルテンプレート含む)
- カスタムフィールド(システム含む)
- アイテムアップロード
- アイテムの編集
- ユーザー作成・更新
- グループ作成・更新
- サイト作成
大規模サイトのメンテナンス等でデータ更新を抑止したいケースを想定しています。
抑止した場合、ユーザーがデータ保存を実行したときに、任意のエラーメッセージを表示することが可能です。
2.使い方
更新を抑止したい場合、システム管理画面またはサイト管理画面の「プラグイン」→「DataUpdateSuppressor」→「設定」の「更新抑止」を選択して保存してください。また「MTユーザへのメッセージ」に表示させたいメッセージを設定します。
3.その他
プラグインの詳細は「DataUpdateSuppressorプラグイン」のページをご確認ください、
tailコマンドでファイルがローテートされても追従する方法
tailコマンドでファイルがローテートされても追従する方法を紹介します。
1.問題点
tailコマンドでapacheのファイルを監視しています。
# cd /etc/httpd/logs/
# tail -f access_log
ログがローテートされると監視が途切れてしまいますが、方法が分かりません。
ということで、tailコマンドでファイルがローテートされても追従する方法を紹介します。
2.tailコマンドでファイルがローテートされても追従する
tailコマンドでファイルがローテートされても追従するには"-F"オプションを使用します。
# cd /etc/httpd/logs/
# tail -F access_log
3.サンプル
下記のサンプルで追従することを確認できます。
ターミナルAでファイル「test.txt」に任意の文字を書き込み、ターミナルBでtailを開始します。
ターミナルA
# echo foo > test.txt
ターミナルB
# tail -F test.txt
foo
ファイル名を変更します。tailしているターミナルに「~はアクセス不能になりました」という警告が表示されますが、そのままで問題ありません。
ターミナルA
# mv test.txt test_old.txt
ターミナルB
tail: `test.txt' はアクセス不能になりました: そのようなファイルやディレクトリはありません
再び元のファイル名に書き込むと、tailが再開します。
ターミナルA
# echo bar > test.txt
ターミナルB
# tail -F test.txt
bar
4.その他の方法
tailのバージョンによっては"-F"がサポートされていない場合がありますので、manコマンドでご確認ください。
"-F"がサポートされていない場合は、"--follow=name --retry"でも同様の動作になります。
# tail --follow=name --retry test.txt
"--follow=name"は、指定したファイル名に追従するオプションです。
"--retry"は、指定したファイルに対し何度もファイルオープンを試みるオプションです。
"--follow=name --retry"と"-F"は等価のようです。
なおこちらで動作を確認したところ、"--retry"は指定しなくても大丈夫かもしれません。
# tail --follow=name test.txt
色々ためしてみてください。
Perlで「Subroutine permission redefined at~」を抑止する方法
Perlで「Subroutine permission redefined at~」を抑止する方法を紹介します。
1.問題点
Perlde定義済の関数を上書きすると、
Subroutine permission redefined at~
というワーニングが表示されます。
このワーニングを抑止したいのですが方法がわかりません。
ということで、Perlで「Subroutine permission redefined at~」を抑止する方法を紹介します。
2.「Subroutine permission redefined at~」を抑止する
「Subroutine permission redefined at~」を抑止するには、関数の上書きを行っている個所の前に、下記を追加します。
use warnings;
no warnings 'redefine';
解決しない場合は、上書きされている方の関数の直前に、上の2行を記述してみてください。
svnでファイルやディレクトリを削除する方法
svnでファイルやディレクトリを削除する方法を紹介します。
1.問題点
下記の手順でディレクトリとファイルをリポジトリに追加しました。
# mkdir foo
# svn add foo
# svn commit -m '' foo
# cd foo
# touch test.txt
# svn add test.txt
# svn commit -m '' test.txt
この、fooとtest.test.txtをリポジトリから削除したいのですが方法がわかりません。
ということで、svnでファイルやディレクトリを削除する方法を紹介します。
2.svnでファイルやディレクトリを削除する
ァイルやディレクトリを削除するには、deleteとcommitで実施します。
# cd foo
# rm -f test.txt
# svn delete test.txt
# svn commit -m '' test.txt
# cd ..
# rmdir foo
# svn delete foo
# svn commit -m '' foo
これでリポジトリから削除されます。
Rubyで実行ラインのトレース結果をファイルに出力する方法
業務の都合でRubyを調べることになりました。
最初に、Rubyで実行ラインのトレース結果をファイルに出力する方法を紹介します。
1.問題点
下記の簡単なRubyスクリプトを書きました。
foo = 123
このスクリプトのトレース結果を出力させたいのですが、方法が分かりません。
ということで、Rubyで実行ラインをトレースしてファイルに出力する方法を紹介します。
2.Rubyで実行ラインをトレースしてファイルに出力する方法
標準出力に表示するには、下記の赤字部分を追加します。
require 'tracer'
Tracer.on
foo = 123
Tracer.off
実行結果
# ruby test.rb
#0:test.rb:4::-: foo = 123
#0:test.rb:6::-: Tracer.off
ファイルに表示するには、下記の赤字部分を追加します。
require 'tracer'
fp = File.open('/tmp/foo.txt', "w")
Tracer.stdout = fp
Tracer.on
foo = 123
Tracer.off
実行後の出力ファイル
# cat /tmp/foo.txt
#0:test.rb:6::-: foo = 123
#0:test.rb:8::-: Tracer.off
3.解説
トレーサ用のライブラリを読み込みます。
require 'tracer'
トレース出力を開始したいポイントに「Tracer.on」を記述します。
Tracer.on
トレース出力を終了したいポイントに「Tracer.off」を記述します。
Tracer.off
ファイルに出力する場合は、ファイルを書き込みモードで開きます。
fp = File.open('/tmp/foo.txt', "w")
そしてファイルポインタをトレーサの標準出力先に指定すればOKです。
Tracer.stdout = fp
4.注意事項
Tracer.on/Tracer.offは、埋め込んだ位置によって正常に動作しないようです。
bashでMySQLのselect結果を出力する方法
bashでMySQLのselect結果を出力する方法を紹介します。
1.問題点
MySQLで次のようなデータベース・テーブルを作成し、2件のデータをinsertしました。
mysql> describe foo;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(32) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> select * from foo;
+------+------+
| id | name |
+------+------+
| 1 | aaa |
| 2 | bbb |
+------+------+
2 rows in set (0.00 sec)
が、このデータをbashで出力する方法が分かりません。
ということで、bashでMySQLのselect結果を出力する方法を紹介します。
2.bashでMySQLのselect結果を出力する
bashでMySQLのselect結果を出力するには次のようにします。
#!/bin/sh
server="localhost"
database="test"
user="root"
pass="[パスワード]"
sql="select * from foo"
result=`mysql -h $server -D $database -u $user -p"$pass" -N -e "${sql}"`
echo "$result"
実行結果
# ./test.sh
1 aaa
2 bbb
PayPalにおける銀行口座への資金移動の理由
PayPalにおける銀行口座への資金移動の理由を調べてみました。
PayPalから資金移動依頼のメール(下記抜粋)が届きました。
PayPalは、世界各地で事業を展開しているすべての場所で、現地の法律および規制を遵守するよう努めています。日本の決済サービス法の改正により導入された新しい要件に基づき、弊社は日本でのサービスについて、いくつかの新しい措置を導入しました。
PayPal Japanでは、使用する予定のない資金をお客さまのPayPalアカウント残高に保持されないよう求めています。これは、原則として、お客さまが今月中に使用する予定のある残高のみを保持する必要があることを意味します。
(中略)
PayPal残高が100万円を超える場合は、毎月通知をお送りします。次の通知は2月上旬に送信されます。
資金を移動する理由がよくわからないので、2021年5月1日にリリースされたPayPalの記事を読み返してみました。
が、ここでも資金を移動する理由がよくわかりません。
ただ、資金決済法の改正が影響していることはわかりました。
さらにネットで調べたところ、こちらの記事で理由がわかりました。
「PayPayマネー」の残高上限が500万円から100万円に“減額” 6月1日以降
要約すると、下記の通りです。
まず、資金決済法改正で、資金移動業者が「第一種」「第二種」「第三種」に細分化されます。
- 第一種:認可制、取引金額に上限なし
- 第二種:登録制、取引金額は100万円まで
- 第三種:登録性、取引金額は5万円まで
さきほどの「資金決済法改正にあたってのご案内」で、PayPalのユーザー(プレミアアカウント及びビジネスアカウント)は第二種としたため、上限を100万円にせざるを得なかったものと思われます。
ちなみに、資金移動業者が第一種資金移動業者になるには、認可を取得する必要があります。
また、第一種資金移動業者には下記の滞留規制が課されます。
- 送金先や送金日時の指示がない資金の受け入れの禁止
- 資金処理に必要な期間を超える資金の滞留の禁止
上記の「『PayPayマネー』の残高上限が500万円から100万円に“減額” 6月1日以降」では、100万円を超える残高を持つユーザーは、改正法令の規定により、サービスの利便性を享受しきれなくなってしまう、と書かれており、PayPalは上記ユーザーについて利便性を重視して、第二種とする判断をされたものと思われます。
コンテンツデータでMTEntriesWithSubCategoriesの代替テンプレートタグ
コンテンツデータで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>
のように増やしてください(もうちょっとエレガントな方法はあると思いますが)。
XML::Simpleのインストールでエラーになる場合の対処
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
これでインストールでき、冒頭のスクリプトも正常に動作しました。
Workflowプラグイン(コンテンツタイプ別の権限設定対応・その他)
現在販売中のWorkflowプラグイン(MT7版すべてのグレード)について、コンテンツタイプ別の権限設定に対応しました。
1.追加機能
ロール編集画面に「コンテンツデータの作成(承認つき)」および「コンテンツデータの承認」権限を追加しました。
この権限を選択した場合、すべてのサイトに適用されます(注:他のユーザーのコンテンツデータも一覧に表示)
また、ロール編集画面のコンテンツタイプ別の権限設定欄にも、「コンテンツデータの作成(承認つき)」および「コンテンツデータの承認」権限を追加しました。
この権限を利用した場合、適用したコンテンツタイプのみがユーザーの左メニューに表示されます。
また、「コンテンツデータの作成(承認つき)」を適用したロールのユーザーは、コンテンツデータ一覧には自分のコンテンツデータしか表示されなくなります。
今回の変更により、コンテンツタイプ処理の権限チェックを大幅に見直しました。
たとえば、コンテンツタイプAとコンテンツタイプBがあり、
- 承認者ロールX:コンテンツタイプAの承認権限
- 承認者ロールY:コンテンツタイプBの承認権限
- 承認者ロールZ:コンテンツタイプA・Bの承認権限
という紐づけを行っている場合、ライターがコンテンツデータAの作成を行い、承認依頼を行えるのは、承認者ロールX・Zのユーザーのみに制限されます。
もう少し複雑な設定で、多段階承認で同順位の承認者に上記のように異なる権限の承認者が混在していても、該当のコンテンツタイプに権限のない承認者に承認依頼メールは送信しないようにすることも可能です(=承認依頼時のチェックボックスが非表示になります)。ただし承認・差し戻し時のCcメールは送信されます。
2.その他の追加機能
ライターの編集画面で削除ボタン表示・非表示をプラグイン設定画面で選択可能にしました(お客様によって要望が異なるため)。
ロール作成で、ライター・承認者のロール名を自由に設定できるようにしました。
「多段階+グループ複数承認版」で、承認者が他グループの記事・コンテンツデータを開いた場合、「グループの承認者に属していません。」という警告を表示します。
承認者を設定する前に「ライター(承認つき)」のユーザーが記事を作成しようとした場合、「承認者が設定されていません。」という警告を表示します。
今回の機能追加に伴い、マニュアルも一部見直しました。
3.評価版ダウンロード・購入
評価版ダウンロード・ご購入はWorkflowプラグインのページにアクセスしてください。
MTContentNextタグ、MTContentPreviousタグを出力ファイル名(ベースネーム)でソートする方法
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ブロック終了後に表示するようにしました。