This might be a little long, but I wrote some steps and code snippets about how to use templates (FPTemplate):
Creating CGI or Apache applications with WebModule, using HTML templates (FPTemplate)
Hello World first:
1. File -> New -> CGI application or Apache module
2. in the Project -> Compiler options put the path to the httpd22 (we are using Apache 2.2 web server) directory into the Other Unit files field
(ex: C:\pp\units\i386-win32\httpd22\)
3. Click inside the webmodule if not already selected
4. In the Object Inspector double click on the "Actions"
5. Click on +Add to create a new action for your web module
6. Change Default to True if you wish this one to be the default action
7. Change the action name to "func1call" (this will be the calling identifier of this action from the web browser. Something like
http://localhost/mod_apache1/func1call?param1=...)
8. Inside the Events tab, double click on the "OnRequest" to create the procedure called "func1callRequest" that handles this action
9. Enter the following into the procedure body:
procedure TFPWebModule1.func1callRequest(Sender: TObject; ARequest: TRequest;
AResponse: TResponse; var Handled: Boolean);
begin
AResponse.Content := '<html><body>Hello World!</body></html>';
Handled := true;
end;
10. Save all, compile, configure the apache server to load the module:
in your apache httpd.conf you can put
LoadModule mod_apache1 "/<path to the module>/mod_apache1.dll" #or mod_apache1.so, etc.
<Location /myapache>
SetHandler mod_apache1
Order allow,deny
Allow from all
</Location>
11. Call your module action from your web browser ex:
http://localhost/myapache/func1call?param1=paramvalue112. See "Hello World!" in your browser
13. Repeat from step 4 for other web actions
==============
Using templates:
1. Lets make a simple html template and save it as mytemplate1.html :
<html>
<body>
This is a replaced template tag: {TagName1}
</body>
</html>
2. Save it and put it somewhere your apache module can access it (ex: below the apache module .dll or .so in a directory called "templates/")
3. Declare a procedure for your web module to handle the template tags
private
{ private declarations }
procedure func1callReplaceTag(Sender: TObject; const TagString:String; TagParams: TStringList; Out ReplaceText: String);
4. Create the body of the procedure
procedure TFPWebModule1.func1callReplaceTag(Sender: TObject; const TagString:
String; TagParams: TStringList; Out ReplaceText: String);
begin
if AnsiCompareText(TagString, 'TagName1') = 0 then
begin
ReplaceText := 'Here I am from the web module!';
end else begin
//Not found value for tag -> TagString
ReplaceText := 'Template tag {' + TagString + '} is not implemented yet.';
end;
end;
5. In step 9 above in the fist example change the procedure body to:
procedure TFPWebModule1.func1callRequest(Sender: TObject; ARequest: TRequest;
AResponse: TResponse; var Handled: Boolean);
begin //Template:TFPTemplate is a property of the web Action
Template.FileName := 'pathtotemplate/mytemplate1.html';
Template.AllowTagParams := true;
Template.OnReplaceTag := @func1callReplaceTag;
AResponse.Content := Template.GetContent;
Handled := true;
end;
6. Compile, etc. and call it. Should show
This is a replaced template tag: Here I am from the web module!
======================
More complicated HTML template design notes:
1. Template tag delimiters.
Template.StartDelimiter := '{+';
Template.EndDelimiter := '+}';
should be used if there are { or } characters in the HTML template (ex: Javascript exist in the template)
more in the FPC /packages/fcl-web/fptemplate.txt
2. For "same as Delphi" template tag handling, use
Template.StartDelimiter := '<#';
Template.EndDelimiter := '>';
Template.ParamStartDelimiter := ' ';
Template.ParamEndDelimiter := '"';
Template.ParamValueSeparator := '="';
ex: <#TagName1 param1="value1" param2="value2">
more in the FPC /packages/fcl-web/fptemplate.txt
======================
Passing tag parameters:
You can pass parameters to your CGI/Apache web module from the templates.
Example HTML template tag:
{+HereIsATag
[-param1=param1value-] //some text here to ignore
-]
[-param3=param3value-]
+}
ex: {+DATETIME [-FORMAT=MM/DD hh:mm:ss-]+}
Code:
procedure TFPWebModule1.func1callRequest(Sender: TObject; ARequest: TRequest;
AResponse: TResponse; var Handled: Boolean);
var s:String;
begin //Template:TFPTemplate is a property of the web Action
Template.FileName := 'pathtotemplate\templatename.html';
Template.AllowTagParams := true;
Template.StartDelimiter := '{+';
Template.EndDelimiter := '+}';
Template.OnReplaceTag := @func1callReplaceTag;
AResponse.Content := Template.GetContent;
Handled := true;
end;
procedure TFPWebModule1.func1callReplaceTag(Sender: TObject; const TagString:
String; TagParams: TStringList; Out ReplaceText: String);
begin
if AnsiCompareText(TagString, 'DATETIME') = 0 then
begin
ReplaceText := FormatDateTime(TagParams.Values['FORMAT'], Now);
end else begin
//Not found value for tag -> TagString
ReplaceText := 'Template tag {' + TagString + '} is not implemented yet.';
end;
end;
For example, this way if the web designer changes the look of a page, - in this case the format of the date/time on the page - no changes are needed in the apache module
code, therefore no recompiling or apache restart is needed. The best way is to make the project such, that the web/html design is separated from the back end apache module as much as possible.