|  | @@ -1,190 +0,0 @@
 | 
	
		
			
			| 1 |  | -<%inherit file="local:templates.master"/>
 | 
	
		
			
			| 2 |  | -
 | 
	
		
			
			| 3 |  | -<%def name="title()">
 | 
	
		
			
			| 4 |  | -Learning TurboGears 2.3: Quick guide to the Quickstart pages.
 | 
	
		
			
			| 5 |  | -</%def>
 | 
	
		
			
			| 6 |  | -
 | 
	
		
			
			| 7 |  | -   <div class="row">
 | 
	
		
			
			| 8 |  | -      <div class="span12">
 | 
	
		
			
			| 9 |  | -        <div class="page-header">
 | 
	
		
			
			| 10 |  | -          <h2>Architectural basics of a quickstart TG2 site.</h2>
 | 
	
		
			
			| 11 |  | -        </div>
 | 
	
		
			
			| 12 |  | -
 | 
	
		
			
			| 13 |  | -        <p>The TG2 quickstart command produces this basic TG site. Here's how it works.</p>
 | 
	
		
			
			| 14 |  | -      </div>
 | 
	
		
			
			| 15 |  | -
 | 
	
		
			
			| 16 |  | -      <div class="span4">
 | 
	
		
			
			| 17 |  | -        <div class="well" style="padding: 8px 0;">
 | 
	
		
			
			| 18 |  | -          <ul class="nav nav-list">
 | 
	
		
			
			| 19 |  | -            <li class="nav-header">About Architecture</li>
 | 
	
		
			
			| 20 |  | -            <li><a href="#data-model">Data Model</a></li>
 | 
	
		
			
			| 21 |  | -            <li><a href="#url-structure">URL Structure</a></li>
 | 
	
		
			
			| 22 |  | -            <li><a href="#template-reuse">Web page element's reuse</a></li>
 | 
	
		
			
			| 23 |  | -            <li py:if="tg.auth_stack_enabled" class="nav-header">Authentication</li>
 | 
	
		
			
			| 24 |  | -            <li py:if="tg.auth_stack_enabled"><a href="#authentication">Authorization and Authentication</a></li>
 | 
	
		
			
			| 25 |  | -          </ul>
 | 
	
		
			
			| 26 |  | -        </div>
 | 
	
		
			
			| 27 |  | -
 | 
	
		
			
			| 28 |  | -        <div class="well" id="data-model">
 | 
	
		
			
			| 29 |  | -          <h3>Code my data model</h3>
 | 
	
		
			
			| 30 |  | -
 | 
	
		
			
			| 31 |  | -          <p>When you want a model for storing favorite links or wiki content, the
 | 
	
		
			
			| 32 |  | -          <code>/model</code> folder in your site is ready to go.</p>
 | 
	
		
			
			| 33 |  | -
 | 
	
		
			
			| 34 |  | -          <p>You can build a dynamic site without any data model at all. There still be a
 | 
	
		
			
			| 35 |  | -          default data-model template for you if you didn't enable authentication and
 | 
	
		
			
			| 36 |  | -          authorization in quickstart. If you have enabled authorization, the auth
 | 
	
		
			
			| 37 |  | -          data-model is ready-made.</p>
 | 
	
		
			
			| 38 |  | -        </div>
 | 
	
		
			
			| 39 |  | -
 | 
	
		
			
			| 40 |  | -        <div class="well" id="url-structure">
 | 
	
		
			
			| 41 |  | -          <h3>Design my URL structure</h3>
 | 
	
		
			
			| 42 |  | -
 | 
	
		
			
			| 43 |  | -          <p>The "<code>root.py</code>" file under the <code>/controllers</code> folder has
 | 
	
		
			
			| 44 |  | -          your URLs. When you called this url (<code><a href=
 | 
	
		
			
			| 45 |  | -          "${tg.url('/about')}">about</a></code>), the command went through the
 | 
	
		
			
			| 46 |  | -          RootController class to the <code>about()</code> method.</p>
 | 
	
		
			
			| 47 |  | -
 | 
	
		
			
			| 48 |  | -          <p>Those Python methods are responsible to create the dictionary of variables
 | 
	
		
			
			| 49 |  | -          that will be used in your web views (template).</p>
 | 
	
		
			
			| 50 |  | -        </div>
 | 
	
		
			
			| 51 |  | -      </div>
 | 
	
		
			
			| 52 |  | -
 | 
	
		
			
			| 53 |  | -      <div class="span8"><img src=
 | 
	
		
			
			| 54 |  | -      "http://www.turbogears.org/2.1/docs/_images/tg2_files.jpg" alt=
 | 
	
		
			
			| 55 |  | -      "TurboGears2 quickstarted project" /></div>
 | 
	
		
			
			| 56 |  | -    </div>
 | 
	
		
			
			| 57 |  | -
 | 
	
		
			
			| 58 |  | -    <div class="row">
 | 
	
		
			
			| 59 |  | -      <div class="span12" id="template-reuse">
 | 
	
		
			
			| 60 |  | -        <h3>Reuse the web page elements</h3>
 | 
	
		
			
			| 61 |  | -
 | 
	
		
			
			| 62 |  | -        <p>A web page viewed by user could be constructed by single or several reusable
 | 
	
		
			
			| 63 |  | -        templates under <code>/templates</code>. Take 'about' page for example, each
 | 
	
		
			
			| 64 |  | -        reusable templates generating a part of the page. We'll cover them in the order of
 | 
	
		
			
			| 65 |  | -        where they are found, listed near the top of the about.html template</p>
 | 
	
		
			
			| 66 |  | -
 | 
	
		
			
			| 67 |  | -        <div class="row">
 | 
	
		
			
			| 68 |  | -          <div class="span6">
 | 
	
		
			
			| 69 |  | -            <p><strong><span class="label label-info">header.html</span></strong> - The
 | 
	
		
			
			| 70 |  | -            "header.html" template contains the HTML code to display the 'header': The div,
 | 
	
		
			
			| 71 |  | -            the h1 tag, and the subtitle are there, and the the blue gradient, TG2 logo,
 | 
	
		
			
			| 72 |  | -            are placed by way of the .css file (from style.css) are all at the top of every
 | 
	
		
			
			| 73 |  | -            page it is included on. When the "about.html" template is called, it includes
 | 
	
		
			
			| 74 |  | -            this "header.html" template (and the others) with a <code><xi:include
 | 
	
		
			
			| 75 |  | -            /></code> tag, part of the Genshi templating system. The "header.html"
 | 
	
		
			
			| 76 |  | -            template is not a completely static HTML -- it also includes (via
 | 
	
		
			
			| 77 |  | -            <code><xi:include/></code> tag) "master.html", which dynamically displays
 | 
	
		
			
			| 78 |  | -            the current page name with a Genshi template method called "replace" with the
 | 
	
		
			
			| 79 |  | -            code: <code><span py:replace="page"/></code>. It means replace this
 | 
	
		
			
			| 80 |  | -            <code><span /></code> region with the contents found in the variable
 | 
	
		
			
			| 81 |  | -            'page' that has been sent in the dictionary to this "about.html" template, and
 | 
	
		
			
			| 82 |  | -            is available through that namespace for use by this "header.html" template.
 | 
	
		
			
			| 83 |  | -            That's how it changes in the header depending on what page you are
 | 
	
		
			
			| 84 |  | -            visiting.</p>
 | 
	
		
			
			| 85 |  | -
 | 
	
		
			
			| 86 |  | -            <p><strong><span class="label label-info">sidebars.html</span></strong> - The
 | 
	
		
			
			| 87 |  | -            sidebars (navigation areas on the right side of the page) are generated as two
 | 
	
		
			
			| 88 |  | -            separate <code>py:def</code> blocks in the "sidebars.html" template. The
 | 
	
		
			
			| 89 |  | -            <code>py:def</code> construct is best thought of as a "macro" code... a simple
 | 
	
		
			
			| 90 |  | -            way to separate and reuse common code snippets. All it takes to include these
 | 
	
		
			
			| 91 |  | -            on the "about.html" page template is to write</p>
 | 
	
		
			
			| 92 |  | -            <pre><span>$</span>{sidebar_top()}
 | 
	
		
			
			| 93 |  | -<span>$</span>{sidebar_bottom()}
 | 
	
		
			
			| 94 |  | -  </pre>in the page where they are wanted. CSS styling (in "/public/css/style.css") floats
 | 
	
		
			
			| 95 |  | -  them off to the right side. You can remove a sidebar or add more of them, and the CSS
 | 
	
		
			
			| 96 |  | -  will place them one atop the other.
 | 
	
		
			
			| 97 |  | -
 | 
	
		
			
			| 98 |  | -            <p>This is, of course, also exactly how the header and footer templates are
 | 
	
		
			
			| 99 |  | -            also displayed in their proper places, but we'll cover that in the
 | 
	
		
			
			| 100 |  | -            "master.html" template below.</p>
 | 
	
		
			
			| 101 |  | -
 | 
	
		
			
			| 102 |  | -            <p>Oh, and in sidebar_top we've added a dynamic menu that shows the link to
 | 
	
		
			
			| 103 |  | -            this page at the top when you're at the "index" page, and shows a link to the
 | 
	
		
			
			| 104 |  | -            Home (index) page when you're here. Study the "sidebars.html" template to see
 | 
	
		
			
			| 105 |  | -            how we used <code>py:choose</code> for that.</p>
 | 
	
		
			
			| 106 |  | -          </div>
 | 
	
		
			
			| 107 |  | -
 | 
	
		
			
			| 108 |  | -          <div class="span6">
 | 
	
		
			
			| 109 |  | -            <p><strong><span class="label label-info">footer.html</span></strong> - The
 | 
	
		
			
			| 110 |  | -            "footer.html" block is simple, but also utilizes a special "replace" method to
 | 
	
		
			
			| 111 |  | -            set the current YEAR in the footer copyright message. The code is:</p>
 | 
	
		
			
			| 112 |  | -            <pre>
 | 
	
		
			
			| 113 |  | -  <span py:replace="now.strftime('%Y')">
 | 
	
		
			
			| 114 |  | -  </pre>and it uses the variable "now" that was passed in with the dictionary of variables.
 | 
	
		
			
			| 115 |  | -  But because "now" is a datetime object, we can use the Python <code>"strftime()"</code>
 | 
	
		
			
			| 116 |  | -  method with the "replace" call to say "Just Display The Year Here". Simple, elegant; we
 | 
	
		
			
			| 117 |  | -  format the date display in the template (the View in the Model/View/Controller
 | 
	
		
			
			| 118 |  | -  architecture) rather than formatting it in the Controller method and sending it to the
 | 
	
		
			
			| 119 |  | -  template as a string variable.
 | 
	
		
			
			| 120 |  | -
 | 
	
		
			
			| 121 |  | -            <p><strong><span class="label label-info">master.html</span></strong> - The
 | 
	
		
			
			| 122 |  | -            "master.html" template is called last, by design. The "master.html" template
 | 
	
		
			
			| 123 |  | -            controls the overall design of the page we're looking at, calling first the
 | 
	
		
			
			| 124 |  | -            "header" py:def macro, then the putting everything from this "about.html"
 | 
	
		
			
			| 125 |  | -            template into the "main_content" div, and then calling the "footer" macro at
 | 
	
		
			
			| 126 |  | -            the end. Thus the "master.html" template provides the overall architecture for
 | 
	
		
			
			| 127 |  | -            each page in this site.</p>
 | 
	
		
			
			| 128 |  | -
 | 
	
		
			
			| 129 |  | -            <p>But why then shouldn't we call it first? Isn't it the most important?
 | 
	
		
			
			| 130 |  | -            Perhaps, but that's precisely why we call it LAST. The "master.html" template
 | 
	
		
			
			| 131 |  | -            needs to know where to find everything else, everything that it will use in
 | 
	
		
			
			| 132 |  | -            py:def macros to build the page. So that means we call the other templates
 | 
	
		
			
			| 133 |  | -            first, and then call "master.html".</p>
 | 
	
		
			
			| 134 |  | -
 | 
	
		
			
			| 135 |  | -            <p>There's more to the "master.html" template... study it to see how the
 | 
	
		
			
			| 136 |  | -            <title> tags and static JS and CSS files are brought into the page.
 | 
	
		
			
			| 137 |  | -            Templating with Genshi is a powerful tool and we've only scratched the surface.
 | 
	
		
			
			| 138 |  | -            There are also a few little CSS tricks hidden in these pages, like the use of a
 | 
	
		
			
			| 139 |  | -            "clearingdiv" to make sure that your footer stays below the sidebars and always
 | 
	
		
			
			| 140 |  | -            looks right. That's not TG2 at work, just CSS. You'll need all your skills to
 | 
	
		
			
			| 141 |  | -            build a fine web app, but TG2 will make the hard parts easier so that you can
 | 
	
		
			
			| 142 |  | -            concentrate more on good design and content rather than struggling with
 | 
	
		
			
			| 143 |  | -            mechanics.</p>
 | 
	
		
			
			| 144 |  | -          </div>
 | 
	
		
			
			| 145 |  | -
 | 
	
		
			
			| 146 |  | -          <div class="span12" id="authentication" py:if="tg.auth_stack_enabled">
 | 
	
		
			
			| 147 |  | -            <h3>Authentication & Authorization in a TG2 site.</h3>
 | 
	
		
			
			| 148 |  | -
 | 
	
		
			
			| 149 |  | -            <p>If you have access to this page, this means you have enabled authentication
 | 
	
		
			
			| 150 |  | -            and authorization in the quickstart to create your project.</p>
 | 
	
		
			
			| 151 |  | -
 | 
	
		
			
			| 152 |  | -            <p>The paster command will have created a few specific controllers for you. But
 | 
	
		
			
			| 153 |  | -            before you go to play with those controllers you'll need to make sure your
 | 
	
		
			
			| 154 |  | -            application has been properly bootstapped. This is dead easy, here is how to do
 | 
	
		
			
			| 155 |  | -            this:</p>
 | 
	
		
			
			| 156 |  | -            <pre>paster setup-app development.ini</pre>
 | 
	
		
			
			| 157 |  | -
 | 
	
		
			
			| 158 |  | -            <p>inside your application's folder and you'll get a database setup (using the
 | 
	
		
			
			| 159 |  | -            preferences you have set in your development.ini file). This database will also
 | 
	
		
			
			| 160 |  | -            have been prepopulated with some default logins/passwords so that you can test
 | 
	
		
			
			| 161 |  | -            the secured controllers and methods.</p>
 | 
	
		
			
			| 162 |  | -
 | 
	
		
			
			| 163 |  | -            <p>To change the comportement of this setup-app command you just need to edit
 | 
	
		
			
			| 164 |  | -            the <code>websetup.py</code> file.</p>
 | 
	
		
			
			| 165 |  | -
 | 
	
		
			
			| 166 |  | -            <p>Now try to visiting the <a href=
 | 
	
		
			
			| 167 |  | -            "${tg.url('/manage_permission_only')}">manage_permission_only</a> URL. You will
 | 
	
		
			
			| 168 |  | -            be challenged with a login/password form.</p>
 | 
	
		
			
			| 169 |  | -
 | 
	
		
			
			| 170 |  | -            <p>Only managers are authorized to visit this method. You will need to log-in
 | 
	
		
			
			| 171 |  | -            using:</p>
 | 
	
		
			
			| 172 |  | -            <pre>login: manager
 | 
	
		
			
			| 173 |  | -password: managepass</pre>
 | 
	
		
			
			| 174 |  | -
 | 
	
		
			
			| 175 |  | -            <p>Another protected resource is <a href=
 | 
	
		
			
			| 176 |  | -            "${tg.url('/editor_user_only')}">editor_user_only</a>. This one is protected by
 | 
	
		
			
			| 177 |  | -            a different set of permissions. You will need to be <code>editor</code> with a
 | 
	
		
			
			| 178 |  | -            password of <code>editpass</code> to be able to access it.</p>
 | 
	
		
			
			| 179 |  | -
 | 
	
		
			
			| 180 |  | -            <p>The last kind of protected resource in this quickstarted app is a full so
 | 
	
		
			
			| 181 |  | -            called <a href="${tg.url('/secc')}">secure controller</a>. This controller is
 | 
	
		
			
			| 182 |  | -            protected globally. Instead of having a @require decorator on each method, we
 | 
	
		
			
			| 183 |  | -            have set an allow_only attribute at the class level. All the methods in this
 | 
	
		
			
			| 184 |  | -            controller will require the same level of access. You need to be manager to
 | 
	
		
			
			| 185 |  | -            access <a href="${tg.url('/secc')}">secc</a> or <a href=
 | 
	
		
			
			| 186 |  | -            "${tg.url('/secc/some_where')}">secc/some_where</a>.</p>
 | 
	
		
			
			| 187 |  | -          </div>
 | 
	
		
			
			| 188 |  | -        </div>
 | 
	
		
			
			| 189 |  | -      </div>
 | 
	
		
			
			| 190 |  | -    </div>
 |