Changeset 1998d46
- Timestamp:
- Feb 23, 2009, 8:23:04 PM (16 years ago)
- Branches:
- master, debian, mac, no-cups, web
- Children:
- 4b9d354
- Parents:
- b748ed1
- git-author:
- Edward Z. Yang <edwardzyang@…> (02/23/09 20:23:04)
- git-committer:
- Edward Z. Yang <edwardzyang@…> (02/23/09 20:23:04)
- Location:
- gutenbach-web
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
gutenbach-web/about.html
r7f1e63c r1998d46 9 9 <head> 10 10 <meta content="text/html; charset=UTF-8" http-equiv="content-type" py:replace="''"/> 11 <title> Learning TurboGears 2.0: Quick guide to the Quickstart pages.</title>11 <title>About / sipbmp3 web</title> 12 12 </head> 13 13 14 14 <body> 15 <div id="getting_started"> 16 <h2>Architectural basics of a quickstart TG2 site.</h2> 17 <p>The TG2 quickstart command produces this basic TG site. Here's how it works.</p> 18 <ol id="getting_started_steps"> 19 <li class="getting_started"> 20 <h3>Code my data model</h3> 21 <p> When you want a model for storing favorite links or wiki content, 22 the <strong>/model</strong> folder in your site is ready to go.</p> 23 <p> You can build a dynamic site without any data model at all. There 24 still be a default data-model template for you if you didn't enable 25 identity in quickstart. If you enable identity, you'll got 26 identity data-model made for you.</p> 27 </li> 28 <li class="getting_started"> 29 <h3>Design my URL structure</h3> 30 <p> The "<span class="code">root.py</span>" file under the 31 <strong>/controllers</strong> folder has your URLs. When you 32 called this url (<span class="code"><a href="${tg.url('/about')}">about</a></span>), 33 the command went through the RootController class to the 34 <span class="code">about</span><span class="code">()</span> method.</p> 35 <p> Those Python methods are responsible to create the dictionary of 36 variables that will be used in your web views (template).</p> 37 </li> 38 <li class="getting_started"> 39 <h3>Reuse the web page elements</h3> 40 <p> A web page viewed by user could be constructed by single or 41 several reusable templates under <strong>/templates</strong>. 42 Take 'about' page for example, each reusable templates generating 43 a part of the page. We'll cover them in the order of where they are 44 found, listed near the top of the about.html template</p> 45 <p> <strong><span class="code">header.html</span></strong> - The 46 "header.html" template contains the HTML code to display the 47 'header': The blue gradient, TG2 logo, and some site text at the 48 top of every page it is included on. When the "about.html" template 49 is called, it includes this "header.html" template (and the others) 50 with a <span class="code"><xi:include /></span> tag, part of 51 the Genshi templating system. The "header.html" template is not a 52 completely static HTML -- it also dynamically displays the current 53 page name with a Genshi template method called "replace" with the 54 code: <span class="code"><span py:replace="page"/></span>. 55 It means replace this <span class="code"><span /></span> 56 region with the contents found in the variable 'page' that has 57 been sent in the dictionary to this "about.html" template, and is 58 available through that namespace for use by this "header.html" 59 template. That's how it changes in the header depending on what 60 page you are visiting. 15 <div> 16 <p> 17 sipbmp3 is the MP3 spooler for SIPB office, which allows office 18 users to print MP3 files to a server and have them be played 19 on external speakers. 61 20 </p> 62 <p> <strong><span class="code">sidebars.html</span></strong> - The 63 sidebars (navigation areas on the right side of the page) are 64 generated as two separate <span class="code">py:def</span> blocks 65 in the "sidebars.html" template. The <span class="code">py:def</span> 66 construct is best thought of as a "macro" code... a simple way to 67 separate and reuse common code snippets. All it takes to include 68 these on the "about.html" page template is to write 69 <span class="code"> 70 <br/><br/> 71 <br/> 72 <br/><br/> 73 </span> in the page where they are wanted. CSS styling (in 74 "/public/css/style.css") floats them off to the right side. You can 75 remove a sidebar or add more of them, and the CSS will place them one 76 atop the other.</p> 77 <p>This is, of course, also exactly how the header and footer 78 templates are also displayed in their proper places, but we'll 79 cover that in the "master.html" template below.</p> 80 <p>Oh, and in sidebar_top we've added a dynamic menu that shows the 81 link to this page at the top when you're at the "index" page, and 82 shows a link to the Home (index) page when you're here. Study the 83 "sidebars.html" template to see how we used 84 <span class="code">py:choose</span> for that.</p> 85 <p> <strong><span class="code">footer.html</span></strong> - The 86 "footer.html" block is simple, but also utilizes a special 87 "replace" method to set the current YEAR in the footer copyright 88 message. The code is: 89 <span class="code"><span py:replace="now.strftime('%Y')"> 90 </span> and it uses the variable "now" that was passed 91 in with the dictionary of variables. But because "now" is a 92 datetime object, we can use the Python 93 <span class="code">"strftime()"</span> method with the "replace" 94 call to say "Just Display The Year Here". Simple, elegant; we 95 format the date display in the template (the View in the 96 Model/View/Controller architecture) rather than formatting it in 97 the Controller method and sending it to the template as a string 98 variable.</p> 99 <p> <strong><span class="code">master.html</span></strong> - The 100 "master.html" template is called last, by design. The "master.html" 101 template controls the overall design of the page we're looking at, 102 calling first the "header" py:def macro, then the putting everything 103 from this "about.html" template into the "main_content" div, and 104 then calling the "footer" macro at the end. Thus the "master.html" 105 template provides the overall architecture for each page in this 106 site.</p> 107 <p>But why then shouldn't we call it first? Isn't it the most 108 important? Perhaps, but that's precisely why we call it LAST. 109 The "master.html" template needs to know where to find everything 110 else, everything that it will use in py:def macros to build the 111 page. So that means we call the other templates first, and then 112 call "master.html". </p> 113 <p>There's more to the "master.html" template... study it to see how 114 the <title> tags and static JS and CSS files are brought into 115 the page. Templating with Genshi is a powerful tool and we've only 116 scratched the surface. There are also a few little CSS tricks 117 hidden in these pages, like the use of a "clearingdiv" to make 118 sure that your footer stays below the sidebars and always looks 119 right. That's not TG2 at work, just CSS. You'll need all your 120 skills to build a fine web app, but TG2 will make the hard parts 121 easier so that you can concentrate more on good design and content 122 rather than struggling with mechanics.</p> 123 </li> 124 </ol> 125 <p>Good luck with TurboGears 2!</p> 126 </div> 21 <p> 22 This website will tell you (eventually) <strong>what's 23 playing</strong>, as well as allowing you to adjust the volume. 24 </p> 25 </div> 127 26 </body> 128 27 </html> -
gutenbach-web/footer.html
r84ed773 r1998d46 4 4 <py:def function="footer"> 5 5 <div id="footer"> 6 <div class="flogo"> 7 <p><a href="http://www.turbogears.org/2.0/">Powered by TurboGears 2</a></p> 8 </div> 9 <div class="clearingdiv"></div> 6 <div><a href="http://www.turbogears.org/2.0/">Powered by TurboGears 2</a></div> 7 <div class="clearingdiv"></div> 10 8 </div> 11 </py:def> 9 </py:def> 12 10 </html> -
gutenbach-web/header.html
r84ed773 r1998d46 5 5 <div id="header"> 6 6 <h1> 7 sipbmp3 web7 sipbmp3 <span class="web">web</span> 8 8 </h1> 9 9 <div class="subtitle">what's playing?</div> -
gutenbach-web/index.html
r84ed773 r1998d46 14 14 <body> 15 15 <div id="status"> 16 <h2>Status</h2> 17 <p>The volume is: $volume</p> 16 <p>The volume is <span class="volume">$volume</span></p> 18 17 </div> 19 18 <div class="clearingdiv" /> -
gutenbach-web/master.html
r84ed773 r1998d46 15 15 16 16 <body py:match="body" py:attrs="select('@*')"> 17 <div class="wrapper"> 17 18 ${header()} 18 19 <ul id="mainmenu"> 19 <li class="first"><a href="${tg.url('/')}" class="${('', 'active')[defined('page') and page==page=='index']}"> Welcome</a></li>20 <li class="first"><a href="${tg.url('/')}" class="${('', 'active')[defined('page') and page==page=='index']}">Status</a></li> 20 21 <li><a href="${tg.url('/about')}" class="${('', 'active')[defined('page') and page==page=='about']}">About</a></li> 21 <li><a href=" http://groups.google.com/group/turbogears">Contact</a></li>22 <li><a href="mailto:sipb@mit.edu">Contact</a></li> 22 23 </ul> 23 24 <div id="content"> … … 27 28 <div py:replace="select('*|text()')"/> 28 29 <!-- End of main_content --> 29 ${footer()}30 30 </div> 31 <div class="push"></div> 32 </div> 33 ${footer()} 31 34 </body> 32 35 </html> -
gutenbach-web/root.py
r7f1e63c r1998d46 18 18 @expose('sipbmp3web.templates.index') 19 19 def index(self): 20 out = dict( )20 out = dict(page="index") 21 21 out["volume"] = remctl("zygorthian-space-raiders.mit.edu", command=["v", "get"]).stdout 22 22 return out … … 24 24 @expose('sipbmp3web.templates.about') 25 25 def about(self): 26 return dict( )26 return dict(page="about") 27 27 -
gutenbach-web/style.css
r84ed773 r1998d46 1 html { 2 margin: 0; 3 height: 100%; 4 } 5 body { 6 font-size: 87.5%; 7 line-height: 1.5em; 8 font-family: Tahoma, Sans, sans-serif; 9 height: 100%; 10 margin: 0; 11 } 12 #header h1 { 13 margin-top: 0; 14 padding-top: 2em; 15 margin-bottom: 0.3em; 16 } 17 #header h1 .web { 18 color: #0BF; 19 } 20 #header .subtitle { 21 margin-bottom: 1em; 22 margin-top: 0; 23 margin-left: 9em; 24 } 25 ul#mainmenu { 26 margin: 0 0 2em 0; 27 padding: 0; 28 } 29 ul#mainmenu li { 30 list-style-type: none; 31 display: inline; 32 margin: 0 0.6em; 33 padding: 0 0.3em; 34 } 35 ul#mainmenu li.first { 36 margin-left: 0; 37 } 38 ul#mainmenu li .active { 39 color: #000; 40 font-weight: bold; 41 text-decoration: none; 42 } 43 .wrapper { 44 min-height: 100%; 45 margin: 0 auto -3em; 46 padding: 0 3em; 47 max-width: 50em; 48 } 49 .push { 50 height: 3em; 51 } 52 #footer { 53 height: 3em; 54 text-align: right; 55 padding: 0 3em; 56 } 57 #flash { 58 font-size:120%; 59 font-weight:bolder; 60 margin:0pt auto 0.5em; 61 width:680px; 62 } 63 #flash div { 64 padding:5px 15px 15px 55px; 65 } 66 #flash .ok { 67 background:#EEEEFF url(../images/ok.png) no-repeat scroll left center; 68 border:1px solid #CCCCEE; 69 } 70 #flash .warning { 71 background:#FF9999 url(../images/error.png) no-repeat scroll left center; 72 border:1px solid #FF3333; 73 } 74 #flash .alert { 75 background:#FFFF99 url(../images/info.png) no-repeat scroll left center; 76 border:1px solid #FFFF00; 77 } 78 .notice { 79 background:#EEEEFF url(../images/info.png) no-repeat scroll left center; 80 border:1px solid #CCCCEE; 81 margin:0.5em auto; 82 padding:15px 10px 15px 55px; 83 width:680px; 84 } 85 .fielderror { 86 color:red; 87 font-weight:bold; 88 } 89 div.clearingdiv { 90 clear: both; 91 } 1 92 93 /* Content CSS */ 94 .volume { 95 color: #009; 96 font-family: Helvetica; 97 font-weight: bold; 98 font-size: 1.1em; 99 }
Note: See TracChangeset
for help on using the changeset viewer.