Dec 04, 2008, 01:22 PM *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
Search via SMF or Google: modx forums all of modxcms.com web
  MODxCMS.com   Forums   Help Login Register  
News:Read what MODx Developers say: MODx Dev. Blogs
Pages: [1]   Go Down
  Print  
Author Topic: スニペットのオプションに使えない文字  (Read 1785 times)
0 Members and 1 Guest are viewing this topic.
kazuike
Member
**
Posts: 55


WWW
« on: Dec 10, 2007, 08:35 PM »

スニペットを自作しています。

条件によって、出力するHTMLのタグを切り替えるようなものなのですが、
スニペットに渡すオプションの値として、
HTMLのタグの属性のようなもの、例えば「&attr=`hoge="huga"`」とか、
正規表現「&regex=`/^[\w]+$/`」等を、
なんとか指定できないものかと試行錯誤しています。

そのままではイコール「=」や括弧「[」「]」は、渡せないようですが、
何か良い方法はありませんでしょうか?
URLエンコードしてオプションに指定し、スニペットでデコードするとか、
そういった方法もあるかと思いますが、それではちょっと使いづらそうなので、
皆様のお知恵をお借りできればありがたいです。

また、スニペットに使えない(使うと問題が起こる可能性がある)文字は、
イコール「=」や括弧「[」「]」以外にもありますでしょうか?

よろしくお願い致します。
Logged
tkfm
Committed to MODx
*****
Posts: 624


WWW
« Reply #1 on: Dec 10, 2007, 11:03 PM »

こんにちは~

PHPプログラミングはほとんど分からないのでさらに突っ込まれると泣いちゃいますが... Cry

そのままではイコール「=」や括弧「[」「]」は、渡せないようですが、
何か良い方法はありませんでしょうか?
また、スニペットに使えない(使うと問題が起こる可能性がある)文字は、
イコール「=」や括弧「[」「]」以外にもありますでしょうか?

「=」「&」「?」は渡せないようですね。
ZeRoさんのスニペット「pieX」でも、この3文字は引数としての記法が別指定されていますし。

あと日本人にはあまり関係ありませんが、
仏語や独語にあるような特殊文字も同じ不具合が出ているみたいです。

バグレポート等を見ていると、この問題はかなり前からあるようですが、まだ解決策が見つかっていませんね。
0.9.7では改善する方向で検討しているみたいです。

プログラミングが良く分かっていませんが、
例えばChunkに値を書いておいて、Chunk名でスニペットに引き渡して読み出す...
なんてのはダメでしょうか?
エンコード/デコード的な処理より少しは簡単になりそうな気はしますが... Huh
Logged
kazuike
Member
**
Posts: 55


WWW
« Reply #2 on: Dec 11, 2007, 12:20 AM »

tkfm さんありがとうございます。
Quote
あと日本人にはあまり関係ありませんが、
仏語や独語にあるような特殊文字も同じ不具合が出ているみたいです。

バグレポート等を見ていると、この問題はかなり前からあるようですが、まだ解決策が見つかっていませんね。
0.9.7では改善する方向で検討しているみたいです。
そうなんですか…
せめてバックスラッシュか何かでエスケープするぐらいになってくれると嬉しいです。
#2007年「最も期待できるオープンソースCMS」ですから、期待大です。 Smiley

で、チャンクですが、あちこちで使えるようなものはチャンクは良いですよね。
そういう時はとても助かるんで良いんですが、
そこでしか使わないようなものをチャンクにするのもちょっと抵抗があったりするんですよね。
とりあえず、DirectPHPを見習って、urlencodeで対応しようかな~
って考えています。

だいたい、以下の文字はurlencodeするってことで…
   =   =>   %3D
   ?   =>   %3F
   %   =>   %25
   &   =>   %26
   `   =>   %60
   [   =>   %5B
   ]   =>   %5D
Logged
tkfm
Committed to MODx
*****
Posts: 624


WWW
« Reply #3 on: Dec 11, 2007, 02:59 AM »

そこでしか使わないようなものをチャンクにするのもちょっと抵抗があったりするんですよね。
やっぱり、良い案ではないですよね~ Tongue

あとはプレイスホルダで受け渡すとか、物理的にファイルに書いちゃうとか。
あんまりChunkと変わらないか... Wink

どんなスニペットを作成されているのか分かりませんが、
完成したら是非公開して下さいね!
Logged
kazuike
Member
**
Posts: 55


WWW
« Reply #4 on: Dec 11, 2007, 04:26 AM »

tkfm さん
ありがとうございます。
とりあえずスニペットを作ることができました。

条件分岐スニペット: StartIf & EndIf 1.00
http://modxcms.com/forums/index.php/topic,20716.0.html

とりあえず、urlencodeを使っていますが、そのうち、チャンクにも対応するオプションをつけたいと思っています。
今後とも、よろしくお願いいたします。
Logged
Phize
Member
**
Posts: 69



WWW
« Reply #5 on: Dec 11, 2007, 06:27 AM »

こんばんは。
以前、同じようなことではまりました Undecided

これにまつわる処理は、/manager/includes/document.parser.class.inc.php の evalSnippetsメソッドにあるのですが、
「[[」、「]]」、「&」、「`」、「?」、「=」の文字で単純に分割しているみたいなので、スニペットだけでは対応できなそうでした。

マルチバイト関数に変えて、パラメータは正規表現でパースするようにするといいのかなあ、と思ったのですが、
結局、アップデート時のことを考えて独自のエスケープ方法で対応しました。

致命的というほどではないですが、0.9.7で改善されるといいですよね。
« Last Edit: Dec 11, 2007, 06:31 AM by Phize » Logged
tkfm
Committed to MODx
*****
Posts: 624


WWW
« Reply #6 on: Dec 11, 2007, 10:18 AM »

こんばんわ~

これにまつわる処理は、/manager/includes/document.parser.class.inc.php の evalSnippetsメソッドにあるのですが、
「[[」、「]]」、「&」、「`」、「?」、「=」の文字で単純に分割しているみたいなので、スニペットだけでは対応できなそうでした。
なんだかすごくタイミングよく、昔のスレッド(1年半以上前のもの)が新規投稿で上がってきました。
http://modxcms.com/forums/index.php/topic,3772.0.html
Phizeさんの書かれた「単純に分割」ってこういうことなんですね~

バグレポートを見ていると一旦解決されたのにまたバグが見つかったようですね。
一旦解決したときの解決策が上記のスレッドに書かれているものなのかな?
(PHP4の環境でUTF-8を使うと問題が起こるようなことが書かれています → ここ )
Logged
kazuike
Member
**
Posts: 55


WWW
« Reply #7 on: Dec 11, 2007, 12:27 PM »

Phize さんに触発されて、ちょっとソースを眺めてみました。

outputContentで、[! => [[、!] => ]] の全置換をしておいて、
evalSnippetsで、[[と]]ではさまれた部分を抽出、
それぞれ、最初に現われた?で前後に分けて(前がスニペット名、?を含めて後ろがパラメータ)、
パラメータについて、
 ?を全て削除して(…これ最初の一つだけで良いのでは?)、
 &を&に全て置換して、
 &で分割して(…これもすごいな)、
 分割したそれぞれについて、
  =で分割して(…これまた強烈)
  分割した2番目の要素の、最初と最後の`の間にある値を使う。
という処理を行ってますね。
(どこかで、パラメータは空白で分割するって読んだような気がしますが、関係ないですね)

つまり、スニペットのパラメータで問題になりそうな文字は、
[!、[[、!]、]]、?、&(&含む)、=、`
ということでしょうか?

でも、確か、[か]でも、何か不都合が起こっていたような気がするのですが…
きっと、これはスニペット以外の処理で関係あるのでしょうね。
« Last Edit: Dec 11, 2007, 12:30 PM by kazuike » Logged
Phize
Member
**
Posts: 69



WWW
« Reply #8 on: Dec 12, 2007, 06:12 AM »

>>tkfmさん

詳しい動作はkazuikeさんが書いてくださってますが、そのスレははじめて知りました。
ありがとうございます、チェックしてきます Cheesy


>>kazuikeさん

evalSnippetsあたりしか眺めてないのですが、その限りでは

Code:
[[スニペット? &パラメータ名=`パラメータ` &パラメータ名=`パラメータ`]]
[!スニペット? &パラメータ名=`パラメータ` &パラメータ名=`パラメータ`!]

という形式なら、正規表現などでもっと簡単に「[[」「]]」「[!」「!]」「=」「&」「&」を使えるようにパースできそうですよね。
正規表現を使わない理由があるのかはよくわかりませんが、パフォーマンスとかセキュリティ上の問題なんでしょうか…。
« Last Edit: Dec 12, 2007, 06:20 AM by Phize » Logged
Phize
Member
**
Posts: 69



WWW
« Reply #9 on: Dec 12, 2007, 09:17 AM »

正規表現を使って、スニペットでは通常使えない文字(「]]」、「`」を含む)を使えるようにできたっぽいので貼ってみます(強引っぽいですが)。
パラメータはバッククォートあり・なし、値なしのどの場合でも通常とほぼ同じような動作になります。

スニペットコールの例:
Code:
[[Snippet? param1  =  `?= ‵ [] &‵ &` &param2= &param3=[]?= &param4 &param?5=`[[Lea más...]]`]]
パラメータ名と値の解析結果($parameterのvar_dump):
Code:
array
  'param1' => string '?= ` [] &` &' (length=11)
  'param2' => string '' (length=0)
  'param3' => string '[]?=' (length=4)
  'param5' => string '[[Lea más...]]' (length=15)

  • 通常の動作と同様に、1つ目のパラメータ名の「&」は補完されます。(param1の例)
  • 通常の動作と同様に値のないパラメータは無視されます。(param4の例)
  • 通常の動作と同様にパラメータ名の「?」は「?」の部分だけが削除されます。(param5の例)
  • 値をバッククォートで囲んだ場合は、「`」以外の文字が使えます。(param1, 6の例)
  • 値をバッククォートで囲まない場合は、通常使える文字に加えて「`」、「&」、空白文字以外の記号が使えます(param2, 3の例)。
  • 値をバッククォートで囲んでいる場合に限って、数値文字参照「‵」や「&#x2035」が「`」に変換されます。(param1の例)
  • マルチバイト文字は、うちのローカル環境(XAMPP+PHP 4.4.7&PHP 5.2.4)では問題ないみたいですが詳しくテストしてません。(param5の例)

パラメータ名と値をつなぐ「=」の前後の空白文字の扱いと「&」の扱いだけは、パース結果「param1」のように通常のMODxの動作とは異なります。
通常のMODxの動作は、1番目のパラメータ名は「param1  」になりますが、このコードでは前後の空白文字は削除したほうが自然だと思うのでそうしてます。
また、通常は「&paramx=`value`」という文字があると最初に「&」が「&」に変換され、その後「paramx=`value`」という一つのパラメータとして扱われますが、このコードではバッククォートの処理の後に変換しているためパラメータとしては扱われません。

あと「[[」と「]]」、「`」は相変わらず使えないです Cry
「[[」と「]]」はevalSnippetsメソッドの1行目の正規表現を工夫すればできそうな気もしないでもないですが…


2007/12/15 全ての文字を使えるようにしてみました。1つ目のパラメータ名に「&」が省略されていた場合にパラメータが無視されていた(通常の動作と異なる)のと、その他の細かい処理を修正しました。


MODx 0.9.5~0.9.6.1
/manager/includes/document.parser.class.inc.php  evalSnippetsメソッド内
(行数は 0.9.6.1 のものです。)

784行目あたり~(変更前):
Code:
    function evalSnippets($documentSource) {
        preg_match_all('~\[\[(.*?)\]\]~', $documentSource, $matches);
784行目あたり~(変更後):
Code:
    function evalSnippets($documentSource) {
        preg_match_all('~\[\[((?:.*?(?:`(?:[^`]|[^]]\])*?`)?)*?)\]\]~', $documentSource, $matches);


836行目あたり~(変更前):
Code:
                // current params
                $currentSnippetParams= $snippetParams[$i];
                if (!empty ($currentSnippetParams)) {
                    $tempSnippetParams= str_replace("?", "", $currentSnippetParams);
                    $splitter= "&";
                    if (strpos($tempSnippetParams, "&") > 0)
                        $tempSnippetParams= str_replace("&", "&", $tempSnippetParams);
                    //$tempSnippetParams = html_entity_decode($tempSnippetParams, ENT_NOQUOTES, $this->config['etomite_charset']); //FS#334 and FS#456
                    $tempSnippetParams= split($splitter, $tempSnippetParams);
                    $snippetParamCount= count($tempSnippetParams);
                    for ($x= 0; $x < $snippetParamCount; $x++) {
                        if (strpos($tempSnippetParams[$x], '=', 0)) {
                            if ($parameterTemp= explode("=", $tempSnippetParams[$x])) {
                                $fp= strpos($parameterTemp[1], '`');
                                $lp= strrpos($parameterTemp[1], '`');
                                if (!($fp === false && $lp === false))
                                    $parameterTemp[1]= substr($parameterTemp[1], $fp +1, $lp -1);
                                $parameter[$parameterTemp[0]]= $parameterTemp[1];
                            }
                        }
                    }
                }

836行目あたり~(変更後):
Code:
                // current params
                $currentSnippetParams= $snippetParams[$i];
                if (!empty ($currentSnippetParams)) {
                    $tempSnippetParams= preg_replace("~^\s*\?\s*~", "", $currentSnippetParams);
                    $splitter= "&";
                    if (strpos($tempSnippetParams, $splitter) != 0)
                        $tempSnippetParams= $splitter . $tempSnippetParams;
                    //$tempSnippetParams = html_entity_decode($tempSnippetParams, ENT_NOQUOTES, $this->config['etomite_charset']); //FS#334 and FS#456
                    $snippetParamCount= preg_match_all("~" . $splitter
                                      . "([^" . $splitter . "=]*(?:=\s*`[^`]*`"
                                      . "|=[^" . $splitter . "\s]*"
                                      . "|[^" . $splitter . "]*))~", $tempSnippetParams, $matches);
                    $tempSnippetParams= @ $matches[1];
                    for ($x= 0; $x < $snippetParamCount; $x++) {
                        if (preg_match('~([^=\s]*)\s*=\s*`?([^`]*)`?~', $tempSnippetParams[$x], $parameterTemp)) {
                            $parameterTemp[2]= preg_replace("~&#0*8245;|&#x0*2035;~", "`", $parameterTemp[2]);
                            if (strpos($parameterTemp[2], "&amp;") > 0)
                                $parameterTemp[2]= str_replace("&amp;", "&", $parameterTemp[2]);
                            $parameterTemp[1]= str_replace("?", "", $parameterTemp[1]);
                            $parameter[$parameterTemp[1]]= $parameterTemp[2];
                        }
                    }
                }
« Last Edit: Dec 15, 2007, 06:54 AM by Phize » Logged
Phize
Member
**
Posts: 69



WWW
« Reply #10 on: Dec 15, 2007, 06:33 AM »

「[[」、「]]」を含めて、スニペットで通常使えない文字を全て(?)使えるようにできたので、先日の書き込み(このポストの一つ前のポスト)のコードを修正しました  Cheesy
バッククォート「`」は、数値文字参照を「`」に変換するようにしてみました。

対象は0.9.5~0.9.6.1までです。それ以前のバージョンは確認してません。
マルチバイト文字、他の機能との連携時のテストは不完全です。

お気づきの点などあれば、ご指摘いただけるとうれしいです  Shocked
« Last Edit: Dec 15, 2007, 06:56 AM by Phize » Logged
Pages: [1]   Go Up
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP

Copyright © 2005-2008 MODxCMS, All rights reserved. Contact Us
Styles by ziworks.com

Powered by SMF 1.1.4 | SMF © 2005, Simple Machines LLC

Valid XHTML 1.0! Valid CSS!