lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

On Wed, 20 Jan 2010, Romulo wrote:

> I think the worst part is matching lines: where the user declared the
> tag, and where the code generator puts the associated
> expression/statement. With the template-is-a-Lua-script approach, it's
> somewhat hard to identify in what line  an expression is, because
> whilst you can check with the debug library what line the tag function
> was called, you can't tell which line the attribute is being declared
> ( span{ \n\n href="${ obj:link_to( 'blog' ) }" } ). Perhaps with a
> proper XML parser this can be made easier.
Hm, with a proper parser, yes. The parser I use is strictly regexp based
and henca has no notion of the line it is on. I would have to make that
a tad more sophisticated and store at least the line where the tag
starts in order to have better debugging. However, that applies to the
parsing and template compilation only. The compiled template is entirely
oblivious to the input. But the at that point I shall be past the issues
anyway where the template input has much impact on possible errors.

> I've thought of something similar, it is way simpler to just buffer
> all the output, or to send each buffer as it is available. However,
> there are some pages that are too big. too slow to generate or both.
> IMO, one alternative is to buffer all sequential statements of a block
> and output at it's end. More specifically, before each "end", be it
> belonging to an "if" or "for", call a "flush" command and let the
> webserver decides if it wants to buffer everything or not. This is
> just an idea, tough; I've not tested it yet.
That issue is bigger and I'm not entirely convinced that this can be
done automatically. I like to avoid to buffer things in the webserver
because I like to avoid memory allocations that I have to free. Having
parcle side by side with parclate puts me in the sweet position that I
can signal between the two as I like, even if that means I have to
violate WSAPI - which I do anyway in places because of performance. A
workable approach might be to have the developer declare break points in
the template something like <tag blah="bloh" l:yield=""> . That would
make the template engine return a chunk and a signal to the server not
to close the connection but wait for the next buffer. That however can
be implemented with coroputines quite nicely - even without buffering in
the server itself. Doing the chunking automatically is either error
prone or resource hogging I think.

> >> Do you plan to implement a forelse special attribute (i.e: if the loop
> >> never enters, then the "else" value shall be evaluated). If so, with
> >> what semantics?
> > Hm, if I get you right, you mean an empty table so it never loops, so I
> > wanna display another element. I think that can be done with tools
> > on board, even if not really pretty.
> Not only empty tables, but an empty iterator:
> ~~
> <pre>
> <div l:for="line in 'file.txt' ):lines()">
> ${ line }
> </div>
> </pre>
> ~~

For iterators that might be tricky. The forelse idea is resource
friendly becuase it would not open the file handle twice as it would
have to in the example above (when done in parclate). I think in the XML
approach it's quite hard to implement (as in howto reference the for
loop refering to in the forelse).

> I'm also considering to implement a _forfirst and _forlast, but am
> afraid of becoming too clunky and having to extend the syntax
> (_forfirst and _forlast would have to be elements/tags instead of
> attributes).
I would implement these things only if a real need for them comes up.
People have a tendency to help themselves and they come up with
solutions and also problems you never thought about. And they complain
if they really hit a road block.

I have put up a technical level doc on parclate, it explains how it gets
from markup to output based on an example:

Have a look if you want.