[ZPT] response.setHeader() best practice
Alan Kennedy
zpt@xhaus.com
Wed, 10 Apr 2002 12:19:45 EST5EDT
Toby,
Taking this off list, since I'm not sure it's relevant to
the list any more.
> You
> are assuming that "SAX2 events" is a convenient format
for the output
> data.
Honestly, I couldn't see it operating any other way. A Sax
event stream gives such fantastic code separation, at a
very low cost. Every xml parser supports it, and there's
oodles of SAX handlers already "out there". But this does
mean that I can't deal with non well-formed HTML files,
which might create a problem for Netscape 4.x and other
early browsers (Die, Netscape 4, die, put us all out of our
misery ;-).
> If the data is going over the wire then your event
handlers
> perform encoding.
Exactly.
> Do your SAX2 events receive strings in unicode?
Precisely. Though, because it's Java and Jython, they are
simply java.lang.String's or PyString's.
> If so there is very little difference between the
> two models.
It's quite likely we've both seen the same mistakes made
before, and have taken a similar approach to solving them.
>>But I am at a loss to think of any "further textual
>>processing" I might want to do.
>
> .....pass the string into a grammar checker, store the
result as an
> object attribute, or maybe pass it into a module which
writes the text
> into a banner gif. Im not always calculating a whole
document, or
> 'response'
OK, I see your point now. Actually, dealing with structure
validation is one of the next problems I am going to
address. I plan to use either Relax-NG or TREX (which
should be fairly straightforward to implement as SAX
handlers).
> Yes, encoding comes last in both models. You do it
incrementally, I do
> it in one big hit in ZPublisher.
Although I do the encoding incrementally, I still most
often capture the content in a buffer at the end, so that I
can gzip it.
> >Keeping the output as structured SAX2 events until the
very
> >last minute eliminates the need for "further textual
> >processing", i.e. I don't have to go parsing textual
HTML
> >looking for a/@href and form/@action attributes to
modify.
>
> Im not sure 'textual' is the right word, but i will use
it anyway... I
> guess you would perform your textual processing at the
SAX2 level?
Indeed. For me, URL rewriting is simply a case of
subclassing the base SAX2 handler, and overriding
the "startElement" handler to look for HTML attributes that
might contain URLs. If it finds any, it create a new SAX
AttributesImpl object, copied from the original Attributes,
modifies whichever attributes contain URIs, and passes it
onto the next handler in the chain.
Here is a demo code snippet (tabs shortened cos of email
word wrap)
============================================================
======
def createOutputBuffer(outFileName, encoding):
"""
Create an output file buffer to capture the output.
"""
try:
fbuf = TALFileWriter(TALOutputConstants.OUTPUT_HTML,
outFileName, encoding)
return fbuf
except java.io.IOException, exc:
print "Error creating file output buffer:" + outFileName
+ ":" + exc.getMessage()
sys.exit(0)
def createRewritingOutputBuffer(fileBuffer):
"""
Create a rewriting buffer which hands onto a file buffer.
The file buffer is a simple character stream.
The rewriter object is anything that has an "encodeURL"
method,
such as javax.servlet.http.HttpServletResponse
"""
try:
handler = TALUrlRewriteFilter(fileBuffer,
TALOutputConstants.HTML4RewriteAttrs, createRewriter())
return handler
except java.io.IOException, exc:
print "Error creating file output buffer:" + outFileName
+ ":" + exc.getMessage()
sys.exit(0)
def evalTemplate(template, outFileName, encoding, globals,
locals):
"""
Evaluate the template in the provided namespaces. Output
the results to file named by outFileName
"""
try:
fileBuf = createOutputBuffer(outFileName, encoding)
rewritingBuf = createRewritingOutputBuffer(fileBuf)
template.evaluate(rewritingBuf, globals, locals)
fileBuf.close()
except TALInterpretException, exc:
print "Error evaluating template:" + exc.getMessage()
sys.exit(0)
============================================================
======
> One good thing about your model is that you can
seperately get at:
>
> 1. A method that sets the response headers for character
encoding,
> sets up the encoder event handler for the right encoding,
then passes
> the document through the whole system to create the
response.
That's why I redesigned the whole TAL thing, to achieve
exactly that. As you can see from the code snippet above,
it makes for nice clean code. If I wanted, I could
1. Set the HTTP headers
2. Set the output stream for the template to be the output
stream from the response object
3. Evaluate the template
And that's it! Although that wouldn't allow me to do nice
HTTP 1.1 things like set the content-length and gzip the
content. If you're interested, I'll send you my demo
servlet (session tracking, url-rewriting) code.
> 2. The raw SAX2 events. There is no assumption that it is
generating a
> 'response'. Encoding doesnt come into it. (I would like
to get at a
> unicode string, not an event stream, but I think that
difference is
> trivia)
I have a simple TALByteBuffer which captures the output to
a byte array.
All output in my system goes through a
java.io.OutputStreamWriter, which either backs onto a
java.io.ByteArrayOutputStream or a java.io.FileWriter. The
transcoding is simply an extra parameter to the
OutputStreamWriter constructor.
> That is very much more than minor philosophy.
Jython and Java has *really* changed my brain. I can't
recommend it enough.
But then again, I never made an investment in Zope to begin
with. What got me interested in ZPT was
1. I was struggling to invent a HTML templating system that
didn't involve using non-HTML element names, and was not
getting very far.
2. I happily stumbled on ZPT, which was of course created
by the Great Guido.
3. The scales fell from my eyes.
Nuff said.
Cheers,
Alan.
---------------------------------------------
This message was sent using WebMail by CyberGate.
http://www.gate.net/webmail