Mercurial > cgi-bin > hgweb.cgi > tincan
diff README.html @ 0:e726fafcffac draft
For backup purposes, UNFINISHED!!
author | David Barts <n5jrn@me.com> |
---|---|
date | Sun, 12 May 2019 15:26:28 -0700 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README.html Sun May 12 15:26:28 2019 -0700 @@ -0,0 +1,93 @@ +<!DOCTYPE html> +<html> + <head> + <meta http-equiv="content-type" content="text/html; charset=UTF-8"> + <title>Introducing TinCan</title> + <style type="text/css"> + .kbd { font-family: monospace; } + </style> + </head> + <body> + <h1>Introducing TinCan, a “Code-Behind” MVC Framework for Bottle</h1> + <h2>Introduction</h2> + <p>TinCan is a Python 3 code-behind web framework implemented in the Bottle + microframework. As with Bottle, all the code is in one module, and there + is no direct dependency on anything that is not part of the standard + Python library (except of course for Bottle itself).</p> + <p>The default templating engine for TinCan is <a href="https://chameleon.readthedocs.io/en/latest/">Chameleon</a>. + TinCan adds Chameleon as a fully-supported templating engine for Bottle. + Any template engine supported by Bottle can be used to render TinCan + Pages.</p> + <h2>Why Do This?</h2> + <p>In short, there is too much repeating oneself in most all Python web + frameworks (and this includes Bottle). One is always saying “this is + controller <span class="kbd">foo</span>, whose view is in the template <span + class="kbd">foo.pt</span>, at route <span class="kbd">/foo</span>.”</p> + <p>That’s a lot more busywork than just writing <span class="kbd">foo.php</span> + or <span class="kbd">foo.cgi</span>, so many simple webapps end up being + implemented via the latter means. That’s unfortunate, as CGI isn’t very + resource-efficient, and there’s much nicer languages to code in than PHP + (such as Python :-) ). Worst of all, you now have logic and presentation + all scrambled together, never a good idea.</p> + <p>What if, instead, you could write <span class="kbd">foo.pspx</span> and + <span class="kbd">foo.py</span>, and a framework would automatically + create the <span class="kbd">/foo.pspx</span> route for you, much like + ASP.NET or JSP would for a <span class="kbd">.aspx</span> or <span class="kbd">.jsp</span> + file? The matching code-behind in the <span class="kbd">.py</span> file + would be easily detected (same name, different extension) and + automatically associated with the template, of course. You could focus on + writing pages instead of repeating yourself saying the obvious over and + over again. </p> + <p>This is what TinCan lets you do.</p> + <h2>Hang On, Code-Behind Isn’t MVC!</h2> + <p>Why <em>isn’t</em> it? The model, as always, is the data and containing + core business logic. The template file defines the view presented to the + user, and the code-behind is the intermediary between the two. A + controller by any other name…</p> + <h2>How Can There Be Multiple Views for One Controller?</h2> + <p>Easily. Take a look at the <code>#python</code> header directive. </p> + <h2>Multiple Controllers for One View?</h2> + <p>Personally, I don’t think this is the best of ideas. Just because two + controllers might be able to share a view <em>now</em> does not mean they + will continue to in the future. Then you change one (controller, view) + pair and another controller someplace else breaks!</p> + <p>However, if you insist, check out the <code>#template</code> and <code>#hidden</code> + header directives. </p> + <h2>But This Causes Less SEO-Friendly Routes!</h2> + <p>First, this is not always important. Sometimes, all you want to do is get + a small, simple, special-purpose, site up and running with a minimum of + busywork. Why should you be forced to do more work just because that extra + work benefits someone <em>else</em>?</p> + <p>Second, when it is, you can always use <code>RewriteRule</code> (Apache) + <code>rewrite</code> (nginx), or the equivalent in your favorite Web + server, and code your templates to use the SEO-friendly version of your + URL’s. With TinCan sitting behind a good, production-grade web server, you + get the best of both worlds: fast, simple deployment when you want it, and + SEO-friendly URL’s when you want it. </p> + <h2>But What about Routing Things Based on Both Path and Method?</h2> + <p>That’s easy enough to do, as TinCan is implemented on top of Bottle. You + can add your Bottle routes, using the <code>@route</code> decorator on + your controller methods, same as always. Just stick them in the same + start-up script you use to launch your TinCan files.</p> + <p>If for some reason you don’t want to mess with manually creating routes + and associating them with controllers in Bottle (even in cases like this + where it arguably makes sense), and want to do <em>everything</em> the + TinCan way, you can create a set of hidden (using the <code>#hidden</code> + directive) pages and a main dummy page whose code-behind forwards (<code>page.request.app.forward</code>) + to the appropriate hidden page depending on request method. </p> + <h2>What about Launching Multiple TinCan Webapps?</h2> + <p>It works just as well (and just as poorly) as launching multiple Bottle + webapps. Note that the big limitation here is Python’s module subsystem; + there is only one. Thus, all webapps share the same module path. There is + no way to have one webapp using an older version of a given module served + by the same server as another using a newer version, save renaming one of + the modules. This is a Python issue, not a Bottle issue or a TinCan issue.</p> + <p>Note that TinCan bypasses the Python module cache and manages its own + importing of code-behind files, so there is no problem if you have + multiple webapps using the same relative URL paths. TinCan will keep all + those code-behind files straight; it will not confuse one webapp’s <span + class="kbd">/index.py</span> with another’s.</p> + <h2>What about Bottle Plugins?</h2> + <p>I am working on adding support for these.</p> + </body> +</html>