[Seaside] WAResponse and XML
Jay Hardesty
jayh at panix.com
Sat Aug 6 17:31:26 UTC 2011
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.
query = 'getAvailableScores' ifTrue: [
| 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!
Jay
More information about the seaside
mailing list