Home » ブログ
検索・リンク
ブログ  ブログ以外
最近の記事
Amazon

‘MODx’ カテゴリーのアーカイブ

2009 年 5 月 28 日

MODxで動的に画像を作成する。

MODxでスニペットを呼び出して動的画像(imagepngを使用)を作成しようと思った。
うまくいかない。
php単独だとうまくいく
ソースは以下(よくWebで紹介されているもの:ここ参考


<?php
    //出力文字の取得
    $setstring = "aaaa";
    //画像の作成
    $img = imagecreate(100, 20);
    //色の作成(背景色)
    $backcol = imagecolorallocate($img, 160, 160, 160);
    //背景色を塗る
    imagefilledrectangle($img, 0, 0, 200, 80, $backcol);
    //色の作成(文字)
    $col = imagecolorallocate($img, 255, 255, 255);
    //文字を書く
    imagestring($img, 2, 10, 4, $setstring, $col);
    //画像出力
    header("Content-type: image/png");
    header("Cache-control: no-cache");
    imagepng($img);
    //画像の消去(メモリの解放)
    imagedestroy($img);
?>

こいつをそのままスニペット(imagecreate)化して

<img title="TEST" src="[!imagecreate!]" alt="TEST" width="100" height="20" />

というコンテンツを作成したが表示されない。
以前、javascriptで同じように処理を作成した時はうまくいったのに…
あることに気づいた。スニペットが先に処理されているのを忘れていた。
ということで、コンテンツを2つ作成して順次処理させればOKだ。

<img title="TEST" src="/modx/imagecreatedummy.html" alt="TEST" width="100" height="20" />

imagecreatedummy.htmlの内容

[!imagecreate!]

phpのソースを作成して呼び出せばもちろんOKなのだが...
(それじゃMODxのスニペット化の意味がないか。処理は同じだが...)

2009 年 5 月 10 日

MODxで動的ページを静的HTMLファイルに出力する。

MODx(0961p2)で動的ページを静的ページとしてファイル出力している。
フリーソフトのWeb巡回ソフトで動的ページを出力していたのだが、内部コンテンツの変換(特にリンク関係)に不満があった。
出力されたhtmlファイルに対して、変換補正やファイル名の変更が必要だ。
Web巡回出力と変換補正(perlを使用)で膨大な時間を費やす。
そこで、MODxのエクスポート機能を使用してみた。巡回ソフトのようにページャーで作成された「次へ」リンクページは出力されない(当然か)し、出力が遅い。
topでプロセスを見る。

ソースは見ていないが、1ドキュメント単位にhttpdへパケットが送信されているようだ。
(Web巡回ソフトと基本的に同じ動きだ。)
結局、自前でスニペットを作成してhtmlファイル出力することにした。
ポイントは以下。

  1. document.parser.class.inc.phpのexecuteParserのコピーexecuteParserAを作成する。
  2. document.parser.class.inc.phpのprepareResponseのコピーprepareResponseAを作成する。
  3. document.parser.class.inc.phpのoutputContentのコピーoutputContentAを作成する。
  4. executeParserAのprepareResponseの呼出をprepareResponseAにする。
  5. prepareResponseAのoutputContentの呼出をoutputContentAにする。
  6. outputContentAの最後あたり
    echo $this->documentOutput

    をコメントにし、

    $docout = $this->documentOutput;

    のようにしてprepareResponseAへreturnする。後は、prepareResponseA、executeParserAでも同様だ。(必要に応じて不要部分を削除したほうが良い)

  7. 動的出力スニペット
  8. $_REQUESTにアクセスページ(alias)やパラメータを設定する。
  9. $_GETも$_REQUESTと同様に必要に応じて値を設定。
  10. executeParserAを呼出し、取得したページを出力する。

httpdへ再リクエストしないようにしたら、巡回ソフトの出力時間の約1/5の時間で終了するようになった。
最新のMODxのバージョンではエクスポート機能が改善されているかもしれない。
(まだ、最新もインストールしていない)

※MODxの記事を公開すると海外からのクラッカー攻撃が増えるので悲しいかな今回もコメントとトラックバックを中止します。

2009 年 3 月 19 日

MODxのチャンク出力で改行を「<br/>」に変換する

MODxでチャンク出力してデータの改行に<br/>をいれようと試してみた。
環境はMODx0961p2、サーバfedora10で文字コードはUTF-8である。

$replace =  "\n";
$scriptphp = "<br/>";
$data = str_replace($replace, $scriptphp, $data);

※$data チャンク出力してデータ
こんなかんじで実装してみたがうまくいかない。
MODxを使用しない環境でチャンク出力したデータではないがPHPを動かすとうまくいく。
試しに、MODxで

$data = nl2br($data);

これはOK。
改行コードをWindowsに変更してみた。

$replace =  "\r\n";

うまく変換する。
おいおいおい、私の頭は混乱中。

2009 年 3 月 2 日

MODxのDittoでrssを出力するが、bodのアクセスの関係で断念

MODx(0961p2)でDittoでRss出力をした。
Bodがくるようになったらrssにアクセスばかりしていて止まらない。
2~3分おきにきている。よく調べてみる。ほっとくと1日ぐらいはこの状態が続くらしい。
何が悪いかというと更新していません「304」を返していないのが悪かったようだ。
未だ、MODxで「304」の返し方が分からないので、自作でrssをファイルに出力するように変更した。
Apacheのほうで、If-Modifiedの対応をしてくれるのでこれでアクセスがなくなった。
悲しいかなDiito。

2009 年 2 月 17 日

MODxでドキュメントが5,000を越えたらキャッシュでエラー

MODx(0.961p2)でドキュメントの数に制限があるのが分からなかった。
ドキュメントを6,000個作成したら、管理画面が真っ白になった。
apacheのerror_logを見る。

[client 127.0.0.1] PHP Fatal error:  Allowed memory size of 33554432 bytes exhausted (tried to allocate 31457280 bytes) in /modxshop/assets/cache/siteCache.idx.php on line 21363
 

どうやら、Cacheのサイズに制限があるようだ。
MODxのフォーラムをみるとドキュメント数は5,000ぐらいが限界で、バージョン0.97でこの問題を解決するようなことが記載されていた。
しかし、諦めきれないので、単純にメモリを増やすことを試みる。
php.iniのメモリを増加

memory_limit = 32M      ; Maximum amount of memory a script may consume (16MB)
                                ↓
memory_limit = 64M      ; Maximum amount of memory a script may consume (16MB)

これでhttpdをrestartしたらOKだった。
しかしパフォーマンスが悪い。この際だから不要なものは整理。
siteCacheの内容をみる。ドキュメントとしての情報は以下。

$a = &$this->aliasListing;
$d = &$this->documentListing;
$m = &$this->documentMap;
$d['home'] = 1;
$a[1] = array('id' => 1, 'alias' => 'home', 'path' => '');
$m[] = array('0' => '1');
$d['feed.rss.xml'] = 51;
$a[51] = array('id' => 51, 'alias' => 'feed.rss.xml', 'path' => '');
$m[] = array('0' => '51');
$d['doc-not-found'] = 27;
$c = &$this->contentTypes;
$c[1] = 'text/html';
$c[27] = 'text/html';

これらの配列がドキュメントの数だけある。
当処理で不要な以下を削除することにした。cache_sync.class.processor.phpを改造。

  1. 配列cの’text/html’(5958個)
  2. 配列mの最下層クラス(5900個)

1.は当処理で問題なし。
2.はサイドメニュー(Wayfinder)の処理がおかしい。しかしメチャメチャ速くなる。
WayfinderはgetParentIdsで親子関係の処理ができなくなるようだ。
汎用のロジックを諦め、当処理用に独自改造してOK。
MODx0.96系ではドキュメント数が少ないコンテンツには適しているが、多くなるとパフォーマンスのためにロジックの見直しがかなり必要だと分かった。

ドキュメントが多くなると注意すべきこと

  1. SEO Strict URLs(全ドキュメントに対するrewrite処理)
  2. Wayfinder(親子関係のlevelの検索,sql)
  3. Ditto(同上)
  4. 大量のタグ(1バッファーにある大量のタグの変換)
2009 年 2 月 14 日

MODxでタグつきチャンクを大量に1ページに作成(sitemap等)したらレスポンス悪化

MODx(0.961p2)で2,000ページぐらいのドキュメントを作成した。
sitemap.xmlをDiitoで作成したけど、処理が終わらない。
DiitoでSQLを発行するまでの時間がかかっているようだ。
Diitoを使用しないで、独自の処理を行う。
これでCeleron D 320(2.40GHz)(メモリ1G)で
1分30秒かかっていた処理が20秒くらいになった。

ページが4,000ページぐらいに増えた。
処理が20秒から30秒かかるようになった。
sitemap.xmlの容量は1Mバイトにも達していない。
これはおかしいと思いソースを調べた。
sitemap.xmlを作成はチャンクを使用している。
このチャンクにタグを使用していたのが悪さをしている。(下記はチェンクの一部)

<loc>[(site_url)]xxxxx</loc>

チャンクは4,000ページ分を作成してoutputに纏められる。
纏められた後に、4,000ある[(site_url)]を文字列に変換している。(多分ひとつひとつ)
さすがにメモリを使用しているとはいえ、バッフォーを取り直しているのだから数あれば遅くなる。
結局、チェンクにはタグを使わないようにプレイスホルダを設定した。
処理は30秒から8秒と高速に終了するようになった。
(現在のMODx(0.963)がこのへんの改善がされているのかわからない。)

又、telnet(port80)でGETしてsitemapのテストをしていた時に思ったこと。
sitemapのドキュメントのキャッシュ無効にしていたのにも関わらず、site_urlがキャッシュされるようだ。
テストした時の手順は以下
1.ドキュメントのキャッシュをクリアする。
2.telnetでGETする。HOSTをaaa.jpと指定する。site_urlにはhttp://aaa.jpが入る。
3.HOSTを指定しないでGET。site_urlがhttp://aaa.jpと出力。(キャッシュされっぱなし。)
内側からのテストだったので、外からはこのようにならないかもしれない。
用心のため、config.inc.phpにsite_urlを固定で設定してしまった。

2009 年 2 月 2 日

MODxで大量ドキュメントを作成。Wayfinder、Dittoのパフォーマンスに泣く。

MODx(0.961p2)で2000件ぐらいのドキュメントを作成した。
親フォルダの下の2000件ぐらいのドキュメントがぶら下がっているイメージ。
Wayfinder(2.0)でメニューを表示させる。
しかし、2000件を表示させるのは無理なので親フォルダ1件だけ表示させる。
Webの画面を開く。ぜんぜん帰ってこない。httpdでcpu率の100%nearが永遠と続く。
Wayfinderのソースをみる。なんだこりゃ!
SQLを以下のように吐き出している。

SELECT DISTINCT sc.id,
sc.menutitle,
sc.pagetitle,
sc.introtext,
sc.menuindex,
sc.published,
sc.hidemenu,
sc.parent,
sc.isfolder,
sc.description,
sc.alias,
sc.longtitle,
sc.type,if(sc.type='reference',sc.content,'') as content,
sc.template,
sc.link_attributes FROM `modxshopdb`.`modx_site_content` sc LEFT JOIN
`modxshopdb`.`modx_document_groups` dg ON dg.document = sc.id
WHERE sc.published=1 AND sc.deleted=0 AND (sc.privateweb=0) AND
sc.hidemenu=0 AND
sc.id IN (95,
2065,〜   → 2000件

このINの要素(小ドキュメント)を作成するのに時間をかけ、さらにここでも時間がかかるSQLを発行している。
結局、Wayfinderは使わず、自分でスニペットを作成してメニューを表示。(汎用にはしていなので当然速い)
ここを解決したら、次はDitto(2.02)。sitemapを作成する処理を作っていたが、これもWayfinderと同じような処理。
超遅い。podがアクセスしたらタイムアウトしてしまう。ここもDittoを諦め、自前で作成。
MODxって詳細解説書がないので困ったものだ。スニペットのソースまでは見ていられない。

2009 年 1 月 4 日

MODxでPHPコードで作成したスニペットからスニペット、チャンクを呼び出すrunSnippet、getChunk、parseChunk。

MODxでPHPコードで作成したスニペットの中からからスニペットを呼び出したり、チャンクを呼び出す方法を調べていてわかったことを以下に示す。

スニペットの呼び出し

runSnippet($snippetName, $params= array ())

イメージは以下

modx->runSnippet('snippet-name, array('param1'=>'value1', 'param2'=>'value2'));
 

param1、param2が引数でvalue1、value2がその値である。

チャンクの呼び出し

$chunk = $modx->getChunk('chunk-name')

※チャンクの場合はプレイスフォルダを使用することが多いので変数の受け渡しには呼び出す前にsetPlaceholderで変数を設定する。$chunkにチャンクからの出力が入る。

一覧を表示したい場合は以下。

parseChunk($chunkName, $chunkArr, $prefix='[[+', $suffix=']]')

イメージは以下

$data = array();
for($i=0;$i<$tot;$i++){
  $chunkArr = array(
                 'parm1' => 'value1',
                 'parm2' => 'value2',);
  $data[$i+1] = $modx->parseChunk($chunkName, $chunkArr, '[+', '+]');
}

※$dataにチャンクからの出力が入る。
MODxってAPIの解説本がないのでさびしい。ネットで探すのも疲れる。
MODx特有のページャーが発見できない。ないのかも?。(pearを使うしかないか?)

2008 年 12 月 31 日

MODxで「自動転送がループしています」が出てしまった。

MODxでフレンドリURLを設定していたのだが、フレンドリURLをはずしたら
「自動転送がループしています」というエラーが出てしまう。
しかも特定のページのみ。

Cookie、キャッシュのクリアや.htaccessをみても特におかしいところはわからない。
よくよく調べてみたら「SEO Strict URLs」のプラグインを使用していた。
とりあえず停止してみた。

表示されるようになった。
ひとつ勉強になった。

2008 年 11 月 29 日

MODxのテンプレート変数に既定値を設定しているが、ドキュメントの新規/修正では改行コードがカットされDBに格納され不整合が発生する

MODxのテンプレート変数(text)に既定値を設定している。
テンプレート変数には広告関係の値を設定している。
GoogleAdSenseの設定パラメータだ。
このパラメータをテンプレート変数の既定値に設定した時点では、全ドキュメントにGoogleAdSenseの広告が表示された。
しかし、ドキュメントを修正したり、新規にドキュメントを作成すると広告が表示されない。
よく見たら、広告が表示されないGoogleAdSenseのパラメータは改行コードがなくなっている。
DBを見てみたら、修正/新規ドキュメントのテンプレート変数が固有にDBに登録されている。しかも改行コードがカットされている。
改行コードをカットするなら全てのドキュメントに対してカットすればすぐ分かったものの...。
修正/新規のものに対しては、MODxの画面のテンプレート変数入力欄に改行コードがカットされた既定値がCOPYされる。それが保存時にローカルなテンプレート変数としてDBに格納される。
改行コードをカットされない属性のテンプレート変数を探すしかないのだが、取り合えずの対応としてテンプレートに直接パラメータ値を設定した。汚いテンプレートがさらに汚くなった。

△ページトップ

Google
ページ
最近のブログ
アーカイブ
カテゴリー
最近のコメント
最近のトラックバック
    No Responses.