1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>8. Using OOP to program a website</title>
<META NAME="description" CONTENT="8. Using OOP to program a website">
<META NAME="keywords" CONTENT="tut">
<META NAME="resource-type" CONTENT="document">
<META NAME="distribution" CONTENT="global">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="STYLESHEET" href="tut.css" type='text/css'>
<link rel="first" href="tut.html">
<link rel="contents" href="contents.html" title="Contents">
<LINK REL="next" HREF="node11.html">
<LINK REL="previous" HREF="node9.html">
<LINK REL="up" HREF="tut.html">
<LINK REL="next" HREF="node11.html">
<meta name='aesop' content='information'>
</head>
<body>
<DIV CLASS="navigation">
<table align="center" width="100%" cellpadding="0" cellspacing="2">
<tr>
<td><A HREF="node9.html"><img src="../icons/previous.gif"
border="0" height="32"
alt="Previous Page" width="32"></A></td>
<td><A HREF="tut.html"><img src="../icons/up.gif"
border="0" height="32"
alt="Up One Level" width="32"></A></td>
<td><A HREF="node11.html"><img src="../icons/next.gif"
border="0" height="32"
alt="Next Page" width="32"></A></td>
<td align="center" width="100%">CherryPy Tutorial</td>
<td><A HREF="node2.html"><img src="../icons/contents.gif"
border="0" height="32"
alt="Contents" width="32"></A></td>
<td><img src="../icons/blank.gif"
border="0" height="32"
alt="" width="32"></td>
<td><img src="../icons/blank.gif"
border="0" height="32"
alt="" width="32"></td>
</tr></table>
<b class="navlabel">Previous:</b> <a class="sectref" HREF="node9.html">7. Class, instance, method</A>
<b class="navlabel">Up:</b> <a class="sectref" HREF="tut.html">CherryPy Tutorial</A>
<b class="navlabel">Next:</b> <a class="sectref" HREF="node11.html">9. Using several modules</A>
<br><hr>
</DIV>
<!--End of Navigation Panel-->
<H1><A NAME="SECTION0010000000000000000000">
8. Using OOP to program a website</A>
</H1>
<P>
One the the most powerful feature of CherryPy is that you can really use an <b>object oriented</b> approach
to "program" your website.
<P>
When you look at a complex website, you'll realize that some parts have a lot in common:
<UL>
<LI>They use the same functionalities but these functionalities are applied to a different type of data
</LI>
<LI>They display the same information, but the data is displayed differently (for instance, when you have multiple versions of a website, or you have several
versions in several languages)
</LI>
</UL>
<P>
In both cases, OOP provides an elegant solution to the problem and minimizes the amount of code that is required to
implement the solution.
<P>
To show you how this can be done, we'll create a website that comes in two versions: the English version
and the French version. Not only do the text and labels change, but also the colors and the way modules are displayed.
<P>
Enter the following code for the website:
<div class="verbatim"><pre>
#######################
CherryClass Airline abstract:
#######################
function:
def localize(self, stri):
return self.dictionnary.get(stri, stri)
mask:
def header(self):
<html><body>
<center>
<H1 py-eval="self.localize('Welcome to CherryPy airline')"></H1>
<div py-if="self==airlineFrench">
<a py-attr="request.base+'/airlineEnglish/index'" href="">
Click here for English version
</a>
</div><div py-else>
<a py-attr="request.base+'/airlineFrench/index'" href="">
Cliquez ici pour la version française
</a>
</div>
<br><br><br><br>
def footer(self):
</center>
</body></html>
def squareWithText(self, title, text):
<table border=0 cellspacing=0 cellpadding=1 width=200><tr>
<td py-attr="self.borderColor" bgColor="">
<table border=0 cellspacing=0 cellpadding=5><tr>
<td py-attr="self.insideColor" bgColor=""
align=center width=198 py-eval="'<b>%s</b><br><br>%s'%(title,text)">
</td>
</tr></table>
</td>
</tr></table>
view:
def bookAFlight(self):
page=self.header()
page+=self.squareWithText(self.localize('Booking a flight'),
self.localize('To book a flight, think about where you want to go, and you should dream about it tonight'))
page+=self.footer()
return page
#######################
CherryClass AirlineFrench(Airline):
#######################
variable:
insideColor='#FFFF99'
borderColor='#FF6666'
dictionnary={
'Welcome to CherryPy airline': 'Bienvenue chez CherryPy airline',
'Booking a flight': 'Rserver un vol',
'To book a flight, think about where you want to go, and you should dream about it tonight':
'Pour rserver un vol, pensez trs fort la destination, et vous devriez en rver cette nuit'
}
view:
def index(self):
page=self.header()
page+=self.squareWithText('Rserver un vol', 'Pour rserver un vol, cliquez sur <a href="%s/bookAFlight">réserver</a>'%self.getPath())+'<br>'
page+=self.squareWithText('Prsentation', 'CherryPy airline est la compagnie qui vous emmne au 7me ciel')
page+=self.footer()
return page
#######################
CherryClass AirlineEnglish(Airline):
#######################
variable:
insideColor='#00CCFF'
borderColor='#3333FF'
dictionnary={}
view:
def index(self):
page=self.header()
page+=self.squareWithText('Presentation', 'CherryPy airline is the company that will take you to cloud 9')+'<br>'
page+=self.squareWithText('Book a flight', '<a href="%s/bookAFlight">Click here</a> to book a flight'%self.getPath())
page+=self.footer()
return page
#######################
CherryClass Root(AirlineEnglish):
#######################
</pre></div>
<P>
This program uses a lot of new features of CherryPy. Let's try to understand how it works:
<P>
The idea is to use a generic CherryClass (<var>Airline</var>) that contains functions, masks and views that are
common to both versions (English and French) or the website. Then we use 2 CherryClasses (<var>AirlineFrench</var>
and <var>AirlineEnglish</var>) to implement specificities of each version.
<P>
We use two different ways to implement specificities of each version:
<UL>
<LI>Either the only difference is the labels (they are translated into French for the French version). In this case,
we just use a dictionnary to implement the translation.
</LI>
<LI>Or the presentation of the information also changes. In this case, we write 2 versions of each method.
</LI>
</UL>
<P>
This example also shows some new features of CherryPy:
<P>
<UL>
<LI><b>Abstract CherryClasses</b>: in this example, you'll notice that CherryClass <var>Airline</var> is declared "abstract". This
just means that the server won't create any instance of the CherryClass called <var>airline</var>. As a result, you can't
use the URL <a class="url" href="http://localhost:8000/airline/index">http://localhost:8000/airline/index</a>. The idea behind this is that <var>Airline</var> cannot be used directly.
It has to be derived into sub-classes, and only these sub-classes can be accessed from the browser.
</LI>
<LI><b>Variable section</b>: you'll notice that this example uses a new kind of section in a CherryClass: <var>variable</var>. This
is just used to set variables by default for this CherryClass.
</LI>
<LI><b>self.getPath()</b>: by default, CherryPy creates a method called <var>getPath</var> for each CherryClass. This method returns
the URL of the CherryClass. For instance, for the <var>AirlineFrench</var> CherryClass, <var>getPath</var> would return
<a class="url" href="http://localhost:8000/airlineFrench">http://localhost:8000/airlineFrench</a>.
<P>
This method also takes an optional argument <var>includeRequestBase</var>, which defaults to 1. If you set it to 0 then the returned URL won't include the domain name.
For instance, for the <var>AirlineFrench</var> CherryClass, <var>getPath(0)</var> would return
<a class="url" href="/airlineFrench">/airlineFrench</a>.
</LI>
</UL>
<P>
In the next chapter, we'll learn how to split our code in several source files...
<P>
<DIV CLASS="navigation">
<p><hr>
<table align="center" width="100%" cellpadding="0" cellspacing="2">
<tr>
<td><A HREF="node9.html"><img src="../icons/previous.gif"
border="0" height="32"
alt="Previous Page" width="32"></A></td>
<td><A HREF="tut.html"><img src="../icons/up.gif"
border="0" height="32"
alt="Up One Level" width="32"></A></td>
<td><A HREF="node11.html"><img src="../icons/next.gif"
border="0" height="32"
alt="Next Page" width="32"></A></td>
<td align="center" width="100%">CherryPy Tutorial</td>
<td><A HREF="node2.html"><img src="../icons/contents.gif"
border="0" height="32"
alt="Contents" width="32"></A></td>
<td><img src="../icons/blank.gif"
border="0" height="32"
alt="" width="32"></td>
<td><img src="../icons/blank.gif"
border="0" height="32"
alt="" width="32"></td>
</tr></table>
<b class="navlabel">Previous:</b> <a class="sectref" HREF="node9.html">7. Class, instance, method</A>
<b class="navlabel">Up:</b> <a class="sectref" HREF="tut.html">CherryPy Tutorial</A>
<b class="navlabel">Next:</b> <a class="sectref" HREF="node11.html">9. Using several modules</A>
<hr>
<span class="release-info">Release 0.10, documentation updated on 19 March 2004.</span>
</DIV>
<!--End of Navigation Panel-->
<ADDRESS>
See <i><a href="about.html">About this document...</a></i> for information on suggesting changes.
</ADDRESS>
</BODY>
</HTML>
|