WebStencilsProcessorの使用例

解決


jiro  2026-09-29 18:21:43  No: 152313

WebStencilsProcessorを利用するサンプルプログラムを書いて実験していますが
予定している動作をしません問題点指摘いただけると助かります。


uses System.JSON;

procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject;
  Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var
  jstemp: TJSONObject;
  ja, jatemp: TJSONArray;
begin
  WebStencilsProcessor1.InputLines.Text:='''
  @ForEach Items {
  <p>@loop.id</p>
    @ForEach (var Data in loop.Datas) {
    <p>@Data.tag</p>
    }
  }
  ''';
  ja:=TJSONArray.Create;
  for var i := 1 to 5 do
  begin
    jstemp:=TJSONObject.Create;
    jatemp:=TJSONArray.Create;
    ja.AddElement(jstemp);
    jstemp.AddPair('id',i);
    jstemp.AddPair('Datas',jatemp);

    for var j := 10 downto 1 do
    begin
      jstemp:=TJSONObject.Create;
      jstemp.AddPair('tag',j);
      jatemp.AddElement(jstemp);
    end;
  end;
  WebStencilsProcessor1.AddVar('Items',ja);
  Response.Content := WebStencilsProcessor1.Content;
end;


AAAAA  2026-09-30 20:47:28  No: 152314

WebStencilsProcessor1.OnError でエラー表示みてる?


jiro  2026-10-01 19:38:43  No: 152315

お疲れ様ですAAAAA様
書き込みありがとうございます以下のハンドラを追加してみましたが
HTMLの記述がおかしいのかJSONObjectだと難しいのかよくわからない状況です

procedure TWebModule1.WebStencilsProcessor1Error(Sender: TObject;
  const AMessage: string);
begin
  TFile.AppendAllText('log.txt',AMessage,TEncoding.ANSI);
end;
まずは休日を利用して取り組んでみます


AAAAA  2026-10-01 20:43:29  No: 152316

プロパティ "id" が "loop" クラスの "TJSONObject" オブジェクトで見つかりません
プロパティ "Datas" が "loop" クラスの "TJSONObject" オブジェクトで見つかりません
ループ サブオブジェクト "Datas" が "loop" で見つかりません
プロパティ "id" が "loop" クラスの "TJSONObject" オブジェクトで見つかりません
プロパティ "Datas" が "loop" クラスの "TJSONObject" オブジェクトで見つかりません
ループ サブオブジェクト "Datas" が "loop" で見つかりません
プロパティ "id" が "loop" クラスの "TJSONObject" オブジェクトで見つかりません
プロパティ "Datas" が "loop" クラスの "TJSONObject" オブジェクトで見つかりません
ループ サブオブジェクト "Datas" が "loop" で見つかりません
プロパティ "id" が "loop" クラスの "TJSONObject" オブジェクトで見つかりません
プロパティ "Datas" が "loop" クラスの "TJSONObject" オブジェクトで見つかりません
ループ サブオブジェクト "Datas" が "loop" で見つかりません
プロパティ "id" が "loop" クラスの "TJSONObject" オブジェクトで見つかりません
プロパティ "Datas" が "loop" クラスの "TJSONObject" オブジェクトで見つかりません
ループ サブオブジェクト "Datas" が "loop" で見つかりません

とでると思うけど
エラーそのまま プロパティーがないから 

    jstemp.AddPair('id',i);
    jstemp.AddPair('Datas',jatemp);
   jstemp.AddPair('tag',j);

オブジェクトの Property を見ているみたいで
この id とか Datas とか tag とかは参照できないぽい

unit Web.Stencils;
interface
uses
  System.SysUtils, System.Classes, System.Generics.Collections, System.Rtti,
  System.Bindings.EvalProtocol, Data.DB, Web.HTTPApp;

   System.JSON ないしね。



TWebStencilsProcessor の

    function EvalVariableValue(const AObjName, APropName: string; ARetType: TRetType): Variant;
    function EvalExpressionValue(const AExpression: string; ARetType: TRetType): Variant;
    function DoStream(AStream: TStream): string; virtual;

あたりを見ると わかるかも

    function EvalVariableValue(const AObjName, APropName: string; ARetType: TRetType): Variant;
 で

    else if LVar.LoopObject is TStrings then
    ..
      NAME , VALUE   (loop.name や loop.Value で見れる)
    ..
    else if LVar.LoopObject is TDataSet then
    ..
   else 
      GetObjectProperty(LVar.LoopObject, AObjName, APropName, LBool);
  でプロパティーを見にいっている

      loop.(オブジェクトのプロパティー名)で見れる


jiro  2026-10-01 21:14:00  No: 152317

何とか完成できました
エレガントには感じられないけれどpublic propertyしないと読み取りませんという意見をAIから受けました。
試してみると確かにうまくいきました。
ご報告です 

 TData = class
  private
    FTag: string;
    FId: integer;
  public
    property Tag: string read FTag write FTag;
    property Id: integer read FId write FId;
  end;

  TMyData = array [0..5] of TData;

  TItem = class
  private
    FId: integer;
    FDatas: TObjectList<TData>;
  public
    constructor Create;
    destructor Destroy; override;
    property id: integer read FId write FId;
    property Datas: TObjectList<TData> read FDatas;
  end;

var
  WebModuleClass: TComponentClass = TWebModule1;

implementation

{%CLASSGROUP 'Vcl.Controls.TControl'}

{$R *.dfm}

uses System.JSON, System.IOUtils;

procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject;
  Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
  WebStencilsProcessor1.InputLines.Text:='''
    @ForEach Items {
    <p>@loop.id</p>
        @ForEach (var Data in loop.Datas) {
            <p>@Data.id / @Data.tag</p>
        }
    }
    ''';
  var ls:=TObjectList<TItem>.Create;
  for var i := 0 to 3 do
  begin
    var item:=TItem.Create;
    ls.Add(item);
    item.id:=i;
    for var j := 2 downto 1 do
    begin
      var data:=TData.Create;
      item.Datas.Add(data);
      data.Tag:='active';
      data.Id:=j;
    end;
  end;
  WebStencilsProcessor1.AddVar('Items',ls);
  Response.Content := WebStencilsProcessor1.Content;
end;

procedure TWebModule1.WebStencilsProcessor1Error(Sender: TObject;
  const AMessage: string);
begin
  TFile.AppendAllText('log.txt',AMessage,TEncoding.ANSI);
end;

{ TItem }

constructor TItem.Create;
begin
  FDatas:=TObjectList<TData>.Create;
end;

destructor TItem.Destroy;
begin
  FDatas.Free;
  inherited;
end;


※作成する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。







   このエントリーをはてなブックマークに追加