[Seaside] WAResponse and XML

Jay Hardesty jayh at panix.com
Sat Aug 6 17:54:55 UTC 2011


On Aug 6, 2011, at 7:31 PM, Jay Hardesty wrote:

> 
> 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.

should note that in my case the ultimate values in my XMLDocument instance exist as attributes in the leaf nodes - tagged values would require just a little more code to generate the appropriate WAXmlCanvas tags




More information about the seaside mailing list