Welcome to Xierpa. This is the stable 1.2 version which was developed by Petr van Blokland + Claudia Mens (buro@petr.com) and is maintained by Michiel Kauw-A-Tjoe. It is subclassed by the Museum Meermanno and American Express applications.

Building a site with CmsBuilder

The simplest site

Create the folder structure and standard files

  1. Create a folder for the site under it’s own name, e.g. called xyz
  2. Inside create the folders xyz/_xsl, xyz/_py, xyz/_m, xyz/_images, xyz/_js and xyz/_graffles. These folders will respectively hold the XSL templates, the Python appliciation classes and additional methods, text modules that are not part of the database, the images, the javascripts of the site and the datamodel.
  3. Create an empty file xyz/_xsl/_base that will indicate the position of unbased paths such as ./_m/abc.xml and ./_images/image.png.
  4. Create and empty file xyz/_py/__init__.py (2x2 underscores) that will indicate to Python that this folder contains modules to be imported.
  5. Create a file xyz/_py/_packagename containing the name of Python package (e.g. xyz).

Create a “Hello world” application

  1. Create and open an UTF-8 file named xyz/_py/xyzapp.py
  2. Set the content of the file to:
    # -*- coding: UTF-8 -*-
    # =============================================================================
    #	xierpa server
    #	(c) 2012 buro@petr.com, www.petr.com
    #	
    #	X I E R P A
    #
    #	No distribution without permission.
    #
    # .............................................................................
    #
    from xpyth.xierpa.builders.cmsbuilder import CmsBuilder
    
    class XyzApp(CmsBuilder):
    	pass
    
  3. Then create and open an UTF-8 file named xyz/index.py.
  4. Set the content of the file to:
    # -*- coding: UTF-8 -*-
    # =============================================================================
    #	xierpa server
    #	(c) 2012 buro@petr.com, www.petr.com
    #	
    #	X I E R P A
    #
    #	No distribution without permission.
    #
    # .............................................................................
    #
    from xpyth.defines import DEBUGSERVER
    
    if DEBUGSERVER:
    	import xyz
    	reload(xyz)
    	import xyz.xyzapp
    	reload(xyz.xyzapp)
    
    from xyz.xyzapp import XyzApp
    
    class Home(XyzApp):
    	pass
    	
    Home(e, result).build()
    
Now the simple site works under link http://yourdomain.com/xyz/index.

You should see a white page containing:
[self.buildcontent] To be redefined in an application class.
This means that the site is running. Now we are going to add some content. The DEBUGSERVER flag indicates on which kind of server the application is running. If the flag is True then on every request the xyzapp.XyzApp is included. This allows to make changes to the class source show in the page while developing. On a production server the class is only read once.

The current warning on the page indicates that the main method, displaying the content on the page, is not defined. Replace the definition of the Home class by the following code:
class Home(XyzApp):
	def buildcontent(self):
		self.text('Hello world')
Reloading the page should now show:
Hello world
We made our Home class inheriting the CmsBuilder class. The inheritance of the Xierpa builderclasses make a huge set of methods and tags available to our page builder. In the order or inheritance:
  • Builder is providing the standard open-tag and close-tag behaviour.
  • HtmlBuilder is providing the full set of standard XHTML tags.
  • XierpaBuilder, the main library of all kinds of useful tags and redefinitions of the XHTML set.
  • LayoutBuilder, the layout related method, interpreting the layour GNode structure.
  • SiteBuilder is providing a full set of (mostly empty or default) methods with the default behaviour that a minimal site runs.
  • CmsBuilder contains the full set of methods to add a CMS to the site using a database for content and page structure.

Adding CSS

The CSS of the page is defined by the method buildcsscontent. Add the following method definition to the XyzApp class definition.
class XyzApp:
	def buildcsscontent(self):
		self.css(ids='body, td',
			valign='top', align='left',
			backgroundcolor='gray', color='white', 
			fontfamily='Georgia', fontsize=36)
...
The buildcsscontent is de place where CSS definition of the site takes place. There are two of inserting the CSS in the page. Default is that the CSS code is referred to the page HTML as a separate document with the url /xyz/index/-/css.css. Note that this is the same application, but the css.css parameter will direct the SiteBuilder application to generate only CSS as output.

It is possible to include the CSS inside the page e.g. for debugging or when the CSS code is context dependent and needs rebuilding for every page separate. By inserting the class variable:
class XyzApp:
	REMOTECSS = False
...
the SiteBuilder will include the CSS code inside the HTML page. Currently the remote css does not work in FireFox, due to the fact that it really wants the file meme of type text/css.

Adding layouts

There are various ways to defined the layouts of pages and templates. The default behaviour is that the page calls the buildcontent and the application builds its own layout.
If there is a local definition of VIEWERLAYOUTS as a dictionary of gnode layouts, this is recognized and used by the inherited LayoutBuilder class.
	VIEWERLAYOUTS = {
		1:	gnode(border=0, padding='6 6 6 6', nodes=[
			gnode(y=2, x=1,	mode='a', w='25%', class_='normal', hook=xyzcontent),
			gnode(y=2, x=2,	mode='b', w='25%', class_='normal', hook=xyzcontent),
			gnode(y=2, x=3,	mode='c', w='25%', class_='normal', hook=xyzcontent),
			gnode(y=2, x=4,	mode='d', w='25%', class_='normal', hook=xyzcontent),
		])
	}
In order to make this work the following line should be defined below the application class definition:
from xpyth.xierpa.imaging.gstate import gnode
Also we defined ad hook in the layout table to xyzcontent. This custom method will be called for every cell in this example.
	def xyzcontent(self, gnode):
		self.text('Hello world')
This will now show a layout with 4 columns, each

Adding multiple page

In generlal there is only one index application for all pages of the site. The choice between the pages is done throught a url parameter, e.g. as in .../index/-/page-123. Our current xyzcontent method should recognize this parameters and choose different content from it.
	def xyzcontent(self, gnode):
		e = self.e
		if e.form['page'] in [None, '123']:
			self.text('Hello world 123')
		elif e.form['page'] == 'abc':
			self.text('Hello world of only letters')
		else:
			self.error('I cannot find a page with the name ' + str(e.form['page']))
This example makes a simple switch between the page parameter from th url. In the navigations this parameter can be add by self.link(params={'page': 'abc'}). Normally the content if the switch comes from XML files or database records. In this example we can extend the coding of page so it is equal to the names of the files in the _m folder.
	def xyzcontent(self, gnode):
		e = self.e
		if not e.form['page']:
			e.form['page'] = 'index'
		self.xml(src='./_m/%s.xml' % e.form['page'], template='./_xsl/template.xsl')	
which assumes that there is content file named ./_m/index.xml. All others files in the _m can be reached by .../index/-/page-xxxx.xml where the “xxxx” refers to the file name.