|Pliant talk forum
Discussion: Graphic design and HTML templates
How to allow Pliant fill-in disconnected areas on HTML page
designed by graphic artist.
|Message posted by maybe Boris Reitman on 2007/05/12 18:54:36
|Pliant .page mechanism is great for writing quick and dirty
user interfaces, as the programmer generates all the HTML
content with "text", "text_input" etc. commands.
This is fine when all the user interface is in the middle of
the page, between header and footer.
(The header and footer is a mess of HTML designed by graphic artist).
But on a real website, GUI elements are spread out all over the page, in
boxes. For example, in the menu, there can be a box for search, or a drop-down
box with a list of countries. The body could be a checkout form that user
must fill in, which needs to be pretty, and have layout that is easilly modified
by a graphic designer with standard HTML design graphics program like
So, basically, I need to get pliant to work with templates. It can be something
like ASP/PHP model where HTML is interrupted and pliant code starts. I don't
like it because it is a mess.
Or it can be another mechanism, where certain spots in the template are marked
as boxes, and all the HtmlPage methods will render themself into correct boxes.
method page fill_designer1_template
arg_rw HtmlPage page
# current template is "default"
page template "designer1"
# current template is "designer1"
page template_box "box1"
text "this text appears in box1 of template designer1"
page template_box "box2"
text "this text appears in box2 of template designer1"
# as we leave the template block, the template is generated and all the data
# is printed.
# current template is again "default"
method page fill_main_page
page template "main_page"
page template_box "main_content"
page template_box "search"
So to summarize, page methods render into bits of HTML templates,
and all the nested templates are put together by the way function invocations
The "page template" block will change current template when the block begins,
and pop it to restore the old value, when the block ends.
For a common case that a table needs to be generated, and each row is a template
itself, the row template spec can be embedded in the main template HTML file
with some syntax, like this:
<table><tr> <th>col1</th> <td>col2</th></tr>
<tr><td> %%LEFT_CELL%% </td><td> %%RIGHT_CELL%% </td></tr>
The LEFT_CELL, RIGHT_CELL are the boxes into which pliant will print.
When the table template is loaded, the <define_template> definition
will be replaced with %%ROW_TEMPLATE1%% and the template code for ROW_TEMPLATE1
will be available as a template for use with "page set_template" method.
What are you thoughts ?
How can I implement this easily ? I need all the .page methods to print into
strings organized in a dictionary keyed by box name. When it is time to generate
the HTML from the running template, the strings will be printed into the boxes.
Can I get the .page elements to print into a stream of my choosing ?
In C++, for example, there is a StringStream class. I could write something
similar for pliant, and tell .page elements to print into that stream.
|Message posted by maybe Boris Reitman on 2007/05/12 23:43:29
|After some thought, another way to implement this without printing into
strings keyed by box ids, is this algorithm:
The "set_template" instruction is a meta that rearranges the order in
which "template_box" blocks inside it are invoked, to match the order of
%%box_name%% tags in the template. This is done by "goto" statements
that jump in the right order between the blocks, and this order can be
changed at run time, because this allows for the template to be updated
without server restart.
So this is implemented as a finite state machine "switch". When a
template is loaded, we initialize an order of boxes and save it into
an array which is cached for future use. It is an array of fixed size
equal to the number of template_box blocks in the code. The values of
the array is where to jump next. Essentially, this is a linked list in an
array. At the end of each "template_box" block the array is looked up to
decide to which "template_box" its required to jump. If the value is -1,
we have reached the last block.
Note, that array must be reinitilized every time the function is invoked
and the referenced template file was changed on disk.
The values of the array should really be offsets into the generated
code, but since the sizes of the code to generate "template_box" tags
are variable, another array of the same size compiled into function body
should record the offset to beginning of each block. Leaving the last
template_box block is equivalent to implementation of "leave part" code.
The advantages of this design is that no changes need to be done to .page
instructions (text, text_input) etc. It is also better because printing
is done into the output stream, and not into strings. Thus, there is
no danger of creating a very large string that would take a lot of memory.
Any tips on writing such meta are appreciated.
|Message posted by maybe Hubert Tonneau on 2007/05/13 08:46:51
|There is both a scalability and latency issue with your design if the server has
to store all the content of the answer before final processing it then sending
it instead of sending it on the fly.
It is the way the Pliant HTTP server worked in it's early days.
My point of view is that the protocol has to be light on server side so that
server scalability be maximal. Remember that a server has to service many
clients, and nowdays a server is not significantly more powerfull than a client
so it's important than normal usage of the application don't bring significant
computation constrain on the server.
graphical toolkit for remote mainly database services is that it's easy to
build a toolkit for any plateform and it can be light on the server side.
Remember: the key difference between HTML and native graphical toolkits is that
in HTML, the client computes the positions which can be just as expensive as
rendering and cannot be hardware accelerated.
So, my conclusion, also it may not fit others wishes, usage field and expierence,
was that a three tiers system is better:
. the server uses a light clean protocol to send to the proxy, so that it will
waste no time, and avoid most memory exhaused issues
. the poxy deals with all computations to switch from clean protocol to what the
final client expects
This is the way the new HTTP server is led. At beginning I thought that having
but I changed my mind after experimenting.
The way designers currently work is, from my point of view, amateuristic (not
professional). I mean it is nearly granted that any significant application
will not work with all browsers in the future AND that what will need to be
upgraded all the time will be spread over the all code. The fact that they
don't know how to work properly, mostly because of using too poor tools, does
not mean that it's a good way to work.
|Message posted by maybe Boris Reitman on 2007/05/13 10:24:14
|My last design has no memory footprint -- I am printing/generating on the fly.
Read my second message. The whole idea is to order the execution of code blocks
in to the order in which corresponding template placeholders
appear in the template.
So, for a template of the form:
Suppose we have three page functions:
each emitting lots of text
Then, the following code will apply data to the template, without any memory
var List:Str htmlparts := load_and_split_template "mytemplate1.html"
The problem is that I need to know that placeholder_C comes before placeholder_B
in the template, so I need to invoke write_content_for_C before write_content_for_B,
in the code. I want to remove the need to know this information by writing a meta
that will turn the following code into the one above:
(i used syntax "section" instead "template_box" since it is a more
The template meta will detect that C comes before B, and will reorder B and C
section blocks. It is easy to reorder them at compile time, by just switching the blocks
around, but this way the system will not respond at runtime to updates
to mytemplate1.html file. Therefore the reordering must be done with jump table and
setting instruction:jump member properly.
|Message posted by maybe Hubert Tonneau on 2007/05/13 12:56:03
|Now I understand what you want to do.
It's fairly simple with Pliant:
You will execute your .page, but each section will record a Pliant delayed
action (Pliant lazy evaluation mechanism),
then you start copying your template to the client, and tigger each delayed
action execution when you find the corresponding keyword.
|Message posted by maybe Boris Reitman on 2007/05/14 20:10:43
|Here's what I got:
The compile error message:
The error happens at the "e freeze" line.
Note: I would like to get the template code to work with Stream first,
so that I can test it. And then, with HtmlPage. And I want to have both options
available, because sometimes I need to render templates not in .page mode
(when generating email, for example).
|Message posted by maybe Hubert Tonneau on 2007/05/14 22:19:30
|That's fairly simple. Each time you ask Pliant to freeze some expression
(create a DelayedAction object that will later be restarted) all local variables
used in the body will be copied.
Some kind of variables must not be copied but rather passed by address. So are
In your code, you force 'context' to be by address, but your Stream is named
'stream', so Pliant just reminds you that your 'stream' variable has 'Stream'
data type and 'Stream' data type has a flag set that says that it's instances
must not be copied.
|Message posted by maybe on 2007/05/15 09:06:28
|Ok, it works. I updated the template.pli at above URL, and wrote this test too:
Thanks for your help,
|Message posted by maybe Boris Reitman on 2007/05/18 09:07:38
|I have a question about thread safety and memory usage.
Here is the scenario:
I have added a feature to the template code to parse tags of the form:
The value is available by calling get_template_value. For example,
template "A <TEMPLATE NAME=[dq]xxx[dq]>yyy</TEMPLATE> B"
var Str value := get_template_value # returns "yyy"
#dostuff # call again
I would ideally want to allocate template_value on the heap, since I want it to
be different at runtime, but to have one actions dictionary per function
definition, so that recursively calling a function doesn't allocate Dictionaries.
How do I create a C-like "static" dictionary initialized lexically, once per
block (the "template" block) ?
If I allocate template_value on the heap, whats the best way to pass it to
freezed actions ? Like the page/stream object ?
To understand why I would want to call dostuff recursively, here is how I am
using the template meta to slurp an SSI file and allow inplace editting of each
method page insert_editable_ filename depth
arg_rw HtmlPage page
arg Int depth ; arg Str filename
if depth > 10
text "ERROR: looks like cyclic recursion (too deep): "+filename ; eol
var Str data := slurp_text_file filename
var Bool is_block := data:len > 10
css class "editable_area" block is_block style "background: "+(shunt depth%2=0 "#eee" "#ccc")
var Str space0 space1 include include_type
while (data eparse any "<!--#include" spaces:space0 any:include_type "=[dq]" any:include "[dq]" spaces:space1 "-->" any)
var Str match := "<!--#include"+space0+include_type+"=[dq]"+include+"[dq]"+space1+"-->"
var Str new_filename
if include:0 = "/" and include_type = "virtual"
new_filename := get_apache_site_dir + include
new_filename := dirname:filename + "/" + include
data := replace data match "<TEMPLATE NAME=[dq]ssi_include[dq]>"+new_filename+"</TEMPLATE>"
insert_editable_ get_template_value depth+1
css class "edit_icon" block false
Once again, the code is here:
|Message posted by maybe Hubert Tonneau on 2007/05/29 09:21:14
|> How do I create a C-like "static" dictionary initialized lexically, once per
> block (the "template" block) ?
I don't understand what C feature you are expecting.
Pliant is very similar to C: either the variable is local to the function, or
it is global.
If you want to avoid copying a large data structure over and over, I would
suggest keeping track of the changes instead, so that you can reverse the
changes when you leave a bloc.
The TagStack data structure is used to efficiently keep track of each styling
attribute in the Pliant old HTTP server styling engine.
As an example, if we have something like
font face "Helvetica"
then when executing 'body', we need to be abble to query what is the current
Basically, we have an array specifying current value for each index (each named
is mapped to an index, offset, or whatever you prefer to call it), and we have
a list of transitions.
Each time we enter a block, we had a mark tag to the transitions list.
Each time we modify an entry, we fist copy the old value in the list.
Each time we leave a block, we read the list blackward up to the mark to restore
|Message posted by maybe Boris Reitman on 2007/05/29 21:11:26
|I guess, the only way to do what I want is to have the "template" meta
propagate some information to nested template_section meta.
gvar Link:Argument current_actions old_actions
meta template e
old_actions :> current_actions
current_actions :> argument local Link:(Dictionary Str DelayedAction)
# suckup children
# call generate_template function passing current_actions and template string as args
current_actons :> old_actions
meta template_section e
# record delayed action into current_actions local variable
This way i still allocate a dictionary for each instance, but there are no thread
safety issues i have to handle.
If this code:
template "... %%A%% ... %%B%% ..."
Is converted to:
var Int offset := 0
while offset < template:len
var Str token := get_next_token template offset
if token = "%%B%%"
eif token = "%%A%%"
offset += token:len
There are no allocation issues at all and no thread safety issues.
|Message posted by maybe Hubert Tonneau on 2007/05/29 21:40:04
|I say it again: if you want more efficiency, you need to write your extended
dictionary data structure with backtracking capabilities.
|Message posted by maybe Boris Reitman on 2007/06/02 16:33:33
|My last message didn't post somehow. I have updated the code to a propecly