First impressions with Kotti
The boss is away this week, so I'm learning about Kotti. Here's how I solved the problem of limiting a content type to the root of the site.
My application is very simple. There are two content types; Forum and Idea. A forum is added to the root of the site, and then ideas are added to the forum.
I was already familiar with kotti's documentation and the tutorial there, so getting the basic application running was very easy.
First, I set up a virtualenv, and installed kotti along with a skeleton for my package.
$ virtualenv --no-site-packages kotti_agora-27 $ cd kotti_agora-27/ $ ./bin/pip install -r https://raw.github.com/Kotti/Kotti/master/requirements.txt $ wget https://raw.github.com/Kotti/Kotti/master/app.ini $ ./bin/pip install kotti_paster $ ./bin/paster create -t kotti_addon kotti_agora $ cd kotti_agora/ $ ../bin/python setup.py develop
The pip install step takes a little while.
From there, I was able to add code to kotti_agora, including my two content types, their views, and some kotti plumbing to wire it all up. For the most part, I stole everything from the kotti tutorial mentioned above and from the source code for kotti_blog.
Limiting Ideas to a Forum
The first problem I had to solve was limiting ideas to a forum. Kotti has an addable_to attribute when creating content types. I set the addable_to attribute of Idea to Forum.
class Idea(Content): id = Column(Integer(), ForeignKey('contents.id'), primary_key=True) body = Column(Text()) date = Column('date', UTCDateTime()) type_info = Content.type_info.copy( name=u'Idea', title=u'Idea', add_view=u'add_idea', addable_to=[u'Forum'], )
Limiting Forum to the Site Root
At this point, I had an application that worked. I could add a forum to the root of my site, and then add ideas to it.
But, you could add a Forum to any document in the site, and you could add more than one Forum.
I asked a couple questions about this on the #kotti irc channel and was pointed to an example in kotti_media. The solution to both problems is a custom TypeInfo. This one checks whether we have the site root for our context, and if a Forum already exists.
class ForumTypeInfo(TypeInfo): def addable(self, context, request): """only add once, and only at the root""" addable = context == get_root() child_type_already_added = self in [ c.type_info for c in context.children] return addable and not child_type_already_added
I then use ForumTypeInfo for Forum's type_info. Note how this is different from the Idea class above.
class Forum(Content): id = Column(Integer(), ForeignKey('contents.id'), primary_key=True) type_info = ForumTypeInfo( name=u'Forum', title=u'Forum', add_view=u'add_forum', addable_to=[u'Document'], )
Add Forum Automatically
For a little icing on the cake, I decided to add the Forum to the site automatically, using a populator. I put mine in __init__.py. If forum does not exist, the populator adds it.
def populate(): root = get_root() if 'forum' not in root.keys(): root['forum'] = Forum(title=u'Forum')
Then add configuration to your .ini file.
kotti.populators = kotti_agora.populate
Now, there is one Forum and it only exists at the root of the site. And, if it doesn't exist, it is created when the site starts.
There are so many options for python web programmers these days. My expertise is with Plone, but after using Pyramid for a few small projects I wanted to try out Kotti CMS. Something about Pyramid seems right to me, and Kotti fits the same mold. Kind of like working on a bicycle or a VW bus. I can see it all. It fits in my head nicely, and the problems are approachable.
Kotti has great documentation, which helps you get started. The project is relatively young and there are some holes in the narrative documentation, but it has evolved in the short time I've used it.
And, a big shout out to the #kotti irc channel. Very friendly. Very helpful.