Frequently Asked Questions
| Status: | Contributed, Log in to edit |
|---|
Table of contents
General
- What is TurboGears? (Q-001)
- Is there a mailing list for TurboGears? (Q-002)
- How is TurboGears licensed? Can I use it for commercial applications? (Q-023)
- How does TurboGears compare to Ruby on Rails/Django/Pylons/etc.? Which framework should I choose for my new project? (Q-018)
- Who uses TurboGears? Can you list my TurboGears-driven app/site on your webpage? (Q-041)
- What is the current version of TurboGears? When will version 2.0 come out? (Q-042)
- Who is the author of TurboGears? Who are the people behind the project? (Q-047)
- How can I help to support the TurboGears project? (Q-043)
Documentation
- Where can I find documentation about using TurboGears? (Q-003)
- What books are available for learning TurboGears? (Q-011)
- What should I learn to become a (better) Python web application developer? Which other books should I read? (Q-017)
- Why are so many pages on the docs wiki locked down? (Q-013)
- How can I make corrections, improvements or additions to the documentation? (Q-046)
Installation
For now, there is also a separate page for Installation Troubleshooting
- When can we expect Python 2.5 support? (Q-025)
- How can I save the eggs that easy_install downloads, so I can install them to another host or location later without having to download them again? (Q-021)
- How can I install TurboGears on a Unix-like system without root user privileges? (Q-027)
Troubleshooting
- Why do I see the exception "TypeError: generate_content() takes exactly 1 argument (2 given)" whenever I access any page of my TurboGears application? (Q-004)
- Why do I see all logging messages twice when I run my application in development mode? (Q-019)
- Why does the JavaScript/CSS code of my widgets not get included in my page? (Q-026)
- Why do I get "'Stream' object has no attribute 'tag'" (Q-034)
- Why does my application work fine until it's idle for a while then the next request returns a "500 Internal Error" response? (Q-031)
- Why do my AJAX-enabled widgets stop working after some minutes? (Q-045)
Components
- Why does TurboGears still use CherryPy 2.x instead of CherryPy 3? (Q-030)
- How do I use SQLAlchemy instead of SQLObject for my project? What are the pros and cons of this exchange? (Q-014)
- Which alternative template engines can I use with TurboGears? What are the pros and cons of each? (Q-036)
- Can I use more than one database handle with TurboGears? (Q-028)
- How can I port my project from Kid & TG widgets to Genshi & ToscaWidgets? (Q-035)
- Can I use MochiKit 1.4 with TurboGears? (Q-038)
Deployment
- Do I have to copy my configuration file and/or database when I deploy my TurboGears application as an egg? (Q-037)
How do I ...?
Project structure
- How do I change the name of a project (Q-033)
- How do I divide controller.py and model.py into separate files? (Q-006)
- How can I find out the filesystem location of my application's project directory or its package directory? (Q-022)
Controller
- How can I use special (non-identifier) characters in my URLs resp. controller method names? (Q-024)
Templates
- How can I display HTML markup in my template variable without having kid escape the HTML special characters? (Q-039)
- How can I have templates in subdirectories of my project's templates directory? (Q-005)
- How to I specify an alternate template to use in my controller method? (Q-032)
Widgets
- How can set the options/attributes of a form or a form field widget? (Q-015)
- How do I pre-fill (some) fields when I display a widgets-based form? (Q-040)
- How can I re-use the definition of a form field list for another form? (Q-008)
- How can I access a method of a custom widget from its template? (Q-009)
- How do I validate two forms on the same page? (Q-020)
- How do I prevent the error message from a chained validator to show up next to all form fields? (Q-010)
- How can I write a widget which displays an image? (Q-044)
Logging
- How can I log exception tracebacks in my production server logs? (Q-016)
Miscellaneous
- How do I do full text indexing with TurboGears? (Q-012)
- How do I activate localization of TurboGears? (Q-029)
Wanted answers
- How do I add new questions to the FAQ list? (Q-007)
General
What is TurboGears?
TurboGears is a rapid development "front-to_back" web meta-framework. Its aim is to simplify and speed up the development of modern web applications written in the Python programming language.
Please see also the TurboGears homepage for a description of the project's goals.
Is there a mailing list for TurboGears?
Yes, there are in fact several of them. Please see the Getting help page for more information.
How is TurboGears licensed? Can I use it for commercial applications?
TurboGears itself is licensed under the MIT license. Its different parts may be licensed differently. Please read the details on the license page.
In general, all licenses allow commercial usage and even closed-source distribution of your application if you include a copy of the resp. license, but if in doubt, please consult your lawyer.
How does TurboGears compare to Ruby on Rails/Django/Pylons/etc.? Which framework should I choose for my new project?
This is an ever popular topic on the mailing list. See, for example, these threads:
- TurboGears vs Django (older) (2006-07-29)
- TurboGears vs JSP vs PHP vs Ruby on Rails vs Webware (2006-08-15)
- Who are the core TurboGears developers (2006-11-14)
- Sharing between TurboGears/Django/Pylons/etc. (2006-12_02)
- TurboGears vs Django (2006-12-05)
And these blog articles:
Who uses TurboGears? Can you list my TurboGears-driven app/site on your webpage?
Since TurboGears is Open Source and everybody is free to use it without having to ask, we can't really be sure. But if you have build something with TurboGears, let the world know by listing it here:
- If you have built a website, list it here: SitesUsingTurboGears
- If you have built an application which other can download and run on their sites, list it here: TurboGearsApplications
What is the current version of TurboGears? When will version 2.0 come out?
Please see the TurboGears Development Status page.
Who is the author of TurboGears? Who are the people behind the project?
Please see the TurboGears Team page.
How can I help to support the TurboGears project?
Please see the Contributing to TurboGears page.
Documentation
Where can I find documentation about using TurboGears?
There is a wiki for all documentation. Start with the TurboGears 1.0 Documentation page.
What books are available for learning TurboGears?
The "official" TurboGears book is Rapid Web Applications with TurboGears by Mark Ramm et al. The book has its own homepage at http://www.turbogearsbook.com/ and you can also visit the Amazon page for this book.
What should I learn to become a (better) Python web application developer? Which other books should I read?
Please refer to these mailing list discussions:
- What's My Learning Path?
- Suggestions for a intermediate or advanced python book
- Best advanced python text?
Why are so many pages on the docs wiki locked down?
The pages are locked down to maintain quality control over the official docs. Our previous wiki had a lot of interesting information, but it was a complete mess and you never knew whether a code snippet would work or not or whether a doc was still up to date.
We think the documents marked "Official" are pretty good, but we know we're not perfect. If you see a problem, either drop a comment or ping the mailing list. Most comments get incorporated into the docs within a day or two. If you're looking to add a new article or a significant amount of information, feel free to create a new page and link it off the wild and wooly RoughDocs page.
How can I make corrections, improvements or additions to the documentation?
Visit the Contributing Documentation page for several ways to contribute.
Installation
When can we expect Python 2.5 support?
TurboGears supports Python 2.5 as of version 1.0.2. There is a wiki page about official Python 2.5 support here.
How can I save the eggs that easy_install downloads, so I can install them to another host or location later without having to download them again?
You can use the recipe explained in this mailing list post:
TurboGears-1.0 available at WebFaction (2007-01-05)
In short, download the eggs with:
easy_install -zmaxd <somedir> TurboGears
and install them with:
easy_install -H None -f <somedir> TurboGears
where <somedir> should be the directory where you want to save the .egg files.
How can I install TurboGears on a Unix-like system without root user privileges?
An easy and quick way is to use the virtualenv program to create a separate, clean Python environment and install TurboGears in this environment. The basic steps are:
- install virtualenv with easy_install virtualenv.
- Run virtualenv <new env dir>
- source <new env dir>/bin/activate
- Download tgsetup.py and run python tgsetup.py.
- Install additional eggs, like nose, pysqlite, SQLObject, SQLAlchemy, etc. with easy_install <package name>
<new env dir> is the name of a directory that virtualenv should create. It will contain the new Python environment. Everytime you want to work with this environment, you need to carry out step 3. from above, so that the library modules and scripts from the environment are used.
See also How to Install TurboGears Without root Privileges for detailed instructions.
Troubleshooting
Why do I see the exception "TypeError: generate_content() takes exactly 1 argument (2 given)" whenever I access any page of my TurboGears application?
This is an incompatibilty between kid version 0.9.3 and 0.9.4.
Solution: delete all *.pyc files in your templates folder and subfolders and restart your application.
See also ticket #1200.
Why do I see all logging messages twice when I run my application in development mode?
This is normal. The TurboGears application server, Cherrypy 2.x, runs two processes when in development mode and it's set to autoreload. Each process outputs logging messages and that is why they appear twice. This does not happen in production mode and also doesn't happen in newer (i.e. CP3) CherryPy versions (which TurboGears does not use yet), which involved a rewrite of the reloading mechanism.
Why does the JavaScript/CSS code of my widgets not get included in my page?
Do your templates inherit from master.kid? See the mailing list post scripts in head for details.
What causes "'Stream' object has no attribute 'tag'" ?
This is most probably caused by mixing Genshi and ToscaWidgets incorrectly.
In the beginning, there was Kid and "traditional" widgets. Traditional widgets returned an ElementTree object, which the Kid engine converted into HTML. In Genshi, you can use traditional widgets, but you must use the "ET()" function to explicitly convert them to HTML. (If you get "<script element at ASDFASDF>" in your output, that is a sign that you are handing a traditional widget back to Genshi, and NOT wrapping it in ET().)
ToscaWidgets, on the other hand, return HTML natively. If you wrap a ToscaWidget reference in ET(), you will get a stack trace saying "'Stream' object has no attribute 'tag'".
Why does my application work fine until it's idle for a while then the next request returns a "500 Internal Error" response?
Are you using a MySQL database? If so, this is probably the MySQL time out. Because CherryPy is a long running process it doesn't make a new connection on every page load. After a period of inactivity the MySQL server will timeout the connection. This causes an error the next time the application attempts to use the connection.
One solution some people use is to set up a cron job that every so often wgets a page from the application that will cause a database query. There is also apparently a MySQL wait_timeout setting that can be adjusted to stop the connection from timing out.
Why do my AJAX-enabled widgets stop working after some minutes?
This might be due to the fact that you have enabled identity and the session has timed out and the AJAX-calls from your widget (e.g. loadJSONDoc) encounter a 401 ("Unauthorized") or 500 ("Internal Server Error") error.
A simple method to handle this would be to wrap the loadJSONDoc call and always add a errback callback function that catches this error:
function ljd_errhandler(result) {
if (result instanceof XMLHttpRequestError &&
(result.number == 401 || result.number == 500) {
/* handle error here, for example simply display an error message */
}
}
function do_loadjsondoc(url, cb_func) {
d = loadJSONDoc(url);
d.addCallbacks(cb_func, ljd_erhandler);
return d;
}Components
Why does TurboGears still use CherryPy 2.x instead of CherryPy 3?
When TurboGears was created, CP3 didn't exist and there where major changes between CP2 and CP3. The current plan is to introduce the breaking changes required to support CP3 in TG 1.1, if at all. This will largely depend on how many people are interested in a CP3 port at that time.
Which alternative template engines can I use with TurboGears? What are the pros and cons of each?
In principle, you can use any templating language that provides a Buffet plugin interface, either directly or through a separate template engine plugin package. Template engines, that have been successfully used with TurboGears, include Genshi, Cheetah and Jinja. For general information how to use non-standard template engines with TurboGears, see Using Alternate Templating Engines.
If you are using widgets, you need Kid to render the widgets, but you can still use a different template engine for your page templates. With ToscaWidget you can use any Buffet-compliant template engine for your widgets.
For a long mailing list thread with a discussion of different template engines and speed comparisons, see Kid vs Cheetah
How do I use SQLAlchemy instead of SQLObject for my project? What are the pros and cons of this exchange?
See the article SQLObject vs SQLAlchemy.
Can I use more than one database handle with TurboGears?
You sure can! The page MultipleDatabases explains how to do it with SQLAchemy.
How can I port my project from Kid & TG widgets to Genshi & ToscaWidgets?
See the page Migrating Your Project From TurboGears 1.0 to 1.1 for hints on this.
Can I use MochiKit 1.4 with TurboGears?
Yes, that is possible, but you have to include the new MochiKit version with your project. There are two ways to do this.
Copy the latest MochiKit.js in the static/javascript directory of your project and include it manually in master.kid or in each template that needs it with the following tag in the HTML head section:
<script src="${tg.url('/static/javascript/MochiKit.js')}" />Create a custom widget that wraps MochiKit and include it in tg_include_widgets. Here's how to do this:
Create sub-package called widgets in your project:
$ mkdir <yourproject>/widgets $ touch <yourproject>/widgets/__init__.py
Create sub-sub-package called widgets.jslibs in your project:
$ mkdir -p <yourproject>/widgets/jslibs/static/javascript $ vi <yourproject>/widgets/jslibs/__init__.py
# <yourproject>/widgets/jslibs/__init__.py __all__ = [ 'mochikit' ] import pkg_resources from turbogears.widgets import JSLink, register_static_directory js_dir = pkg_resources.resource_filename("yourproject.widgets.jslibs", "static") register_static_directory("jslibs", js_dir) mochikit = JSLink("jslibs", "javascript/MochiKit.js")- Put MochiKit.js 1.4 in yourproject/widgets/jslibs/static/javascript
Use it in your application by e.g. setting this in app.cfg:
tg.include_widgets = ['myproject.widgets.jslibs.mochikit']
Deployment
Do I have to copy my configuration file and/or database when I deploy my TurboGears application as an egg?
From TurboGears version 1.0.4b3 onwards it is easy to include a default configuration file in your application's egg file, which then will be found by the standard start script automatically. You just have to uncomment a section in your project's setup.py file, which is appropriatly commented. Older projects can be updated to use this technique by following the instructions on the Upgrade page.
While, in principle, one could also include a default database in the egg, this would only make sense for single-file databases, like those used by SQLite, but then again, one wouldn't normally want to write to files contained in an egg.
One solution is to provide a custom tg-admin command for your application, that asks the user for the database connection parameters and then initializes the database using the tg-admin sql create command followed by some custom code to fill the the dadabase with some bootstrap data.
How do I ...?
Project structure
How do I divide controller.py and model.py into separate files?
Please see this mailing list post:
How use tgbig to break controllers.py into multiple files (2007-01-17)
How can I find out the filesystem location of my application's project directory or its package directory?
Use the pkg_resources module which comes with setuptools
For example, You can get the full path to the templates directory inside the wiki20 package by:
from pkg_resources import resource_filename
resource_filename('wiki20', 'templates')You can then easily move up an down in the filesystem by using the functions form the standard os.path module.
Please bear in mind, when you have installed your application as an egg, there is no "project directory" per se, in fact, the files of your application may not even reside directly in the filesystem but in a ZIP archive. You can build an egg that contains additiional data file alongside your application's package directory. See the setuptools documentation for more information.
Controller
How can I use special (non-identifier) characters in my URLs resp. controller method names?
You can't because method names have to conform to the rules for Python identifiers. But you can work around this by handling URL dispatching yourself in an exposed default method of your controller, ex: setattr(class, irregular, method) to effectively alias the page.
See post irregular controller names for details.
How do I change the name of a project?
To change the name of a project called "foo" created by tg-admin quickstart, you have to manually go through all the files of the project and replace all occurences of "foo" with "matrix", where "matrix" is the new name of the project. If you are under Linux/Mac, you can automate this tedious work with this shell snippet:
find . -name "*" | \
while read f; do
sed -e 's#foo#matrix#g' < "$f" > /tmp/x
mv /tmp/x "$f"
doneTemplates
How can I display HTML markup in my template variable without having kid escape the HTML special characters?
Use ${XML(mytemplatevar)} or refactor by defining and using a kid template function, for example:
<a py:def="link(url, text)" href='${url}'>${text}</a>Then in your template you use:
${link('http://foo.com/', 'Foo.com')}Which will render to this output:
<a href='http://foo.com/'>Foo.com</a>
How can I have templates in subdirectories of my project's templates directory?
Short answer: Just put an empty file named __init__.py in the subdirectory.
Long answer: templates are looked up by the template engines via the normal Python module package mechanisms and the templates directory is therefore a Python package. Subdirectories have to be sub-packages as well and you can achieve that by placing an __init__.py file in them. The __init__.py can contain Python code, but an empty file will do just as well.
How to I specify an alternate template to use in my controller method?
Put tg_template set to the name of the template you want to use into the dictionary you return from your controller method, e.g.:
@expose('.templates.index')
def index(self, **kw):
d = dict(message='Hello World!')
if some_condition:
d['tg_template'] = '.templates.other'
return dWidgets
How can set the attributes of a form or a form field widget?
Please refer to the "Tips" section on the Widgets Tips & Tricks page.
How do I pre-fill (some) fields when I display a widgets-based form?
You provide a dictionary to the value parameter when you display the widget in the template. The dictionary must contain the the field names as keys and their preset value as values. You pass both the widget form object and the values dictionary to the template from your controller method.
Example:
# widgets.py
myform = TableForm(
fields = [
widgets.TextField('name'),
widgets.TextField('email')
)# controllers.py
from widgets import myform
class MyController(controllers.controller):
...
@expose('.templates.form_template')
def showform(sefl, **kw):
form_values = dict(
name = "Joe Doe",
email = "joe@doe.com"
)
return dict(form=myform, form_values=form_values)<!-- form_template.kid -->
...
${form(value=form_values)}
...How can I access a method of a custom widget from its template?
Please see this mailing list post:
Adding custom method to a custom widget (2007-01-27)
How can I re-use the definition of a form field list for another form?
Please see this mailing list post:
how to reuse form definition (2007-01-29)
How do I prevent the error message from a chained validator to show up next to all form fields?
Please see this mailing list post:
custom validator help (2007-01-26)
How do I validate two forms on the same page?
Just set the action attribute of each form to a different value making them submit to two different controller methods.
You can then use a @validate decorator with a different form argument on each method.
How can I write a widget which displays an image?
That's easy. Just include an image tag in the template of the widget:
class ImageWidget(widgets.Widget):
template = '<img xmlns:py="http://purl.org/kid/ns#" src="${value}" />'and provide the image URL when you display the widget:
${myimagewidget(tg.url('myimage.png'))}If you want to serve a dynamically generated image, you have to provide a controller method for this, and use the URL to this controller method as the value for the widget.
Logging
How can I log exception tracebacks in my production server logs?
Please see this mailing list post:
How to get python tracebacks into production log (2007-01-14)
Miscellaneous
How do I do full text indexing with TurboGears?
Krys Wilken has released TurboLucene, which makes it easy to use Lucene based searches within TurboGears. You can find our more at: http://dev.krys.ca/turbolucene/
Alternatively, Nadav Samet explains how to do full text indexing with Xapian on his blog:
http://www.thesamet.com/blog/2007/02/04/pumping-up-your-applications-with-xapian-full-text-search/
How do I activate localization for my TurboGears project?
Keywords: i18n, l10n
If you want to activate localization for your project, you need to do the following. This will copy the localized strings of TurboGears into your project. These steps are necessary if you want get TurboGears's built-in texts translated, even if you have not localized your part of the project.:
tg-admin i18n collect tg-admin i18n add <locale> tg-admin i18n compile
TurboGears does support localized validation error messages from FormEncode since 1.0.2 (ticket 1136). Please note that you need at least FormEncode 0.7 for localized validation error messages.
Wanted answers
How do I add new questions to the FAQ list?
Please add requests for new questions and answers to be added to the FAQ list to the list below. You can edit this page by clicking on the "Edit" link at the bottom of the page.
If you want to add a new question with an answer, please add it directly to the appropriate section (or create a new section, if necessary). Please give a unique number to your question and format the actual question in bold and the answer as normal paragraphs. You should also put an internal hyperlink target before the question, to allow direct links to it from the table of contents and elsewhere. See the source code of this page for examples of how this is done.
Please refer to the DocHelp page for additional style guidelines.
Answers wanted to the following questions:
Does TurboGears support migrations?
Does TurboGears let me subclass/inherit from my models?
Where does code belong, in model, view or controller?
E.g., if importing XML from an external web site, does the xml processing functions belong in the model?
Should the formatting of the data take place in the controller or should there be a model function?