Templates vs. Scripts
Web Connection supports two very similar mechanisms for 'scripting'. One uses templates and one uses scripts. The difference between the two are relatively subtle but the key points are:
Used with: Response.ExpandTemplate()
- Are evaluated
- Can be updated as text files and immediately reflect changes
- Can only evaluate FoxPro expressions or CodeBlocks
- Cannot use nested block code other then
- Are fast to execute, especially if you only use expressions
Used with: Response.ExpandScript()
- Are (automatically) compiled as FoxPro code
- Are turned into real PRG files that you can debug
- Support complex logic including expressions, codeblocks and nested control flow blocks
- Are more difficult to update in multi-instance applications due to FXP locking
In summary, templates work great if you don't have to execute code inside of your scripts. They are quick to execute, but most importantly you can update them and are guaranteed to see changes reflected immediately as soon as you update the file.
Scripts support the full gamut of FoxPro code, so you can create much more complex logic than with templates. If you need to build layout that loops over FoxPro data
but they are more complex to administer because the code has to be compiled on the server and FXP files have to be updated. And although Scripts run fully compiled FoxPro code, there's a bit of overhead involved in checking to ensure that compiled files exist and can execute. Scripts can also be compiled into an application optionally.
Scripts are little programs that are based on VFP's TEXTMERGE mechanism. Web Connection converts the scripts you create into a real runnable PRG file that outputs into a TEXTMERGE file which is captured and returned to the Web browser.
Here's a simple example script page:
<html> <body style="font:normal normal 10pt Verdana"> <h1>Customer Table Display</h1> <hr> <% SELECT * FROM TT_CUST INTO Cursor TQuery lnReccount = RECCOUNT() %> Customer Table has <%= Reccount() %> records.<p> <table border=1 style="font:normal normal 8pt Tahoma"> <% SCAN %> <tr><td><%= TQuery.Company %></td><td><%= TQuery.Address %></td></tr> <% ENDSCAN %> </table> </body></html>
To run this page save it to a .WCS (Web Connection Script) extension and call it via Web URL:
Notice that you use for blocks of script code that run like a program, and to output expressions that return a value. should only be used with a single expression while can host multiple commands (translated into TEXTMERGE terms are TextMerge expressions, while is considered pure code. Anything else (the static HTML) is what goes between TEXT...ENDTEXT directives).
If you have an error in your code the page will bring back an error. For example if I misspell Reccount() above as Recount() you get a Scripting Error Page that says:
Error: File 'recount.prg' does not exist. Code: Recount() Error Number: 1 Line No: 9
If you're in debug mode (DEBUGMODE .T. in wconnect.h) Web Connection will also try to find the line of code that caused the error and position the cursor on it. This is not always possible due to the nature of the error, but in most cases and especially those were a simple typo occurred you can edit the change save and re-run the request immediately.
Fixing up the example
Let's change the example around a little more to allow a little more flexibility. Let's fix up the display by adding the WestWind stylesheet, clean up the table display and add another field (phone) and finally support for asking the user which records he wants to see:
<html> <head> <title>Customer Table Scripting Demo</title> <LINK rel="stylesheet" type="text/css" href="westwind.css"> </head> <body> <h1>Customer Table Display</h1> <hr> <% lcCompany = UPPER(Request.Form("txtCompany")) lcWhere = "" IF !EMPTY(lcCompany) lcWhere = "WHERE UPPER(company) = lcCompany" ENDIF SELECT * FROM TT_CUST &lcWhere ; INTO Cursor TQuery ; ORDER BY Company lnReccount = RECCOUNT() %> <form method="POST" action="customertable.wcs"> Company Filter: <input type="text" name="txtCompany" value="<%= lcCompany %>"> <input type="Submit" value=" Get Customers"> </form> <hr> Selected <b><%= Reccount() %></b> records.<p> <table border="1"> <tr bgcolor="#EEEEEE"><th>Company</th><th>Address</th><th>Phone</th></tr> <% SCAN %> <tr> <td valign="top"><%= TQuery.Company %></td> <td><%= IIF(EMPTY(TQuery.Address),[<br>],DisplayMemo(TQuery.Address)) %></td> <td><%= IIF(EMPTY(TQuery.Phone),[<br>],DisplayMemo(TQuery.Phone)) %></td> </tr> <% ENDSCAN %> </table> <hr> <HR> </body> </html>
Note that this form has now become both an input and output form at the same time because we're using the form field (txtCompany) in a
Comment or report problem with topic