Okay, starting my 3rd attempt at the recipe database. Doing it all by hand was waaaaay too time-consuming and wheel-reinventing. Doing it as a Zope application was nicer, but the learning curve was still tremendously steep, and the results still looked ugly. Hopefully doing it in Plone is yet another step "upwards" in terms of avoiding reinvention. OS X plone installation: - start with "sudo /Applications/Plone2/Tools/start default" - site runs on localhost:8200 - accounts: 'admin'/ root-passwd 'sussman' / xxx DEBUGGING: - start zope, not plone, to see why the product didn't load: sudo -u plone ./Sites/Default/bin/runzope Architecture: Plone --> CMF --> Zope (highlevel --> web app --> web OS) Notes from hazmat (Kapil Thangavelu ): - use 'cmf' and 'archetypes', in particular. - create a 'cookbook' with a recipes attribute (btree) Archetypes: - a way of defining new objects - object fields can be queried, organized, linked etc. the "database-ness" is implicit in the functionality. ------------------------------ Goal for today: - get basic recipe.py type functional: X - enable discussion by default on a recipe. X - add 'ingredients' as a text field. --> write parser/validator!! - choose correct widgets that render well, both for view & edit. - front-page link to search-urls APPLY PATCH: http://sourceforge.net/tracker/index.php?func=detail&aid=1093026&group_id=75272&atid=543430 - workflow: - who gets to review/publish things? how do roles work? - new CSS template for displaying? - try to make use of 'ratings' component. - brand site, generically, for now. - figure out a way to dump/load recipe documents (from python??) learn about migration issues in general. - install on win32 box when ready. ---------------- from Products.CMFCore.util import getToolByName from Products.Archetypes.public import * class Recipe(BaseContent): # normal stuff schema = Schema(( StringField('category', vocabulary='makeCategories' widget=SelectionWidget() ) )) def makeCategories(self): catalog = getToolByName(self, 'portal_catalog') query = {'portal_type':'Category'} brains = catalog(query, sort_on='title') return DisplayList([(brains[id], brains[title]) for brain in brains ]) registerType(Recipe) ------------------------ BookReViews: lofi-rev8:21pmsussman, that's for the ReferenceField - it used the AT catalog to reference other objects - you tell it what kinds of objects (i.e. allowed_types) to use and what they are related to to (relationship - category) lofi-rev8:21pmThis lets you not need to use the vocabulary at all, and it's totally dynamic - ok - now I really go --------------- hazmat: I would use getCategoriesVocabulary() ----------- how to make links to search-urls? ------------ linking docs together: AT "references" class has a 'validate_fieldname(self, value)' method -------------------- Ingredient AT --> quantity (integer) --> unit (textfield with enforceVocabulary set) --> reference to a Food document (popdown list, dynamically populated display list from catalog) Food AT --> food name (textfield) --> fun facts about food (textfield) --> etc. Recipe AT --> a bunch of textfields --> list of references to Ingredient documents ---------------- Get 'kupu', a wysiwyg embeddable html editor, so that html is always generated. or... if in your accessor you do getMyField(mimetype='text/plain') instead of getMyField() it will convert to text/plain alternatively, you could write your accessor like so: def getMyField(self): pt = getToolByName(self, 'portal_Transforms') return pt.convertTo('text/plain', self.attribute_where_my_field_is_stored)