Warning: Can't synchronize with repository "(default)" (Unsupported version control system "svn": No module named svn). Look in the Trac log for more information.

Ticket #1655 (closed defect: migrated)

Opened 11 years ago

Last modified 8 years ago

Create some kind of "component" architecture for TG2

Reported by: mramm Owned by: plewis
Priority: normal Milestone: 2.2
Component: TurboGears Version: trunk
Severity: normal Keywords:
Cc: lmacken


Django has mini apps inside of a "project" so your website could be made up of a blog-app, a wiki app, a forum app, etc. And it has some helpers to make this nice, automtic discovery of models, etc.

Basically this is implemented as apps directories inside your django project, which you configure URL's to and they dispatch from there. Apps contain controllers, templates, and models. User modification of the apps is then easy because they are just code in your project. But syncing up to a newer version of the blog-app is difficult.

In TG2 this could be accomplished by creating a components directory, putting components in there, and having the init on the controller of a component will register the models in the app (and can take setup parameters). So if you mount a blog component in 4 different places it can be configured 4 different ways by passing in different defaults when you instantiate the component's root controller object...

Change History

comment:1 Changed 11 years ago by mramm

At CodeMash? there was quite a bit of discussion on this topic:

Django user contributed apps are one of the main reasons people use django (another is the django admin).

TurboGears has most of the infrastructure to make this as easy as it is in django, but there have been some reservations about doing it, and we definitely have not created project and social structures to encourage the development of reusable application components.

One thing people have been concerned about is copying these components into the project directory. This is definitely the easy way to do it, and it is the way Django works. But there are potential issues because your project becomes totally divorced from upstream fixes to the app...

We could do some kind of 3-way-merge thing to help this out. Either using code from mercurial, or mercurial itself.

comment:2 Changed 11 years ago by khorn

The "obvious" way to accomplish something like this, to me, would be to leverage setuptools (which is likely installed on most machines running TG anyway).

Couldn't we establish a "tg2app" entry point, and then have a loadTGApp() function.

So you would ideally have something like:


blog = loadTGApp('blog_app') wiki = loadTGApp('wiki_app')

the loadTGApp() function (or class or whatever) would search the setuptools entrypoint for apps registering that name, and then load them.

I'm sure it sounds easier than it will end up being, but I think this would be a nice way to handle the "multiple app" problem.

Also, in your "main" app, you could just require the 'blog_app', 'wiki_app', etc. packages and let setuptools get the latest ones for you.

comment:3 Changed 11 years ago by mramm

  • Milestone changed from 2.0 to 2.0-preview-2

comment:4 Changed 11 years ago by mramm

  • Milestone changed from 2.0-preview-2 to 2.0

comment:5 Changed 11 years ago by plewis

  • Status changed from new to assigned
  • Owner changed from anonymous to plewis

comment:7 Changed 11 years ago by mramm

  • Milestone changed from 2.0 to 2.0-preview-2

We should evaluate silverplate as a potential start on this problem.

Also, we should break this down into some smaller steps if possible.

comment:8 Changed 11 years ago by mramm

  • Milestone changed from 2.0-preview-2 to 2.0

comment:9 Changed 10 years ago by jorge.vargas

I totally agree with the "load TG app" approach. I think the "django way" of having a "installed apps" config variable is the way to go, then handle everything else to setuptools.

comment:10 Changed 10 years ago by jorge.vargas

  • Milestone changed from 2.0 to 2.1

as per today's discussion this has been set as a 2.1 goal.

comment:11 Changed 10 years ago by lmacken

  • Cc lmacken added

comment:12 Changed 10 years ago by lszyba1

So how will tg-registration look in this scenario...what tg-registration did was to put its code under one of the folders. User then changed configuration files and we were ready to go. Rum has a nice entry points, where you load the app, add one configuration file and it takes over the master template look. I think the biggest problem for me at this point is how to create an application that can be loaded by another tgapp? I think simple tutorial on how to create tg2 app that can be called by another tg2app,and get its master template, db connection, authentication. Thanks, Lucas

comment:13 Changed 10 years ago by jorge.vargas

@Lucas, the case of tg.registration will probably be fixed in a similar way as how tgext.admin/catwalk2 work. it will piggyback on your master.html and simply provide a controller you can mount.

I think the real blocker here is when a component demands config values and/or db storage/access, because we'll have to develop some tool to handle this.

comment:14 Changed 10 years ago by jorge.vargas

  • Summary changed from Create some kind of "component" archetecture for TG2 to Create some kind of "component" architecture for TG2


comment:15 Changed 10 years ago by jorge.vargas

Adding two more items to the laundry list.

  • How to handle multiple tables/objects form different components
  • How to handle multiple BaseControllers?
  • How to handle "merged controllers" aka mount two app at the same component.

comment:16 follow-up: ↓ 17 Changed 10 years ago by sevenseeker

I currently am using zope.interface and find it quite nice. I also rolled my own very similar interface that looked also like the Trac plugin architecture.

Right now, I am doing everything through interfaces but will be switching to using Abstract Base Classes as soon as I have time :)

This is because of my late and lazy binding which are not liked by pickle and thus multiprocessing. ABC has features to allow this type of binding.

I have toyed with with using entry points as well.

All in all, I like zope.interface the best since it is out of the box and I frankly was surprised I would like it at all. :)

Due to each having their place (strengths and weaknesses) perhaps instead of discussing implementation at this point, we should discuss the reasons for wanting a modular system and what the goals are. After all, the golden question is as usual, "What exactly are you trying to do?"

comment:17 in reply to: ↑ 16 Changed 10 years ago by jorge.vargas

Replying to sevenseeker:

This goes a lot better if discussed in the ML, also see #2275

comment:18 Changed 9 years ago by mramm

  • Milestone changed from 2.1 to 2.2

comment:19 Changed 8 years ago by pedersen

  • Status changed from assigned to closed
  • Resolution set to migrated
Note: See TracTickets for help on using tickets.