Permalink
Browse files

Kajiki Quickstart and some fixes in quickstarts

  • Loading branch information...
1 parent 874a852 commit 137fb7476cbd6c503c5240f5b539df12831b901a @amol- amol- committed Apr 29, 2012
@@ -109,6 +109,10 @@ class QuickstartCommand(command.Command):
help="default templates jinja",
action="store_true", dest="jinja")
+ parser.add_option("-k", "--kajiki",
+ help="default templates kajiki",
+ action="store_true", dest="kajiki")
+
parser.add_option("-g", "--geo",
help="add GIS support",
action="store_true", dest="geo")
@@ -181,23 +185,25 @@ def command(self):
"Enter package name [%s]: " % package).strip() or package
if self.no_input:
-
#defaults
self.mako = False
self.jinja = False
+ self.kajiki = False
self.auth = True
- if self.jinja is None and self.mako is None:
+ if self.jinja is None and self.mako is None and self.kajiki is None:
template = None
while template is None:
template = raw_input(
- "Would you prefer to use an alternative template system? (m=mako, j=jinja, n=no [default]): ")
- template = dict(m="mako", j="jinja", n="none").get(
+ "Would you prefer to use an alternative template system? (m=mako, j=jinja, k=kajiki, n=no [default]): ")
+ template = dict(m="mako", j="jinja", k='kajiki', n="none").get(
template.lstrip()[:1].lower() or 'n')
if template == "mako":
self.mako = True
elif template == "jinja":
self.jinja = True
+ elif template == "kajiki":
+ self.kajiki = True
elif template is None:
print "Please enter an option or n(o)."
@@ -269,6 +275,7 @@ def command(self):
cmd_args.append("tgversion=%s" % self.version)
cmd_args.append("mako=%s"%self.mako)
cmd_args.append("jinja=%s"%self.jinja)
+ cmd_args.append("kajiki=%s"%self.kajiki)
cmd_args.append("migrations=%s"%self.migrations)
cmd_args.append("cookiesecret=%s"%self.cookiesecret)
# set the exact ORM-version for the proper requirements
@@ -293,27 +300,23 @@ def command(self):
if file == "empty":
os.remove(os.path.join(base, file))
- #copy over the mako templates if appropriate
- if self.mako:
- print 'Writing mako template files to ./'+os.path.join(self.package, 'templates')
-
- #remove existing template files
- package_template_dir = os.path.abspath(os.path.join(self.package, 'templates'))
- shutil.rmtree(package_template_dir, ignore_errors=True)
-
- #replace template files with mako ones
- mako_template_dir = os.path.abspath(os.path.dirname(__file__))+'/quickstart_mako'
- shutil.copytree(mako_template_dir, package_template_dir)
- elif self.jinja:
- print 'Writing jinja template files to ./'+os.path.join(self.package, 'templates')
-
- #remove existing template files
- package_template_dir = os.path.abspath(os.path.join(self.package, 'templates'))
- shutil.rmtree(package_template_dir, ignore_errors=True)
-
- #replace template files with jinja ones
- jinja_template_dir = os.path.abspath(os.path.dirname(__file__))+'/quickstart_jinja'
- shutil.copytree(jinja_template_dir, package_template_dir)
+ #copy over the alternative templates if appropriate
+ if self.mako or self.kajiki or self.jinja:
+ def overwrite_templates(template_type):
+ print 'Writing ' + template_type + ' template files to ./'+os.path.join(self.package, 'templates')
+ #remove existing template files
+ package_template_dir = os.path.abspath(os.path.join(self.package, 'templates'))
+ shutil.rmtree(package_template_dir, ignore_errors=True)
+ #replace template files with alternative ones
+ alt_template_dir = os.path.abspath(os.path.dirname(__file__))+'/quickstart_'+template_type
+ shutil.copytree(alt_template_dir, package_template_dir)
+
+ if self.mako:
+ overwrite_templates('mako')
+ elif self.jinja:
+ overwrite_templates('jinja')
+ elif self.kajiki:
+ overwrite_templates('kajiki')
if self.ming:
print 'Writing Ming model files to ./'+os.path.join(self.package, 'model')
@@ -28,6 +28,7 @@
<ul class="nav">
<li class="${('', 'active')[defined('page') and page=='index']}"><a href="${tg.url('/')}">Welcome</a></li>
<li class="${('', 'active')[defined('page') and page=='about']}"><a href="${tg.url('/about')}">About</a></li>
+ <li class="${('', 'active')[defined('page') and page=='data']}"><a href="${tg.url('/data')}">Serving Data</a></li>
<li class="${('', 'active')[defined('page') and page=='environ']}"><a href="${tg.url('/environ')}">WSGI Environment</a></li>
</ul>
<ul class="nav pull-right" py:if="tg.auth_stack_enabled">
@@ -51,7 +52,7 @@
<!-- Footer included from an external template -->
<footer class="footer hidden-tablet hidden-phone">
- <a class="pull-right" href="http://www.turbogears.org/2.1/"><img style="vertical-align:middle;" src="${tg.url('/images/under_the_hood_blue.png')}" alt="TurboGears 2" /></a>
+ <a class="pull-right" href="http://www.turbogears.org/2.2/"><img style="vertical-align:middle;" src="${tg.url('/images/under_the_hood_blue.png')}" alt="TurboGears 2" /></a>
<p>Copyright &copy; ${getattr(tmpl_context, 'project_name', 'TurboGears2')} ${h.current_year()}</p>
</footer>
</div>
@@ -22,6 +22,7 @@
<ul class="nav">
<li class="{% if page == 'index' %}active{% endif %}"><a href="{{ tg.url('/') }}">Welcome</a></li>
<li><a href="{{ tg.url('/about') }}" class="{% if page == 'about' %}active{% endif %}">About</a></li>
+ <li><a href="{{ tg.url('/data') }}" class="{% if page == 'data' %}active{% endif %}">Serving Data</a></li>
<li><a href="{{ tg.url('/environ') }}" class="{% if page == 'environ' %}active{% endif %}">WSGI Environment</a></li>
</ul>
@@ -52,7 +53,7 @@
<!-- End of main_content -->
<footer class="footer hidden-tablet hidden-phone">
- <a class="pull-right" href="http://www.turbogears.org/2.1/"><img style="vertical-align:middle;" src="{{tg.url('/images/under_the_hood_blue.png')}}" alt="TurboGears 2" /></a>
+ <a class="pull-right" href="http://www.turbogears.org/2.2/"><img style="vertical-align:middle;" src="{{tg.url('/images/under_the_hood_blue.png')}}" alt="TurboGears 2" /></a>
<p>Copyright &copy; {{ tmpl_context.project_name|default('TurboGears2') }} {{h.current_year()}}</p>
</footer>
</div>
@@ -0,0 +1,2 @@
+# -*- coding: utf-8 -*-
+"""Templates package for the application."""
@@ -0,0 +1,138 @@
+<html py:extends="master.xml" py:strip="True">
+ <head py:block="head" py:strip="True">
+ <title py:block="master_title">Learning TurboGears 2.2: Quick guide to the Quickstart pages.</title>
+ <meta name="generator" content="HTML Tidy for Linux/x86 (vers 11 February 2007), see www.w3.org" />
+ </head>
+
+ <body py:block="body" py:strip="True">
+ <div class="row">
+ <div class="span12">
+ <div class="page-header">
+ <h2>Architectural basics of a quickstart TG2 site.</h2>
+ </div>
+
+ <p>The TG2 quickstart command produces this basic TG site. Here's how it works.</p>
+ </div>
+
+ <div class="span4">
+ <div class="well" style="padding: 8px 0;">
+ <ul class="nav nav-list">
+ <li class="nav-header">About Architecture</li>
+ <li><a href="#data-model">Data Model</a></li>
+ <li><a href="#url-structure">URL Structure</a></li>
+ <li><a href="#template-reuse">Templates</a></li>
+ <li py:if="tg.auth_stack_enabled" class="nav-header">Authentication</li>
+ <li py:if="tg.auth_stack_enabled"><a href="#authentication">Authorization and Authentication</a></li>
+ </ul>
+ </div>
+
+ <div class="well" id="data-model">
+ <h3>Code my data model</h3>
+
+ <p>When you want a model for storing favorite links or wiki content, the
+ <code>/model</code> folder in your site is ready to go.</p>
+
+ <p>You can build a dynamic site without any data model at all. There still be a
+ default data-model template for you if you didn't enable authentication and
+ authorization in quickstart. If you have enabled authorization, the auth
+ data-model is ready-made.</p>
+ </div>
+
+ <div class="well" id="url-structure">
+ <h3>Design my URL structure</h3>
+
+ <p>The "<code>root.py</code>" file under the <code>/controllers</code> folder has
+ your URLs. When you called this url (<code><a href=
+ "${tg.url('/about')}">about</a></code>), the command went through the
+ RootController class to the <code>about()</code> method.</p>
+
+ <p>Those Python methods are responsible to create the dictionary of variables
+ that will be used in your web views (template).</p>
+ </div>
+
+ <div class="well" id="template-reuse">
+ <h3>Reuse the web page elements</h3>
+
+ <p>A web page viewed by user could be constructed by single or several reusable
+ templates under <code>/templates</code>.
+ Each projects gets quickstarted with a <strong><span class="label label-info">master.html</span></strong>
+ template and a bunch of templates for the pages provided by the RootController.
+ </p>
+ </div>
+ </div>
+
+ <div class="span8"><img src=
+ "http://www.turbogears.org/2.1/docs/_images/tg2_files.jpg" alt=
+ "TurboGears2 quickstarted project" /></div>
+ </div>
+
+ <div class="row">
+ <div class="span12">
+ <div class="row">
+ <div class="span12">
+ <h3>The Master Template</h3>
+
+ <p>The <strong><span class="label label-info">master.html</span></strong> template
+ controls the overall design of the page we're looking at. It draws the headers,
+ the footer, the notices flash and embeds the content of each page of your web applications.
+ Thus the "master.html" template provides the overall architecture for
+ each page in this site.</p>
+
+ <p>There's more to the "master.html" template... study it to see how the
+ &lt;title&gt; tags and static JS and CSS files are brought into the page.
+ Templating with Genshi is a powerful tool and we've only scratched the surface.
+ There are also a few little CSS tricks hidden in these pages, like the use of a
+ "clearingdiv" to make sure that your footer stays below the sidebars and always
+ looks right. That's not TG2 at work, just CSS. You'll need all your skills to
+ build a fine web app, but TG2 will make the hard parts easier so that you can
+ concentrate more on good design and content rather than struggling with
+ mechanics.</p>
+ </div>
+
+ <div class="span12" id="authentication" py:if="tg.auth_stack_enabled">
+ <h3>Authentication &amp; Authorization in a TG2 site.</h3>
+
+ <p>If you have access to this page, this means you have enabled authentication
+ and authorization in the quickstart to create your project.</p>
+
+ <p>The paster command will have created a few specific controllers for you. But
+ before you go to play with those controllers you'll need to make sure your
+ application has been properly bootstapped. This is dead easy, here is how to do
+ this:</p>
+ <pre>paster setup-app development.ini</pre>
+
+ <p>inside your application's folder and you'll get a database setup (using the
+ preferences you have set in your development.ini file). This database will also
+ have been prepopulated with some default logins/passwords so that you can test
+ the secured controllers and methods.</p>
+
+ <p>To change the comportement of this setup-app command you just need to edit
+ the <code>websetup.py</code> file.</p>
+
+ <p>Now try to visiting the <a href=
+ "${tg.url('/manage_permission_only')}">manage_permission_only</a> URL. You will
+ be challenged with a login/password form.</p>
+
+ <p>Only managers are authorized to visit this method. You will need to log-in
+ using:</p>
+ <pre>login: manager
+password: managepass</pre>
+
+ <p>Another protected resource is <a href=
+ "${tg.url('/editor_user_only')}">editor_user_only</a>. This one is protected by
+ a different set of permissions. You will need to be <code>editor</code> with a
+ password of <code>editpass</code> to be able to access it.</p>
+
+ <p>The last kind of protected resource in this quickstarted app is a full so
+ called <a href="${tg.url('/secc')}">secure controller</a>. This controller is
+ protected globally. Instead of having a @require decorator on each method, we
+ have set an allow_only attribute at the class level. All the methods in this
+ controller will require the same level of access. You need to be manager to
+ access <a href="${tg.url('/secc')}">secc</a> or <a href=
+ "${tg.url('/secc/some_where')}">secc/some_where</a>.</p>
+ </div>
+ </div>
+ </div>
+ </div>
+ </body>
+</html>
@@ -0,0 +1,43 @@
+<html py:extends="master.xml" py:strip="True">
+ <head py:block="head" py:strip="True">
+ <title py:block="master_title">Learning TurboGears 2.2: Quick guide to the Quickstart pages.</title>
+ </head>
+
+ <body py:block="body" py:strip="True">
+ <div class="row">
+ <div class="span6">
+ <h2>Content Type Dispatch</h2>
+ <p>
+ This page shows how you can provide multiple pages
+ directly from the same controller method. This page is generated
+ from the expose decorator with the template defintion provided.
+ You can provide a url with parameters and this page will display
+ the parameters as html, and the json version will express
+ the entries as <code>JSON</code>.
+ </p>
+
+ <p>Click here for the <a href="${tg.url('/data.json', params=params)}">JSON Version of this page.</a></p>
+ </div>
+ <div class="span6">
+ <p>The data provided in the template call is:
+ <table class="table table-bordered table-striped">
+ <thead>
+ <tr>
+ <th>Key</th>
+ <th>Value</th>
+ </tr>
+ </thead>
+ <tbody>
+ <py:for each="key, value in params.iteritems()">
+ <tr>
+ <td>${key}</td>
+ <td>${value}</td>
+ </tr>
+ </py:for>
+ </tbody>
+ </table>
+ </p>
+ </div>
+ </div>
+</body>
+</html>
@@ -0,0 +1,25 @@
+<html py:extends="master.xml" py:strip="True">
+ <head py:block="head" py:strip="True">
+ <title py:block="master_title">Learning TurboGears 2.2: Information about TG and WSGI</title>
+ <meta name="generator" content="HTML Tidy for Linux/x86 (vers 11 February 2007), see www.w3.org" />
+ </head>
+
+ <body py:block="body" py:strip="True">
+ <h2>The WSGI nature of the framework</h2>
+ <p>In this page you can see all the WSGI variables your request object has,
+ the ones in capital letters are required by the spec, then a sorted by
+ component list of variables provided by the Components, and at last
+ the "wsgi." namespace with very useful information about your WSGI Server</p>
+ <p>The keys in the environment are:
+ <table class="table">
+ <py:for each="key in sorted(environment)">
+ <tr>
+ <td>${key}</td>
+ <td>${str(environment[key])}</td>
+ </tr>
+ </py:for>
+ </table>
+
+ </p>
+</body>
+</html>
@@ -0,0 +1,17 @@
+<html py:extends="master.xml" py:strip="True">
+ <head py:block="head" py:strip="True">
+ <title py:block="master_title">A ${code} error has Occurred</title>
+ </head>
+
+<body py:block="body" py:strip="True">
+ <h1>Error ${code}</h1>
+
+<?python
+import re
+mf = re.compile(r'(</?)script', re.IGNORECASE)
+def fixmessage(message):
+ return mf.sub(r'\1noscript', message)
+?>
+ <div>${literal(fixmessage(message))}</div>
+</body>
+</html>
Oops, something went wrong.

0 comments on commit 137fb74

Please sign in to comment.