So yesterday I came across this other framework called Rialto which is marketed as language agnostic. They directly support Python (among other dynamic languages). They also say that their goal is to enable people to create RIAs without having to write DHTML, javascript or understanding DOM concepts.
They have a tutorial integrating their toolkit with CherryPy, so to teach my self Rialto, I decided to port their tutorial to TurboGears . Read along for how to make a simple app looking like the figure below.
I assume readers of this howto will be somewhat familiar with TurboGears, otherwise what's the point? So the first step is to generate a bare-bones TurboGears app with "tg-admin quickstart". Then Download and install rialtoPython from the Rialto website.
Then go to you controllers.py and first add the required import line:
from rialtoPython import *
Then, in the class root, empty the guts of the index method. Change the decorator of this method to:
@expose
def index(self):
Now we can proceed to insert the Rialto content inside the method. RialtoPython works by assembling the HTML page as a big string using python objects to generate the javascript parts. It's easy for a simple example like this but might get out of hand quickly for larger projects. I believe the python calls made within the index method could be done inside a Kid template, separating the view from the controller part as it is expected in a Turbogears application.
Here is the contents of the index Method:
@expose()Let's now go over how it works, in the beginning of the index method, the RialtoPython is instantiated and some variables are defined in order to make the following calls a little more readable.
def index(self):
rp = rialtoPython.RialtoPython()
out = []
DIV = "document.body"
LAYOUT = "ihmDemo"
WINDOW = "myWindow"
WINDOW_TITLE = "Rialto-Turbogears Integration Example"
FRAME = "boxDemo"
FORM = "myForm"
URL = "do"
# assembling the page
out.append(rp.addImport(devMode=False))
out.append('')
out.append('\trialto/I18N.setLanguage("en");\n')
#layout
out.append(rp.openLayout(LAYOUT))
#app components
out.append(rp.windowTag(WINDOW, WINDOW_TITLE, DIV))
out.append(rp.frameTag(FRAME, '30', '30', '300', '120', 'My 1st python Box', 'true', 'false', 'relative', 'false', WINDOW))
out.append(rp.formTag(FORM,URL,FRAME))
out.append(rp.labelTag('label1', '25', '10', 'Spam', FORM))
out.append(rp.textTag('login', '25', '90', '200', 'A', FORM, 'true', 'true', 'Eggs'))
out.append(rp.buttonTag('doLogon', 'Ni!', '70', '10', 'And now to something completely different', ['FORM', FORM], FORM))
out.append(rp.buttonTag('default', 'Camelot!', '70', '100', 'The television reception isnt good here anyway', ['FORM', FORM], FORM))
# close the layout Tag
out.append(rp.closeLayout(LAYOUT))
out.append(rp.init(LAYOUT))
# Completing the Html code
out.append('\n')
out.append('\n\n')
return " ".join(out)
All "rp" methods called, return strings that are stored sequentially in the "out" list and the joined into a single string which contains the complete code of the application page. The App contains a frame with a form in it containing a text lable, a text input box, and a couple of buttons, when we call the method that returns the form code, a URL is specified to handle the the data coming from the form. On Turbogears, the URLs are exposed methods of the Root class. So let us write this method:
@expose()
def do(self,login,action):
res=rialtoPython.RialtoPython()
out=[]
error_msg=[]
if action=='doLogon':
if login=="":
error_msg.append("Empty Spam")
elif login!="Eggs":
error_msg.append("Unknown Spam")
if len(error_msg)>0:
out.append(res.showAlert('myAlert', ','.join(error_msg)))
else:
out.append(res.showAlert('myAlert', 'This Spam was good!'))
elif action == 'default':
out.append(res.showAlert('myAlert', 'Are you sure, you want to go to camelot?'))
else:
out.append(res.showAlert('myAlert', 'I dont know anything about the action %s'% action))
return ''.join(out)
The method "do" shows a floating alert window in response to pressing a button in the form. The method takes two arguments: "login", which is the contents of the input text box of the same name. Action is generated by the rialto API and contains the name of the button pressed.
There is only a couple of other things left for us to do before our app is ready:
- You have to download the Rialto javascript API source distribution, and unzip it in the same directory we have our controllers.py. After you do that, you should have a "rialtoEngine" directory in it.
- Now you have to add the following code to your app.cfg in order to let Turbogears find the Rialto code:
[/rialtoEngine]Now just start your application and point your browser to http://localhost:8080 to see your first rich internet application, written entirely in Python, running.
static_filter.on=True
static_filter.dir="%(top_level_dir)s/rialtoEngine"
[/config.js]
static_filter.on=True
static_filter.file="%(top_level_dir)s/rialtoEngine/config.js"
[/javascript]
static_filter.on=True
static_filter.dir="%(top_level_dir)s/rialtoEngine/javascript"
[/rialto.js]
static_filter.on=True
static_filter.file="%(top_level_dir)s/rialtoEngine/javascript/rialto.js"
[/images]
static_filter.on=True
staticFilter.dir="%(top_level_dir)s/rialtoEngine/images"
[/style]
static_filter.on=True
static_filter.dir="%(top_level_dir)s/rialtoEngine/style"
Tips: This code may require the latest version of RialtoPython released in may 2007.