In my latest concoction, I feel I've got a decent mix between readability, speed and flexibility.
It started out with my feeling that using "readable lookup columns" was a bit to verbose/data-heavy for templating.
I like pipe-separated column values, but on their own, in a template, they can be hard to read.
template = "<tr><td>$1</td><td>$2</td></tr>"
What I want to write is something like this:
template = "<tr><td>$name</td><td>$address</td></tr>"
In the demoapp I'm currently working on, I pick the field-labels (e.g. $name) from the first line in the lookup-column (fields := ...) using the Formula-property of NotesColumn.
fields := "firstName" : "lastName" : "company" : "address";
@Implode( @Transform( fields ; "fieldname" ;
@Text( @GetField( fieldname ) ) ) ; "|" )
This way, I don't have to maintain documentation of the indexes of the different values, nor the position of the values.
To get the most performance out of the rendering-engine, one more or less has to use evaluated formula-code. Iterating over an array of column-values using Forall/Replace is slower. It's more and more noticable the more documents/values one is putting through the rendering engine. If it's slow with one user, it's going to get a lot slower with hundred users/etc.
If all you were rendering were static content, and have a decent caching-engine, performance per render would be less of a problem.
My current solution is to join the array of column-values to a formula-interpretable-list. Due to Evaluate's limit on length of returned data, I have to process the data in snippets.
array = ["Party","Hard"] '(brackets to indicate an array)
formulaListString = |"| + Join( array, |":"| ) + |"|
All the templates are "compiled" to @ReplaceSubstring. You can see how I compile/process the templates and data when the demoapp is complete.
Another downside to using pure LS-processing of templates is that it's hard to do conditional templating without slowing down the rendering-engine/writing a lot of code.
Since all data are being processed by Evaluate/Formula, it's quite easy to add conditional compiling as well (@If condition -> conditionalTemplate ). If you want, you can use one template for all the data, or you can have multiple conditions, and a default template.
Example-code from an agent printing a table from 499 documents
Result - odd/even-template
Result - mixed conditional template
At the bottom of the above HTML-files, you can see the amount of values/rendering-time. The time includes all processing, getting field-indexes, columnvalues, rendering, etc. The processing is done on localhost, on my laptop (Core 2 Duo 2GHz/2GB RAM) in Windows XP.
I'm not done yet with the implementation. The current engine is comprised of two classes. One that renders arrays of pipe-separated values (could also process CSV-files), and a subclass that processes the columnvalues of a view.
I plan to add another subclass to the first. This would let you use ft-search on a view, and sort the resulting columnvalues on a field/value in the resulting columnvalues.
If you have further suggestions/wishes/are curious about the code, contact me. Preferably throught comments. :)
I can't say when the demoapp is complete. I'll probably have another update or two before the app is ready for the masses.