annotate README.html @ 48:f89b560b7278 draft

Ensure correct exit status.
author David Barts <n5jrn@me.com>
date Thu, 30 May 2019 20:16:39 -0700
parents e726fafcffac
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
1 <!DOCTYPE html>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
2 <html>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
3 <head>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
4 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
5 <title>Introducing TinCan</title>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
6 <style type="text/css">
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
7 .kbd { font-family: monospace; }
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
8 </style>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
9 </head>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
10 <body>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
11 <h1>Introducing TinCan, a “Code-Behind” MVC Framework for Bottle</h1>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
12 <h2>Introduction</h2>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
13 <p>TinCan is a Python 3 code-behind web framework implemented in the Bottle
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
14 microframework. As with Bottle, all the code is in one module, and there
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
15 is no direct dependency on anything that is not part of the standard
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
16 Python library (except of course for Bottle itself).</p>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
17 <p>The default templating engine for TinCan is <a href="https://chameleon.readthedocs.io/en/latest/">Chameleon</a>.
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
18 TinCan adds Chameleon as a fully-supported templating engine for Bottle.
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
19 Any template engine supported by Bottle can be used to render TinCan
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
20 Pages.</p>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
21 <h2>Why Do This?</h2>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
22 <p>In short, there is too much repeating oneself in most all Python web
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
23 frameworks (and this includes Bottle). One is always saying “this is
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
24 controller <span class="kbd">foo</span>, whose view is in the template <span
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
25 class="kbd">foo.pt</span>, at route <span class="kbd">/foo</span>.”</p>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
26 <p>That’s a lot more busywork than just writing <span class="kbd">foo.php</span>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
27 or <span class="kbd">foo.cgi</span>, so many simple webapps end up being
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
28 implemented via the latter means. That’s unfortunate, as CGI isn’t very
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
29 resource-efficient, and there’s much nicer languages to code in than PHP
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
30 (such as Python :-) ). Worst of all, you now have logic and presentation
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
31 all scrambled together, never a good idea.</p>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
32 <p>What if, instead, you could write <span class="kbd">foo.pspx</span> and
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
33 <span class="kbd">foo.py</span>, and a framework would automatically
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
34 create the <span class="kbd">/foo.pspx</span> route for you, much like
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
35 ASP.NET or JSP would for a <span class="kbd">.aspx</span> or <span class="kbd">.jsp</span>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
36 file? The matching code-behind in the <span class="kbd">.py</span> file
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
37 would be easily detected (same name, different extension) and
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
38 automatically associated with the template, of course. You could focus on
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
39 writing pages instead of repeating yourself saying the obvious over and
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
40 over again. </p>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
41 <p>This is what TinCan lets you do.</p>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
42 <h2>Hang On, Code-Behind Isn’t MVC!</h2>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
43 <p>Why <em>isn’t</em> it? The model, as always, is the data and containing
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
44 core business logic. The template file defines the view presented to the
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
45 user, and the code-behind is the intermediary between the two. A
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
46 controller by any other name…</p>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
47 <h2>How Can There Be Multiple Views for One Controller?</h2>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
48 <p>Easily. Take a look at the <code>#python</code> header directive. </p>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
49 <h2>Multiple Controllers for One View?</h2>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
50 <p>Personally, I don’t think this is the best of ideas. Just because two
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
51 controllers might be able to share a view <em>now</em> does not mean they
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
52 will continue to in the future. Then you change one (controller, view)
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
53 pair and another controller someplace else breaks!</p>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
54 <p>However, if you insist, check out the <code>#template</code> and <code>#hidden</code>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
55 header directives. </p>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
56 <h2>But This Causes Less SEO-Friendly Routes!</h2>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
57 <p>First, this is not always important. Sometimes, all you want to do is get
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
58 a small, simple, special-purpose, site up and running with a minimum of
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
59 busywork. Why should you be forced to do more work just because that extra
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
60 work benefits someone <em>else</em>?</p>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
61 <p>Second, when it is, you can always use <code>RewriteRule</code> (Apache)
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
62 <code>rewrite</code> (nginx), or the equivalent in your favorite Web
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
63 server, and code your templates to use the SEO-friendly version of your
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
64 URL’s. With TinCan sitting behind a good, production-grade web server, you
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
65 get the best of both worlds: fast, simple deployment when you want it, and
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
66 SEO-friendly URL’s when you want it. </p>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
67 <h2>But What about Routing Things Based on Both Path and Method?</h2>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
68 <p>That’s easy enough to do, as TinCan is implemented on top of Bottle. You
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
69 can add your Bottle routes, using the <code>@route</code> decorator on
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
70 your controller methods, same as always. Just stick them in the same
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
71 start-up script you use to launch your TinCan files.</p>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
72 <p>If for some reason you don’t want to mess with manually creating routes
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
73 and associating them with controllers in Bottle (even in cases like this
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
74 where it arguably makes sense), and want to do <em>everything</em> the
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
75 TinCan way, you can create a set of hidden (using the <code>#hidden</code>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
76 directive) pages and a main dummy page whose code-behind forwards (<code>page.request.app.forward</code>)
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
77 to the appropriate hidden page depending on request method. </p>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
78 <h2>What about Launching Multiple TinCan Webapps?</h2>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
79 <p>It works just as well (and just as poorly) as launching multiple Bottle
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
80 webapps. Note that the big limitation here is Python’s module subsystem;
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
81 there is only one. Thus, all webapps share the same module path. There is
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
82 no way to have one webapp using an older version of a given module served
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
83 by the same server as another using a newer version, save renaming one of
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
84 the modules. This is a Python issue, not a Bottle issue or a TinCan issue.</p>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
85 <p>Note that TinCan bypasses the Python module cache and manages its own
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
86 importing of code-behind files, so there is no problem if you have
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
87 multiple webapps using the same relative URL paths. TinCan will keep all
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
88 those code-behind files straight; it will not confuse one webapp’s <span
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
89 class="kbd">/index.py</span> with another’s.</p>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
90 <h2>What about Bottle Plugins?</h2>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
91 <p>I am working on adding support for these.</p>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
92 </body>
e726fafcffac For backup purposes, UNFINISHED!!
David Barts <n5jrn@me.com>
parents:
diff changeset
93 </html>