summaryrefslogtreecommitdiff
path: root/packages/fcl-mustache/examples/mustache.lpr
diff options
context:
space:
mode:
Diffstat (limited to 'packages/fcl-mustache/examples/mustache.lpr')
-rw-r--r--packages/fcl-mustache/examples/mustache.lpr207
1 files changed, 207 insertions, 0 deletions
diff --git a/packages/fcl-mustache/examples/mustache.lpr b/packages/fcl-mustache/examples/mustache.lpr
new file mode 100644
index 0000000000..7a48df1dad
--- /dev/null
+++ b/packages/fcl-mustache/examples/mustache.lpr
@@ -0,0 +1,207 @@
+program mustache;
+
+{$mode objfpc}{$H+}
+
+uses
+ {$IFDEF UNIX}
+ cthreads,
+ {$ENDIF}
+ Classes, SysUtils, CustApp, strutils, fpjson, jsonparser, csvdataset, fpMustache, fpexmustache, fpdbmustache, iostream;
+
+type
+
+ { TMustacheApplication }
+
+ TMustacheApplication = class(TCustomApplication)
+ private
+ FTemplate : TMustacheString;
+ FJSON : TJSONStringType;
+ FCSV: TCSVDataset;
+ FPartials,
+ FDefines : TStrings;
+ FAllowExpressions : Boolean;
+ Foutput,
+ FSection,
+ FRootPath : String;
+ procedure DoGetDefine(const aName: TMustacheString; var aHandled: Boolean;
+ var aValue: TMustacheString);
+ procedure ProcessOptions;
+ Procedure Createoutput;
+ procedure Usage(ErrorMsg: String);
+ protected
+ procedure DoRun; override;
+
+ public
+ constructor Create(TheOwner: TComponent); override;
+ destructor Destroy; override;
+ end;
+
+{ TMustacheApplication }
+
+procedure TMustacheApplication.Usage(ErrorMsg : String);
+
+begin
+ If ErrorMsg<>'' then
+ Writeln('Error : ',ErrorMsg);
+ Writeln('Usage : mustache [options]');
+ Writeln('Where options is one or more of:');
+ writeln('-c --csv=FILE Use a CSV file as data source. First line must contain column names.');
+ writeln('-d --define=name=value Define fixed value.');
+ writeln('-e --expressions Allow expressions.');
+ writeln('-h --help This message.');
+ writeln('-j --json=JSON Use JSON as data source. @FILENAME will read JSON from file (UTF8).');
+ writeln('-o --output=FILE output file to write output to. If empty, stdout is assumed.');
+ writeln('-p --partial=name=PARTIAL Register partial. @FILENAME reads partial from file.');
+ writeln('-r --root=PATH Register variables at root path PATH for expression engine');
+ writeln('-s --section=SECTIOn Section name for CSV data');
+ writeln('-t --template=TEMPLATE Use TEMPLATE as data source. @FILENAME will read template from file (UTF8). Required.');
+ Halt(Ord(ErrorMsg<>''));
+end;
+
+procedure TMustacheApplication.ProcessOptions;
+
+ Function StringOrFile(S : String) : UTF8String;
+
+ begin
+ if Copy(S,1,1)<>'@' then
+ Result:=S
+ else
+ With TFileStream.Create(Copy(S,2,Length(S)-1),fmOpenRead or fmShareDenyNone) do
+ try
+ SetLength(Result,Size);
+ ReadBuffer(Result[1],Size);
+ finally
+ Free;
+ end;
+ end;
+
+Var
+ S : String;
+
+begin
+ if Not HasOption('t','template') then
+ Raise Exception.Create('Need a template');
+ if HasOption('c','csv') and HasOption('j','json') then
+ Raise Exception.Create('Cannot specify both JSON or CSV');
+ FTemplate:=StringOrFile(GetOptionValue('t','template'));
+ if HasOption('j','json') then
+ FJSON:=StringOrFile(GetOptionValue('j','json'))
+ else if HasOption('c','csv') then
+ begin
+ FCSV:=TCSVDataset.Create(Self);
+ FCSV.FileName:=GetOptionValue('c','csv');
+ FCSV.CSVOptions.FirstLineAsFieldNames:=True;
+ FCSV.Open;
+ end;
+ for S in GetOptionValues('d','define') do
+ FDefines.Add(S);
+ for S in GetOptionValues('p','partial') do
+ FPartials.Add(ExtractWord(1,S,['='])+'='+StringOrFile(ExtractWord(2,S,['='])));
+ FAllowExpressions:=HasOption('e','expressions');
+ FRootPath:=GetOptionValue('r','root');
+ FSection:=GetOptionValue('s','section');
+ if FSection='' then
+ FSection:='data';
+ Foutput:=GetOptionValue('o','output');
+end;
+
+procedure TMustacheApplication.DoGetDefine(const aName: TMustacheString;
+ var aHandled: Boolean; var aValue: TMustacheString);
+
+Var
+ Idx : Integer;
+
+begin
+ Writeln('Getting define ',aName);
+ Idx:=FDefines.IndexOfName(aName);
+ aHandled:=Idx<>-1;
+ if aHandled then
+ aValue:=FDefines.ValueFromIndex[Idx]
+ else
+ aValue:='';
+end;
+
+procedure TMustacheApplication.DoRun;
+var
+ ErrorMsg: String;
+begin
+ Terminate;
+ // quick check parameters
+ ErrorMsg:=CheckOptions('het:j:c:d:o:r:', ['help','template','json','csv','define','output','expressions','root']);
+ if (ErrorMsg<>'') or HasOption('h','help') then
+ Usage(ErrorMsg);
+ ProcessOptions;
+ CreateOutput;
+end;
+
+procedure TMustacheApplication.CreateOutput;
+
+Var
+ M : TMustache;
+ C : TMustacheContext;
+ O : TStream;
+ S : TMustacheString;
+
+begin
+ O:=Nil;
+ M:=Nil;
+ C:=Nil;
+ try
+ if FAllowExpressions then
+ M:=TMustache.Create(Self)
+ else
+ begin
+ M:=TMustacheExpr.Create(Self);
+ if (FRootPath<>'') and (FJSON<>'') then
+ TMustacheExpr(M).RegisterVariables(FJSON,FRootPath,True);
+ end;
+ M.Partials:=FPartials;
+ if Assigned(FCSV) then
+ begin
+ C:=TMustacheDBContext.Create(@DoGetDefine);
+ TMustacheDBContext(C).AddDataset(FCSV,FSection);
+ end
+ else if (FJSON<>'') then
+ C:=TMustacheJSONContext.Create(GetJSON(FJSON),@DoGetDefine)
+ else
+ C:=TMustacheContext.Create(@DoGetDefine);
+ if Foutput<>'' then
+ O:=TFileStream.Create(Foutput,fmCreate)
+ else
+ O:=TIOStream.Create(iosOutput);
+ M.Template:=FTemplate;
+ S:=M.Render(C);
+ O.WriteBuffer(S[1],Length(S));
+ finally
+ O.Free;
+ C.Free;
+ M.Free;
+ end;
+end;
+
+constructor TMustacheApplication.Create(TheOwner: TComponent);
+begin
+ inherited Create(TheOwner);
+ FPartials:=TStringList.Create;
+ FDefines:=TStringList.Create;
+ StopOnException:=True;
+end;
+
+destructor TMustacheApplication.Destroy;
+begin
+ FreeAndNil(FPartials);
+ FreeAndNil(FDefines);
+ FreeAndNil(FCSV);
+ inherited Destroy;
+end;
+
+
+var
+ Application: TMustacheApplication;
+begin
+ Application:=TMustacheApplication.Create(nil);
+ Application.Title:='Mustache Templater';
+ Application.Run;
+ Application.Free;
+end.
+