4D v16

4D 変換タグ

 
4D v16
4D 変換タグ

4D 変換タグ  


 

 

4Dでは、参照を4D変数や式に挿入したり、異なる種類の処理をソーステキストに対して実行したりするための変換タグのセットを用意しています。これは別名 ”テンプレート” とも呼ばれます。これらのタグはソーステキストが実行されてアウトプットテキストが生成されたときに解釈されます。

これらの原理は特に4D Web サーバーにおいてセミダイナミックページ を生成するのに使用されます。

これらのタグは原則としてHTMLコメント(<!--#Tag Contents--> )として挿入されます。しかしながら、 <!--Beginning of list--> などの他のコメントも使用可能です。複数のタイプのタグを混用することも可能です。例えば、以下のHTML構造は、何の問題もなく実行可能です:

<HTML>
...
<BODY>
<!--#4DSCRIPT/PRE_PROCESS-->         (メソッド呼び出し)
<!--#4DIF (myvar=1)-->               (If 条件)
   <!--#4DINCLUDE banner1.html-->   (サブページ挿入)
<!--#4DENDIF-->                     (End if)
<!--#4DIF (mtvar=2)-->
   <!--#4DINCLUDE banner2.html-->
<!--#4DENDIF-->

<!--#4DLOOP [TABLE]-->               (カレントセレクションでのループ)
<!--#4DIF ([TABLE]ValNum>10)-->         (If [TABLE]ValNum>10)
   <!--#4DINCLUDE subpage.html-->   (サブページの挿入)
<!--#4DELSE-->                     (Else)
   <B>Value: <!--#4DTEXT [TABLE]ValNum--></B><BR>
                              (フィールド表示)
<!--#4DENDIF-->
<!--#4DENDLOOP-->                  (End for)
</BODY>
</HTML>

"テンプレート"ページの中身のパースには、二通りのやり方があります:

  • PROCESS 4D TAGS コマンドを使用する: このコマンドは"テンプレート"に加えて引数(任意)を入力として受け付けて処理し、結果のテキストを返します。
  • 4Dの統合されたHTTPサーバーを使用する: セミダイナミックページWEB SEND FILE(.htm, .html, .shtm, .shtml)、WEB SEND BLOB (text/html型BLOB)、および WEB SEND TEXT コマンドによって送信、あるいはURLで呼び出します。URLで呼び出す場合、“.htm” と “.html” で終わるページは最適化のため解析されません。この場合にHTMLページを強制的に解析させるには、終わりを“.shtm” または“.shtml”とする必要があります(例 http://www.server.com/dir/page.shtm)。詳細に関しては、Webサーバ 内の セミダイナミックページ の章を参照ください。

以下の表は、利用可能な4D 変換タグの一覧です。詳細については、その先のタグの詳細を参照して下さい。

タグ振る舞い$ シンタックス(*)コメント
4DTEXT4D 変数および式をテキストとして挿入<!--#4DTEXT [Customer]Name-->Oデータが外部で処理された際には、悪意あるコードのインジェクションを避けるために推奨される
4DHTMLHTML コードを挿入<!--#4DHTML <br/>-->Oデータが外部で処理された際には推奨されない
4DEVAL4D 式を評価する<!--#4DEVAL a:=20-->Oデータが外部で処理された際には推奨されない
4DSCRIPT/4D メソッドに引数を渡して実行<!--#4DSCRIPT/MyMethod/MyParam-->
4DINCLUDEHTML ページを他のページ内に含める<!--#4DINCLUDE subpage.html-->
4DBASE4DINCLUDEで使用されるファイルを指定<!--#4DBASE ../file/-->
4DCODE4D コードを挿入<!--#4DCODE ALERT(myVar)-->Supports CR、LF (4D コードブロック)をサポート
4DIF, 4DELSE, 4DELSEIF, 4DENDIFタグ内のコードに条件式を挿入<!--#4DIF (myVar=1)-->
4DLOOP, 4DENDLOOPタグ内のコードにループを挿入<!--#4DLOOP [table]-->テーブル、配列、メソッド、式、ポインター配列に対して使用可能

(*)原則としてタグはHTML コメント(<!--#Tag Content-->)としてソーステキストに挿入します。値を返すタグにおいては特定の条件下において、XMLに準拠するための代替手段として$ 記号を使用したシンタックスを使用することができます。詳細な情報については、以下の4DTEXT、4DHTML、4DEVALにおける代替シンタックス を参照して下さい。

4DTEXT4DHTML4DEVAL4DSCRIPT4DIF4DELSEIF あるいは 4DLOOP で4D メソッドをWeb リクエスト経由で実行の可否は、メソッドのプロパティ内で定義されている"4DタグとURL(4DACTION...)"属性の値によります。メソッドにおいてその属性がチェックされていない場合、そのメソッドはWebリクエスト経由で実行することはできません。この点についての詳細な情報については、接続セキュリティ の章を参照して下さい。

4D タグは繰り返し解釈されます。4Dは常に変換の結果を解釈しようとし、新しい変換が起きた際にはそれに伴い新しく解釈が実行され、取得した結果がこれ以上変換の必要がなくなるまで繰り返されます。例えば、以下のような宣言があった場合:

<!--#4DHTML [Mail]Letter_type--> 

もし[Mail]Letter_type テキストフィールドにタグ(例えば<!--#4DSCRIPT/m_Gender--> など)が含まれていた場合、このタグは4DHTMLタグの解釈の後、それに伴って評価されます。

この強力な原則はテキスト変換に関連するほとんどの需要を満たすことができます。しかしながら、これは場合によっては悪意のあるコードの侵入を許す可能性があるという点に注意が必要です。この点についてのより詳細な情報は、以下の章を参照ください。

4D変換タグは様々なタイプのデータを引数として受け入れます。テキスト、変数、メソッド、コマンド名、etc...。これらのデータが自分で書いたコードから提供される場合、そのインプットを自分でコントロールできるので、悪意あるコードの侵入のリスクは無いと言っていいでしょう。しかしながら、 データベースのコード扱うデータは、多くの場合外部ソース(ユーザー入力、読み込み、等)を通じて導入されたものです。
この場合、4DEVALや4DSCRIPTなどの変換タグは使用しないのが賢明です。なぜならこれらのタグはこういったデータを直接使って変数を評価するからです。
これに加え、繰り返しの原則(前章参照のこと)に従い、悪意あるコード自身が変換タグを含んでいる可能性もあります。この場合、4DTEXT タグを使用する必要があります。
例として、"Name"という名前のWebフォームフィールドがあり、ユーザーがそこに名前を入力しなければならない場合を考えてみましょう。この名前は<!--#4DHTML vName--> タグを使用してページ内に表示されます。もし"<!--#4DEVAL QUIT 4D-->" 型のテキストが名前の代わりに入力されたとしたら、このタグを解釈するとアプリケーションは終了してしまいます。
このリスクを避けるため、この場合にはシステム全体で4DTEXT タグを使用します。このタグは特殊HTML文字をエスケープするため、挿入された悪意ある再起的コードは、再解釈されることはありません。前の例でいうと、"Name"フィールドにはこの場合"&lt;!--#4DEVAL QUIT 4D--&gt;" が含まれ、これは変換されません。

4D のバージョンや言語に関係なく、タグ経由で式の評価が正確に行われることを確実にするため、バージョン間で名前が変わりうる要素(コマンド、テーブル、フィールド、定数)については、トークンシンタックスを使用することが推奨されます。例えば、コマンドを挿入するためには、"Current time:C178"と入力します。この点の詳細については、フォーミュラ内でのトークンの使用 の章を参照して下さい。

v15 R4以降、4DTEXT、4DVAR、4DHTML、4DHTMLVAR、および4DEVAL(に加えて、旧4DVAR および 4DHTMLVAR )の4D タグを使って数値表現を評価する際には、4Dは常にピリオド文字(.)を小数点として採用します。今後、これに関するリージョン設定は無視される点に留意ください。

この機能により、4Dの言語設定とバージョンが異なっていてもメンテナンスが容易となり互換性が保たれます。

例えば、以下のコードはリージョン設定に関わらず使用可能です:

 value:=10/4
 input:="<!--#4DTEXT value-->"
 PROCESS 4D TAGS(input;output)
  // 例え小数点が ',' に設定されていた場合でも、出力は常に2.5になります。

互換性に関する注意: 以前のバージョンから変換したご自身のコードが、4D タグによる数値表現の評価においてリージョン設定を遵守している場合、Stringコマンドを使用してそのコードを適応させる必要があります:

  • ピリオドを小数点として使用したvalueを取得する場合: <!--#4DTEXT value-->
  • リージョン設定に基づいた小数点を使用したvalueを取得する場合: <!--#4DTEXT String(value)-->

4DTEXT  

シンタックス: <!--#4DTEXT VarName--> または <!--#4DTEXT 4DExpression-->

代替シンタックス: $4DTEXT(VarName) または $4DTEXT(4DExpression) ( 4DTEXT、4DHTML、4DEVALにおける代替シンタックス 参照)

タグ <!--#4DTEXT VarName--> を使用して4D変数や値を返す式への参照を挿入します。例えば(HTMLページ内にて)以下のように記述すると:

<P>Welcome to <!--#4DTEXT vtSiteName-->!</P>

4D変数 vtSiteName の値がHTMLページに送信時に挿入されます。値はテキストとして挿入されます。">"のようなHTMLの特殊文字は、自動的にエスケープされます。

4DTEXT タグを使用して、変数だけでなく4D式も挿入できます。フィールドの値を直接挿入できますし (例 <!--#4DTEXT [tableName]fieldName-->) 、または配列要素の値も挿入できますし (例 <!--#4DTEXT tabarr{1}-->) 、値を返すメソッドも使用できます (<!--#4DTEXT mymethod-->)。

式の変換は変数のそれと同じルールが適用されます。さらに式は4Dのシンタックスルールに適合していなければなりません。

解釈エラーの場合、“<!--#4DTEXT myvar--> : ## error # error code” のように表示されます。

注:
  • プロセス変数を使用する必要があります。
  • ピクチャーフィールドの内容を表示できます。しかしピクチャー配列の要素を表示することはできません。
  • 4D式を使用して、オブジェクトフィールドの中身を表示させることができます。例えば、以下の様に記述します。
    <!--#4DTEXT OB Get:C1224([Rect]Desc;\"color\")-->
  • セキュリティ上の理由から、悪意あるコードの侵入・挿入を防ぐために、アプリケーション外から導入されたデータを処理するときにはこのタグを使用する事が推奨されます(後述の の章を参照して下さい)。
  • 通常はテキスト変数を使用します。しかしBLOB変数を使用することもできます。この場合長さ情報なしのテキストBLOBを使用します。

4DHTML  

シンタックス: <!--#4DHTML VarName--> または <!--#4DHTML 4DExpression-->

代替シンタックス: $4DHTML(VarName) または $4DHTML(4DExpression) (4DTEXT、4DHTML、4DEVALにおける代替シンタックスを参照して下さい)

4DTEXT タグ同様、この4DHTMLタグを使用すると、変数や値を返す4D式をHTML式として挿入できます。一方4DTEXT タグとは異なり、このタグはHTML特殊文字(例: ">")をエスケープしません。

例えば4Dのテキスト変数 myvar を4Dタグを使用して処理した結果は以下の様になります:

myvar 値タグWebページに挿入されるテキスト
myvar:="<B>"<!--#4DTEXT myvar-->&lt;B&gt;
myvar:="<B>"<!--#4DHTML myvar--><B>

解釈エラーの場合、“<!--#4DHTML myvar--> : ## エラー # エラーコード”のように表示されます。

注: セキュリティ上の理由から、悪意あるコードの侵入・挿入を防ぐために、アプリケーション外から導入されたデータを処理するときには4DTEXT タグを使用する事が推奨されます(後述の使用上の注意の章を参照ください)。

シンタックス: <!--#4DEVAL VarName--> または <!--#4DEVAL 4DExpression-->
代替シンタックス:
$4DEVAL(VarName) または $4DEVAL(4DExpression) (4DTEXT、4DHTML、4DEVALにおける代替シンタックスを参照して下さい)

4DEVAL タグを使用すると、変数や4D式を挿入できます。既存の4DHTMLタグのように、4DEVALタグはテキストを返す際にHTML特殊文字をエスケープしません。しかしながら、4DHTMLや4DTEXTと異なり、4DEVALは有効な4D宣言であればどれでも実行することができます(値を返さない割り当てや式も含まれます)。

例えば、以下の様なコードを実行することができます:

 $input:="<!--#4DEVAL a:=42-->" //割り当て
 $input:=$input+"<!--#4DEVAL a+1-->" //計算
 PROCESS 4D TAGS($input;$output)
  //$output = "43"

解釈エラーの場合、“<!--#4DEVAL expr--> : ## エラー # エラーコード”のように表示されます。

注: セキュリティ上の理由から、悪意あるコードの侵入・挿入を防ぐために、アプリケーション外から導入されたデータを処理するときには4DTEXT タグの使用が推奨されます (後述の使用上の注意の章を参照ください)。

シンタックス: <!--#4DSCRIPT/MethodName/MyParam-->

4DSCRIPT タグを使用して、スタティックなHTMLページを処理する際に4Dメソッドを実行することを可能にします。<!--#4DSCRIPT/MyMethod/MyParam--> タグがHTMLコメントとしてページに現れると、MyMethodメソッドが$1引数に Param を受け取って実行されます。

注: タグがWebプロセスのコンテキストにおいて呼び出された場合、Webページがロードされると、4Dは On Web Authenticationデータベースメソッド を (存在すれば) 呼び出します。このメソッドがTrueを返すと、4Dはメソッドを実行します。

メソッドは$0にテキストを返す必要があります。文字列がコード1から始まっていると、それは HTMLソースとして扱われます (4DHTMLのときと同じ原則)。

例えば、以下のコメントをセミダイナミックWebページに挿入したとしましょう “Today is <!--#4DSCRIPT/MYMETH/MYPARAM-->” 。ページをロードする際、4Dは On Web Authenticationデータベースメソッド を (存在すれば) 呼び出し、そして MYMETH メソッドの$1引数に文字列 “/MYPARAM” を渡して呼び出します。

メソッドは$0にテキストを返します (例えば “14/12/31”)。コメント “Today is <!--#4DSCRIPT/MYMETH/MYPARAM-->” は結果 “Today is 14/12/31” となります。

MYMETHメソッドは以下のとおりです:

  //MYMETH
 C_TEXT($0;$1//このパラメーターは常に宣言する必要があります
 $0:=String(Current date)

警告: $0$1 引数を宣言しなければなりません。

注: 4DSCRIPTから呼び出されるメソッドはインタフェース要素 (DIALOG, ALERT...) 等を呼び出してはいけません。

4Dはメソッドを見つけた順に実行するので、ドキュメント中で離れて参照される変数の値を設定するメソッドを呼び出すことも可能です。モードは関係ありません。テンプレートには必要なだけ <!--#4DSCRIPT...--> コメントを記述できます。

シンタックス: <!--#4DINCLUDE Path-->

このタグは主に、このコメントを使用して、(path引数で指定された) 他のHTMLページを、これから送信するHTMLに含めるためにデザインされました。デフォルトでHTMLのボディー部、つまり<body> と</body>タグの間の内容だけが統合されます (bodyタグは含まれません)。これによりヘッダーに含まれるメタタグ関連の衝突が回避されます。しかしpathで指定されたHTML中に<body></body>タグが含まれない場合、ページ全体が統合されます。この場合メタタグの整合性を管理するのは開発者の役割です。

<!--#4DINCLUDE --> コメントは、テスト (<!--#4DIF-->) やループ (<!--#4DLOOP-->) と使用するととても便利です。条件に基づきあるいはランダムにタグを含める便利な方法です。
このタグを使用してページをインクルードするとき、拡張子にかかわらず、4Dは呼び出されたページを解析してから、内容を4DINCLUDE呼び出し元のページに挿入します。

<!--#4DINCLUDE --> コメントで挿入されたページはロードされ、URLで呼ばれたページやWEB SEND FILEコマンドで送信されたページと同じように、Webサーバーキャッシュに格納されます。

pathには、含めるドキュメントへのパスを記述します。

警告: 4DINCLUDE呼び出しの場合、パスは解析される親ドキュメントを起点とした相対パスです。フォルダ区切り文字にはスラッシュ (/) を使用し、レベルをさかのぼるには2つのドットを使用します (HTMLシンタックス)。

:
  • PROCESS 4D TAGSコマンドで4DINCLUDEタグを使用する場合、デフォルトフォルダーはデータベースストラクチャーが置かれているフォルダーです。
  • 4DINCLUDE タグで使用されるデフォルトフォルダーは <!--#4DBASE -->タグを使って変更できます (後述)。
ページ内で使用できる<!--#4DINCLUDE path-->数に制限はありません。しかし<!--#4DINCLUDE path-->の呼び出しは1レベルのみ有効です。つまり、例えばmydoc1.html内の<!--#4DINCLUDE mydoc2.html-->で呼ばれるmydoc2.htmlページのボディに、<!--#4DINCLUDE mydoc3.html--> を入れ子にすることはできません。

さらに、4Dはインクルードが再帰的かどうかを確認します。

エラーの場合、“<!--#4DINCLUDE path--> : ドキュメントを開けません”のように表示されます。

例題

<!--#4DINCLUDE subpage.html-->
<!--#4DINCLUDE folder/subpage.html-->
<!--#4DINCLUDE ../folder/subpage.html-->

4DBASE  

シンタックス: <!--#4DBASE folderPath-->

<!--#4DBASE --> タグは<!--#4DINCLUDE-->タグで使用されるワーキングディレクトリを指定します。
Webページ内でこのタグが使用されると、<!--#4DBASE --> タグはこのページ内でそのあとに続くすべての<!--#4DINCLUDE--> 呼び出しのディレクトリを変更します。組み込まれたファイル内で<!--#4DBASE -->フォルダーが変更されると、親のファイルから元となる値を取得します。

folderPath 引数には現在のページに対する相対パスを指定し、パスは"/"で終わっていなければなりません。指定するフォルダーはWebフォルダー内になければなりません。
WEBFOLDER キーワードを渡すと、デフォルトパスに戻されます (そのページに対して相対)。

4D v12では以下のように各呼び出しごとに相対パスをしていなければなりませんでした:

<!--#4DINCLUDE subpage.html--> 
<!--#4DINCLUDE folder/subpage1.html-->
<!--#4DINCLUDE folder/subpage2.html-->
<!--#4DINCLUDE folder/subpage3.html-->
<!--#4DINCLUDE ../folder/subpage.html-->

<!--#4DBASE --> タグを使用すれば以下のように記述できます:

<!--#4DINCLUDE subpage.html--> 
<!--#4DBASE folder/-->
<!--#4DINCLUDE subpage1.html-->
<!--#4DINCLUDE subpage2.html-->
<!--#4DINCLUDE subpage3.html-->
<!--#4DBASE ../folder/-->
<!--#4DINCLUDE subpage.html-->
<!--#4DBASE WEBFOLDER-->

Example  

<!--#4DBASE --> タグを使用してホームページのディレクトリを設定する:

/* Index.html */
<!--#4DIF LangFR=True-->
    <!--#4DBASE FR/-->
<!--#4DELSE-->
    <!--#4DBASE US/-->
<!--#4DENDIF-->
<!--#4DINCLUDE head.html-->
<!--#4DINCLUDE body.html-->
<!--#4DINCLUDE footer.html-->

head.html ファイル内でカレントフォルダーが<!--#4DBASE -->を使用して変更されているが、index.html内では変更されない:

/* Head.htm */
/* ここでのワーキングディレクトリはインクルードされるファイルに対して相対的 (FR/ または US/) */
<!--#4DBASE Styles/-->
<!--#4DINCLUDE main.css-->
<!--#4DINCLUDE product.css-->
<!--#4DBASE Scripts/-->
<!--#4DINCLUDE main.js-->
<!--#4DINCLUDE product.js-->

4DCODE  

4DCODEタグを使用すると、テンプレートに複数行の4Dコードのブロックを挿入する事ができます。

"<!--#4DCODE" シークエンスとそれに続くスペース、CRまたはLF文字が検知されると、4Dは次の"-->"シークエンスまでのコードを解釈します。コードブロック自体はキャリッジリターンもラインフィードも、あるいはその両方も含む事ができ、4Dによってシーケンシャルに解釈されます。

例えば、4DCODEタグを使用して、以下のようにテンプレート内に書く事ができます:

<!--#4DCODE
//PARAMETERS 初期化
C_OBJECT:C1216($graphParameters)
OB SET:C1220($graphParameters;"graphType";1)
$graphType:=1
//...ここにコードを書く
If(OB Is defined:C1231($graphParameters;"graphType"))
    $graphType:=OB GET:C1224($graphParameters;"graphType")
    If($graphType=7)
        $nbSeries:=1
        If($nbValues>8)
            DELETE FROM ARRAY:C228 ($yValuesArrPtr{1}->;9;100000)
            $nbValues:=8
        End if
    End if
End if
-->

注: 4DCODEタグ内では、4Dコードは必ずEnglish-US言語で書かれている必要があります。そのため、4DCODEは4Dランゲージの"リージョナルシステム設定を使用"のユーザー設定を無視します(コマンドと定数のためのランゲージを参照して下さい)。

4DCODEタグの機能は以下の通りです:

  • TRACEコマンドはサポートされており、4Dデバッガを起動するので、テンプレートコードをデバッグすることができます。
  • どのようなエラーであろうと、標準のエラーダイアログが表示され、ユーザーがコードの実行を中止したりデバッグモードに入ったりすることができます。
  • <!--#4DCODE と --> の間のテキストは改行され、どのような改行コードでも受け取ります(cr、lf、またはcrlf)
  • テキストは PROCESS 4D TAGSを呼び出したデータベースのコンテキストにてトークナイズドされます。これは例えばプロジェクトメソッドの認識等において重要です。
    注: "4DタグとURLの4DACTION経由で利用可"メソッドプロパティは考慮されません(以下のセキュリティに関する注意も参照して下さい)。
  • テキストが常にEnglish-US設定であったとしても、あるバージョンの4Dから他のバージョン間においてコマンドや定数名が改名されていることによる問題を避けるために、コマンド名や定数名はトークンシンタックスを使用する事が推奨されいます。
    注: :Cxxxシンタックスに関する詳細な情報については、フォーミュラ内でのトークンの使用の章を参照して下さい。

セキュリティに関する注意: 4DCODEタグがどのような4Dランゲージコマンドあるいはプロジェクトメソッドでも呼び出せると言う事実は、特にデータベースがHTTP経由で使用可能な場合等に、セキュリティ上の問題になり得ます。しかしながら、タグはサーバー側でのコードをテンプレートファイルから実行するため、タグそのものはセキュリティ上の問題にはなりません。このようなコンテキストにおいては、どのようなWebサーバーと同様、セキュリティは主にサーバーファイルへのリモートアクセスレベルにおいて管理されています。

シンタックス: <!--#4DIF expression--> {<!--#4DELSEIF expression2-->...<!--#4DELSEIF expressionN-->} {<!--#4DELSE-->} <!--#4DENDIF-->

<!--#4DELSEIF--> (オプション), <!--#4DELSE--> (オプション) と <!--#4DENDIF--> コメントと共に使用することで、<!--#4DIF expression--> コメントはコードの一部に条件分岐を実行させることを可能にします。

expression 引数はブール値を返す有効な4D式です。式は括弧の中に記述され、4Dのシンタックスルールに準拠していなければなりません。

<!--#4DIF expression--> ... <!--#4DENDIF--> を複数レベルでネストできます。4Dのようにそれぞれの <!--#4DIF expression--><!--#4DENDIF-->とマッチしなければなりません。

解釈エラーの場合、<!--#4DIF --><!--#4DENDIF-->“の間のコンテンツの代わりに、<!--#4DIF expression-->: ブール式が必要です”が挿入されます。

同様に、<!--#4DIF -->が同じ数の<!--#4DENDIF-->で閉じられていない場合、“<!--#4DIF expression-->: 4DENDIFが必要です” が<!--#4DIF --><!--#4DENDIF-->の間のコンテンツの代わりに挿入されます。

<!--#4DELSEIF--> タグを使用すると、条件テストの記述が容易になります。最初にTrueと判定されたブロック内にあるコードだけが実行されます。Trueブロックがない場合、文は実行されません (<!--#4DELSE-->がなければ)。
最後の<!--#4DELSEIF-->の後に<!--#4DELSE-->タグを記述できます。すべての条件がFalseの場合、<!--#4DELSE-->ブロックの文が実行されます。

以下の2つのコードは同等です

  • 4DELSEのみを使用する場合:
    <!--#4DIF Condition1-->
      /* Condition1 is true*/
    <!--#4DELSE-->
        <!--#4DIF Condition2-->
            /* Condition2 is true*/
        <!--#4DELSE-->
            <!--#4DIF Condition3-->
                /* Condition3 is true */
            <!--#4DELSE-->
                /*None of the conditions are true*/
            <!--#4DENDIF-->
        <!--#4DENDIF-->
    <!--#4DENDIF-->
  • 同じ内容を4DELSEIFタグを使用して記述した場合:
    <!--#4DIF Condition1-->
         /* Condition1 is true*/
    <!--#4DELSEIF Condition2-->
         /* Condition2 is true*/
    <!--#4DELSEIF Condition3-->
        /* Condition3 is true */
    <!--#4DELSE-->
        /* None of the conditions are true*/
    <!--#4DENDIF-->

スタティックなHTMLページに書かれたこの例題のコードは、vname#"" 式の結果に応じ、異なるラベルを表示します:

<BODY>
...
<!--#4DIF vname#""-->
Names starting with <!--#4DVAR vname-->.
<!--#4DELSE-->
No name has been found.
<!--#4DENDIF-->
...
</BODY>

この例題は接続したユーザーに基づき異なるページを返します:

<!--#4DIF LoggedIn=False-->
    <!--#4DINCLUDE Login.htm -->
<!--#4DELSEIF User="Admin"-->
    <!--#4DINCLUDE AdminPanel.htm -->
<!--#4DELSEIF User="Manager"-->
    <!--#4DINCLUDE SalesDashboard.htm -->
<!--#4DELSE-->
    <!--#4DINCLUDE ItemList.htm -->
<!--#4DENDIF-->

シンタックス: <!--#4DLOOP condition--> <!--#4DENDLOOP-->


このコメントを使用して、条件を満たす間、コードの一部を繰り返すことができます。繰り返し部のコードは<!--#4DLOOP--> と <!--#4DENDLOOP-->で挟まれます。

<!--#4DLOOP condition--> ... <!--#4DENDLOOP--> ブロックはネストできます。4Dと同様、それぞれの<!--#4DLOOP condition--> は同じ数の <!--#4DENDLOOP-->で閉じられていなければなりません。

条件には5種類あります:

  • <!--#4DLOOP [テーブル]-->
    このシンタックスは、指定された table のカレントプロセスのカレントセレクションに基づき、レコードごとにループします。2つのコメントの間のコードはカレントセレクションレコード毎に繰り返されます。
注: 4DLOOPタグがテーブルを条件として使用されると、レコードが"読み込みのみ"モードでロードされます。

以下のコードは:

<!--#4DLOOP my_method--> 
<!--#4DTEXT var--> <BR> 
<!--#4DENDLOOP-->

4Dランゲージで表すと以下のとおりです:

 FIRST RECORD([People])
 While(Not(End selec tion([People])))
    ...
    NEXT RECORD([People])
 End while

  • <!--#4DLOOP 配列-->
    このシンタックスは、配列項目ごとにループします。2つのコメントの間のコードが繰り返されるたびに、配列のカレント項目がインクリメントされます。

注: このシンタックスで二次元配列を使用することはできません。この場合、ネストしたループでメソッドを条件に使用します。

以下のコードは:

<!--#4DLOOP arr_names-->
<!--#4DTEXT arr_names{arr_names}--><BR>
<!--#4DENDLOOP-->

4Dランゲージで表すと以下のとおりです:

 For($Elem;1;Size of array(arr_names))
    arr_names:=$Elem
    ...
 End for

  • <!--#4DLOOP method-->
    このシンタックスでは、メソッドがTrueを返す間ループが行われます。メソッドは倍長整数タイプの引数を受け取ります。まずメソッドは引数0を渡されます。これは (必要に応じて) 初期化ステージとして使用できます。その後、Trueが返されるまで1, 2, 3と渡される引数値がインクリメントされます。
セキュリティのため、Webプロセス内では、On Web Authenticationデータベースメソッド が初期化ステージ (引数に0が渡されて実行される) の前に一度呼び出されます。認証されると、初期化に進みます。

警告: コンパイルのため、C_BOOLEAN($0) とC_LONGINT($1) が宣言されていなければなりません。

例題以下のコードは:

<!--#4DLOOP my_method-->
<!--#4DTEXT var--> <BR>
<!--#4DENDLOOP-->

4Dランゲージで表すと以下のとおりです:

 If(AuthenticationWebOK)
    If(my_method(0))
       $counter:=1
       While(my_method($counter))
  //...
          $counter:=$counter+1
       End while
    End if
 End if

my_method は以下のようになります:

 C_LONGINT($1)
 C_BOOLEAN($0)
 If($1=0)
  `Initialisation
    $0:=True
 Else
    If($1<50)
  //...
       var:=...
       $0:=True
    Else
       $0:=False `Stops the loop
    End if
 End if
  • <!--#4DLOOP 4D式-->
    このシンタックスでは、4DLOOPタグは4D式がTrueを返す間ループが行われます。式は有効なブール式であれば問題はなく、無限ループを防ぐために、毎ループごとに評価されるための変数部分を含んでいる必要があります。
    例えば以下のコードは:

<!--#4DEVAL $i:=0-->
<!--#4DLOOP ($i<4)-->
<!--#4DEVAL $i-->
<!--#4DEVAL $i:=$i+1-->
<!--#4DENDLOOP-->

以下の結果を生成します:

0
1
2
3

  • <!--#4DLOOP ポインター配列-->
    この場合、4DLOOPタグは配列のときと同じように振るまいます:ポインターによって参照された配列の要素ごとにループを繰り返します。カレントの配列要素は、コードの部分が繰り返される度に増加していきます。
    このシンタックスは PROCESS 4D TAGS コマンドの引数に対して配列ポインターを渡した場合に有用です
    例えば:

 ARRAY TEXT($array;2)
 $array{1}:="hello"
 $array{2}:="world"
 $input:="<!--#4DEVAL $1-->"
 $input:=$input+"<!--#4DLOOP $2-->"
 $input:=$input+"<!--#4DEVAL $2->{$2->}--> "
 $input:=$input+"<!--#4DENDLOOP-->"
 PROCESS 4D TAGS($input;$output;"elements = ";->$array)
  // $output = "elements = hello world "

解釈エラーの場合、“<!--#4DLOOP expression-->: エラーの説明” が<!--#4DLOOP --><!--#4DENDLOOP-->の間のコンテンツの代わりに挿入されます。

以下のメッセージが表示されます:
- 予期しない式のタイプ (標準のエラー);
- テーブル名が正しくありません (テーブル名のエラー);
- 配列が必要です (変数が配列でないか、二次元配列が指定された);
- メソッドが存在しません;
- シンタックスエラー (メソッド実行時);
- アクセス権エラー (テーブルやメソッドにアクセスする権限がない)。
- 4DENDLOOP が必要です (<!--#4DLOOP -->が対応する<!--#4DENDLOOP-->で閉じられていない)。

いくつかの既存の4D変換タグは、$-ベースのシンタックスを使用して表現する事ができます:
<!--#4dtag expression--> の代わりに、$4dtag (expression) という表記を使用する事ができます。

この代替シンタックスは、処理後の値を返すタグにおいてのみ使用可能です:

  • 4DTEXT
  • 4DHTML
  • 4DEVAL

(その他のタグ、例えば4DIFや4DSCRIPTなどでは、通常のシンタックスを使用して書かなければなりません)。

例えば、以下のようなコードを:

<!--#4DEVAL(UserName)-->

このような表記で置き換える事ができます:

$4DEVAL(UserName)

このシンタックスの主な利点としては、XML準拠のテンプレートを書く事ができるという点です。一部の4Dデベロッパーは、XML準拠のテンプレートを標準のXMLパーサーツールを使用して評価する必要があります。"<"文字はXML属性値としては無効なため、ドキュメントのシンタックスを破らずに4Dタグの"<!-- -->"シンタックスを使用する事はできませんでした。その一方で、"<"文字をエスケープしてしまうと、4Dがタグを正常に解釈できなくなってしまいます。

例えば、以下のコードは属性値の最初の"<"文字のためにXMLパースエラーを引き起こします:

<line x1="<!--#4DEVAL $x-->" y1="<!--#4DEVAL $graphY1-->"/>

$シンタックスを使用すると、パーサーによって以下のコードが評価されます:

<line x1="" y1=""/>

ここで、$4dtag<--#4dtag --> は厳密には同じではないという点に注意して下さい。<--#4dtag -->とは異なり、$4dtagは4Dタグを繰り返し解釈する事はしません。$タグは常に一度だけ解釈され、その結果は標準テキストとして読まれます。

注: 繰り返し処理については、再起的処理の段落を参照して下さい。

この違いの理由は、悪意あるコードの侵入を防ぐためにあります。以下に説明されているように、ユーザーテキストを使用していてタグの不要な繰り返し処理を避けるためには、4DHTMLタグではなく4DTEXTタグの使用が強く推奨されます。4DTEXTを使用した場合、"<"などの特殊記号はエスケープされてしまうため、<!--#4dtag expression --> シンタックスを使用している4Dタグは全て元の意味を失ってしまいます。しかしながら4DTEXTは$記号はエスケープしないので、悪意あるコードの侵入を防ぐために$4dtag (expression) シンタックスにおける繰り返し解釈のサポートを取りやめる事にしました。

以下の例では、使用されるシンタックスとタグによる処理の結果の違いを表しています:

  // 例 1
 myName:="<!--#4DHTML QUIT 4D-->" //悪意あるコードの侵入
 input:="My name is: <!--#4DHTML myName-->"
 PROCESS 4D TAGS(input;output)
  //4D は終了していまいます

  // 例 2
 myName:="<!--#4DHTML QUIT 4D-->" //悪意あるコードの侵入
 input:="My name is: <!--#4DTEXT myName-->"
 PROCESS 4D TAGS(input;output)
  //結果は"My name is:  & lt;!--#4DHTML QUIT 4D-->"

  // 例 3
 myName:="" //悪意あるコードの侵入
 input:="My name is: <!--#4DTEXT myName-->"
 PROCESS 4D TAGS(input;output)
  //結果は"My name is: ERROR: missing ')'"

シンタックスでは合致した引用符や括弧を閉じる事をサポートしているという点に注意して下さい。例えば、以下の(非現実的な)文字列を評価しなければならない場合:

String(1) + "\"(hello)\""

以下のように書く事ができます:

 input:="$4DEVAL( String(1)+\"\\\"(hello)\\\"\")"
 PROCESS 4D TAGS(input;output)
 -->output is 1"(hello)"