Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2012-07

Generating templates with FPTemplate

7 messages · 3 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

luciano de souza

Hello all,

I am trying to create an example with the FPTemplate unit. Firstly, I wrote a hypothetical unit template.

{e030.txt}

unit <#name>;
{$mode objfpc}{$H+}

interface
uses
<#modules>

implementation
end.

And now the code:

{e030.pp}

program e030;
{$mode objfpc}{$H+}
uses
fptemplate, classes;
var
source: TFPTemplate;
parser: TTemplateParser;
BEGIN
source := TFPTemplate.create;
parser := TTemplateParser.create;
try
source.filename := 'e030.txt';
parser.values['name'] := 'freevox';
parser.values['modules'] := 'sysutils, classes';
writeln(parser.ParseString(source.template));
finally
parser.free;
source.free;
end;
end.

I am not successful in filling up the template. If I do writeln(source.template), the answer is an empty string. If I do writeln(source.GetContent), the answer is the template without the needed replacements.

So I ask: what is wrong? How can I get a file, to replace tags and to get a replaced string?

Regards,

Luciano de Souza
Unknown author
to luciano de souza
luciano de souza wrote
Hello all, I am trying to create an example with the FPTemplate unit. Firstly, I wrote a hypothetical unit template.

[snip]

Show quoted text 8 lines
I am not successful in filling up the template. If I do writeln(source.template), the answer is an empty string. If I do writeln(source.GetContent), the answer is the template without the needed replacements. So I ask: what is wrong? How can I get a file, to replace tags and to get a replaced string?

1. You need only one of the two classes, never both at the same time.
2. You need to set the correct delimiters. Default are { and }

If you want to have fixed values for parameters, the easiest is TTemplateParser. TFPCustomTemplate (or TFPTemplate) does not have fixed values, everything is event driven.

So, the following will do what you want:

program e30;
{$mode objfpc}{$H+}
uses
   fptemplate, classes;
var
   T : TTemplateParser;
   Fin,Fout : TFileStream;
BEGIN
   T := TTemplateParser.create;
   try
     T.StartDelimiter:='<#';
     T.EndDelimiter:='>';
     T.values['name'] := 'freevox';
     T.values['modules'] := 'sysutils, classes';
     T.AllowTagParams:=False;
     Fin:=TFileStream.Create('e30.txt',fmOpenRead);
     try
       Fout:=TFileStream.Create('freevox.pas',fmCreate);
       try
         T.ParseStream(fin,fout);
       finally
         Fout.Free;
       end;
     finally
       Fin.Free;
     end;
   finally
     T.free;
   end;
end.

Running this produces the file you want:

fsb: >e30
fsb: >cat freevox.pas
unit freevox;
{$mode objfpc}{$H+}

interface
uses
sysutils, classes

implementation
end.

That's it.

In revision 21977, I added a ParseFiles call, which makes the program even easier:

program e30;
{$mode objfpc}{$H+}
uses
   fptemplate, classes;
var
   T : TTemplateParser;
BEGIN
   T := TTemplateParser.create;
   try
     T.StartDelimiter:='<#';
     T.EndDelimiter:='>';
     T.values['name'] := 'freevox';
     T.values['modules'] := 'sysutils, classes';
     T.AllowTagParams:=False;
     T.ParseFiles('e30.txt','freevox.pas');
   finally
     T.free;
   end;
end.

Michael.

leledumbo
to luciano de souza: I am trying to create an example with the FPTemplate unit. Firstly, I wrote a…

try this:

type
  TMyTemplate = class(TFPTemplate)
  private
    procedure ReplaceMyTags(Sender : TObject; Const TagString : String;
TagParams:TStringList; Out ReplaceText : String);
  public
    constructor Create;
  end;
procedure TMyTemplate.ReplaceMyTags(Sender : TObject; Const TagString :
String; TagParams:TStringList; Out ReplaceText : String);
begin
  // use if-else if-else if your compiler version doesn't support case
statement with string variable
  case TagString of
    'name': ReplaceText := 'sysutils, classes';
    'modules': ReplaceText := 'freevox';
  end;
end;
constructor TMyTemplate.Create;
begin
  inherited Create;
  StartDelimiter := '<#';
  EndDelimiter := '>';
  OnReplaceTag := @ReplaceMyTags;
end;
begin
  with TMyTemplate.Create do
    try
      FileName := 'e030.txt';
      WriteLn(GetContent);
    finally
      Free;
    end;
end.

if you want to use your style, you can try adapting http://free-pascal-general.1045716.n5.nabble.com/file/n5710450/view.pp my unit . It's more or less like what you want, only with more features as I support parameters.

View this message in context: http://free-pascal-general.1045716.n5.nabble.com/Generating-templates-with-FPTemplate-tp5710448p5710450.html Sent from the Free Pascal - General mailing list .
leledumbo
to Unknown author: [snip] 1. You need only one of the two classes, never both at the same time. 2. You need…

Hey, that's nice, Michael. I never think of using TTemplateParser directly as I thought it was meant to be used internally by TFPTemplate only. Now I see that it actually has more features through OO approach instead of event driven.

View this message in context: http://free-pascal-general.1045716.n5.nabble.com/Generating-templates-with-FPTemplate-tp5710448p5710451.html Sent from the Free Pascal - General mailing list .
Luciano de Souza
to leledumbo: try this: type TMyTemplate = class(TFPTemplate) private procedure ReplaceMyTags(Sender :…
leledumbo wrote 57 lines
try this: type TMyTemplate = class(TFPTemplate) private procedure ReplaceMyTags(Sender : TObject; Const TagString : String; TagParams:TStringList; Out ReplaceText : String); public constructor Create; end; procedure TMyTemplate.ReplaceMyTags(Sender : TObject; Const TagString : String; TagParams:TStringList; Out ReplaceText : String); begin // use if-else if-else if your compiler version doesn't support case statement with string variable case TagString of 'name': ReplaceText := 'sysutils, classes'; 'modules': ReplaceText := 'freevox'; end; end; constructor TMyTemplate.Create; begin inherited Create; StartDelimiter := '<#'; EndDelimiter := '>'; OnReplaceTag := @ReplaceMyTags; end; begin with TMyTemplate.Create do try FileName := 'e030.txt'; WriteLn(GetContent); finally Free; end; end. if you want to use your style, you can try adapting http://free-pascal-general.1045716.n5.nabble.com/file/n5710450/view.pp my unit . It's more or less like what you want, only with more features as I support parameters. -- View this message in context: http://free-pascal-general.1045716.n5.nabble.com/Generating-Yes, it's really very good. An example like that could be added to the source package. Templating with parameters? Oh! Yes, there are lots of interesting things I can do with it! Thank you! templates-with-FPTemplate-tp5710448p5710450.html Sent from the Free Pascal - General mailing list . _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Luciano de Souza
to Unknown author: [snip] 1. You need only one of the two classes, never both at the same time. 2. You need…

Michael,
Your example is very clear. I am not very good to understand source codes. But this style seems to be very good and logical. It's really wonderful: FPC owns units for everything! Thank you.

Show quoted text 113 lines
On Fri, 27 Jul 2012, luciano de souza wrote: > Hello all, > > I am trying to create an example with the FPTemplate unit. Firstly, I > wrote a hypothetical unit template. [snip] > > I am not successful in filling up the template. If I do > writeln(source.template), the answer is an empty string. If I do > writeln(source.GetContent), the answer is the template without the > needed replacements. > > So I ask: what is wrong? How can I get a file, to replace tags and to > get a replaced string? 1. You need only one of the two classes, never both at the same time. 2. You need to set the correct delimiters. Default are { and } If you want to have fixed values for parameters, the easiest is TTemplateParser. TFPCustomTemplate (or TFPTemplate) does not have fixed values, everything is event driven. So, the following will do what you want: program e30; {$mode objfpc}{$H+} uses fptemplate, classes; var T : TTemplateParser; Fin,Fout : TFileStream; BEGIN T := TTemplateParser.create; try T.StartDelimiter:='<#'; T.EndDelimiter:='>'; T.values['name'] := 'freevox'; T.values['modules'] := 'sysutils, classes'; T.AllowTagParams:=False; Fin:=TFileStream.Create('e30.txt',fmOpenRead); try Fout:=TFileStream.Create('freevox.pas',fmCreate); try T.ParseStream(fin,fout); finally Fout.Free; end; finally Fin.Free; end; finally T.free; end; end. Running this produces the file you want: fsb: >e30 fsb: >cat freevox.pas unit freevox; {$mode objfpc}{$H+} interface uses sysutils, classes implementation end. That's it. In revision 21977, I added a ParseFiles call, which makes the program even easier: program e30; {$mode objfpc}{$H+} uses fptemplate, classes; var T : TTemplateParser; BEGIN T := TTemplateParser.create; try T.StartDelimiter:='<#'; T.EndDelimiter:='>'; T.values['name'] := 'freevox'; T.values['modules'] := 'sysutils, classes'; T.AllowTagParams:=False; T.ParseFiles('e30.txt','freevox.pas'); finally T.free; end; end. Michael. _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Unknown author
to Luciano de Souza
Luciano de Souza wrote
Michael, Your example is very clear. I am not very good to understand source codes. But this style seems to be very good and logical. It's really wonderful: FPC owns units for everything!

Well, I use FPC for everything. So, I need tools for everything, and what better way than to make these tools open source and share them ?

This way everyone benefits, me included...

Michael.