Aaxsys Notes
|
  More articles |
An immediate question is how to link the data from the various fields in client and property records to these documents? The solution in Aaxsys is to provide a special scripting method - ASL, "Aaxsys Scripting Language" - to bridge the gap between the database and the presentation (html). ASL is similar to PHP in that |
In a web-based environment, such as Aaxsys, using HTML is
a natural way providing documents. The user already has
a browser. No other viewing program (e.g., Acrobat Reader
for PDF) is needed. Moreover, HTML is a completely open
document format, it is directly legible and can be edited
with any text editor. Using CSS and additional graphical
elements, sophisticated styles can be achieved.
The user's browser will not see any of these extra characters. They
are "translated" into "pure" HTML by the server. The user only
sees an end result such as
Dear John Smith welcome to your ... | ||||||||||||||||||||
| |||||||||||||||||||||
it mixes with the HTML by utilizing the processing
instruction (PI) tags <?..?>.
The most straightforward and - at the same time - perhaps the most
necessary usage of this functionality is to embed simple data fields
into an HTML document:
Dear <? $Field(FirstName) $Field(LastName), ?> welcome to your ... |
Then why not use XSLT, the designated way to transform XML into HTML? For achieving the results needed here, XSLT appears excessively verbose and technical. To learn to use ASL in its simplest form, using the $Field keyword, is trivial compared with the learning needed for utilizing XSLT. Secondly, apart from simple field value references, ASL provides some necessary functionality that would be difficult to achieve using XLST alone. The complexity and extent of the XSLT would overpower that of the HTML and would transform a simple document into a complicated example of XML stylesheet programming. |
$Field to
print record field values into the document is the simple
(but major) first step, creating conditional content is the
next one. Suppose that we want to print the unit bedroom type.
It should be Studio when the number
of bedrooms is zero. For other cases, it should read (for
purposes of this example) (the number of
bedrooms) with the tag BR.
In ASL, this would be accomplished as follows:
$IFEQ($Field(Bedrooms),0,Studio,$Field(Bedrooms) BR) But how do we then do more complicated control structures? It is possible to embed $IFEQ functions into others, but the expressions quickly get unwieldy. In fact, ASL favors definitions to keep the templates looking simple.
$DEF(Beds) $IFEQ($Field(Bedrooms),0,Studio,$Field(Bedrooms) BR) $END(Beds) This property is a <? $Beds ?> unit and ... |
While using the keyword
$DEF(Call) $IFEQ($Upper(#1),RESERVATIONS,call #1 at 1-414-447-2000) $IFEQ($Upper(#1),MAINTENANCE,call #1 at 1-414-447-2007) $IFEQ($Upper(#1),RECEPTION,call #1 at 1-414-447-2015) $END(Call) ASL prefers definitions instead of complex control structures. Due to its simple parsing, one cannot even use string arguments containg commas, because in ASL there is no such a thing as "string in quotes". Thus, given two strings "This is an example of ..." and "This is another example of ...", to compare them using the keyword $IFEQ one should first define the corresponding macros:
$DEF(Text1) This is an example ...$END(Text1) $DEF(Text2) This is another example ...$END(Text2) and continue with $IFEQ($Text1,$Text2,...). In the above example, the definition keyword $DEF could have as well been replaced with $SET. The difference between $DEF and $SET is the following: While the former creates a genuine macro definition, the latter "sets" a permanent variable value. In case the value itself is constant (such as static text), then there is no difference between these two keywords.
|
This is accomplished with the keyword $FOREACH.
Let's say that the (top-level) element of the records
is So let us define a new keyword that creates a simple list of units and their monthly rates: $DEF(DoUnits) <table> <tr><th>Address</th><th>Rate</th></tr>' $FOREACH(Unit) <tr> <td>$Field(Address)</td> <td>$Field(MRate)</td> </tr> $END(Unit) </table> $END(DoUnits)
For example, let use define a macro that shows the status of a unit with respect to a given field. In case we only needed to show the smoking/non-smoking status, we could just define a "static" macro for this purpose:
$DEF(SmokingStatus) (1) $IFEQ($Field(Smoking),T,Smoking,Non-smoking) $END(SmokingStatus) However, by using parameters we can define a dynamic status macro:
$DEF(Status) (2) $IFEQ($Field(#1),T,#2) $IFEQ($Field(#1),F,#3) $END(Status) |
Then we can use the macro with any suitable field.
For example, $Status(Smoking,Smoking,Non-Smoking)
and $Status(Pets,Pet-friendly,Pet-free)
are both possible applications of the macro. (Also please note
the subtle difference between 1) and
2). The former always gives a result,
while the second only gives a (non-empty) result for
field values T and F.)
A classical initial test for a compiler is to be able to compile itself. In the same vein, an initial requirement for invoice templates would be to be able to re-produce the standard Aaxsys invoice. On the next page, we give a full listing for the standard default template. It can be used as a starting point for the user's own invoice templates, and also illustrates several ASL programming points. |
<? $STRICTON ?> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE>Guest Invoice for Client <? $Field(ClientNo)?></TITLE> <STYLE> <!-- TABLE {width:640;} TD,TH,A.link,SPAN.text { font-family: Arial, Helvetica, sans-serif; font-size: 10pt;} TH{font-family:arial,verdana,helvetica,sans-serif;} TH.title{font-family:arial,verdana,helvetica,sans-serif;color:white;background:#6699cc;} .header { font-family: Times New Roman, Times, Serif; TH.simple {border:0px none #ffffff; font-size: 12pt;background: #9fc7c7;} .text{font-family:arial,helvetica,sans-serif;font-size:10pt;} .extra{font-family:arial,helvetica,sans-serif;font-size:10pt;color:blue;} div {width:640;} --> </STYLE> <SCRIPT LANGUAGE="JavaScript1.2"><!-- function jsCloseFunction(e) { var ow = window.opener; var keyID = (window.event) ? event.keyCode : e.keyCode; if (keyID == 27) { window.close(); if (ow) ow.focus();} } //--></SCRIPT> </HEAD> <BODY BGCOLOR=#FFFFFF onKeyPress="jsCloseFunction(event);"> <? $DEF(SetStandardHeader) $BEGIN(VendorInformation) <H1> $Field(Company) </H1> <H3> $Field(Address) ($Field(Phone))</H3> <H3>$Field(City) $Field(State) $Field(Zip)</H3> $END(VendorInformation) $END(SetStandardHeader) ?> |
<? $DEF(SetHeader) $IFNEQ($Field(HeaderFile),,$INSERTFILE($Field(HeaderFile)),$SetStandardHeader) $END(SetHeader) ?> <? $SetHeader ?> <FORM $Field(EmailLink) method=post> <TABLE BORDER = 0 CELLSPACING="0" CELLPADDING="0"> <TR><TH COLSPAN = "5" class="title"><? $Field(ReportTitle) ?></TH> </TR> <TR><TD colspan="5"><img src="/pixel.gif" height="4"></TD></TR> <TR><TD colspan="5"><B><? $Field(InvoiceNo) ?></B></TD></TR> <TR><TD colspan="5"><img src="/pixel.gif" height="4"></TD></TR> <TR><TH></TH><TH COLSPAN = "2" align = "left">Client/Billing address </TH> <TH COLSPAN = 2 align = "left">Reservation information </TH></TR> <TR><TD></TD><TD colspan="4" bgcolor="RoyalBlue"><img src="/pixel.gif" height="1"></TD></TR> <TR><TD colspan="5"><img src="/pixel.gif" height="4"></TD></TR> <TR><TD></TD><TD COLSPAN = 2 valign = "top"> <B><? $Field(LastName),$Field(FirstName) ?></B><BR> <B></B><BR> <B></B> <B></B> <B></B><BR> </TD> <TD COLSPAN = 2 valign = "top"> <? $DEF(ResInfo) $BEGIN(ReservationInformation) Guest No: $Field(ClientNo)<BR> Agent: $Field(Agent)<BR> Unit: $Field(PropertyCode)<BR> Address: $Field(Address1)<BR> $IFNEQ($Field(Address2),, $Field(Address2)<BR>) $IFNEQ($Field(Suite),,Suite: $Field(Suite)<BR>) Parking: $Field(Parking)<BR> Phone: $Field(Phone)<BR> Start date: $Field(StartDate)<BR> End date: $Field(EndDate)<BR> Rent: $Field(Rent) $END(ReservationInformation) $END(ResInfo) ?> |
<? $IFEQ($Field(ClientType),Tenant,$ResInfo) ?> <BR> </TD></TR> <TR><TD></TD></TR> <TR> <TH COLSPAN=1 BGCOLOR=#F5F5DC align = "left" > Class</TH> <TH COLSPAN=1 BGCOLOR=#F5F5DC align = "left" > Reference #</TH><TH COLSPAN=1 BGCOLOR=#F5F5DC align = "left" > Description</TH> <TH COLSPAN=1 BGCOLOR=#F5F5DC align = "left" > Date</TH><TH COLSPAN=1 BGCOLOR=#F5F5DC align = "right"> Amount</TH> </TR> <TR><TD></TD></TR> <TR><TD colspan="5"><img src="/pixel.gif" height="4"></TD></TR> <TR><TD COLSPAN = "5" ALIGN = "left" BGCOLOR="#ECECEC"><B>CHARGES:</B></TD></TR> <TR><TD colspan="5"><img src="/pixel.gif" height="4"></TD></TR> <? $BEGIN(Charges) $FOREACH(ChargeItem) <TR> <TD WIDTH = 20%> </TD> <TD WIDTH = 20%> $Field(TransactionNo)</TD> <TD WIDTH = 30%> $Field(Description)</TD> <TD WIDTH = 15%> $Field(Date)</TD> <TD WIDTH = 15% ALIGN = "right"> $Field(Amount)</TD> </TR> $END(ChargeItem) <TR><TD colspan="5"><img src="/pixel.gif" height="2"></TD></TR> <TR><TD></TD><TD colspan="4" bgcolor="RoyalBlue"> <img src="/pixel.gif" height="1"></TD></TR> <TR><TD colspan="5"\><img src="/pixel.gif" height="2"></TD></TR> <TR><TD></TD><TD COLSPAN = 2><B>Total charges: </B></TD> <TD></TD><TD ALIGN ="right"><B>$Field(TotalCharges)</B></TD></TR> <TR><TD></TD></TR> $END(Charges) ?> |
<? $DEF(DoPayments) <TR><TD colspan="5"><img src="/pixel.gif" height="4"></TD></TR> <TR><TD COLSPAN = "5" ALIGN = "left" BGCOLOR="#ECECEC"><B>PAYMENTS:</B></TD></TR> <TR><TD colspan="5"><img src="/pixel.gif" height="4"></TD></TR> $BEGIN(Payments) $FOREACH(PaymentItem) <TR> <TD WIDTH = 20%> </TD> <TD WIDTH = 20%> $Field(TransactionNo)</TD> <TD WIDTH = 30%> $Field(Description)</TD> <TD WIDTH = 15%> $Field(Date)</TD> <TD WIDTH = 15% ALIGN = "right"> $Field(Amount)</TD> </TR> $END(PaymentItem) <TR><TD></TD><TD COLSPAN = 2><B> Total payments: </B></TD> <TD></TD><TD ALIGN ="right"><B>$Field(TotalPayments)</B></TD></TR> $END(Payments) $END(DoPayments) ?> <? $IFEQ($Field(?HasPayments),T,$DoPayments) ?> <TR><TD></TD></TR> <TR BGCOLOR = #9FC7C7><TD></TD> <TD COLSPAN = "2"> Balance due </TD> <TD></TD><TD ALIGN = "right"> <? $Field(BalanceDue) + ?></TD> </TR> <? $DEF(DoCredits) <TR><TD colspan="5"><img src="/pixel.gif" height="4"></TD></TR> <TR><TD COLSPAN = "5" ALIGN = "left" BGCOLOR="#ECECEC"><B>CREDITS:</B></TD></TR> <TR><TD colspan="5"><img src="/pixel.gif" height="4"></TD></TR> $BEGIN(Credits) $FOREACH(CreditItem) <TR> <TD WIDTH = 20%> </TD> <TD WIDTH = 20%> $Field(TransactionNo)</TD> <TD WIDTH = 30%> $Field(Description)</TD> <TD WIDTH = 15%> $Field(Date)</TD> <TD WIDTH = 15% ALIGN = "right"> $Field(Amount)</TD> </TR> $END(CreditItem) |
<TR><TD colspan="5"><img src="/pixel.gif" height="2"></TD></TR> <TR><TD></TD><TD colspan="4" bgcolor="RoyalBlue"> <img src="/pixel.gif" height="1"></TD></TR> <TR><TD colspan="5"\><img src="/pixel.gif" height="2"></TD></TR> <TR><TD></TD><TD COLSPAN = 2><B>Total credits: </B></TD> <TD></TD><TD ALIGN ="right"><B>$Field(TotalCredits)</B></TD></TR> <TR><TD></TD></TR> $END(Credits) $END(DoCredits) ?> <? $DEF(DoRefunds) <TR><TD colspan="5"><img src="/pixel.gif" height="4"></TD></TR> <TR><TD COLSPAN = "5" ALIGN = "left" BGCOLOR="#ECECEC"><B>REFUNDS:</B></TD></TR> <TR><TD colspan="5"><img src="/pixel.gif" height="4"></TD></TR> $BEGIN(Refunds) $FOREACH(RefundItem) <TR> <TD WIDTH = 20%> </TD> <TD WIDTH = 20%> $Field(TransactionNo)</TD> <TD WIDTH = 30%> $Field(Description)</TD> <TD WIDTH = 15%> $Field(Date)</TD> <TD WIDTH = 15% ALIGN = "right"> $Field(Amount)</TD> </TR> $END(RefundItem) <TR><TD colspan="5"><img src="/pixel.gif" height="2"></TD></TR> <TR><TD></TD><TD colspan="4" bgcolor="RoyalBlue"> <img src="/pixel.gif" height="1"></TD></TR> <TR><TD colspan="5"\><img src="/pixel.gif" height="2"></TD></TR> <TR><TD></TD><TD COLSPAN = 2><B>Total credits: </B></TD> <TD></TD><TD ALIGN ="right"><B>$Field(RefundItem)</B></TD></TR> <TR><TD></TD></TR> $END(Refunds) $END(DoRefunds) ?> <? $IFEQ($Field(?HasCredits),T,$DoCredits) $IFEQ($Field(?HasRefunds),T,$DoRefunds) ?> </TABLE> <? $IFNEQ($Field(InvFile2),,<p><div class="text">$Field(InvFile2)</div>) ?> </BODY> </HTML> |
|