RAD Studio バージョン12.2では、WebBrokerおよびRAD Serverテクノロジーに対するHTMLファイルのサーバーサイドのスクリプトベースの統合/処理を実現するWebStencilsが導入されました。
WebStencilsは、「テンプレートエンジン」とも呼ばれる機能で、このコンポーネントは、WebBroker および RAD Server で使用できますが、DataSnap や Web 以外のアプリケーションでも使用でき、HTML、JSON、YAML、カンマ区切りファイル、または特定のデータをマージする必要があるその他のファイルを作成できます。アプリケーションコードは、DelphiまたはC++で記述できます。
WebStencilsの主な目的は、サーバーサイドスクリプトを提供し、RAD ServerをWebサービスエンジンからWebサイトおよびWebサービスツールに変えることで、RAD Studioの既存のWebテクノロジー(WebBroker、DataSnap、RAD Server)を大幅に拡張することです。つまり、標準ツールでHTMLページを作成し、CSSやJavaScriptライブラリを任意に採用できる一方で、データベース クエリの結果やその他の複雑なデータ処理など、アプリケーションから生成されたページからデータを追加する機能も保持します。
言い換えれば、主な目的は、ブログ、オンライン カタログ、オンライン注文システム、辞書のようなリファレンス、Wiki などのナビゲーションおよびインタラクティブな Web サイトを支援することです。これらはすべて、ナビゲーションWebサイトの例です。
主な目的は、ナビゲーションとインタラクティブなWebサイトを支援することです。ブログ、オンラインカタログ、オンライン注文システム、辞書のようなリファレンス、Wikiなどです。これらはすべてナビゲーションウェブサイトの例です。さらに、WebStencilsはWeb開発ソリューションとしてHTMXの優れた基盤となります。この2つのテクノロジーはうまく連携します。HTMXページはサーバーサイドのコード生成のメリットを享受でき、コンテンツの更新に関してRESTサーバーに接続できます。DelphiのWebテクノロジーは、非常に高い品質レベルでのページ生成とREST APIの提供が可能です。
さらに、WebStencils は、Web 開発ソリューションとしての HTMX の優れた基盤となり、この 2 つのテクノロジはうまく連携します。HTMX ページは、サーバー側コード生成のメリットを享受でき、コンテンツの更新に関して REST サーバーに接続できます。Delphi Webテクノロジは、非常に高品質なページ生成と REST API を提供できます。
Table of Contents
PageProducerからWebStencilsProcessorへ
従来のWebBrokerとDataSnapライブラリは、Webサーバーアプリケーションが返すHTMLをカスタマイズするために、PageProducerコンポーネントおよび派生コンポーネントを使用していました。処理は非常に限定的で、Webサイトのページに共有テンプレートを用意する簡単な方法はありませんでした。また、タグベースの表記法(<#custom attrib=「value」>)は、あまり使いやすいものではありませんでした。WebStencilsは、複雑なHTMLページへの記述やメンテナンスが容易な異なる表記法(以前のタグは、@custom.valueとなります)を提供し、条件分岐やループ処理のステートメントを追加し、テンプレートとインクルードのメカニズムを導入しています。
新しいWebStencilsProcessorコンポーネントは、同じインターフェースを実装しており、WebBroker や DataSnap WebAction で使用できるため、PageProducerの代替コンポーネントとして機能します。さらにこのコンポーネントを WebModule(RAD StudioのWeb アプリケーションで使用される設計時データモジュール)に配置し、アクションにフックすれば、すぐに使い始めることができます。それでは簡単なデモを紹介する前に、WebStencils の構文とその他の主要な要素について確認しておきましょう。
下図は、WebStencilsProcessorコンポーネントがWebBrokerのアクションに接続されている例です。
WebStencilsの構文
RAD StudioのWebStencilsスクリプト言語は、以下の要素に基づいた非常にシンプルな構文を持っています。
- @symbolは、HTMLに追加する特別なマーカーで、@symbolの後に続くのは次の通りです。
- オブジェクト名またはフィールド名
- 特別な処理キーワード (foreach、if、layoutpage、loginrequired、loop、renderbody、include、query 等)
- もう一つの @ symbol
- 中括弧 { } は、オプションまたは繰り返しブロックを表し、条件文やループで使用
オブジェクトの値へのアクセス
一般的な値へのアクセスは、ドット記法(@myobject.value)に基づいています。これは何を意味するのでしょうか?
オブジェクトの名前(myobject)は、シンボリックなローカル名です。複数の方法で定義できます。
- スクリプト変数、サーバーサイドアプリケーションの実際のオブジェクトへのシンボリックな名前付きマップであり、スクリプトが実行される前に WebStencilsProcessor に割り当てられます。
- 属性でマークされた WebModule 変数にすることができます。 (Delphi のみ)
- 特定のWebStencilsProcessorコンポーネントのOnGetValueイベントハンドラを処理するコード内で解決できます。この場合、サーバー アプリケーションの任意のデータ構造で名前を完全な柔軟性で検索できます。
オブジェクトの特定の要素(値)の名前は、以下にマッピングすることができます。
- オブジェクト自体のプロパティ名
- オブジェクトがデータセットの場合のフィールド名
- Processorに関連付けられた OnGetValue イベントハンドラに渡される一般的な文字列
ドット表記による値へのアクセス
HTML WebStencilsのスニペットとして例えば、 以下のようなコードがあるとします。
1 2 |
<h2>GetValue</h2> <p>Value obtained from data: @data.name</p> |
以下のようにイベント ハンドラ(OnValue イベント) を持つコンポーネントを使用してデータを提供できます。
1 2 3 4 5 6 7 8 9 10 |
procedure TWebModule13.WebStencilsValueFromEventValue( Sender: TObject; const ObjectName, FieldName: string; var ReplaceText: string; var Handled: Boolean) begin if SameText (ObjectName, 'data') then begin Handled := True; ReplaceText := 'You requested ' + FieldName; end; end; |
この単純なケースでは、コードはオブジェクト名 (ドットの前のシンボルの最初の部分) のみをチェックしますが、通常は、ドットの後のシンボルである FieldName もチェックする必要があります。
別の方法として、オブジェクトを使用して値を提供することもできます。この場合、オブジェクトをActionのProducerに関連付けるように構成する必要があります。
以下のコードは、Name 文字列プロパティを持つ TMyObject クラスを想定した完全な例です。
Delphiの複数行文字列を使用してHTMLテンプレートを定義するコードは、オブジェクトをスクリプト変数として登録し(AddVarを呼び出す)、「world」という名前で登録し、そのContentプロパティにアクセスしてスクリプトを実行すると、その実行結果は「Value obtained from data: Hello hello.」になります。
DataSet を利用する
オブジェクトではなく、データセットの現在のレコードを使用する代替オプションもあります。例えば、ClientDataSetの場合、初期化コードは次のようになります。
上記のコード例では、名前がdatasetのClientDataSetを登録します。対応するHTMLでは、foreachループとループの現在の要素(つまり、現在のレコード)を参照するWebStencilsキーワード@loopを使用して、オブジェクトと各レコードのフィールドの一部を参照することができます。
そして出力結果は、以下の通りです。
テンプレート:レイアウトと本文
テンプレートエンジンに必須の機能は、共有HTMLテンプレートと実際のページコンテンツをマージする機能で、以下の特別な記号を使用して実現されます。。
- @LayoutPage filename: このコマンドは、特定の HTML ページ(通常はページの先頭)で使用し、特定のページの構造としてどのテンプレートファイルを使用するかを指定します。複数のページで同じテンプレートを共有することは可能ですが、プロジェクト内のすべてのページ(TWebStencilsEngineを使用する場合でも)や仮想フォルダで同じテンプレートを使用する必要はありません。 1つのページでこのコマンドを使用できるのは1回だけであることに注意してください。 2つ以上の@LayoutPageを使用しようとすると、例外によりブロックされます。
- @RenderBody: このコマンド(パラメータなし)は、特定のページの実際のコンテンツを配置する場所を示すテンプレートファイル内のプレースホルダです。
特定のページとサンプルテンプレートにおける@LayoutPageと@RenderBodyの使用例は、以下の通りです。ご覧のとおり、ページは特定のテンプレートを参照しており、一方、テンプレートにはページコンテンツをマージする場所を示す一般的なプレースホルダがあります。これは上記のページを生成するために使用されたHTMLコードの縮小版であることに注意してください。
Test.html
1 2 3 |
@LayoutPage BaseTemplate <h2>Page Test3</h2> <p>Local data param one is @page.name (the page name)</p> |
BaseTemplate.html
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<html lang="en"> <head> <link href="https://.../bootstrap.min.css" rel="stylesheet"> </head> <body> <nav class="navbar navbar-expand-md bg-dark mb-4">... <main class="container"> <div class="bg-light p-5 rounded"> @RenderBody </div> </main> </body> </html> |
2つのWebStencilsコンポーネント
最後に、新しいWebStencilsパッケージで提供される2つの異なるコンポーネントについて触れておきたいと思います。
- WebStencilsProcessor コンポーネント:このコアコンポーネントは、HTMLファイルを受け取り、WebStencils表記を埋め込み、@タグを処理した後にプレーンなHTMLに変換します。このコンポーネントは、メモリ内またはファイル(および関連するテンプレートがある場合)内のHTML文字列を処理できます。プロセッサは次のいずれかです。
- スタンドアロンで使用され、TWebActionItem.Producerプロパティに割り当てられます。
- TWebStencilsEngine コンポーネントによって自動的に作成および呼び出され、実際の処理が実行されます。
- WebStencilsEngineコンポーネント:これは「エンジン」コンポーネントであり、次の 2 つの異なるシナリオで使用できます。
- 特定のプロセッサごとにカスタマイズするのではなく、1 つ以上の WebStencilsProcessor コンポーネントに接続して、共有設定と動作を提供できます。
- 必要に応じてWebStencilsProcessorコンポーネントを作成し、このコンポーネントのみをWebモジュールに配置することができます。
両方のコンポーネントを含むWebModuleは下図のとおりです。
これは一見しただけではあまり明白ではないかもしれませんが、全体的には、WebStencilsProcessorは単一のURLを処理するために使用され(1つのアプリケーションに複数のURLを定義することもできます)、WebStencilsEngineはURLを実際の処理対象ファイルにマッピングする独自の定義を行うことができ、さらに各サーバーサイドコードを実行するメカニズムも提供しています。こちらの方法はまた別の機会に紹介したいと思います。
WebStencilsEngineの紹介
本ブログでは、ここまででWebBroker のアクションに直接的または間接的に関連付けられた Processors コンポーネントを使用した簡単なデモを紹介いたしました。これは便利ですが、数十または数百の異なる URL を持つ Web サーバーには対応していません。そのためEngineコンポーネントも用意されています。
しかし、これはどのように動作するのでしょうか。URLを処理するファイルにマッピングするにはどうすればよいのでしょうか。またサーバー上で実行する特定のコードを関連付けるにはどうすればよいのでしょうか。 WebStencilsEngineコンポーネントには、URLパスを特定のファイルに関連付けるために使用できるPathTemplatesコレクションプロパティがあります。下記は、RAD Serverパッケージの例です。
PathTemplates コレクション プロパティには別の目的もあります。それがマッピングされていない値 (company など) がリストされている理由です。コレクション内の各項目に、URL が一致したときに実行される初期化コードを持つイベントハンドルを関連付けることができます。これは前述の OnAction イベントハンドラのコードと同様です。例えば、companyの URLに関する以下のコード例では、URL に渡されてスクリプト変数に保存された ID パラメーターがあるかどうかを確認し、それを使用して Web ページに表示するデータセット内の特定のレコードを検索します。
WebStencilsエンジンの補足情報
WebStencilsエンジンはかなり複雑です。WebStencilsキーワードは他にもたくさんあり、2つのコンポーネントで数十のプロパティ、メソッド、イベントがあります。Embarcadero DocWikiのWebStencilsに説明がありますが、現在、もっと詳細なドキュメントの作成に取り組んでおります。またWebStencilsの1専門家が一人が書籍を作成中です。WebStencilsにつきましては、もし機会があればまたブログで取り上げたいと思います。
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition