The rapid html unit is a bunch of functions that output HTML using simple records and functions. The more complex GUI widgets are stored in objects/classes/records. It is almost like using a GUI generation tool without having to hand-code HTML. The rapid html unit is not like WebTemplateOut.. but you could even use a combination of templates and rapid html functions together.
The rapid html unit is powerful because you can output widgets on the fly and generate their properties based on preconditions or logic. The disadvantage of them is that they are not like templates where model, view, and controller are separated so statically (i.e. a static template stored on the server versus a procedure you can call and modify based on logic) . The lack of static template gives you more power, to avoid javascript hacks sometimes done in templating.
One can still place all his rapid html functions into separate GUI functions to try and obey MVC in your program.. but it is recompiled each time and harder to edit than a template is. Separating most gui from core logic is good when you want that decoupling. However many powerful GUI components actually depend on the logic, otherwise you resort to javascript hacks in your templates. SO again, choose what is best. Use templates when things are fairly static and try Jorge's template called PWebApplication on SVN in extras.
Even if logic can't be perfectly separated from the view in real life, it's just a form of discipline to follow. MVC is not a perfect paradigm.. but it teaches us some lessons about decoupling code from the GUI so it can be maintained easier.
One could go as far as separating the GUI into a DLL and you then only have to recompile the GUI "view dll" while leaving major code logic in the cgi controller program.
program rapid; {$mode objfpc}{$H+} uses pwumain, // or dynpwu strwrap1, htmw; // html wrapper, clean design via pascal code instead of html snips var // this could be in a Pascal unit and put in the uses clause TopPanel: THtmCustomBox = ( position: cpAbsolute; left: 0; top: 2; height: 0; width: 96; pad: 6; HeightUnit: hmPixel; WidthUnit: hmPercent; bgcolor: 'gray'; PageAlign: caCenter; border: cbNone; zindex: 1; text: ''; ); RightPanel: THtmPercentBox; LeftPanel: THtmPercentBox; ContentPanel: THtmPercentBox; FootPanel: THtmPercentBox; begin // open html tags, and set page Title HtmBegin('Pascal Internet Program'); // put some content into the box first TopPanel.text:= StrLoadFile('content1.txt'); BoxOut(TopPanel); // display an html panel/box HtmEnd; // close html tags end.Above example uses a simple THtmCustomBox that acts like a Panel ala delphi, or a Div box ala HTML. But no HTML was done by hand - all widgets were generated on the fly.
To keep model, view, and controller separate - it would be wise to put the THtmCustombox in its own unit, and try to keep code logic separated from GUI widgets. If one was to go further with MVC, one could even place all the GUI related widgets into a DLL and import them into the controller executable. This DLL idea is a bit harder to do than just placing them in separate units and compiling the program all in one executable.
The other option if you don't like the rapid html style of development, is to use the webtemplateout() function with HTML templates instead of using pascal widgets like you see above. Nothing stops you from combining the power of both templates and rapidhtml though.. such as calling the BOLD() function inside your program for one-off's while using templates for bigger html snippets. It's all about compromise really.
{ make bold text } function Bold(input: string): string; { output bold text } procedure BoldOut(input: string);Example:
out('This is some ' + bold('text') + ' that is bold'); outa('This is some ', bold('text'), ' that is bold'); out('This is some <b>text</b> that is bold');The above three lines of code do the same thing, but the first one uses a Pascal function instead of hardcoding html into the sources. If you had a bunch of text to blockquote, you could go:
out('This is a quote:'); out(BlockQt('man is a powerful animal')); out('I got that quote from some web page..');Or:
out('This is a quote:'); blockqtout('man is a powerful animal'); out('I got that quote from some web page..');Or:
out('This is a quote:'); blockqtout(italic('man is a powerful animal')); out('I got that quote from some web page..');You could also write your own combined Blockquote/Italic wrapper:
{ make block quotation } function italqtout(input: string): string; begin out('<blockquote>' + italic(input) + '</blockquote>'); end; begin out('This is a quote:'); italqtout('man is a powerful animal'); out('I got that quote from some web page..'); end.
Widget.Text:= WebFormat(StrLoadFile('test.tpl));(where tpl files are templates with $macrovars in them)
One could also make a cleaner wrapper function to do it that traps file not found errors:
function: TemplateToString(fname: string): string; begin // load a template file into a string result:= StrLoadFile(fname); // strloadfile returns -1NF if file not found which is handy for error checking if result = '-1NF' then begin out('file not found: ' + fname); exit; end; // format macrovars from template now result:= WebFormat(result); end; // .. // ... // now let's use it Widget.text:= TemplateFileToString('test.tpl');