paulb@654 | 1 | <?xml version="1.0" encoding="iso-8859-1"?> |
paulb@354 | 2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
paulb@486 | 3 | <html xmlns="http://www.w3.org/1999/xhtml"><head> |
paulb@654 | 4 | <title>Responses and Presentation</title> |
paulb@486 | 5 | <link href="styles.css" rel="stylesheet" type="text/css" /></head> |
paulb@346 | 6 | <body> |
paulb@346 | 7 | <h1>Responses and Presentation</h1> |
paulb@354 | 8 | <p>After performing some kind of |
paulb@354 | 9 | processing on input information, an |
paulb@354 | 10 | application will then want to produce some kind of response to indicate |
paulb@354 | 11 | what |
paulb@346 | 12 | went on. Here are some examples of responses:</p> |
paulb@346 | 13 | <ul> |
paulb@354 | 14 | <li>Returning the contents of a |
paulb@354 | 15 | requested file.</li> |
paulb@354 | 16 | <li>Showing a message telling |
paulb@354 | 17 | the user that the requested operation succeeded or failed.</li> |
paulb@354 | 18 | <li>Presenting a view onto the |
paulb@354 | 19 | application with the results of the recent activity shown in a Web page.</li> |
paulb@346 | 20 | </ul> |
paulb@346 | 21 | <h2>Generating Responses</h2> |
paulb@354 | 22 | <p>The procedure involved in |
paulb@354 | 23 | generating a response usually involves the |
paulb@346 | 24 | following steps:</p> |
paulb@346 | 25 | <ol> |
paulb@354 | 26 | <li>Setting a response code to |
paulb@354 | 27 | signal whether the application performed the requested operation |
paulb@354 | 28 | successfully.</li> |
paulb@486 | 29 | <li>Setting a content type and a <a>character encoding</a>.</li><li>Possibly setting some response headers.</li> |
paulb@354 | 30 | <li>Producing content and |
paulb@354 | 31 | sending it to the user.</li> |
paulb@346 | 32 | </ol> |
paulb@354 | 33 | <p>The kind of code involved may |
paulb@354 | 34 | well resemble the following:</p> |
paulb@354 | 35 | <pre>from WebStack.Generic import ContentType<br /><br />class MyResource:<br /> def respond(self, trans):<br /> [Perform the requested operations.]<br /><br /> if [the operation was successful]:<br /> trans.set_response_code(200)<br /> trans.set_content_type(ContentType("text/html", encoding="utf-8"))<br /> out = trans.get_response_stream()<br /> out.write([some data either as a plain string suitably encoded or as Unicode])<br /> else:<br /> trans.set_response_code(500) # or some other code<br /> trans.set_content_type(ContentType("text/html", encoding="utf-8"))<br /> out = trans.get_response_stream()<br /> out.write([some other data either as a plain string suitably encoded or as Unicode])</pre> |
paulb@654 | 36 | <h2>Unicode and the Response Stream</h2><p>Although an encoding may be specified or be set as a default by the <code>EncodingSelector</code> (see <a href="selectors.html">"Selectors - Components for Dispatching to Resources"</a>), |
paulb@629 | 37 | it should be noted that the encoding of textual information will only |
paulb@629 | 38 | take place if Unicode objects are written to the stream. Where binary |
paulb@629 | 39 | information or information which should not be changed is being |
paulb@629 | 40 | written, this must be supplied as plain strings to the transaction |
paulb@654 | 41 | object's <code>write</code> method.</p><p>As discussed in <a href="encodings.html">"Character Encodings"</a>, |
paulb@354 | 42 | care |
paulb@354 | 43 | must be taken generating the response so that it meets any expectations |
paulb@354 | 44 | that |
paulb@346 | 45 | browsers and other Web clients may have.</p> |
paulb@346 | 46 | <div class="WebStack"> |
paulb@354 | 47 | <h3>WebStack API - |
paulb@354 | 48 | Response-Related Methods</h3> |
paulb@354 | 49 | <p>Transaction objects have |
paulb@354 | 50 | various methods that can be used in generating |
paulb@346 | 51 | responses:</p> |
paulb@346 | 52 | <dl> |
paulb@346 | 53 | <dt><code>set_response_code</code></dt> |
paulb@354 | 54 | <dd>This accepts an integer |
paulb@354 | 55 | value denoting the response condition as described in the HTTP |
paulb@354 | 56 | specification. If this method is not used, WebStack sets a <code>200</code> |
paulb@354 | 57 | status condition on the response, meaning that the request was |
paulb@354 | 58 | processed successfully.</dd> |
paulb@346 | 59 | <dt><code>set_content_type</code></dt> |
paulb@354 | 60 | <dd>This accepts a content type |
paulb@354 | 61 | object (typically <code>WebStack.Generic.ContentType</code>) |
paulb@354 | 62 | which specifies both the media type and the character encoding (if |
paulb@354 | 63 | relevant) of the data sent to the user. The media type describes the |
paulb@354 | 64 | format of the data (eg. <code>text/html</code> |
paulb@354 | 65 | - a Web page), whereas the character encoding describes how any |
paulb@486 | 66 | character information on the page is encoded - see <a href="encodings.html">"Character Encodings"</a> |
paulb@486 | 67 | for more information.</dd><dt><code>set_header_value</code></dt><dd>This |
paulb@486 | 68 | accepts a header name and a corresponding value. Response headers |
paulb@486 | 69 | convey information to the user (and their software) which is comparable |
paulb@486 | 70 | to that found in <a href="headers.html">request headers</a> sent in to |
paulb@486 | 71 | the Web application; for example, the content type information is |
paulb@654 | 72 | transmitted using response headers (using the <code>Content-Type</code> header name), although the above <code>set_content_type</code> method is a more convenient means of preparing such information.</dd> |
paulb@346 | 73 | <dt><code>get_response_stream</code></dt> |
paulb@354 | 74 | <dd>This returns the output |
paulb@354 | 75 | stream through which data may be sent to the user.</dd> |
paulb@346 | 76 | </dl> |
paulb@346 | 77 | </div> |
paulb@364 | 78 | <h2>Ending the Response Explicitly</h2> |
paulb@364 | 79 | <p>Although it is possible to produce some output and then to let |
paulb@654 | 80 | the <code>respond</code> function complete normally, sometimes it |
paulb@364 | 81 | is appropriate to terminate the response and to hand control straight |
paulb@364 | 82 | back to the server environment; in other words, to decide that no more |
paulb@364 | 83 | activity will be performed within the application and to send the |
paulb@654 | 84 | response immediately. Whilst just using a <code>return</code> |
paulb@364 | 85 | statement might be adequate in many applications...</p> |
paulb@364 | 86 | <pre> # In the respond method...<br /> if some_condition:<br /> [Produce a response.]<br /> return<br /> [Produce a different response.]</pre> |
paulb@654 | 87 | <p>...sometimes a resource's <code>respond</code> method is being |
paulb@364 | 88 | called from another resource, and it may be the case that this other |
paulb@364 | 89 | resource may produce additional output if control is returned to it.</p> |
paulb@364 | 90 | <p>To provide a definitive end of response signal, a special exception |
paulb@364 | 91 | is available:</p> |
paulb@364 | 92 | <pre>from WebStack.Generic import EndOfResponse<br /><br />[The usual declarations for the resource and the respond method...]<br /><br /> # In the respond method (possibly called by another resource)...<br /> if some_condition:<br /> [Produce a response.]<br /> raise EndOfResponse</pre> |
paulb@364 | 93 | <p>This exception, when raised, ensures that the response is sent |
paulb@364 | 94 | exactly as the resource intended upon raising the exception. Note that |
paulb@364 | 95 | although <code>WebStack.Generic.EndOfResponse</code> is an exception, |
paulb@364 | 96 | it will not cause an error condition or change the response code in any |
paulb@509 | 97 | way.</p><h2>Sending the User Elsewhere</h2><p>Instead |
paulb@509 | 98 | of generating any real response, it is also possible to direct an |
paulb@509 | 99 | application's user to another resource or application. This is done by |
paulb@509 | 100 | performing a "redirect" by sending a special response header to the |
paulb@509 | 101 | client, as described in the <a href="redirection.html">"Redirection"</a> document.</p><h2>Integrating with Content Generators</h2> |
paulb@354 | 102 | <p>Just as applications might need to integrate with other systems in |
paulb@354 | 103 | order to fetch information or to perform operations on behalf of the |
paulb@354 | 104 | user, the generation of response content can also be made a lot easier |
paulb@354 | 105 | by using external libraries. In the above example code, the process of |
paulb@354 | 106 | obtaining and formatting the actual data to be written out has been |
paulb@354 | 107 | left unspecified, but for anything more complicated than "hello world" |
paulb@354 | 108 | it is usually advisable to consider using templating systems which |
paulb@354 | 109 | combine raw data and templates to produce formatted output that can be |
paulb@354 | 110 | displayed as a Web page (amongst other things).</p> |
paulb@654 | 111 | <p>See <a href="integrating.html">"Integration with Other Systems"</a> |
paulb@509 | 112 | for more information on the principles of using such external libraries. See also <a href="http://www.boddie.org.uk/python/XSLTools.html">XSLTools</a> |
paulb@509 | 113 | for a distribution of utilities, including a Web forms framework called |
paulb@509 | 114 | XSLForms, which can be of use in generating content for Web |
paulb@509 | 115 | applications.</p> |
paulb@654 | 116 | </body></html> |