[Zope3-checkins] CVS: Zope3/src/zope/pagetemplate - pagetemplatefile.py:1.3
Fred L. Drake, Jr.
fred@zope.com
Fri, 21 Mar 2003 13:02:22 -0500
Update of /cvs-repository/Zope3/src/zope/pagetemplate
In directory cvs.zope.org:/tmp/cvs-serv1637
Modified Files:
pagetemplatefile.py
Log Message:
_cook_check(): When loading a template from a file, actually "sniff"
the content to see if the document should be parsed in XML mode.
document_src(): Before setting the Content-Type header, make sure
we've sniffed the file content to see what the right Content-Type
is.
sniff_type(): New function: Examine some text to see if it's likely
to be XML.
=== Zope3/src/zope/pagetemplate/pagetemplatefile.py 1.2 => 1.3 ===
--- Zope3/src/zope/pagetemplate/pagetemplatefile.py:1.2 Wed Dec 25 09:15:13 2002
+++ Zope3/src/zope/pagetemplate/pagetemplatefile.py Fri Mar 21 13:02:21 2003
@@ -52,7 +52,12 @@
mtime = 0
if self._v_program is not None and mtime == self._v_last_read:
return
- self.pt_edit(open(self.filename), None)
+ f = open(self.filename, "rb")
+ try:
+ text = f.read()
+ finally:
+ f.close()
+ self.pt_edit(text, sniff_type(text))
self._cook()
if self._v_errors:
logging.error('PageTemplateFile: Error in template: %s',
@@ -64,6 +69,10 @@
"""Return expanded document source."""
if REQUEST is not None:
+ # Since _cook_check() can cause self.content_type to change,
+ # we have to make sure we call it before setting the
+ # Content-Type header.
+ self._cook_check()
REQUEST.response.setHeader('Content-Type', self.content_type)
return self.read()
@@ -72,3 +81,20 @@
def __getstate__(self):
raise TypeError("non-picklable object")
+
+
+XML_PREFIXES = [
+ "<?xml", # ascii, utf-8
+ "\xef\xbb\xbf<?xml", # utf-8 w/ byte order mark
+ "\0<\0?\0x\0m\0l", # utf-16 big endian
+ "<\0?\0x\0m\0l\0", # utf-16 little endian
+ "\xfe\xff\0<\0?\0x\0m\0l", # utf-16 big endian w/ byte order mark
+ "\xff\xfe<\0?\0x\0m\0l\0", # utf-16 little endian w/ byte order mark
+ ]
+
+def sniff_type(text):
+ """Return 'text/xml' if text appears to be XML, otherwise return None."""
+ for prefix in XML_PREFIXES:
+ if text.startswith(prefix):
+ return "text/xml"
+ return None