Mercurial > genshi > genshi-test
changeset 110:44fbc30d78cd
update the example TurboGears app and include an example of using TurboGears wigets
author | mgood |
---|---|
date | Fri, 28 Jul 2006 18:57:55 +0000 |
parents | 2de3f9d84a1c |
children | 8a4d9064f363 |
files | examples/turbogears/README.txt examples/turbogears/dev.cfg examples/turbogears/markuptest/config/app.cfg examples/turbogears/markuptest/controllers.py examples/turbogears/markuptest/model.py examples/turbogears/markuptest/release.py examples/turbogears/markuptest/templates/master.html examples/turbogears/markuptest/templates/sitetemplate.html examples/turbogears/markuptest/templates/welcome.html examples/turbogears/sample-prod.cfg examples/turbogears/setup.py examples/turbogears/start-markuptest.py |
diffstat | 12 files changed, 269 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
--- a/examples/turbogears/README.txt +++ b/examples/turbogears/README.txt @@ -1,4 +1,4 @@ MarkupTest This is a TurboGears (http://www.turbogears.org) project. It can be -started by running the start-markuptest.py script. \ No newline at end of file +started by running the start-markuptest.py script.
--- a/examples/turbogears/dev.cfg +++ b/examples/turbogears/dev.cfg @@ -24,7 +24,6 @@ # for Windows users, sqlite URIs look like: # sqlobject.dburi="sqlite:///drive_letter:/path/to/file" - # SERVER # Some server parameters that you may want to tweak
--- a/examples/turbogears/markuptest/config/app.cfg +++ b/examples/turbogears/markuptest/config/app.cfg @@ -10,10 +10,7 @@ # which view (template engine) to use if one is not specified in the # template name -# tg.defaultview = "kid" tg.defaultview = "markup" -markup.search_path = ["%(current_dir_uri)s"] -markup.outputformat = "xml" # The following kid settings determine the settings used by the kid serializer. @@ -29,12 +26,92 @@ # Allow every exposed function to be called as json, # tg.allow_json = False -# Set to True if you'd like all of your pages to include MochiKit -# tg.mochikit_all = False +# List of Widgets to include on every page. +# for exemple ['turbogears.mochikit'] +# tg.include_widgets = [] # Set to True if the scheduler should be started # tg.scheduler = False +# VISIT TRACKING +# Each visit to your application will be assigned a unique visit ID tracked via +# a cookie sent to the visitor's browser. +# -------------- + +# Enable Visit tracking +visit.on=True + +# Number of minutes a visit may be idle before it expires. +# visit.timeout=20 + +# The name of the cookie to transmit to the visitor's browser. +# visit.cookie.name="tg-visit" + +# Domain name to specify when setting the cookie (must begin with . according to +# RFC 2109). The default (None) should work for most cases and will default to +# the machine to which the request was made. NOTE: localhost is NEVER a valid +# value and will NOT WORK. +# visit.cookie.domain=None + +# Specific path for the cookie +# visit.cookie.path="/" + +# The name of the VisitManager plugin to use for visitor tracking. +visit.manager="sqlobject" + +# Database class to use for visit tracking +visit.soprovider.model = "markuptest.model.Visit" + +# IDENTITY +# General configuration of the TurboGears Identity management module +# -------- + +# Switch to turn on or off the Identity management module +identity.on=True + +# [REQUIRED] URL to which CherryPy will internally redirect when an access +# control check fails. If Identity management is turned on, a value for this +# option must be specified. +identity.failure_url="/login" + +# identity.provider='sqlobject' + +# The names of the fields on the login form containing the visitor's user ID +# and password. In addition, the submit button is specified simply so its +# existence may be stripped out prior to passing the form data to the target +# controller. +# identity.form.user_name="user_name" +# identity.form.password="password" +# identity.form.submit="login" + +# What sources should the identity provider consider when determining the +# identity associated with a request? Comma separated list of identity sources. +# Valid sources: form, visit, http_auth +# identity.source="form,http_auth,visit" + +# SqlObjectIdentityProvider +# Configuration options for the default IdentityProvider +# ------------------------- + +# The classes you wish to use for your Identity model. Remember to not use reserved +# SQL keywords for class names (at least unless you specify a different table +# name using sqlmeta). +identity.soprovider.model.user="markuptest.model.User" +identity.soprovider.model.group="markuptest.model.Group" +identity.soprovider.model.permission="markuptest.model.Permission" + +# The password encryption algorithm used when comparing passwords against what's +# stored in the database. Valid values are 'md5' or 'sha1'. If you do not +# specify an encryption algorithm, passwords are expected to be clear text. +# +# The SqlObjectProvider *will* encrypt passwords supplied as part of your login +# form. If you set the password through the password property, like: +# my_user.password = 'secret' +# the password will be encrypted in the database, provided identity is up and +# running, or you have loaded the configuration specifying what encryption to +# use (in situations where identity may not yet be running, like tests). + +# identity.soprovider.encryption_algorithm=None [/static] static_filter.on = True static_filter.dir = "%(top_level_dir)s/static"
--- a/examples/turbogears/markuptest/controllers.py +++ b/examples/turbogears/markuptest/controllers.py @@ -3,7 +3,8 @@ import cherrypy import turbogears -from turbogears import controllers, expose, validate, redirect +from turbogears import controllers, expose, validate, redirect, widgets +from turbogears import identity from markuptest import json @@ -14,4 +15,40 @@ def index(self): import time log.debug("Happy TurboGears Controller Responding For Duty") - return dict(now=time.ctime()) + return dict(now=time.ctime(), + widget=widgets.TextArea(name="widget_test", + default="This is a test of using " + "TurboGears widgets with " + "Markup", + rows=5, cols=40)) + + + @expose(template="markuptest.templates.login") + def login(self, forward_url=None, previous_url=None, *args, **kw): + + if not identity.current.anonymous \ + and identity.was_login_attempted() \ + and not identity.get_identity_errors(): + raise redirect(forward_url) + + forward_url=None + previous_url= cherrypy.request.path + + if identity.was_login_attempted(): + msg=_("The credentials you supplied were not correct or " + "did not grant access to this resource.") + elif identity.get_identity_errors(): + msg=_("You must provide your credentials before accessing " + "this resource.") + else: + msg=_("Please log in.") + forward_url= cherrypy.request.headers.get("Referer", "/") + cherrypy.response.status=403 + return dict(message=msg, previous_url=previous_url, logging_in=True, + original_parameters=cherrypy.request.params, + forward_url=forward_url) + + @expose() + def logout(self): + identity.current.logout() + raise redirect("/")
--- a/examples/turbogears/markuptest/model.py +++ b/examples/turbogears/markuptest/model.py @@ -1,1 +1,109 @@ +from datetime import datetime +from sqlobject import * + +from turbogears import identity +from turbogears.database import PackageHub + +hub = PackageHub("markuptest") +__connection__ = hub + +# class YourDataClass(SQLObject): +# pass + +class Visit(SQLObject): + class sqlmeta: + table="visit" + + visit_key= StringCol( length=40, alternateID=True, + alternateMethodName="by_visit_key" ) + created= DateTimeCol( default=datetime.now ) + expiry= DateTimeCol() + + def lookup_visit( cls, visit_key ): + try: + return cls.by_visit_key( visit_key ) + except SQLObjectNotFound: + return None + lookup_visit= classmethod(lookup_visit) + +class VisitIdentity(SQLObject): + visit_key = StringCol(length=40, alternateID=True, + alternateMethodName="by_visit_key") + user_id = IntCol() + + +class Group(SQLObject): + """ + An ultra-simple group definition. + """ + + # names like "Group", "Order" and "User" are reserved words in SQL + # so we set the name to something safe for SQL + class sqlmeta: + table="tg_group" + + group_name = UnicodeCol(length=16, alternateID=True, + alternateMethodName="by_group_name") + display_name = UnicodeCol(length=255) + created = DateTimeCol(default=datetime.now) + + # collection of all users belonging to this group + users = RelatedJoin("User", intermediateTable="user_group", + joinColumn="group_id", otherColumn="user_id") + + # collection of all permissions for this group + permissions = RelatedJoin("Permission", joinColumn="group_id", + intermediateTable="group_permission", + otherColumn="permission_id") + + +class User(SQLObject): + """ + Reasonably basic User definition. Probably would want additional attributes. + """ + # names like "Group", "Order" and "User" are reserved words in SQL + # so we set the name to something safe for SQL + class sqlmeta: + table="tg_user" + + user_name = UnicodeCol(length=16, alternateID=True, + alternateMethodName="by_user_name") + email_address = UnicodeCol(length=255, alternateID=True, + alternateMethodName="by_email_address") + display_name = UnicodeCol(length=255) + password = UnicodeCol(length=40) + created = DateTimeCol(default=datetime.now) + + # groups this user belongs to + groups = RelatedJoin("Group", intermediateTable="user_group", + joinColumn="user_id", otherColumn="group_id") + + def _get_permissions(self): + perms = set() + for g in self.groups: + perms = perms | set(g.permissions) + return perms + + def _set_password(self, cleartext_password): + "Runs cleartext_password through the hash algorithm before saving." + hash = identity.encrypt_password(cleartext_password) + self._SO_set_password(hash) + + def set_password_raw(self, password): + "Saves the password as-is to the database." + self._SO_set_password(password) + + + +class Permission(SQLObject): + permission_name = UnicodeCol(length=16, alternateID=True, + alternateMethodName="by_permission_name") + description = UnicodeCol(length=255) + + groups = RelatedJoin("Group", + intermediateTable="group_permission", + joinColumn="permission_id", + otherColumn="group_id") + +
--- a/examples/turbogears/markuptest/release.py +++ b/examples/turbogears/markuptest/release.py @@ -3,6 +3,7 @@ version = "1.0" # description = "Your plan to rule the world" +# long_description = "More description about your plan" # author = "Your Name Here" # email = "YourEmail@YourDomain" # copyright = "Vintage 2006 - a good year indeed"
--- a/examples/turbogears/markuptest/templates/master.html +++ b/examples/turbogears/markuptest/templates/master.html @@ -1,13 +1,15 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://markup.edgewall.org/" xmlns:xi="http://www.w3.org/2001/XInclude" py:strip=""> + <xi:include href="sitetemplate.html"><xi:fallback/></xi:include> <head py:match="head" py:attrs="select('@*')"> <meta content="text/html; charset=UTF-8" http-equiv="content-type" py:replace="''"/> <title py:replace="''">Your title goes here</title> - ${select('*')} + <meta py:replace="select('*')"/> <style type="text/css"> #pageLogin { @@ -19,12 +21,13 @@ </head> <body py:match="body" py:attrs="select('@*')"> - <div py:if="tg.config('identity.on', False) and not logging_in" - id="pageLogin"> - <span py:if="tg.identity.anonymous"> + <div py:if="tg.config('identity.on',False) and not logging_in" + id="pageLogin" + py:choose=""> + <span py:when="tg.identity.anonymous"> <a href="/login">Login</a> </span> - <span py:if="not tg.identity.anonymous"> + <span py:otherwise=""> Welcome ${tg.identity.user.display_name}. <a href="/logout">Logout</a> </span> @@ -32,7 +35,7 @@ <div py:if="tg_flash" class="flash" py:content="tg_flash"></div> - ${select('*')} + <div py:replace="select('*')"/> <p align="center"><img src="/static/images/tg_under_the_hood.png" alt="TurboGears under the hood"/></p> </body>
new file mode 100644 --- /dev/null +++ b/examples/turbogears/markuptest/templates/sitetemplate.html @@ -0,0 +1,18 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:py="http://markup.edgewall.org/" + xmlns:xi="http://www.w3.org/2001/XInclude" + py:strip=""> +<head py:match="head" py:attrs="select('@*')"> + <meta content="text/html; charset=UTF-8" http-equiv="content-type" py:replace="''"/> + <title py:replace="''">Your title goes here</title> + <link py:for="css in tg_css" py:replace="ET(css.display())" /> + <link py:for="js in tg_js_head" py:replace="ET(js.display())" /> + ${select('*')} +</head> +<body py:match="body" py:attrs="select('@*')"> + <div py:for="js in tg_js_bodytop" py:replace="ET(js.display())" /> + ${select('*')} + <div py:for="js in tg_js_bodybottom" py:replace="ET(js.display())" /> +</body> +</html>
--- a/examples/turbogears/markuptest/templates/welcome.html +++ b/examples/turbogears/markuptest/templates/welcome.html @@ -9,7 +9,7 @@ <title>Welcome to TurboGears</title> </head> -<body id="welcome"> +<body> <p>Congratulations, your TurboGears application is running as of <span py:replace="now">now</span>.</p> <h2>Are you ready to Gear Up?</h2> @@ -31,5 +31,7 @@ <p>Thanks for using TurboGears! See you on the <a href="http://groups.google.com/group/turbogears" >mailing list</a> and the "turbogears" channel on irc.freenode.org!</p> + ${ET(widget.display())} + </body> </html>
--- a/examples/turbogears/sample-prod.cfg +++ b/examples/turbogears/sample-prod.cfg @@ -6,20 +6,23 @@ # (such as template engine, encodings, etc.) all go in # markuptest/config/app.cfg -# DATABASE - # pick the form for your database # sqlobject.dburi="postgres://username@hostname/databasename" # sqlobject.dburi="mysql://username:password@hostname:port/databasename" # sqlobject.dburi="sqlite:///file_name_and_path" +# If you have sqlite, here's a simple default to get you started +# in development +sqlobject.dburi="sqlite://%(current_dir_uri)s/devdata.sqlite" + + # if you are using a database or table type without transactions # (MySQL default, for example), you should turn off transactions # by prepending notrans_ on the uri # sqlobject.dburi="notrans_mysql://username:password@hostname:port/databasename" # for Windows users, sqlite URIs look like: -# sqlobject.dburi="sqlite:///drive_letter|/path/to/file" +# sqlobject.dburi="sqlite:///drive_letter:/path/to/file" # SERVER