[Seaside] WAResponse and XML
Jay Hardesty
jayh at panix.com
Sat Aug 6 18:24:14 UTC 2011
On Aug 6, 2011, at 8:09 PM, Philippe Marschall wrote:
> 2011/8/6 Jay Hardesty <jayh at panix.com>:
>>
>> On Aug 5, 2011, at 8:01 AM, Philippe Marschall wrote:
>>
>>> 2011/8/4 Jay Hardesty <jayh at panix.com>:
>>>>
>>>> On Aug 4, 2011, at 8:04 AM, Philippe Marschall wrote:
>>>>
>>>>> 2011/8/4 Jay Hardesty <jayh at panix.com>:
>>>>>>
>>>>>> Hi - I'm having a problem returning XML as a response from within a Seaside app, after moving to 3.0.
>>>>>>
>>>>>> I used to return XML by:
>>>>>>
>>>>>> self session returnResponse:
>>>>>> (WAResponse new
>>>>>> contentType: 'text/xml';
>>>>>> nextPutAll: xmlString;
>>>>>> yourself)
>>>>>>
>>>>>> but t in Seaside 3.0 I get:
>>>>>> 'You can no longer return a new WAResponse instance. You must instead modify the Response contained in the active RequestContext. Look for senders of #respond: and #response for examples.'
>>>>>>
>>>>>>
>>>>>> Following the nearest examples I can find I tried:
>>>>>>
>>>>>> self requestContext respond: [:response |
>>>>>> | document |
>>>>>> document := MIMEDocument
>>>>>> contentType: 'text/xml';
>>>>>> content: xmlString.
>>>>>> response document: document]
>>>>>>
>>>>>> and:
>>>>>>
>>>>>> self requestContext respond: [:response |
>>>>>> response
>>>>>> contentType: 'text/xml';
>>>>>> nextPutAll: xmlString]
>>>>>>
>>>>>> but in both cases an html document arrives downstream (with XML in the body) rather than the XML itself as previously
>>>>>>
>>>>>> Think I'm missing something basic here... Thanks very much for any pointers,
>>>>>
>>>>> That should absolutely work. The sample code below works for me.
>>>>> You'll probably want to test with Firefox because it renders XML
>>>>> nicely.
>>>>>
>>>>> renderContentOn: html
>>>>> html anchor
>>>>> callback: [
>>>>> self requestContext respond: [ :response |
>>>>> response
>>>>> contentType: 'text/xml';
>>>>> nextPutAll: '<?xml version="1.0"
>>>>> encoding="UTF-8"?><hello><world/></hello>' ] ];
>>>>> with: 'XML'
>>>>>
>>>>> Cheers
>>>>> Philippe
>>>>> _______________________________________________
>>>>> seaside mailing list
>>>>> seaside at lists.squeakfoundation.org
>>>>> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
>>>>
>>>>
>>>> Thank you Phillipe - Yes, your code works for me just as you described.
>>>>
>>>> I guess my problem is that I want my renderContentOn: to immediately return XML in certain circumstances without any user action. As in this variation on your code example:
>>>>
>>>> renderContentOn: html
>>>> self requestContext respond: [ :response |
>>>> response
>>>> contentType: 'text/xml';
>>>> nextPutAll: '<?xml version="1.0" encoding="UTF-8"?><hello><world/></hello>' ]
>>>
>>> That doesn't work. Components are made to generate HTML and in this
>>> case a lot of HTML (<DOCTYPE>, <head>, <body>, …) has already been
>>> generated. You have two options. First you can configure your
>>> components to generate XML. See Seaside-WebServices-Core and
>>> Seaside-Tests-WebServices in the addons repository [1] for examples.
>>> However unless you need #call: and callbacks and friends I found
>>> recommend to use Seaside-REST, also from the addons repository. There
>>> is a short overview on the wiki [2] and you can find some examples
>>> here [3].
>>>
>>>
>>>> If I call this from Firefox, then instead of XML (as in your example) I see
>>>> "XML Parsing Error: XML or text declaration not at start of entity[...]"
>>>> and viewing the page source gives:
>>>> "<!DOCTYPE html PUBLIC [...]"
>>>>
>>>>
>>>> Whereas my old code:
>>>>
>>>> renderContentOn: html
>>>> self session returnResponse:
>>>> (WAResponse new
>>>> contentType: 'text/xml';
>>>> nextPutAll: <?xml version="1.0" encoding="UTF-8"?><hello><world/></hello>' ;
>>>> yourself)
>>>>
>>>> returned and displayed XML just as your example, but without any user action
>>>>
>>>> So what I'm apparently missing is whatever magic happens as a result of the anchor callback being fired in your example. I wonder if there's any way to get that kind of callback behavior programatically(?)
>>>>
>>>>
>>>>> What do you mean with non-Seaside client? Is it a non-browser
>>>>> application, non-HTML application? I
>>>>
>>>>
>>>> Yes, I'm using Seaside apps to serve (music score data) to
>>>> - Seaside web client
>>>> - Flash web client
>>>> - iPhone app
>>>> - code running in Second Life
>>>> - Croquet environment
>>>>
>>>>> In those cases you can still use
>>>>> Seaside. You can either directly write RequestHandlers or you can have
>>>>> a look at Seaside-REST.
>>>>
>>>> Interesting - I'll try to find an example using WARequestHandler, though I suppose this will mean moving the functionality out of my Seaside app (WAComponent subclass)...
>>>
>>> Yes. You can look at WAFileHandler for a complicated examples, for
>>> simple ones look at Seaside-Benchmark in the addons repository [1].
>>>
>>>> Thanks very much for the tips, and for your example which has helped me narrow the scope of the problem
>>>>
>>>
>>> [1] http://www.squeaksource.com/Seaside30Addons
>>> [2] http://code.google.com/p/seaside/wiki/SeasideRest
>>> [3] http://www.squeaksource.com/orion
>>>
>>> Cheers
>>> Philippe
>>> _______________________________________________
>>> seaside mailing list
>>> seaside at lists.squeakfoundation.org
>>> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
>>
>>
>> Among the possibilities you listed, I ended up subclassing WAXmlComponent to return XML programmatically, roughly as follows:
>>
>> renderContentOn: xml
>> | query |
>> query := initialRequest fields keys first.
>
> Where is initialRequest coming from? Do you set that in
> #initialiRequest:?
Yes, exactly.
> If so it's better to replace it with
> self requestContext request
>
>> query = 'getAvailableScores' ifTrue: [
>
> That's quite brittle, something like this should be more reliable
>
> self requestContext request includesKey: 'getAvailableScores'
Super - yes, Bob N. mentioned that pattern in his reply as well
(was pretty sure my line of code couldn't possibly point to the intended API)
Thanks as always
Jay
>
>> | anXMLDocument block |
>> anXMLDocument := self class availableScoresAsXML.
>> block := [:element |
>> | tag |
>> tag := xml tag: element name.
>> element attributes keysAndValuesDo: [:name :value |
>> tag attributeAt: name put: value].
>> tag with: [element elements do: [:each |
>> block value: each]]].
>> block value: anXMLDocument elements first].
>>
>>
>> ...that is, building the tags for the WAXmlCanvas from an instance of XMLDocument. This restores the functionality I had lost going to 3.0.
>>
>> Thank you once more for all your help!
>
>
> Cheers
> Philippe
> _______________________________________________
> seaside mailing list
> seaside at lists.squeakfoundation.org
> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
More information about the seaside
mailing list