Setting a mime-type on a Zope 3 browser view

classic Classic list List threaded Threaded
13 messages Options
Derek Broughton-3 Derek Broughton-3
Reply | Threaded
Open this post in threaded view
|

Setting a mime-type on a Zope 3 browser view

I have a couple of browser views that are trying to render XML and getting
bitten by the "bug" of https://bugs.launchpad.net/zope2/+bug/142801

I realize this isn't really a bug, but how DOES one set a mime-type on a
browser view?  There doesn't seem to be anything in the ZCML <view>
definition.  Because the ISO 19139 xml tags I'm trying to use are mixed
case, but the template is being processed as text/html, the mixed-case tags
below are being rendered in lowercase - and then my xsl stylesheet doesn't
work.  If I put the <?xml-stylesheet?> tag into the viewlet, it would
probably actually look like it worked, but the raw XML would still be wrong,
since those tags really are mixed-case.

My view template is simply:
  <?xml version="1.0" encoding="iso-8859-1" ?>
  <?xml-stylesheet type="text/xsl" href="++resource++ISO2text.xsl" ?>
    <div tal:replace="structure provider:MetadataViewlets"
      xmlns:tal="http://xml.zope.org/namespaces/tal"
    />

while the code included by the viewlet manager starts:

  <mcp:MD_Metadata
      xmlns:ns1="http://www.opengis.net/gml/"
      xmlns:tal="http://xml.zope.org/namespaces/tal"
      xmlns:xlink="http://www.w3.org/1999/xlink"
      xmlns:mcp="http://bluenet3.antcrc.utas.edu.au/mcp"
      xmlns:gco="http://www.isotc211.org/2005/gco"
      xmlns:gmd="http://www.isotc211.org/2005/gmd"
      xmlns:srv="http://www.isotc211.org/2005/srv"
      xmlns:gts="http://www.isotc211.org/2005/gts"
        gco:isoType="gmd:MD_Metadata">
    <gmd:fileIdentifier>
        <gco:CharacterString tal:content="context/id" />
    </gmd:fileIdentifier>
...
--
derek


_______________________________________________
Product-Developers mailing list
[hidden email]
http://lists.plone.org/mailman/listinfo/product-developers
David Glick (GW) David Glick (GW)
Reply | Threaded
Open this post in threaded view
|

Re: [Product-Developers] Setting a mime-type on a Zope 3 browser view

Derek Broughton wrote:

> I have a couple of browser views that are trying to render XML and getting
> bitten by the "bug" of https://bugs.launchpad.net/zope2/+bug/142801
>
> I realize this isn't really a bug, but how DOES one set a mime-type on a
> browser view?  There doesn't seem to be anything in the ZCML <view>
> definition.  Because the ISO 19139 xml tags I'm trying to use are mixed
> case, but the template is being processed as text/html, the mixed-case tags
> below are being rendered in lowercase - and then my xsl stylesheet doesn't
> work.  If I put the <?xml-stylesheet?> tag into the viewlet, it would
> probably actually look like it worked, but the raw XML would still be wrong,
> since those tags really are mixed-case.
>
> My view template is simply:
>   <?xml version="1.0" encoding="iso-8859-1" ?>
>   <?xml-stylesheet type="text/xsl" href="++resource++ISO2text.xsl" ?>
>     <div tal:replace="structure provider:MetadataViewlets"
>       xmlns:tal="http://xml.zope.org/namespaces/tal"
>     />
>
> while the code included by the viewlet manager starts:
>
>   <mcp:MD_Metadata
>       xmlns:ns1="http://www.opengis.net/gml/"
>       xmlns:tal="http://xml.zope.org/namespaces/tal"
>       xmlns:xlink="http://www.w3.org/1999/xlink"
>       xmlns:mcp="http://bluenet3.antcrc.utas.edu.au/mcp"
>       xmlns:gco="http://www.isotc211.org/2005/gco"
>       xmlns:gmd="http://www.isotc211.org/2005/gmd"
>       xmlns:srv="http://www.isotc211.org/2005/srv"
>       xmlns:gts="http://www.isotc211.org/2005/gts"
> gco:isoType="gmd:MD_Metadata">
>     <gmd:fileIdentifier>
>         <gco:CharacterString tal:content="context/id" />
>     </gmd:fileIdentifier>
> ...
>  
You probably need to set the Content-Type HTTP header in the
response...here's an example from
http://svn.plone.org/svn/plone/Plone/branches/3.3/Products/CMFPlone/skins/plone_templates/rss_template.pt 
--

<metal:block tal:define="dummy
python:request.RESPONSE.setHeader('Content-Type',
'text/xml;;charset='+context.plone_utils.getSiteEncoding())" />

David

--
David Glick
Web Developer
Groundwire
206.286.1235x32
[hidden email]
http://groundwire.org

ONE/Northwest is now Groundwire!

_______________________________________________
Product-Developers mailing list
[hidden email]
http://lists.plone.org/mailman/listinfo/product-developers
Derek Broughton-3 Derek Broughton-3
Reply | Threaded
Open this post in threaded view
|

Re: Setting a mime-type on a Zope 3 browser view

David Glick wrote:

> Derek Broughton wrote:
>> I have a couple of browser views that are trying to render XML and
>> getting bitten by the "bug" of
>> https://bugs.launchpad.net/zope2/+bug/142801
>>
>> I realize this isn't really a bug, but how DOES one set a mime-type on a
>> browser view?  There doesn't seem to be anything in the ZCML <view>
>> definition.  Because the ISO 19139 xml tags I'm trying to use are mixed
>> case, but the template is being processed as text/html, the mixed-case
>> tags below are being rendered in lowercase - and then my xsl stylesheet
>> doesn't
>> work.  If I put the <?xml-stylesheet?> tag into the viewlet, it would
>> probably actually look like it worked, but the raw XML would still be
>> wrong, since those tags really are mixed-case.
>>
>> My view template is simply:
>>   <?xml version="1.0" encoding="iso-8859-1" ?>
>>   <?xml-stylesheet type="text/xsl" href="++resource++ISO2text.xsl" ?>
>>     <div tal:replace="structure provider:MetadataViewlets"
>>       xmlns:tal="http://xml.zope.org/namespaces/tal"
>>     />
>>
>> while the code included by the viewlet manager starts:
>>
>>   <mcp:MD_Metadata
>>       xmlns:ns1="http://www.opengis.net/gml/"
>>       xmlns:tal="http://xml.zope.org/namespaces/tal"
>>       xmlns:xlink="http://www.w3.org/1999/xlink"
>>       xmlns:mcp="http://bluenet3.antcrc.utas.edu.au/mcp"
>>       xmlns:gco="http://www.isotc211.org/2005/gco"
>>       xmlns:gmd="http://www.isotc211.org/2005/gmd"
>>       xmlns:srv="http://www.isotc211.org/2005/srv"
>>       xmlns:gts="http://www.isotc211.org/2005/gts"
>> gco:isoType="gmd:MD_Metadata">
>>     <gmd:fileIdentifier>
>>         <gco:CharacterString tal:content="context/id" />
>>     </gmd:fileIdentifier>
>> ...
>>  
> You probably need to set the Content-Type HTTP header in the
> response...here's an example from
>
http://svn.plone.org/svn/plone/Plone/branches/3.3/Products/CMFPlone/skins/plone_templates/rss_template.pt
> --
>
> <metal:block tal:define="dummy
> python:request.RESPONSE.setHeader('Content-Type',
> 'text/xml;;charset='+context.plone_utils.getSiteEncoding())" />
>

Thanks, but I rather hope that's not right.  Are you seriously telling me
that Zope is reading it's own _output_ stream to determine how to parse the
current template?  As near as I could tell, it should have known to use the
XML, rather than HTML, parser by virtue of the <?xml?> tag at the beginning
of the template.

In any case, I tried it, and got a worse error:

  Module zope.pagetemplate.pagetemplate, line 111, in pt_render
   - Warning: Compilation failed
   - Warning: xml.parsers.expat.ExpatError: junk after document element:
line 10, column 4


Where the template is now:
  <?xml version="1.0"?>
  <?xml-stylesheet type="text/xsl" href="++resource++ISO2text.xsl" ?>

  <metal:block
    tal:define="dummy python:request.RESPONSE.setHeader('Content-Type',
'text/xml;;charset='+context.plone_utils.getSiteEncoding())"
    xmlns:tal="http://xml.zope.org/namespaces/tal"
    xmlns:metal="http://xml.zope.org/namespaces/metal"
    />

    <div tal:replace="structure provider:MetadataViewlets"
      xmlns:tal="http://xml.zope.org/namespaces/tal"
    />

and line 10 is the <div>
--
derek


_______________________________________________
Product-Developers mailing list
[hidden email]
http://lists.plone.org/mailman/listinfo/product-developers
Martin Aspeli Martin Aspeli
Reply | Threaded
Open this post in threaded view
|

Re: Setting a mime-type on a Zope 3 browser view

In reply to this post by David Glick (GW)
David Glick wrote:

> Derek Broughton wrote:
>> I have a couple of browser views that are trying to render XML and getting
>> bitten by the "bug" of https://bugs.launchpad.net/zope2/+bug/142801
>>
>> I realize this isn't really a bug, but how DOES one set a mime-type on a
>> browser view?  There doesn't seem to be anything in the ZCML<view>
>> definition.  Because the ISO 19139 xml tags I'm trying to use are mixed
>> case, but the template is being processed as text/html, the mixed-case tags
>> below are being rendered in lowercase - and then my xsl stylesheet doesn't
>> work.  If I put the<?xml-stylesheet?>  tag into the viewlet, it would
>> probably actually look like it worked, but the raw XML would still be wrong,
>> since those tags really are mixed-case.
>>
>> My view template is simply:
>>    <?xml version="1.0" encoding="iso-8859-1" ?>
>>    <?xml-stylesheet type="text/xsl" href="++resource++ISO2text.xsl" ?>
>>      <div tal:replace="structure provider:MetadataViewlets"
>>        xmlns:tal="http://xml.zope.org/namespaces/tal"
>>      />
>>
>> while the code included by the viewlet manager starts:
>>
>>    <mcp:MD_Metadata
>>        xmlns:ns1="http://www.opengis.net/gml/"
>>        xmlns:tal="http://xml.zope.org/namespaces/tal"
>>        xmlns:xlink="http://www.w3.org/1999/xlink"
>>        xmlns:mcp="http://bluenet3.antcrc.utas.edu.au/mcp"
>>        xmlns:gco="http://www.isotc211.org/2005/gco"
>>        xmlns:gmd="http://www.isotc211.org/2005/gmd"
>>        xmlns:srv="http://www.isotc211.org/2005/srv"
>>        xmlns:gts="http://www.isotc211.org/2005/gts"
>> gco:isoType="gmd:MD_Metadata">
>>      <gmd:fileIdentifier>
>>          <gco:CharacterString tal:content="context/id" />
>>      </gmd:fileIdentifier>
>> ...
>>
> You probably need to set the Content-Type HTTP header in the
> response...here's an example from
> http://svn.plone.org/svn/plone/Plone/branches/3.3/Products/CMFPlone/skins/plone_templates/rss_template.pt
> --
>
> <metal:block tal:define="dummy
> python:request.RESPONSE.setHeader('Content-Type',
> 'text/xml;;charset='+context.plone_utils.getSiteEncoding())" />

Instead of doing this in the template, I'd do it in the view itself. e.g.:

class MyView(object):
     def __init__(self, context, request):
         self.context = context
         self.request = request
     def __call__(self):
         self.request.response.setHeader('Content-Type',
'text/xml;;charset="utf-8"')
         return self.index() # render template associated in ZCML

(You can look up the site encoding if you'd like, but it's going to be
utf-8 in virtually all situations. After speaking to Hanno about this
I've made the utf-8 assumption explicit in my code most of the time.)

Martin

--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book


_______________________________________________
Product-Developers mailing list
[hidden email]
http://lists.plone.org/mailman/listinfo/product-developers
Derek Broughton-3 Derek Broughton-3
Reply | Threaded
Open this post in threaded view
|

Re: Setting a mime-type on a Zope 3 browser view

Martin Aspeli wrote:

> David Glick wrote:
>> Derek Broughton wrote:
>>> I have a couple of browser views that are trying to render XML and
>>> getting bitten by the "bug" of
>>> https://bugs.launchpad.net/zope2/+bug/142801
>>>
>>> I realize this isn't really a bug, but how DOES one set a mime-type on a
>>> browser view?  There doesn't seem to be anything in the ZCML<view>
>>> definition.  Because the ISO 19139 xml tags I'm trying to use are mixed
>>> case, but the template is being processed as text/html, the mixed-case
>>> tags below are being rendered in lowercase - and then my xsl stylesheet
>>> doesn't
>>> work.  If I put the<?xml-stylesheet?>  tag into the viewlet, it would
>>> probably actually look like it worked, but the raw XML would still be
>>> wrong, since those tags really are mixed-case.
>>>
>>> My view template is simply:
>>>    <?xml version="1.0" encoding="iso-8859-1" ?>
>>>    <?xml-stylesheet type="text/xsl" href="++resource++ISO2text.xsl" ?>
>>>      <div tal:replace="structure provider:MetadataViewlets"
>>>        xmlns:tal="http://xml.zope.org/namespaces/tal"
>>>      />
>>>
>>> while the code included by the viewlet manager starts:
>>>
>>>    <mcp:MD_Metadata
>>>        xmlns:ns1="http://www.opengis.net/gml/"
>>>        xmlns:tal="http://xml.zope.org/namespaces/tal"
>>>        xmlns:xlink="http://www.w3.org/1999/xlink"
>>>        xmlns:mcp="http://bluenet3.antcrc.utas.edu.au/mcp"
>>>        xmlns:gco="http://www.isotc211.org/2005/gco"
>>>        xmlns:gmd="http://www.isotc211.org/2005/gmd"
>>>        xmlns:srv="http://www.isotc211.org/2005/srv"
>>>        xmlns:gts="http://www.isotc211.org/2005/gts"
>>> gco:isoType="gmd:MD_Metadata">
>>>      <gmd:fileIdentifier>
>>>          <gco:CharacterString tal:content="context/id" />
>>>      </gmd:fileIdentifier>
>>> ...
>>>
>> You probably need to set the Content-Type HTTP header in the
>> response...here's an example from
>>
http://svn.plone.org/svn/plone/Plone/branches/3.3/Products/CMFPlone/skins/plone_templates/rss_template.pt

>> --
>>
>> <metal:block tal:define="dummy
>> python:request.RESPONSE.setHeader('Content-Type',
>> 'text/xml;;charset='+context.plone_utils.getSiteEncoding())" />
>
> Instead of doing this in the template, I'd do it in the view itself. e.g.:
>
> class MyView(object):
>      def __init__(self, context, request):
>          self.context = context
>          self.request = request
>      def __call__(self):
>          self.request.response.setHeader('Content-Type',
> 'text/xml;;charset="utf-8"')
>          return self.index() # render template associated in ZCML
>
> (You can look up the site encoding if you'd like, but it's going to be
> utf-8 in virtually all situations. After speaking to Hanno about this
> I've made the utf-8 assumption explicit in my code most of the time.)

That makes more sense than setting it in the template - at least we have a
content-type before the TAL markup is rendered.  Unfortunately, it doesn't
work either.  I have tried:
- setting the View name to "Text.xml"
- setting an attribute "content_type = 'text/xml'" in the view class
- the examples from you and David
- your example omitting the second, I believe extraneous, ';' in  
  'text/xml;;charset="utf-8"' and/or omitting the __init__() (that's just
  the default method, is it not?)
all with no success.

Is it possible to explicitly invoke the TAL XML parser in the "self.index()"
call above, rather than the HTML parser?  I guess it must be...
--
derek


_______________________________________________
Product-Developers mailing list
[hidden email]
http://lists.plone.org/mailman/listinfo/product-developers
Martin Aspeli Martin Aspeli
Reply | Threaded
Open this post in threaded view
|

Re: Setting a mime-type on a Zope 3 browser view

Derek Broughton wrote:

> Martin Aspeli wrote:
>
>> David Glick wrote:
>>> Derek Broughton wrote:
>>>> I have a couple of browser views that are trying to render XML and
>>>> getting bitten by the "bug" of
>>>> https://bugs.launchpad.net/zope2/+bug/142801
>>>>
>>>> I realize this isn't really a bug, but how DOES one set a mime-type on a
>>>> browser view?  There doesn't seem to be anything in the ZCML<view>
>>>> definition.  Because the ISO 19139 xml tags I'm trying to use are mixed
>>>> case, but the template is being processed as text/html, the mixed-case
>>>> tags below are being rendered in lowercase - and then my xsl stylesheet
>>>> doesn't
>>>> work.  If I put the<?xml-stylesheet?>   tag into the viewlet, it would
>>>> probably actually look like it worked, but the raw XML would still be
>>>> wrong, since those tags really are mixed-case.
>>>>
>>>> My view template is simply:
>>>>     <?xml version="1.0" encoding="iso-8859-1" ?>
>>>>     <?xml-stylesheet type="text/xsl" href="++resource++ISO2text.xsl" ?>
>>>>       <div tal:replace="structure provider:MetadataViewlets"
>>>>         xmlns:tal="http://xml.zope.org/namespaces/tal"
>>>>       />
>>>>
>>>> while the code included by the viewlet manager starts:
>>>>
>>>>     <mcp:MD_Metadata
>>>>         xmlns:ns1="http://www.opengis.net/gml/"
>>>>         xmlns:tal="http://xml.zope.org/namespaces/tal"
>>>>         xmlns:xlink="http://www.w3.org/1999/xlink"
>>>>         xmlns:mcp="http://bluenet3.antcrc.utas.edu.au/mcp"
>>>>         xmlns:gco="http://www.isotc211.org/2005/gco"
>>>>         xmlns:gmd="http://www.isotc211.org/2005/gmd"
>>>>         xmlns:srv="http://www.isotc211.org/2005/srv"
>>>>         xmlns:gts="http://www.isotc211.org/2005/gts"
>>>> gco:isoType="gmd:MD_Metadata">
>>>>       <gmd:fileIdentifier>
>>>>           <gco:CharacterString tal:content="context/id" />
>>>>       </gmd:fileIdentifier>
>>>> ...
>>>>
>>> You probably need to set the Content-Type HTTP header in the
>>> response...here's an example from
>>>
> http://svn.plone.org/svn/plone/Plone/branches/3.3/Products/CMFPlone/skins/plone_templates/rss_template.pt
>>> --
>>>
>>> <metal:block tal:define="dummy
>>> python:request.RESPONSE.setHeader('Content-Type',
>>> 'text/xml;;charset='+context.plone_utils.getSiteEncoding())" />
>> Instead of doing this in the template, I'd do it in the view itself. e.g.:
>>
>> class MyView(object):
>>       def __init__(self, context, request):
>>           self.context = context
>>           self.request = request
>>       def __call__(self):
>>           self.request.response.setHeader('Content-Type',
>> 'text/xml;;charset="utf-8"')
>>           return self.index() # render template associated in ZCML
>>
>> (You can look up the site encoding if you'd like, but it's going to be
>> utf-8 in virtually all situations. After speaking to Hanno about this
>> I've made the utf-8 assumption explicit in my code most of the time.)
>
> That makes more sense than setting it in the template - at least we have a
> content-type before the TAL markup is rendered.  Unfortunately, it doesn't
> work either.  I have tried:
> - setting the View name to "Text.xml"

That's kind of irrelevant. Zope sets the Content-Type header.

> - setting an attribute "content_type = 'text/xml'" in the view class

Don't know why you think that would work. Nothing I know of would look
for it. :)

> - the examples from you and David

My example definitely works. You can see it in action in
plone.namedfile's @@download view for example.

> - your example omitting the second, I believe extraneous, ';' in
>    'text/xml;;charset="utf-8"' and/or omitting the __init__() (that's just
>    the default method, is it not?)
> all with no success.


Why don't you try without the charset first, just to test a simpler
header value?

> Is it possible to explicitly invoke the TAL XML parser in the "self.index()"
> call above, rather than the HTML parser?  I guess it must be...

I'm sure it is, but that's not what controls the Content-Type header
that is sent back to the browser. That header is set by setBody() in
ZPublisher.HTTPResponse::

         isHTML = self.isHTML(self.body)
         if not self.headers.has_key('content-type'):
             if isHTML:
                 c = 'text/html; charset=%s' % default_encoding
             else:
                 c = 'text/plain; charset=%s' % default_encoding
             self.setHeader('content-type', c)
         else:
             c = self.headers['content-type']
             if c.startswith('text/') and not 'charset=' in  c:
                 c = '%s; charset=%s' % (c, default_encoding)

                 self.setHeader('content-type', c)

Martin

--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book


_______________________________________________
Product-Developers mailing list
[hidden email]
http://lists.plone.org/mailman/listinfo/product-developers
David Glick (GW) David Glick (GW)
Reply | Threaded
Open this post in threaded view
|

Re: Setting a mime-type on a Zope 3 browser view

Martin Aspeli wrote:
>
>> Is it possible to explicitly invoke the TAL XML parser in the
>> "self.index()"
>> call above, rather than the HTML parser?  I guess it must be...
>
> I'm sure it is, but that's not what controls the Content-Type header
> that is sent back to the browser. That header is set by setBody() in
> ZPublisher.HTTPResponse::
>
I didn't read Derek's original question carefully enough. He was
actually asking about how to make the TAL parser behave differently (and
deal with mixed-case tags properly), rather than about how to change the
output content type.  Unfortunately I don't know the answer to the
former question.

David

--
David Glick
Web Developer
Groundwire
206.286.1235x32
[hidden email]
http://groundwire.org

ONE/Northwest is now Groundwire!

_______________________________________________
Product-Developers mailing list
[hidden email]
http://lists.plone.org/mailman/listinfo/product-developers
Derek Broughton-3 Derek Broughton-3
Reply | Threaded
Open this post in threaded view
|

Re: Setting a mime-type on a Zope 3 browser view

In reply to this post by Martin Aspeli
Martin Aspeli wrote:

> Derek Broughton wrote:
>> Martin Aspeli wrote:
>>
>>> David Glick wrote:
>>>> Derek Broughton wrote:
>>>>> I have a couple of browser views that are trying to render XML and
>>>>> getting bitten by the "bug" of
>>>>> https://bugs.launchpad.net/zope2/+bug/142801
>>>>>
>>>>> I realize this isn't really a bug, but how DOES one set a mime-type on
>>>>> a
>>>>> browser view?  There doesn't seem to be anything in the ZCML<view>
>>>>> definition.  Because the ISO 19139 xml tags I'm trying to use are
>>>>> mixed case, but the template is being processed as text/html, the
>>>>> mixed-case tags below are being rendered in lowercase - and then my
>>>>> xsl stylesheet doesn't
>>>>> work.  If I put the<?xml-stylesheet?>   tag into the viewlet, it would
>>>>> probably actually look like it worked, but the raw XML would still be
>>>>> wrong, since those tags really are mixed-case.
>>>>>
>>>>> My view template is simply:
>>>>>     <?xml version="1.0" encoding="iso-8859-1" ?>
>>>>>     <?xml-stylesheet type="text/xsl" href="++resource++ISO2text.xsl"
>>>>>     ?>
>>>>>       <div tal:replace="structure provider:MetadataViewlets"
>>>>>         xmlns:tal="http://xml.zope.org/namespaces/tal"
>>>>>       />
>>>>>
>>>>> while the code included by the viewlet manager starts:
>>>>>
>>>>>     <mcp:MD_Metadata
>>>>>         xmlns:ns1="http://www.opengis.net/gml/"
>>>>>         xmlns:tal="http://xml.zope.org/namespaces/tal"
>>>>>         xmlns:xlink="http://www.w3.org/1999/xlink"
>>>>>         xmlns:mcp="http://bluenet3.antcrc.utas.edu.au/mcp"
>>>>>         xmlns:gco="http://www.isotc211.org/2005/gco"
>>>>>         xmlns:gmd="http://www.isotc211.org/2005/gmd"
>>>>>         xmlns:srv="http://www.isotc211.org/2005/srv"
>>>>>         xmlns:gts="http://www.isotc211.org/2005/gts"
>>>>> gco:isoType="gmd:MD_Metadata">
>>>>>       <gmd:fileIdentifier>
>>>>>           <gco:CharacterString tal:content="context/id" />
>>>>>       </gmd:fileIdentifier>
>>>>> ...
>>>>>
>>>> You probably need to set the Content-Type HTTP header in the
>>>> response...here's an example from
>>>>
>>
http://svn.plone.org/svn/plone/Plone/branches/3.3/Products/CMFPlone/skins/plone_templates/rss_template.pt

>>>> --
>>>>
>>>> <metal:block tal:define="dummy
>>>> python:request.RESPONSE.setHeader('Content-Type',
>>>> 'text/xml;;charset='+context.plone_utils.getSiteEncoding())" />
>>> Instead of doing this in the template, I'd do it in the view itself.
>>> e.g.:
>>>
>>> class MyView(object):
>>>       def __init__(self, context, request):
>>>           self.context = context
>>>           self.request = request
>>>       def __call__(self):
>>>           self.request.response.setHeader('Content-Type',
>>> 'text/xml;;charset="utf-8"')
>>>           return self.index() # render template associated in ZCML
>>>
>>> (You can look up the site encoding if you'd like, but it's going to be
>>> utf-8 in virtually all situations. After speaking to Hanno about this
>>> I've made the utf-8 assumption explicit in my code most of the time.)
>>
>> That makes more sense than setting it in the template - at least we have
>> a
>> content-type before the TAL markup is rendered.  Unfortunately, it
>> doesn't
>> work either.  I have tried:
>> - setting the View name to "Text.xml"
>
> That's kind of irrelevant. Zope sets the Content-Type header.

Well, I know that _now_ - but it came from some hints on one of the Zope
lists that, at least at one time, that would work.
>
>> - setting an attribute "content_type = 'text/xml'" in the view class
>
> Don't know why you think that would work. Nothing I know of would look
> for it. :)

For the same reason I tried renaming the view name to Text.xml - and for the
record, I'm pretty sure I'm on the right track.

>
>> - the examples from you and David
>
> My example definitely works. You can see it in action in
> plone.namedfile's @@download view for example.
>
>> - your example omitting the second, I believe extraneous, ';' in
>>    'text/xml;;charset="utf-8"' and/or omitting the __init__() (that's
>>    just the default method, is it not?)
>> all with no success.
>
> Why don't you try without the charset first, just to test a simpler
> header value?
>
>> Is it possible to explicitly invoke the TAL XML parser in the
>> "self.index()"
>> call above, rather than the HTML parser?  I guess it must be...
>
> I'm sure it is, but that's not what controls the Content-Type header
> that is sent back to the browser. That header is set by setBody() in
> ZPublisher.HTTPResponse::

No, I really don't care what content type header is sent back - I suspect
text/html for the content type might work, but that's well beyond my current
problem.  My problem is that TAL, not my browser, is treating the template
as HTML rather than XML and therefore lowercases all the tags (using
HTMLParser.py).

A little debugging shows me that the problem is in using the viewlet.  My
main view template, Text.pt, starts with <?xml... and is treated as XML.  My
viewlet, _cannot_ start with <?xml (generates an error "XML Parsing Error:
XML or text declaration not at start of entity" if I add it).


I put some prints in Products/PageTemplates/PageTemplateFile.py:
def sniff_type(text):
    print __name__, 'sniff', text
    if text.startswith('<mcp:MD_Meta'):
        raise
    for prefix in XML_PREFIXES:
        if text.startswith(prefix):
            return "text/xml"
    return None

and find that I get two prints:
  Products.PageTemplates.PageTemplateFile sniff <?xml versio
  Products.PageTemplates.PageTemplateFile sniff <mcp:MD_Meta
The first is from Text.pt - which is recognized as xml - and the second is
the first line of the viewlet template, and gets treated as html.

I traced back that call, and found in _exec():
            if not response.headers.has_key('content-type'):
                response.setHeader('content-type', self.content_type)
so, yes, really, content_type should be settable in the view, somewhere, and
pulling out all my other code changes it seems that it _does_ work for the
_View_, but not for the _Viewlet_.  The only thing that actually seems to
set "text/xml" for the viewlet is that "sniff_type()" call and afaict it
can't possibly be right - surely the type of a viewlet must always be the
type of it's parent view?

Meanwhile, I haven't found anything that will work for a viewlet, so for
now, I'm going to just pull it out and duplicate the code in the two View
templates that were using it.
--
derek


_______________________________________________
Product-Developers mailing list
[hidden email]
http://lists.plone.org/mailman/listinfo/product-developers
Martin Aspeli Martin Aspeli
Reply | Threaded
Open this post in threaded view
|

Re: Setting a mime-type on a Zope 3 browser view

In reply to this post by David Glick (GW)
David Glick wrote:

> Martin Aspeli wrote:
>>> Is it possible to explicitly invoke the TAL XML parser in the
>>> "self.index()"
>>> call above, rather than the HTML parser?  I guess it must be...
>> I'm sure it is, but that's not what controls the Content-Type header
>> that is sent back to the browser. That header is set by setBody() in
>> ZPublisher.HTTPResponse::
>>
> I didn't read Derek's original question carefully enough. He was
> actually asking about how to make the TAL parser behave differently (and
> deal with mixed-case tags properly), rather than about how to change the
> output content type.  Unfortunately I don't know the answer to the
> former question.

D'oh! :)

I only read your reply and inferred his question from that. Sorry about
that.

Martin

--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book


_______________________________________________
Product-Developers mailing list
[hidden email]
http://lists.plone.org/mailman/listinfo/product-developers
Martin Aspeli Martin Aspeli
Reply | Threaded
Open this post in threaded view
|

Re: Setting a mime-type on a Zope 3 browser view

In reply to this post by Derek Broughton-3
Derek Broughton wrote:
::
>
> No, I really don't care what content type header is sent back - I suspect
> text/html for the content type might work, but that's well beyond my current
> problem.  My problem is that TAL, not my browser, is treating the template
> as HTML rather than XML and therefore lowercases all the tags (using
> HTMLParser.py).

Sorry, I misunderstood your question then. I suspect you still want to
set the response header, but more on that later.

> A little debugging shows me that the problem is in using the viewlet.  My
> main view template, Text.pt, starts with<?xml... and is treated as XML.  My
> viewlet, _cannot_ start with<?xml (generates an error "XML Parsing Error:
> XML or text declaration not at start of entity" if I add it).

I would perhaps think that using viewlets to compose an XML document is
not something viewlets were designed for. You may have more luck just
building the document using the tools that come with lxml, although this
will be more imperative and less template-like.

> I put some prints in Products/PageTemplates/PageTemplateFile.py:
> def sniff_type(text):
>      print __name__, 'sniff', text
>      if text.startswith('<mcp:MD_Meta'):
>          raise
>      for prefix in XML_PREFIXES:
>          if text.startswith(prefix):
>              return "text/xml"
>      return None
>
> and find that I get two prints:
>    Products.PageTemplates.PageTemplateFile sniff<?xml versio
>    Products.PageTemplates.PageTemplateFile sniff<mcp:MD_Meta
> The first is from Text.pt - which is recognized as xml - and the second is
> the first line of the viewlet template, and gets treated as html.
>
> I traced back that call, and found in _exec():
>              if not response.headers.has_key('content-type'):
>                  response.setHeader('content-type', self.content_type)
> so, yes, really, content_type should be settable in the view, somewhere, and
> pulling out all my other code changes it seems that it _does_ work for the
> _View_, but not for the _Viewlet_.  The only thing that actually seems to
> set "text/xml" for the viewlet is that "sniff_type()" call and afaict it
> can't possibly be right - surely the type of a viewlet must always be the
> type of it's parent view?
>
> Meanwhile, I haven't found anything that will work for a viewlet, so for
> now, I'm going to just pull it out and duplicate the code in the two View
> templates that were using it.

Maybe instead of using viewlets, you could use ZPT macros? I assume that
the ZPT parser would read the whole ZPT file and so you coul dhave a
<?xml ..> header in both, but obviously only the bits inside the
metal:define-macro would actually be pulled in.

Martin

--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book


_______________________________________________
Product-Developers mailing list
[hidden email]
http://lists.plone.org/mailman/listinfo/product-developers
Derek Broughton-3 Derek Broughton-3
Reply | Threaded
Open this post in threaded view
|

Re: Setting a mime-type on a Zope 3 browser view

In reply to this post by Martin Aspeli
Martin Aspeli wrote:

> David Glick wrote:
>> Martin Aspeli wrote:
>>>> Is it possible to explicitly invoke the TAL XML parser in the
>>>> "self.index()"
>>>> call above, rather than the HTML parser?  I guess it must be...
>>> I'm sure it is, but that's not what controls the Content-Type header
>>> that is sent back to the browser. That header is set by setBody() in
>>> ZPublisher.HTTPResponse::
>>>
>> I didn't read Derek's original question carefully enough. He was
>> actually asking about how to make the TAL parser behave differently (and
>> deal with mixed-case tags properly), rather than about how to change the
>> output content type.  Unfortunately I don't know the answer to the
>> former question.
>
> D'oh! :)
>
> I only read your reply and inferred his question from that. Sorry about
> that.

No problem, you got me on the trail.
--
derek


_______________________________________________
Product-Developers mailing list
[hidden email]
http://lists.plone.org/mailman/listinfo/product-developers
Derek Broughton-3 Derek Broughton-3
Reply | Threaded
Open this post in threaded view
|

Re: Setting a mime-type on a Zope 3 browser view

In reply to this post by Martin Aspeli
Martin Aspeli wrote:

> Derek Broughton wrote:
> ::
>>
>> No, I really don't care what content type header is sent back - I suspect
>> text/html for the content type might work, but that's well beyond my
>> current
>> problem.  My problem is that TAL, not my browser, is treating the
>> template as HTML rather than XML and therefore lowercases all the tags
>> (using HTMLParser.py).
>
> Sorry, I misunderstood your question then. I suspect you still want to
> set the response header, but more on that later.
>
>> A little debugging shows me that the problem is in using the viewlet.  My
>> main view template, Text.pt, starts with<?xml... and is treated as XML.
>> My viewlet, _cannot_ start with<?xml (generates an error "XML Parsing
>> Error: XML or text declaration not at start of entity" if I add it).
>
> I would perhaps think that using viewlets to compose an XML document is
> not something viewlets were designed for.

It wasn't really my intent, it just turned out that a viewlet was a good way
to include another template at the time.  Then my design changed, and
simplified, and in the end I ended up with a single template that needed a
choice of XSL stylesheets, so it was easy enough to remove the viewlet.

> You may have more luck just
> building the document using the tools that come with lxml, although this
> will be more imperative and less template-like.

...
> Maybe instead of using viewlets, you could use ZPT macros? I assume that
> the ZPT parser would read the whole ZPT file and so you coul dhave a
> <?xml ..> header in both, but obviously only the bits inside the
> metal:define-macro would actually be pulled in.

My turn for a D'oh.  It was using a viewlet because there was originally a
need for a viewlet, but you're absolutely right that this is both a better
idea, and more suited to my current purpose.

Thanks.

(Still, it doesn't seem right that viewlets can have a different content-
type from the view that invokes them),
--
derek


_______________________________________________
Product-Developers mailing list
[hidden email]
http://lists.plone.org/mailman/listinfo/product-developers
Martin Aspeli Martin Aspeli
Reply | Threaded
Open this post in threaded view
|

Re: Setting a mime-type on a Zope 3 browser view

Derek Broughton wrote:

>> I would perhaps think that using viewlets to compose an XML document is
>> not something viewlets were designed for.
>
> It wasn't really my intent, it just turned out that a viewlet was a good way
> to include another template at the time.  Then my design changed, and
> simplified, and in the end I ended up with a single template that needed a
> choice of XSL stylesheets, so it was easy enough to remove the viewlet.

I think the main use case for viewlets is when third-party products need
to "plug into" the UI at specified points, perhaps for specific contexts
and/or views. For example, plone.app.discussion can plug into the area
under the content to show discussion threads everywhere that it makes sense.

They are not a good way to break a single template up into a few
re-usable chunks. For that, they are overkill.

> My turn for a D'oh.  It was using a viewlet because there was originally a
> need for a viewlet, but you're absolutely right that this is both a better
> idea, and more suited to my current purpose.

Good. :)

> Thanks.
>
> (Still, it doesn't seem right that viewlets can have a different content-
> type from the view that invokes them),

Agree. I think this is a quirk of the ZPT engine, though. Bear in mind
that the viewlet isn't really aware of how the template works. A viewlet
just has a render() method that's meant to return some output. Some
viewlets' render() method will invoke a ViewPageTemplateFile which in
turn executes the ZPT engine over a template file. However, that's not
part of the viewlet mechanism: you could just as easily return a
hand-coded string or one built using any other templating engine.

Therefore, the problem is more the sniffing that the ZPT engine is doing
to go into XML mode. I'm sure there's a way to invoke the
ViewPageTemplateFile from render() that forces this without the
sniffing, but I'm not sure how. I doubt many people use ZPTs to build
XML documents (although it's a perfectly reasonable thing to want to do).

Martin

--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book


_______________________________________________
Product-Developers mailing list
[hidden email]
http://lists.plone.org/mailman/listinfo/product-developers