What is TurboGears not?

Standard

In product management, the things you choose not to do are at least as important as the things you choose to do. Though it might seem like adding features is always a good thing, there are actually tradeoffs being made with each feature added. Consider my cell phone (a Nokia Series 60): this thing can do many different things. It keeps my contacts, has games, takes pictures and can wake me up via its alarm clock. Because it has so many features, I have to do *a lot* of clicking around to set an alarm on the alarm clock. If the phone had fewer features, the user experience could be optimized better for setting alarms.

In an open source project, having an idea of what your product truly is becomes critical. Many people will have patches or apparently complementary projects that are ready and free for the taking. But, should you take them?

Numerous times along the way, people have asked about using “template package X” or “database thingy Y” with TurboGears. There have been thoughts of making TurboGears abstract away some of the underlying pieces so that they can be swapped out. (My responses have been that TurboGears shouldn’t stand in the way of using those other packages, but TurboGears itself will not directly support them.)

If what you want is to pick and choose every piece of the application stack, then the web framework you want is CherryPy or, I guess, one of the other controller frameworks. If one tried to support everything in order to become the web framework “to rule them all”, you’d eventually end up with just Python (or some hideous layer on top of Python) and the current collection of fine components available for Python.

TurboGears is not going to go that route. Here are the overarching thoughts that go in to TurboGears’ evolution:

  1. best-of-breed
  2. one way to do it

I want to start with and maintain use of the “best-of-breed” components for each part of the stack. If you use great quality ingredients, you’ll get a great tasting cake.

Of course, “best” is in the eye of the beholder. Often, two components may be equally capable, but have a different feel. That’s when you get into a more subjective area which makes the second rule that much more important: rather than punting when faced with two nearly equal choices, pick one and run with it.

I can’t overstate the importance of TurboGears providing “one obvious way to do it” (at least when it comes to the big picture items). Let’s say that TurboGears specifically supported several templating packages (and there are certainly several to choose from in Python). The documentation would balloon, because it would have to cover both. The users would somehow have to have a basis for choice and the mailing list will get frequent questions of “which one should I use?”. Email traffic related to template issues would likely double. Features like internationalization would need to account for both. And, the path to adding more features that integrate multiple components would be a lot less clear. The new TurboGears widgets package uses Kid to power the appearance of the widgets. The Toolbox makes full use of all of TurboGears’ components.

Am I saying it’s always wrong to provide a choice? No. But, if there is going to be a choice, there has to be a good reason for it. If it’s a specific use case that one tool handles tremendously better than another, document that use case and encourage people to use the right tool for the job. If it’s a case where one component is far better overall, but is just missing a feature that another has, maybe it’s better to try to build that feature into the component of choice.

Wouldn’t some people be turned away if you don’t support the exact component they want to use? Sure. But, expending the effort to support that rather than truly enhancing the user experience will cost far more users than simply not supporting one group’s preference. An example of this is alternative database technologies. Python has quite a few interesting non-relational databases available. There are certainly applications for which those databases make life easier. And, you can even use those technologies with TurboGears, just without special tool support. But, for the vast majority of people writing web applications today, relational databases are the primary storage option and which means that providing optimum support for relational databases is key. Providing support in TurboGears for non-relational databases would muddy the waters considerably. (Would CatWalk have to support those other tools? How about the tg-admin command line tool?) You could end up with half-baked support for a whole bunch of things rather than robust support for the “best-of-breed” toolset.

Note that I’m not saying that TurboGears won’t have plugin support to allow people to mix in other components. The balance being struck here is that TurboGears provides a distinct way to get things done. If you agree in general with the TurboGears approach, but have some specific unusual needs you want to meet, TurboGears should at least try provide a reasonable way to meet those needs while you use the rest of the framework. The “reasonable way” to meet those other needs cannot conflict with the primary tools being used, however.

One more point about when to say “no”: Good ideas come along all the time. At some point, you’ve just gotta ship it. Particularly with software, “good enough” today is worth a lot more than “perfect” at some distant point in the future. 1.0 is not the end, but just the beginning.

TurboGears as envisioned and implemented can meet a wide variety of web app needs in a way that many people find fun to use. It’s impossible to make a framework that makes everyone happy, and to try would mean creating a framework that ultimately makes no one truly happy.

7 thoughts on “What is TurboGears not?

  1. Concerning ‘best of breed’ frameworks, I understand from a few blog postings (i.e. I’m just jumping in randomly here) that the TurboGears community is involved in building a widget and form framework. We in the Zope community have been doing this for many years, and we have many different frameworks available right now, hopefully slowly evolving towards a single Zope 3-based framework in the future. I have the feeling that some of the experience and code we have could be valuable to you.

    Instead of reinventing the widget wheel again, perhaps we can work together on some of this? Of course that would mean your widgets wouldn’t be using kid and ours wouldn’t be using ZPT (they typically aren’t anyway), but if we can create a bigger pool of reusable widgets that sounds good to me.

  2. I’m a little surprised to hear Kid regarded as a “Best of Breed” templating component when development on it had all but ceased prior to TurboGears, and it was originally designed for web services, rather than web pages. I would consider Kid the best of breed if we further narrow the definition of “breed” down to template attribute style languages.

    The performance of it is also rather problematic (http://trac.turbogears.org/turbogears/ticket/28), as with even a moderate amount of markup it becomes as slow as Plone. I’m sure this will likely be remedied eventually, but I’ve already seen some people skip TurboGears entirely due to its abysmal templating performance (and lack of sophisticated caching).

    Of course, even with its speed up to par, the features it has are lacking considerably in the face of Cheetah or Myghty. It’s not just about adding one or two missing features, its missing a ton of great features that both these other template languages have thanks to years of use by demanding users. (While Myghty hasn’t been around years, its benefitted from the experience gained using its Perl ancestor, Mason)

    On the other fronts, ORM, controller, etc. I think you’ve done a great job picking obvious best of breed components. SQLObject is without a doubt the largest and best-of-breed ORM on Python, and CherryPy is obviously out front for its part.

    Out of curiosity, if someone comes along and starts showing how much more speed and power you get from TurboGears thanks to a more full featured “best of breed” template language, would you ever consider switching TurboGears to it? ;)

  3. Martijn: there were a couple of things that I wanted out of TurboGears’ widgets that I didn’t see in the other tools available: the ability to have a form dynamically generated *or* statically generated for full hacking by a designer (usually you get one or the other), and the ability to describe what a widget looks like using Kid. I would’ve preferred to use an existing solution, and Z3’s solution is nice in its own way, but I couldn’t find one that let me do these things.

    Ben: Without a doubt, different people will have different opinions of which tool is the “best of breed”. I think Kid is the best language for generating HTML pages, and that is the #1 thing that templates do in webapps. It provides *many* different ways to compose templates from different parts, and I haven’t particularly been missing any features from Cheetah (which I’ve used heavily).

    Rather than prematurely optimizing by choosing a template language that I do not think is as good, I started with Kid with the knowledge that Python provides a great many ways to improve performance and that we’ll be able to do so.

    I should also note that even if there are people turned away because they don’t like Kid, there are many others who *do* like Kid quite a bit and have said so on the list.

    All of that said, there’s no smiley needed on your last point. It is indeed my intention to maintain TurboGears with best-of-breed components. If I become convinced that a component is not the best and that its deficiencies will not be taken care of readily, I would start working out a migration strategy. That’s what I meant by “maintain use of” the best of breed.

  4. You don’t get off reinventing the widget wheel that easily with me. :)

    “””
    the ability to have a form dynamically generated or statically generated for full hacking by a designer (usually you get one or the other),
    “””

    I’m not sure what you mean by ‘statically generated’. If you mean giving the designer the ability to render the widgets in the place they want, both the venerable Formulator which I wrote in 2000 as well as the new Zope 3 form system can do that just fine (see the hint: we’ve been doing this for a while in the Zope community). If you want to be able to hack actual widget HTML from within the form, I am curious to hear what your use case is; please let me know.

    The ability to use Kid is a more serious objection, but can also be interpreted as a typical Not Invented Here response.I don’t find the use case of having to use a template language for widgets very convincing. For the scope of the HTML generated by the typical widget, generating HTML from Python with a few helper functions is sufficient, and a templating system may be overkill. Perhaps you can expand your argument here.

    If you can gain a common pool of widgets shared between frameworks from the concession of not using your templating system where it may not be such a boon anyway, that might be very worthwhile to you, as you’d have a much greater community of widgets users. I thought this was the philosophy of TurboGears — don’t reinvent the wheel but profit from the code, experience and community of existing projects. I’m willing to spend some time trying to extract the Zope 3 widgets machinery so it can be used standalone if you’re interested in at least considering it.

  5. Sebastian Ware

    Hi Kevin!

    You are absolutely right in these key issues. By focusing on a singel stack that really works, you reduce the learning curve and improve productivity. You also improve maintainability of the framework, thus protecting the investment of the user community. Anybody who wants a custom tailored solution can roll their own and invest the resources neccessary.

    My choice to create a prototype with TurboGears over Zope3, Django, Twisted etc. was:

    1 Well defined framework and vision
    2 Key technologies (MVC and SQLobject)
    3 Up and running in half an hour
    4 The promise of AJAX

    TurboGears will hopefully be living happily side-by-side with some Zope applications.

    Moreover I am very excited about your concept of widgets. It will be fun to see how they will work with SQLobject.

    What I am hoping in the medium term is that it will be possible to migrate FileMaker Pro solutions to TurboGears with considerable ease, retaining the benefits of maintainability of FM PRO, whilst adding extensibilty that just isn’t possible with FM PRO. This would free a lot of resources and agony!

    Keep up the excellent, focused, work!

  6. I’m fine being on the hook for making an effort to reuse existing projects. You’re right that that’s an important part of the philosophy. I’ll also agree that the principle of a widget library that we can all share is a good one.

    My concern would be that I want it to be very easy to create widgets and wouldn’t want to sacrifice that too much for the sake of cross-framework sharing.

    I’m expecting to see quite a few AJAXian and JavaScriptified (to use two crazy buzzwordish things) widgets. Some widgets already have considerably more markup than I’d want to do via string concatenation (though something like STAN could be reasonable). Look at TableForm for an example:

    http://www.turbogears.org/svn/turbogears/trunk/turbogears/widgets/forms.py

    By the way, TurboGears widgets/forms include the validation/conversion that’s necessary to go to/from Python (using the FormEncode package), and provide easy mechanisms for including JavaScript and CSS. Unless I continue to get sidetracked today, I should get two new screencasts up that talk in more detail about how forms work.

    Once I’ve done that, it would be interesting to talk more about Zope 3’s widgets and how they compare. The turbogears.widgets stuff is definitely experimental, so I’m open to better ways of working, if they exist…

Comments are closed.