Name | Modified | Size | Downloads / Week |
---|---|---|---|
Parent folder | |||
codeputty-0.1.0-README | 2004-07-20 | 4.1 kB | |
codeputty-0.1.0.tar.gz | 2004-07-20 | 5.6 kB | |
Totals: 2 Items | 9.7 kB | 0 |
Software Prerequisites: - Apache - Python - mod_python Example Apache Conf: <Directory /path/to/site> <Files *.cpml> SetHandler python-program PythonPath "sys.path+[r'/path/to/codeputty']" PythonHandler CodePutty.modpython::handler PythonDebug On </Files> </Directory> The basic structure of website built on the CodePutty framework is composed of a heirarchy of .cpml files (which are 'templates' that consist of xhtml markup and custom tags that represent other templates) and .py code files. Say in the root of my web site I have a file called 'index.cpml' (which you may want to set up as an index file in your apache configuration), if configured correctly, apache will call the CodePutty handler, which will begin the process of building your page. A page named 'index.cpml' may look like this: <?xml version="1.0"?> <html xmlns="http://www.w3.org/1999/xhtml"> <body> {imagecount} {images <image-render name="{name}"/> } </body> </html> Allow me to explain how CodePutty parses this page and build the final markup that is sent to the user agent. When CodePutty initialized, it loaded up all the template (cpml) files in your website directory structure. Lets say that structure looks like this: /index.cpml /index.py /image/render.cpml /image/render.py Internally CodePutty maps the template files and converts their names to XML-like tags: index image-render The first step parsing a template is to insert any data that may be available to it. This is what the curly brackets indicate: locations that data will be inserted _if_ available. Data is made available through Python files with a matching path to the template being processed, and that contain a data() function. The structure of the return value of the data function is a dictionary whose values can be scalar, lists, or more dictionaries. The example above is not complex, but keep in mind that the nesting of dictionaries can be taken to an absurd level if you wish. Here is what the return data for index.py might looks like: {'imagecount': 2, 'images': [{'name': 'foo.gif'}, {'name': 'bar.gif'}]} How 'imagecount' gets merged in is simple enough, but how about 'images'? Since the value of the 'images' key on the dictionary is a list, then CodePutty will iterate over the list and and insert its values into the contents of the {images ...} block. So the result for that markup at this stage will look like this: <?xml version="1.0"?> <html xmlns="http://www.w3.org/1999/xhtml"> <body> 2 <image-render name="foo.gif"/> <image-render name="bar.gif"/> </body> </html> Ok, so far so good. Next thing that happens is CodePutty looks for an element in this page that has the same tag name as one of our templates. Of course there are two, and it finds the first. CodePutty loads up that template, which may looks like this: <?xml version="1.0"?> <image-render> <img src="http://somewebsite/my/fav/images/{name}/> </image-render> A template that is defining a tag needs to have its name as the root element. CodePutty will attempt to load the file image/render.py and call its data function. Since image-render has an attribute of 'name', that attribute will be passed to the function as a keyword argument. Here are some examples of what that data function might look like: # Require an attribute of name, and simply pass it on to the template def data(name): return {'name': name} # Don't require an attribute of name def data(name=''): return {'name': name} # Just pass whatever I've got to the template, this is the default # behavior when you don't have a .py file def data(**kwargs): return kwargs Of course your data functions can get their data from anywhere, such as a database. Ok, when all is said and done, here's what we've got: <?xml version="1.0"?> <html xmlns="http://www.w3.org/1999/xhtml"> <body> 2 <img src="http://somewebsite/my/fav/images/foo.gif/> <img src="http://somewebsite/my/fav/images/bar.gif/> </body> </html> Cool, eh?