diff options
Diffstat (limited to 'packages/fcl-mustache/examples/mustache.lpr')
-rw-r--r-- | packages/fcl-mustache/examples/mustache.lpr | 207 |
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. + |