1.1 --- a/docs/developing.html Sat Jan 20 23:15:29 2007 +0000
1.2 +++ b/docs/developing.html Sat Jan 20 23:16:22 2007 +0000
1.3 @@ -17,20 +17,20 @@
1.4 <ul>
1.5
1.6
1.7 - <li><a href="paths.html">URLs and Paths</a></li>
1.8 -<ul>
1.9 + <li><a href="paths.html">URLs and Paths</a></li><li><a href="path-strategies.html">Path Processing Strategies</a></li>
1.10 +<li><a href="path-info.html">Paths To and Within Applications</a></li><li><a href="path-design.html">Path Design and Interpretation</a></li><ul>
1.11
1.12
1.13 - <li><a href="path-info.html">Paths To and Within Applications</a></li>
1.14 +
1.15
1.16 - <li><a href="path-design.html">Path Design and Interpretation</a></li>
1.17 +
1.18
1.19
1.20 - <ul>
1.21 + <li><a href="paths-filesystem.html">Treating the Path Like a Filesystem</a> (<code>DemoApp</code> example, <code>Calendar</code> example)</li><li><a href="paths-services.html">Treating the Path Mostly Like a Filesystem</a></li><li><a href="paths-opaque.html">Using the Path as an Opaque Reference into an Application</a></li><ul>
1.22
1.23 - <li><a href="paths-filesystem.html">Treating the Path Like a Filesystem</a> (<code>DemoApp</code> example, <code>Calendar</code> example)</li><ul><li>(<a href="resource-map.html">ResourceMap - Simple Mappings from Names to Resources</a>)</li></ul>
1.24 - <li><a href="paths-services.html">Treating the Path Mostly Like a Filesystem</a></li>
1.25 - <li><a href="paths-opaque.html">Using the Path as an Opaque Reference into an Application</a></li>
1.26 +
1.27 +
1.28 +
1.29
1.30 </ul><li><a href="path-value-encoding.html">Encoding and Decoding Path Values</a></li><li><a href="path-manipulation.html">Manipulating Paths</a></li>
1.31
2.1 --- a/docs/index.html Sat Jan 20 23:15:29 2007 +0000
2.2 +++ b/docs/index.html Sat Jan 20 23:16:22 2007 +0000
2.3 @@ -10,19 +10,19 @@
2.4 using the WebStack framework.</p>
2.5 <h2>Setting Up</h2>
2.6 <p>First of all, let us assume that the WebStack distribution has been
2.7 -unpacked and now sits in the <code>WebStack-1.2.1</code> directory.</p>
2.8 +unpacked and now sits in the <code>WebStack-1.2.2</code> directory.</p>
2.9 <p>Before we begin, we must make sure that the WebStack package is
2.10 available
2.11 to Python. The easiest way to do this is to change into the
2.12 -<code>WebStack-1.2.1</code> directory and to run the <code>setup.py</code>
2.13 +<code>WebStack-1.2.2</code> directory and to run the <code>setup.py</code>
2.14 script provided with the version of Python you are going to be using
2.15 (possibly as a privileged user like <code>root</code>):</p>
2.16 -<pre>cd WebStack-1.2.1<br />python setup.py install</pre>
2.17 +<pre>cd WebStack-1.2.2<br />python setup.py install</pre>
2.18 <p>If you don't want to install WebStack in this way, or if you can't
2.19 do so
2.20 because you don't have <code>root</code> privileges, you can just make
2.21 sure
2.22 -that the <code>WebStack-1.2.1</code> directory sits on your
2.23 +that the <code>WebStack-1.2.2</code> directory sits on your
2.24 <code>PYTHONPATH</code>.</p>
2.25 <h2>Supported Frameworks</h2><p>With the help of Python's built-in
2.26 standard library, WebStack can run without any additional software, but
2.27 @@ -30,7 +30,7 @@
2.28 run WebStack applications in other environments.</p><ul><li><a href="supported-frameworks.html">Supported Frameworks</a></li></ul><h2>Viewing the API Documentation</h2>
2.29 <p>The API documentation for use in conjunction with this
2.30 guide can be found inside the <a href="../apidocs/index.html"><code>apidocs</code></a>
2.31 -directory within the <code>WebStack-1.2.1</code> directory. Of course,
2.32 +directory within the <code>WebStack-1.2.2</code> directory. Of course,
2.33 it is always possible to view WebStack's API documentation
2.34 within Python by importing modules (such as <a href="../apidocs/public/WebStack.Generic-module.html"><code>WebStack.Generic</code></a>)
2.35 and using Python's built-in <code>help</code> function.</p>
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/docs/path-strategies.html Sat Jan 20 23:16:22 2007 +0000
3.3 @@ -0,0 +1,32 @@
3.4 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3.5 +<html xmlns="http://www.w3.org/1999/xhtml"><head> <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type" /><title>Path Processing Strategies</title>
3.6 +<meta name="generator" content="amaya 8.1a, see http://www.w3.org/Amaya/" /> <link href="styles.css" rel="stylesheet" type="text/css" /></head>
3.7 +<body><h1>Path Processing Strategies</h1>
3.8 +<p>In the development of most Web applications, the structure of the
3.9 +application - also known as the "site map" - needs to be defined
3.10 +at a very early stage. We might decide that if a user requests a
3.11 +certain path, a particular part of the application will be invoked, and
3.12 +we might define the site map in a number of different ways:</p><p>As a set of acceptable paths...</p><ul><li><code>/</code> is the main page</li><li><code>/services/finance/salaries/</code> is the salary report page</li><li><code>/services/customer/complaints/</code> is the complaints page</li></ul><p>As a tree of resources...</p><ul><li><code>/</code> is the main page</li><ul><li><code>.../services/</code> refers to services (which may not be defined as anything viewable)</li><ul><li><code>.../finance/</code> is the finance department</li><ul><li><code>.../salaries/</code> is the salary report page</li></ul><li><code>.../customer/</code> is the customer service department</li><ul><li><code>.../complaints/</code> is the complaints page</li></ul></ul></ul></ul><p>Since
3.13 +all of the action in WebStack applications takes place inside
3.14 +resources, the challenge is to define resources in such a way which
3.15 +makes processing paths relatively easy.</p><h2>Chaining Resources</h2><p>Whilst the classic resource, as described in <a href="resources.html">"Applications and Resources"</a>, might resemble a simple class whose <code>respond</code>
3.16 +method performs most of the necessary work, it is useful to reconsider
3.17 +such a resource as doing such work only for a particular narrow part of
3.18 +a larger Web application. Moreover, resources are not restricted in
3.19 +their usage of other objects to carry out their purpose, provided they
3.20 +are initialised with references to those objects.Consequently, it makes sense to consider defining a resource which, if it alone cannot process a request, invokes the <code>respond</code> method on another resource in order to get that resource to continue with the act of processing.</p><p>We
3.21 +can apply this insight to the above path processing scenario. If we
3.22 +first employ a resource to examine details of the path, and if that
3.23 +resource then invokes other resources to produce certain pages, we can
3.24 +separate the path processing from the rest of the application's
3.25 +functionality. So, for the first site map strategy, we could define a
3.26 +path processing resource as follows:</p><pre>from WebStack.Generic import EndOfResponse<br /><br />class PathProcessor:<br /><br /> "A path processing resource."<br /><br /> def __init__(self, main_page, salary_report_page, complaints_page):<br /><br /> # Supplied resources are chained to this resource.<br /><br /> self.main_page = main_page<br /> self.salary_report_page = salary_report_page<br /> self.complaints_page = complaints_page<br /><br /> def respond(self, trans):<br /><br /> # This is where the resources are invoked...<br /><br /> path = trans.get_path_without_query() # should really use an encoding here<br /> if path == "/":<br /> self.main_page.respond(trans)<br /> elif path == "/services/finance/salaries/":<br /> self.main_page.respond(trans)<br /> elif path == "/services/finance/salaries/":<br /> self.main_page.respond(trans)<br /><br /> # Administrative details...<br /><br /> else:<br /> trans.set_response_code(404) # not found!<br /> raise EndOfResponse</pre><p>Of
3.27 +course, more elegant methods of mapping paths to resources could be
3.28 +employed - a dictionary might be an acceptable solution, if defined in
3.29 +the initialiser method. The above class might be initialised as follows:</p><pre>main_page = MainResource()<br />salary_report_page = SalaryReportResource()<br />complaints_page = ComplaintsResource()<br />path_processor = PathProcessor(main_page, salary_report_page, complaints_page)</pre><p>For
3.30 +the second site map strategy, we retain the basic parts of the above
3.31 +strategy, focusing only on one level in the path as opposed to the
3.32 +complete path. However, this means that our path processing resources
3.33 +need to know exactly which part of the path they should be
3.34 +considering, and perhaps which part of the path has already been
3.35 +processed.</p><p>As described in <a href="path-info.html">"Paths To and Within Applications"</a>, special path information of the nature required is provided by two methods: <code>get_virtual_path_info</code> and <code>get_processed_virtual_path_info</code>. Such information can thus be obtained and updated at each level in the processing chain.</p><pre>class MainPathProcessor:<br /><br /> "A path processor for the top of the application."<br /><br /> def __init__(self, main_page, services_processor):<br /> self.main_page = main_page<br /> self.services_processor = services_processor<br /><br /> def respond(self, trans):<br /><br /> # This is where the resources are invoked...<br /><br /> path = trans.get_virtual_path_info() # should really use an encoding here<br /> if path == "/":<br /> self.main_page.respond(trans)<br /> elif path.startswith("/services/"):<br /> trans.set_virtual_path_info(path[len("/services"):]) # cut off "/services"<br /> self.services_processor.respond(trans)<br /><br /> # Administrative details...<br /><br /> else:<br /> trans.set_response_code(404) # not found!<br /> raise EndOfResponse</pre><p>A suite of similar classes can be defined and might be initialised as follows:</p><pre>main_page = MainResource()<br />salary_report_page = SalaryReportResource()<br />complaints_page = ComplaintsResource()<br />finance_processor = FinancePathProcessor(salary_report_page)<br />customer_processor = CustomerPathProcessor(complaints_page)<br />services_processor = ServicesPathProcessor(finance_processor, customer_processor)<br />main_processor = MainPathProcessor(main_page, services_processor)</pre><p>Fortunately, this latter strategy is supported by WebStack in the form of the <code>ResourceMap</code> module. See <a href="paths-filesystem.html">"Treating the Path Like a Filesystem"</a> and <a href="resource-map.html">"ResourceMap - Simple Mappings from Names to Resources"</a> for details.</p></body></html>
3.36 \ No newline at end of file
4.1 --- a/docs/paths.html Sat Jan 20 23:15:29 2007 +0000
4.2 +++ b/docs/paths.html Sat Jan 20 23:16:22 2007 +0000
4.3 @@ -122,7 +122,7 @@
4.4 <p>If we were to just decode the query string and then extract the
4.5 parameters/fields, the result would be two empty parameters with the
4.6 names <code>a</code> and <code>b</code>, as opposed to the correct interpretation of the query string as describing a single parameter <code>a</code> with the value <code>&b</code>.</p>
4.7 -<h3>Conclusion</h3>
4.8 +<h3>Final Note</h3>
4.9 <p>Regardless of all this, all inspection of path parameters should be done using the appropriate methods (see <a href="parameters.html">"Request Parameters and
4.10 Uploads"</a>),
4.11 and direct access to the query string should only occur in situations
5.1 --- a/docs/resources.html Sat Jan 20 23:15:29 2007 +0000
5.2 +++ b/docs/resources.html Sat Jan 20 23:16:22 2007 +0000
5.3 @@ -4,7 +4,6 @@
5.4
5.5 <title>Applications and Resources</title><meta name="generator" content="amaya 8.1a, see http://www.w3.org/Amaya/" />
5.6 <link href="styles.css" rel="stylesheet" type="text/css" /></head>
5.7 -
5.8 <body>
5.9 <h1>Applications and Resources</h1>
5.10 At its simplest a WebStack application is just a single Python
5.11 @@ -50,17 +49,16 @@
5.12 <h2>Testing the Resource</h2>
5.13 <p>To test this resource we need to deploy it, and to do that we need
5.14 an
5.15 -adapter. Here is a quick way of writing an adapter and testing this
5.16 +adapter to connect it to the outside world. Here is a quick way of writing an adapter and testing this
5.17 code:</p>
5.18 <ol>
5.19 <li> Create a file called <code>MyAdapter.py</code> - you
5.20 can choose another name if you want - this will be where the adapter
5.21 code lives.</li>
5.22 - <li>Copy the example adapter in <a href="deploying.html">"Deploying
5.23 -a WebStack Application"</a> and write it into <code>MyAdapter.py</code>.</li>
5.24 - <li>Now, with two files in your directory, <code>MyApplication.py</code>
5.25 + <li>Write into it the following code:</li></ol><pre>from WebStack.Adapters.BaseHTTPRequestHandler import deploy # import the support for the server environment<br />from MyApplication import MyResource # import the main resource class<br />print "Serving..." # just for testing - we might want to remove this later<br />deploy(MyResource()) # connect a resource object to the server environment</pre><p>Now, with two files in your directory, <code>MyApplication.py</code>
5.26 and <code>MyAdapter.py</code>, you may run <code>MyAdapter.py</code>
5.27 -as follows:</li>
5.28 +as follows:</p><ol>
5.29 +
5.30 </ol>
5.31 <pre>python MyAdapter.py</pre>
5.32 <p>This should start the adapter program and print the following
5.33 @@ -68,5 +66,4 @@
5.34 <pre>Serving...</pre>
5.35 <p>You should now be able to visit <code>http://localhost:8080</code>
5.36 in your
5.37 -browser and see the message printed by your application:</p>
5.38 -<pre>Hello world.</pre></body></html>
5.39 \ No newline at end of file
5.40 +browser and see the message printed by your application:</p><pre>Hello world.</pre><h2>Related Examples</h2><p>The code presented in this document is very similar to that found in the following files:</p><ul><li><code>examples/Common/VerySimple/__init__.py</code> (where a package, <code>VerySimple</code>, is used to hold a <code>VerySimpleResource</code> class)</li><li><code>examples/BaseHTTPRequestHandler/VerySimpleApp.py</code> (where the resource is deployed)</li></ul><p>Note that a number of different adapters are provided in the <code>examples</code> directory hierarchy; for example:</p><ul><li><code>examples/CGI/VerySimpleHandler.py</code> (deploys the example as a CGI script)</li><li><code>examples/Twisted/VerySimpleApp.py</code> (deploys the example as a Twisted application)</li></ul><p>See <a href="deploying.html">"Deploying a WebStack Application"</a> for more information about adapters.</p></body></html>
5.41 \ No newline at end of file