%import file="../../globals.dim#*" %> <%invoke script="<%%SITE_ROOT_PATH%%>support/test/essitest_feed.pl" %>
DIML - Demo sequence <%%FRAMEWORK%%>Author: V.G. FREMAUX
E.I.S.T.I. / Cergy, France
Eisti Applied Research Laboratory
Version: EN 1.1 / September 2002, FR 1.1 / September 2002
DIML Specification (local RFC) : essi_<%%FORM::lang%%>.dim
Complete DIML tutorial : on line tutorial
Exhaustive test of the DIML features : document de test (PHP) - document de test (PERL)
The present document is the effective demonstration of DIML injection scheme. It will explain exhaustively the ESSI Processor functionalities, and will demonstrate all the syntactic implementations we choosed to implement. We use it also to evaluate the Processor features. In the text beneath, green parts are the effective result of a dynamic injection operation of the processor.
Actual protoype of the ESSI Processor that compiles DIML tags is written an developped in Perl 5.0 over Apache. Future versions should appear, as a Php library function, and as an ASP call for IIS platform.
This implementation has been tested on Linux operating systems, with Apache up to 2.0, and is compatible with the IISAPI interface of the ActivePerl&tm; Perl distribution (Cf ActivePerl)
Refer to essi_<%%FORM::lang%%>.dim to get a full rationale and draft specification proposal.
DIML has, as a main purpose, to provide Web design teams with a powerfull interface that separates presentational encoding from scripts. When dealing with dynamic Web pages, the general model we choosed was to consider two main informational flows from user to the application.
A web page is essentially a document, and therefore pushes information to user, according to complex and numerous presentational rules. The presentational rules DO NOT have any influence upon the original semantic of the information being presented, but will (or might !) rather have some impact upon how information is perceived by the user.
Many presentational rules are expressed as fixed tags or "elements" which content is the information itself in its simplest form (we should say "the naked concept"). A complete information flow flows from the application to the user and can be considered as the result of merging naked concepts and presentational encoding (style sheets are some form of partial solution to this issue).
Data injection technique provide a simple way to formalize this merging process.
Conversely, as most dynamic Web design and interactive sites have used the hyperlink mechanism as GUI activation primitives, there should be a way for designers, to indicate to script authors the visible resources they should use. The DIML solution will have provision to pass strings and variables through the DIML interface.
The following is the substitution of a single data call as <% %DATA1% %>. Substitution results in:
<% %DATA1% %>
The following is the substitution of a single data call as <%%EMBEDDED%%> with no space between ESSI start markers and variable signal. Substitution results in:
<%%EMBEDDED%%>
Typically, a data injection mark MUST be a valid label (using C language conventions) preceded AND followed by a '%' (percent) character. The form <% % ERRONEOUS % %> is therefore invalid, although ESSI statement is clearly delimited. The statement results in:
Some <% % ERRONEOUS % %> writing produces:
Some <% % ERRONEOUS % %> writing
Any erroneous statement produces either a null counterpart (i.e. a blank chain) on variable calls, or an error message generated by the DIML processor on statements.
When the token is faulty, typical behaviour of the processor (i.e. returning a blank string) can be overriden defining an explicit default to use:
<%%VARIABLE DEFAULT="<BR>DEFAULT VALUE</BR>" MINLENGTH="40"%%>
In this demo, we mistaked willingly the variable name as "VARIALBE" to provoke the error. The result is:
<%%VARIABLE DEFAULT="<BR>DEFAULT VALUE</BR>" MINLENGTH="40"%%>
The following example shows how the ESSI Processor subtitutes variables recursively, until all ESSI statements are processed. The following uses a single call to a variable called <%%NESTING%%>, which should be subtituted with the DIML fragment:
a DIML fragment containing a <%%NESTED%%> data <%%NESTED%%> is in turn to be substituted with its final value: "nested". The test results in:
<%%NESTING%%>
In some cases, specially when some fragments should be encapsulated, it is convenient to pass variable definitions from the designer side to the script author side. This is done using the %set instruction of the DIML definition. Next example shows a call to an hypothetic variable called A_NEW_ENTRY, before and after its in-line definition:
<%%A_NEW_ENTRY%%> (before set) | <%set %A_NEW_ENTRY% = "a quoted string defined in-line" %> | <%%A_NEW_ENTRY%%> (after set) |
<% %A_NEW_ENTRY% %> | <%set %A_NEW_ENTRY% = "a quoted string defined in-line" %> | <% %A_NEW_ENTRY% %> |
A template is a fragment of DIML (Data Injection Markup Language) independant from document body, but that may be stored in the same file than the body itself. Template contents is not part of the document body, unless ESSI statements will ask for template substitution. A document may contain templates that will never be used in this document (eventually that may be not used at all).
A template should rather be written outside the <BODY>...</BODY> entity. Robustness principles will ask ensuring that templates will be parsed even in a document body. The following template defined by:
<TEMPLATE ID="aLocalTemplate"> A first try of an DIML fragment embedded in DIML template file </TEMPLATE>
will specify the template called "this.document#aLocalTemplate"
Correct process isolates the template and stores it into a internal data base. Then body is parsed for ESSI statements, and specifically the "template call" statement as follows:
<%template file="#aLocalTemplate"%>
Let's try now:
<%template file="#aLocalTemplate" %>
If templates are pointing to other files, the processor will extract template definition opening an extra template file. This resumed by the following example:
<%template file="otherfile.dim#aRemoteTemplate"%>
that results in :
<%template file="otherfile.dim#aRemoteTemplate" %>
Just have a look at the external template otherfile.dim
A template may contain a <HEAD></HEAD> section that will provide some script elements or META information the template needs. The ESSI Processor collects all these information and will finally reconstruct a standard conforming <HEAD> section for the generated HTML document. To verify this process, you should have a look at the source code of the present document.
The following lines should include two META tags into the head of the present document, along with a small javascript function. The source code of th e template should be:
<TEMPLATE ID="headedTemplate"%> <HEAD> <META NAME="meta1" VALUE="value1"> <META NAME="meta2" VALUE="value2"> <SCRIPT LANGUAGE=Javascript> function aVoidFunction() { } </SCRIPT> </HEAD> some HTML to insert "in-line"... </TEMPLATE>
Note : The actual collection process limits the script language to Javascript 1.0.
ESSI processor brings much more than simple data substitution. What follows shows how to use iterative calls to construct large HTML tables based on a request in a database. The first example shows how any variable may be substituted n times using a table call syntax:
<%%TAB[10]%%>
where %TAB% is initalized to the string "a row
". That will result in:
<%%TAB[10]%%>
The proper content of the variable TAB will be recursively scaned as usual. The variable may contain directly or recursively some "relative iterative calls". These calls appear as a tabulated syntax with a relative index numeric, or in most cases, without numeric index at all:
TABBED[] or TABBED[-3]
Relative calls may mostly appear within templates, although a call in the main part of a document will retrieve the effective value in the associated array at the current array pointer value. When the DIML is to be parsed, all the eventual array pointers are set to 0. So a %TABBED[]% call in the main flow will be substituted with the value of the %TABBED§0% input of the processor input array. Subsequent calls to %TABBED[]% entry will NOT iterate through the TABBED§x array, thus iteration is handled by template substitution.
Next will come three "main level" calls to the TAB1D monodimensional array:
<% %TAB1D[]% %>
<% %TAB1D[]% %>
<% %TAB1D[]% %>
that results in:
<% %TAB1D[]% %>
<% %TAB1D[]% %>
<% %TAB1D[]% %>
As expected, the iteration do not oper while calls are subsequent in the same corpus of DIML.
This principle may be extended to multiple dimension calls constructed with the same rules. Thus, a bidimensional call within a table that should contain values as:
TAB2D§0§0 :: "upper left corner" | TAB2D§0§1 :: "upper right corner" |
TAB2D§1§0 :: "lower left corner" | TAB2D§1§1 :: "lower right corner" |
may be written as:
<% %TAB2D[][]% %>
that results in:
<% %TAB2D[][]% %>
retrieving the %TABBED§0§0% entry in the ESSInput structure. Note that we are still in the main part of a document, and that NO ITERATION will take place at this time. So any subsequent call to the %TAB2D[][]% variable should return the same "upper left corner" value, until template calls start affecting current indexes.
Conversely, when the relative call is included into a template definition, each call to the template should iter the array index by one. Consider the document containing the following template definition:
<TEMPLATE ID="Iterated"> Some HTML statements... An iterated injection mark : <%%TAB1D[]%%> Some other HTML... </TEMPLATE>
The above definition includes an automatic iteration call to a monodimensional array called TAB1D, retrieving values as entry keys %TAB1D§0% to %TAB1D§n% where n is the number of iterated substitution of the template "Iterated" minus 1.
Any consequent iterated call to the template written as:
<%template src="#Iterated" iterate=4 %>
Will provoque substitution of the template 10 times, with autoincrementation of the array index. This should be equivalent, in case of a local template to the implicit call:
<% %Iterated[4]% %>
Next comes the effective result of both syntactic alternatives:
Explicit "%template..." | Implicit |
---|---|
<%template file="#Iterated" iterate=4 %>
|
<% %Iterated[4]% %>
|
Note that the second column calls continue iterating the array from the current position.
May I cheer you at this point. DIML is NOT intended to become another programming language. But encoding presentationnal models do deal with conditional statements to simplify some simple situations. Most conditional situations could be of course resolved at script level rather than in the presentational template, but allowing some capacity of choice will make it much more flexible.
DIML defines two kinds of conditional statements. They differ in that the former is entirely written within a single DIML tag, and the latter may be spread out through the DIML flow. Allowed syntaxes are:
Compact statements |
---|
<%if (condition) ... %endif %> |
<%if (condition) ... %else ... %endif %> |
Multiline constructs |
---|
<%if (condition) %> ... <%endif %> |
<%if (condition) %> ... |
<%if (condition) %> ... <%elsif (condition) %> ... <%else %> ... <%endif %> |
"One shot" conditional statements will merely be used to make a choice between two alternate variable (or template) calls as in:
<%if (%NEXT% ne "") %NEXT_IMG_CALL% %else %PREV_IMG_CALL% %endif %>
which will obviously call the template:
<TEMPLATE ID="PREV_IMG_CALL"> <IMG SRC="<%%IMAGES_ROOT_URL%%>prev.gif"> </TEMPLATE>
as there is no provision for a defined %NEXT% variable till here (note the use of a global variable call to fix the root of the path to pictures resources).
<%if (%NEXT% ne "") %NEXT_IMG_CALL% %else %PREV_IMG_CALL% %endif %>
Note that condition syntax will depend on the processor implementation.The Perl version of the processor will accept full Perl syntax (i.e., any logical expression that will produce a result in an eval(EXPR) function call), except that the expression is scaned again for eventual DIML variable calls (where will it end !!).
The ELSE clause can be omitted, and thus allowing simple IF...ENDIF structures to be used:
<%if (%NEXT% eq "") %NEXT_IMG_CALL% %endif %>
that will finally call:
<TEMPLATE ID="NEXT_IMG_CALL"> <IMG SRC="<%%IMAGES_ROOT_URL%%>next.gif"> </TEMPLATE>
<%if (%NEXT% eq "") %NEXT_IMG_CALL% %endif %>
Note that either alternative can be a full featured DIML instruction provided it starts with an % and ends with another %. This implies any embedded '%' should be escaped.
For convenience, a similar syntax to SSI constructs have been added to the DIML definition, as it results very useful to switch between two large portions of DIML. This conditional construct uses short DIML conditional statements to define alternate blocks. Conditional structures may be indefinitely nested (just check the performance issues !). The processor will perform a first check of any evaluated fragment to check its conditional integrity.
Important Note: although the DIML syntax is defined as a powerful textual substitution and arrangement tool, conditional integrity MUST be checked within each fragment, BEFORE any substitution opers. Consequently, THERE IS NO WAY a fragment may rely on potential substitution to complete a conditional structure.
Rules for integrity checking are:
Next example will use a simple conditional structure :
<%if (%TEST% eq "one") %> first alternative choosed <%elsif (%TEST% eq "two") %> second alternative choosed <%else %> none of them but<BR> <%if (%TEST% eq "three") %> first embedded alternative choosed <%else %> second embedded alternative choosed <%endif %> <%endif %>
and will present in the following table the results whenever %TEXT% is 'one', 'two', 'threee' or 'four'.
one | two | three | four |
<%set %TEST% = "one" %><%%conditionals%%> |
<%set %TEST% = "two" %><%%conditionals%%> |
<%set %TEST% = "three" %><%%conditionals%%> |
<%set %TEST% = "four" %><%%conditionals%%> |
A DIML document will use some data sources do determine data final values. Some of these sources are predefined as:
Other sources may be totally customized, as script calculation results or database extraction within the feeding script.
The ESSI Processor implementation provides two major methods to invoke the feeder of a DIML document.
In this implementation, the ESSI Processor is a "slave" library function, called by a "main" feeding script. This is the actual feeding way used to compose the present document. The feeding script should only fill up an interface hasharray, and just pass it to the Processor (as a global variable or a reference, depending on implementation).
In this case, the page construction will be represented by the following scheme:
This implementation allows direct invocation of a DIML document, according to the following construction sequence:
The DIML document should then include an %invoke statement to dynamically execute the feeding script portion.
What follows is an example of this technique, calling a Perl script file "testfeed.pl" that will just define the %EXTERNAL1% and %EXTERNAL2% entries.
<%invoke script="<% %SITE_ROOT_PATH% %>support/test/testfeed.php" %>
Before script invocation | "Invoking" | after invocation |
<% %EXTERNAL1% %> = "<% %EXTERNAL1% %>" <% %EXTERNAL2 % %> = "<% %EXTERNAL2 % %>" |
<%invoke script="<% %SITE_ROOT_PATH% %>support/test/testfeed.php" %> | <% %EXTERNAL1% %> = "<% %EXTERNAL1% %>" <% %EXTERNAL2 % %> = "<% %EXTERNAL2 % %>" |
Note the use of SGML escapes '<' and '>' in the script location expression that will avoid confusion with starting and ending markers of a DIML statement.
Copyright (C) 2000 Valery Fremaux for EISTI (vf@eisti.fr), Business Copyright (C) 2000 ADITRI
The Perl DIML Processor is a free software prototype; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
The DIML definition is a free access specification, that is, will need no patent nor royalty when implemented or used in the GNU scope. Use of "DIML" related symbols and acronym is free but IMPLIES a full acceptation of the DIML specification, with some tolerances as:
Mandatory parts of the definition includes:
This license only restricts the former disposition to a non profit use only. Request for implementation as part of commercial products should be addressed to:
ADITRI Software Licensingor emailed to early-licensing@eisti.fr
Some HTML statements...
An iterated injection mark : <% %TAB1D[]% %>
Some other HTML...