Lazarus

Miscellaneous => Suggestions => LCL => Topic started by: Leledumbo on October 18, 2010, 05:17:47 am

Title: The need of web application framework for fpWeb
Post by: Leledumbo on October 18, 2010, 05:17:47 am
These days, in business world web applications rule. And usually I create those web apps using PHP because it has a lot of good frameworks. Lazarus and FPC already have underlying libraries to create web applications, but we miss frameworks. fpWeb have templates, but it's too limited.

First, it can't handle php (lua already does this as well) style web pages where code (though maybe just echo's and foreach's) are mixed with HTML. From fpWeb samples, for instance, if data needs to be displayed in a table, the logic unit should take the row template and replace marked symbols with correct values. This, though not deeply, violates MVC rule where logic should be separated from view. It's better just to pass the value in data structure form to the view and let the view decides how to display the data.

Next, it can't handle inheritance or nested templates. Typical web applications would have title header and navigation menu written for most of its pages, using nested templates, code redundancy for things like this could be eliminated. Even more, nested templates could be used for non-visual elements, such as doctype-html-head-body declarations.

I usually have a base view containing:
Code: [Select]
<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US">
  <head profile="http://gmpg.org/xfn/11">
      <title><?php echo $title ?></title>
      <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
 
      <?php foreach ($styles as $file => $type) echo HTML::style($file, array('media' => $type)), "\n" ?>
      <?php foreach ($scripts as $file) echo HTML::script($file), "\n" ?>
 
  </head>
  <body>
    <?php echo $content ?>
  </body>
</html>
where $title, $styles, $scripts, and $content can be filled or extended by its descendants.

That saves a lot of code, and creates a very extensible and reusable code. What do you think?
Title: Re: The need of web application framework for fpWeb
Post by: bobo on October 18, 2010, 07:35:44 am
I don't think the fptemplate (template handling of fpweb) is as limited as you say.
You can have any code in your templates, it will still work, especially because you can specify the tag start, tag end, tag param start, tag param end, tag value separator strings dynamically on the fly before calling the tag replacements. In fact, these were implemented exactly for the reason that Delphi had the limitations you have mentioned.

I am not sure what you mean exactly by nested templates, but I think you can do those too. Just reconfigure the above parameters and call the replacing again. You can do includes within templates and within template tag handling you can load in additional templates and do those again. It is quite flexible.
For example, you can specify a template include file as a tag parameter, handle it in the tag handling event using the file name passed, and what you want is done /if I understood what you want correctly :) /.

Some info on templates can be found in ...fpc.../packages/fcl-base/texts/fptemplate.txt
and some demos are in ...lazarus/components/fpweb/demo/fptemplate/*.*

Also, fpweb can now handle the Extjs framework to be the back-end server side handler for the nice Extjs GUI clients.
Examples on how ExtJS looks like in the browsers:
http://www.sencha.com/products/js/
http://dev.sencha.com/deploy/dev/examples/
Title: Re: The need of web application framework for fpWeb
Post by: Leledumbo on October 18, 2010, 09:00:36 am
Quote
You can have any code in your templates
OK, do we have something like this:
Code: [Select]
<table>
  <tr>
    <th>No.</th>
    <th>Name</th>
    <th>Age</th>
  </tr>
  <?php foreach ($persons as $no => $person): ?>
  <tr>
    <td><?php echo ++$no ?></td>
    <td><?php echo $person['name'?></td>
    <td><?php echo $person['age'?></td>
  </tr>
  <?php endforeach ?>
</table>
Quote
I am not sure what you mean exactly by nested templates
Not exactly nested template, actually. See it this way, in a traditional MVC, each controller handles one view. If that controller is extended by another, then rendering action of the base controller will  get called followed by descendant one.
Quote
You can do includes within templates and within template tag handling you can load in additional templates and do those again.
Well... hmm... OK, what about the variables?

I can't explain this template based paradigm very well. So, perhaps if you will, you can check out this (http://kerkness.ca/wiki).
Title: Re: The need of web application framework for fpWeb
Post by: bobo on October 18, 2010, 06:21:34 pm
This became a "little bit long", sorry about that... have too much time on my hand it seems...

Yes, it seems what you currently use is totally php based.
This means that everything is handled by php include files basically.
With php the code and display functionality is never really separated.

Obviously, you can not mix the fpweb templates with your php code
because there can be only one handler on the web server for a request,
and we can not ask php to process a request and then call fpweb to process
it again for template tags.
We need to choose which one to use.

The example you list is basically the same example as demonstrated in
...lazarus/components/fpweb/demo/fptemplate/listrecords/...
That is a very basic demo that can be made more complex (ex: instead
of a full record replace with one tag, it can be every field made a tag,
with format strings passed as tag parameters, etc.)
Taking your example, with fpweb it would look something like this:

Code: [Select]
<table>
  <tr>
    <th>No.</th>
    <th>Name</th>
    <th>Age</th>
  </tr>

{+PERSONS
 [-ONEROW=
  <tr>
    <td>~no</td>
    <td>~name</td>
    <td>~age</td>
  </tr>
 -]
+}

</table>

and a call for the fpweb cgi/fcgi/apache_module with the parameters and variables
is needed to find the needed record(s).
For example ...mywebserver.com/cgi-bin/myfpwebcgi.cgi/listpersons?recordidlist=blah
would return with the full html response page loading and processing the above
template and replacing the template tag "PERSONS" with the field values
(~no, ~name and ~age) for every record requested.
Inside the fpweb "listpersons" action event handler on the server side, the pascal
code would be something like:

Code: [Select]
.
.
    onerow := TagParams.Values['ONEROW'];//template for 1 row
    while not SQLQuery.EOF do
    begin
      ReplaceText := ReplaceText + StringReplace(StringReplace(StringReplace(onerow
                       ,'~no', SQLQuery.Fields[0].AsString, [])
                       ,'~name', SQLQuery.Fields[1].AsString, [])
                       ,'~age', SQLQuery.Fields[2].AsString, []) + #13#10;
      SQLQuery.Next;
    end;
.
.

It is basically the same thing both with php or fpweb templates. Except with php,
there is the overhead of the php interpreter while with fpweb there is only parsing
for the template tags. Also the programming is really on the fpweb side while the
html template is just really a screen html template with no code in it.
You can also use frames or IFRAME includes within a template to pull additional
parts of the html page with separate requests from the server, processing additional
templates, infinitely. Or just create tags with tag parameters that helps you create
the response from multiple templates based on the passed parameters.

This way is the way to program web applications when you really want to have all
control both on the browser and server side. Takes much longer to develop a web app
(at least the 1st time) because it is low abstraction level html generation, but you
really have the possibility to micro-manage and customize everything.

The other way is to use some kind of client side framework for the gui, and use
fpweb only for back-end processing and data providing (like using the Extjs framework
for gui for example).

Both can be done with FPC/Lazarus easily.

AB


PS: As for variables, there are no variables in fpweb templates, because there are no
code to interpret and execute in them. Templates are REALLY only for the html look and
feel.
The code and the variables are inside the fpweb request handler pascal code on the
server side. There are only request parameters that can be passed from the browser as
part of the URL or as html form field values.
Title: Re: The need of web application framework for fpWeb
Post by: Leledumbo on October 19, 2010, 04:34:05 am
Quote
Yes, it seems what you currently use is totally php based.
This means that everything is handled by php include files basically.
With php the code and display functionality is never really separated.

Obviously, you can not mix the fpweb templates with your php code
because there can be only one handler on the web server for a request,
and we can not ask php to process a request and then call fpweb to process
it again for template tags.
We need to choose which one to use.
No, no, no. I'm just explaining from php side, which I've ever worked with, and looking for how to implement that in Object Pascal.
Quote
Taking your example, with fpweb it would look something like this:
Exactly.
Quote
It is basically the same thing both with php or fpweb templates.
Not really. In fpWeb, I need to use StringReplace explicitly. While in my PHP framework, the variables can be assigned to the template. The Object Pascal way (that I'm wishing for) perhaps looks like this:
Code: [Select]
AView := TMyView.Create('View filename');
AView['no'] := SQLQuery.Fields[0].AsString;
AView['name'] := SQLQuery.Fields[1].AsString;
AView['age'] := SQLQuery.Fields[2].AsString;
Response := AView.Content;
Quote
As for variables, there are no variables in fpweb templates, because there are no
code to interpret and execute in them. Templates are REALLY only for the html look and
feel.
After re-thinking about it, I guess this is not a limitation. Instead it's a good way to enforce separation between logic and presentation. So, only previous issue left as my problem.
Title: Re: The need of web application framework for fpWeb
Post by: bobo on October 19, 2010, 07:51:55 am
But php does the same "replacestrings", we just do not see it :)
Plus you can do it in other ways, no need to use StringReplace exclusively. It can be anything (FORMAT instruction for example if that is easier for the developer, or a TStringList and then using the TStringList.Text as replacetext if all records are added, etc.), the important thing is that at the end of the tag replacement, we have the string we want the tag to be replaced with in the response.

Taking your "wish" example, you can make that even simpler with fpweb. In the template tag handler for all database fields you can use one single

ReplaceText := SQLQuery.FieldByName(TagString).AsString;

you do not even need to check for tag string matches. The only restriction is, that in the template for all fields coming from the sql query you need use the same tag name as the field name in the table.
Code: [Select]
<table>
  <tr>
    <th>No.</th>
    <th>Name</th>
    <th>Age</th>
  </tr>
  <tr>
    <td>{+ID+}</td>
    <td>{+Name+}</td>
    <td>{+Age+}</td>
  </tr>
</table>
if the table record has these 3 fields (ID, Name, Age), or the sql query at least returns fields with these names.

Of course, this is only good for template values/fields that are not need to be listed from a loop (1 record only, basically). For loops you need some kind of string concatenation to return all records. It is not different with php, it is just not programmed by us directly.
For multiple records it is also a way to just return the table records as a javascript array into the web page replacing a single template tag, and then process them from inside javascript on the client side to display them. But this brings us back again on doing programming and data processing on the client side.
This will probably not beat the ExtJS framework as a gui, which is already freely available to everyone.

Additionally, with fpweb the template designers can pass some additional parameters to the back end.
For example, a current date/time field on the web page can have a tag
{+DATETIME [-FORMAT=MM/DD/YYYY hh:mm-]+}
which passes the format the screen designer wants the datetime to be in. No back-end changes are needed if they want to change the format and in the tag handling we just need to apply the format from the tag parameter. They just change it in the template, the CGI/FCGI/Apache_module does not need to be changed. Something like this can be included for all field types if necessary giving free hand to the screen designers.

AB
Title: Re: The need of web application framework for fpWeb
Post by: Leledumbo on October 19, 2010, 08:36:07 am
Quote
But php does the same "replacestrings", we just do not see it
Yes, of course. But as you can see, using map-like view's variables assignment seems more comfortable than using tag string approach.
Quote
you do not even need to check for tag string matches. The only restriction is, that in the template for all fields coming from the sql query you need use the same tag name as the field name in the table.
Woohoo... I don't think this one is a good idea. Tag string match is still required in most cases.

Anyway, I guess I'll make the framework myself (but it won't anytime soon, needs to play on papers first). I've got ideas from our discussion ;)
Title: Re: The need of web application framework for fpWeb
Post by: bobo on October 19, 2010, 06:52:47 pm
Quote
Woohoo... I don't think this one is a good idea. Tag string match is still required in most cases.
OK, if ya don't like that, you can do a
Code: [Select]
AView := TStringList.Create;//global webmodule stringlist property
AView.Add('no='  + SQLQuery.Fields[0].AsString);
AView.Add('name='  + SQLQuery.Fields[1].AsString);
AView.Add('age='  + SQLQuery.Fields[2].AsString);
AResponse.Content := MyTemplate.GetContent;
AView.Free;

//and in the tag handler for MyTemplate you can do a
ReplaceText := AView.Values[TagString];

Better? :)
Title: Re: The need of web application framework for fpWeb
Post by: Leledumbo on October 20, 2010, 08:02:09 am
Quote
Better?
A little. TStringList does support pseudo-map operation, though it seems a little unnatural. It's not difficult to build a class like I want (constructed with a template filename and use pure map operation to assign variables).

What looks difficult is the controller (or in fpWeb jargon, fpWeb module) inheritance. Consider this example:
The base controller handles request to draw banner and navigation menu, and provide empty Content variable. The descendant classes fill that variable with view and data they handle. When a request comes, it's redirected to the correct descendant classes' method based on URI, and due to this inheritance the banner and navigation menu still gets rendered. What's the fpWeb style solution for this?
Title: Re: The need of web application framework for fpWeb
Post by: bobo on October 20, 2010, 07:10:40 pm
I am not sure you even need to do any fancy object, descendants, inheritance juggling for this at all.
Webmodules in fpweb handle actions (web requests) and return with responses to the browser (html pages or page parts in this case).
For this example you can have 3 frames or iframes on your browser screen.
The top frame/iframe is for the banner, the left frame/iframe is for the menu, and the remaining one is for the content.
These 3 frames/iframes mean 3 separate requests to the fpweb module calling different actions in it, lets say ...myserver.com/cgi-bin/mycgi.cgi/top?param1=1&param2=2
...myserver.com/cgi-bin/mycgi.cgi/menu?param1=1&param2=2
...myserver.com/cgi-bin/mycgi.cgi//content?param1=1&param2=2

They are separate requests to the web module (and therefore to the web server), and have 3 separate templates for them (which can have additional embedded parts, etc.). The webmodule action event handler, can process the session identifying people if needed, can process the passed URL query parameters or form field values, etc. and using the proper templates generate the response html parts.
If there is a click on the menu for a new "content" part, then that URL will only get the response for the new content frame (ex. we can use the target="framename" for the hyperlinks to get the response into the proper frame/iframe).

However, I'm not convinced that loading parts of the screens are really that much of a saving. In my experience generating the screens as one (even if from multiple templates) works most of the time.
You can do something like a main template and process include templates instead:

Code: [Select]
<html>
{+INCLUDETEMPLATE [-FILE=top.html-]+}

{+INCLUDETEMPLATE [-FILE=body_screen1.html-]+}

{+INCLUDETEMPLATE [-FILE=bottom.html-]+}
</html>

And by processing the tag parameter "FILE" you know what template to use for that part of the response page.

AB
Title: Re: The need of web application framework for fpWeb
Post by: Leledumbo on October 21, 2010, 06:16:01 am
Quote
For this example you can have 3 frames or iframes on your browser screen.
The top frame/iframe is for the banner, the left frame/iframe is for the menu, and the remaining one is for the content
I'm avoiding frames since I prefer strict XHTML doctype instead of frameset.
Quote
They are separate requests to the web module (and therefore to the web server)
This is what I avoid, except if a webmodule can call other webmodule's method (thus making the request as light as a method call).
Quote
However, I'm not convinced that loading parts of the screens are really that much of a saving. In my experience generating the screens as one (even if from multiple templates) works most of the time.
Exactly.
Quote
You can do something like a main template and process include templates instead:
Hmm... possible, but I still need to handle those three parts for EACH request. With inheritance, the top and bottom could be handled by a base controller and the middle by the correct descendant.
Title: Re: The need of web application framework for fpWeb
Post by: bobo on October 21, 2010, 09:00:18 am
There is no such thing as only parts of the screen handled with using fpweb exclusively, because nothing runs on the client side in the browser (at least with the examples we have discussed).
Only when the client keeps parts of the screen (like frames or iframes, extjs, browser plugins like flash, mono, .net, activex, etc.) can such thing exist. The client needs to store parts of the web page screen in these cases.
This puts an overhead and installation requirements on all clients (all needs the proper version an type plug-in), as well as compatibility problems across platforms, browser versions, etc.

But if you use a framework like extjs for the gui on the browser side, this can all be done with fpweb as a back-end. In fact, this way is the most "RAD" web app development in my opinion for multi-platform.

As for the "inheritance" you are mentioning, it could work with fpweb too, if you cache the top and left/bottom parts for the user using the session id into a table or file. If it exists, then you can skip the generation of that part, if not, then you can generate it once. This way you do not need to do those parts for every request.
Or you can do some javascript on the client side and replace some parts of the web page on the client side with the returned html page parts from the server fpweb app (ex. ajax).
Title: Re: The need of web application framework for fpWeb
Post by: Leledumbo on October 21, 2010, 11:10:33 am
Quote
There is no such thing
What do you refer this "thing" too?
Quote
But if you use a framework like extjs for the gui on the browser side, this can all be done with fpweb as a back-end. In fact, this way is the most "RAD" web app development in my opinion for multi-platform.
This is of course possible, but the application must be ajax enabled / web service like instead of standard web application. I don't consider this as a disadvantage since web service based web application is very good (example: when other people wants to get the application data, just parse the xml / json response, no need to create additional bridge). But most of the time I just want to create simple web application, without any gui library like extjs or anything else.
Quote
As for the "inheritance" you are mentioning, it could work with fpweb too, if you cache the top and left/bottom parts for the user using the session id into a table or file. If it exists, then you can skip the generation of that part, if not, then you can generate it once. This way you do not need to do those parts for every request.
Possible, maybe just need an additional library to automate the process. I'll think about it.
Title: Re: The need of web application framework for fpWeb
Post by: bobo on October 21, 2010, 08:16:17 pm
Well, I am happy that we have arrived from

"...fpWeb have templates, but it's too limited..." and
"...can't handle inheritance or nested templates..."

to an understanding that in fact all can be done relatively easily with fpweb (FPC 2.5.1 and Lazarus 0.9.29).
Nice.

:)
TinyPortal © 2005-2018