help files
Z505 | PasWiki | FUQ | Search | Main Docs | API Guide



Notes

The rapid html package is included with your download in the /extras/rapid-html/ folder.

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.

Don't Rapid Widgets Disobey MVC?

In the real world, model view and controller is never perfect separation. If you can, use templates and forget the rapid html. But some cases you need to generate widgets with power.. that templates don't offer. Or sometimes you need to combine templates with widgets as a compromise.

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.

Compiled In Issues

The real disadvantage of using purely rapid-html widgets is that they are all compiled into your program. Every time you want to change the layout of a site, you have to recompile the CGI. It is good though for cases where you are developing a program that you want no dependencies.

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.

Examples

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.

Less Interesting Functions

The rapid html wrapper unit (htmw.pas) contains many common functions such as:
{ 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.

Using Templates With Rapid-HTML widgets

If you have a widget with a .text field, such as THtmCustomBox, you could even load a template into the widget's content area, to combine the power of templates with structured pascal based rapid html widgets.
  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');





lufdoc, Powtils, fpc, freepascal, delphi, kylix, c/c++, mysql, cgi web framework docs, Z505