Changeset 632

Show
Ignore:
Timestamp:
12/23/09 06:06:58 (2 years ago)
Author:
dray
Message:

freeversity changes, initial work toward deprecating OpenOCW

Location:
enpraxis.educommons/trunk/enpraxis/educommons
Files:
7 added
18 modified

Legend:

Unmodified
Added
Removed
  • enpraxis.educommons/trunk/enpraxis/educommons/browser/configure.zcml

    r239 r632  
    288288     permission="zope2.View" 
    289289     /> 
     290 
     291  <browser:page 
     292     name="school_division_listing" 
     293     for="..interfaces.ISchool" 
     294     class=".DivisionListingView" 
     295     template="school_division_listing.pt" 
     296     allowed_attributes="getDivisions" 
     297     permission="zope2.View" 
     298     /> 
     299 
    290300 
    291301  <browser:page 
  • enpraxis.educommons/trunk/enpraxis/educommons/browser/controlpanel.py

    r506 r632  
    2424from zope.component import adapts, getUtility 
    2525from zope.formlib.form import FormFields 
    26 from zope.schema import TextLine, Bool 
     26from zope.schema import TextLine, List, Bool 
    2727from Products.CMFDefault.formlib.schema import SchemaAdapterBase 
    2828from Products.CMFPlone.interfaces import IPloneSiteRoot 
     
    3232 
    3333class IeduCommonsSchema(Interface): 
     34 
     35    school_descriptor = TextLine(title=_(u'School Descriptor'), 
     36                                   description=_(u"A descriptor that describes how your " 
     37                                                 "institutions are divided. Typically " 
     38                                                 "this will be 'Schools' or 'Universities.'"), 
     39                                   required=True) 
     40 
    3441     
    3542    division_descriptor = TextLine(title=_(u'Division Descriptor'), 
     
    5865                                    description=_(u'The URL to the eduCommons instance utilized by the Reuse Course portlet.'), 
    5966                                    required=True) 
     67                                     
     68    workflow_order = List(title=_(u'Worflow Order'), 
     69                      description=_(u"This setting is utilized in the Course Summary Portlet, allowing the portlet to render workflow states " 
     70                                     "in the proper procedural order. If you utilize a non-standard workflow for content objects, you will need " 
     71                                     "to modify this setting in order for the portlet to render the non-standard states."), 
     72                      required=True, 
     73                      value_type=TextLine(),) 
     74 
    6075 
    6176 
     
    7085        self.props = getUtility(IPropertiesTool) 
    7186        self.ecprops = self.props.educommons_properties 
     87 
     88    def get_school_descriptor(self): 
     89        return self.ecprops.getProperty('school_descriptor') 
     90 
     91    def set_school_descriptor(self, descriptor): 
     92        self.ecprops.manage_changeProperties(school_descriptor=descriptor) 
    7293 
    7394    def get_division_descriptor(self): 
     
    101122        self.ecprops.manage_changeProperties(reusecourse_instance=reusecourse) 
    102123 
     124    def get_workflow_order(self): 
     125        return self.ecprops.workflow_order 
    103126 
     127    def set_workflow_order(self, wf_order): 
     128        self.ecprops.workflow_order = wf_order         
    104129 
     130    school_descriptor = property(get_school_descriptor, set_school_descriptor) 
     131    division_descriptor = property(get_division_descriptor, set_division_descriptor) 
    105132    course_descriptor = property(get_course_descriptor, set_course_descriptor) 
    106     division_descriptor = property(get_division_descriptor, set_division_descriptor) 
    107133    oerrecommender_enabled = property(get_oerrecommender_enabled, set_oerrecommender_enabled) 
    108134    reusecourse_enabled = property(get_reusecourse_enabled, set_reusecourse_enabled) 
    109135    reusecourse_instance = property(get_reusecourse_instance, set_reusecourse_instance) 
     136    workflow_order = property(get_workflow_order, set_workflow_order) 
    110137 
    111138class eduCommonsControlPanel(ControlPanelForm): 
  • enpraxis.educommons/trunk/enpraxis/educommons/browser/coursestopic.py

    r506 r632  
    5151        full_title = self.ecutil.getFullCourseTitle(brain) 
    5252        return full_title 
     53         
     54    def getSchoolInfo(self): 
     55        """ Return URL and title for a School """         
     56        if self.context.aq_inner.aq_parent.portal_type == 'School': 
     57            return self.context.aq_inner.aq_parent 
    5358 
    5459         
     
    117122    def isOpenOCW(self): 
    118123        return IOpenOCWSite.providedBy(self.context.portal_url.getPortalObject()) 
    119          
     124 
     125class SchoolPageView(BrowserView): 
     126    """ A default school page view """ 
     127 
     128    __call__ = ViewPageTemplateFile('templates/school_view.pt') 
     129 
    120130 
    121131class CoursePageView(BrowserView): 
  • enpraxis.educommons/trunk/enpraxis/educommons/browser/divisioncourses.pt

    r8 r632  
    1 <style> 
     1<div class="division-listing">  
     2  <p class="division-title"> 
     3          <span tal:define="item view/getSchoolInfo" 
     4                                        tal:condition="item"> 
     5                  <a href="" 
     6                     tal:attributes="href item/absolute_url" 
     7                     tal:content="item/Title">Division Title</a> | 
     8          </span>  
    29 
    3 </style> 
    4  
    5 <div class="division-listing"> 
    6     <p class="division-title"> 
    7     <a href="" 
    8        tal:attributes="href context/absolute_url" 
    9        tal:content="context/Title">Division Title</a> 
    10     </p> 
     10   <a href="" 
     11      tal:attributes="href context/absolute_url" 
     12      tal:content="context/Title">Division Title</a> 
     13  </p> 
    1114 
    1215  <tal:block tal:repeat="item view/getCourses"> 
  • enpraxis.educommons/trunk/enpraxis/educommons/browser/__init__.py

    r546 r632  
    9595 
    9696        return title, content 
     97 
     98class DivisionListingView(BrowserView): 
     99    """ Return Division in the School """ 
     100 
     101    def getDivisions(self): 
     102        """ Get Sorted Divisions  """ 
     103 
     104        portal_catalog = self.context.portal_catalog 
     105        brains = portal_catalog(path= {'query':'/'.join(self.context.getPhysicalPath())+'/', 'depth':2}, portal_type='Division') 
     106 
     107        #brains = list(brains) 
     108        #brains.sort(lambda x, y : cmp(self.ecutil.getFullCourseTitle(x),self.ecutil.getFullCourseTitle(y))) 
     109 
     110        return brains 
     111 
    97112 
    98113class SortedCourseListingView(BrowserView): 
  • enpraxis.educommons/trunk/enpraxis/educommons/browser/templates/configure.zcml

    r8 r632  
    33           i18n_domain="eduCommons"> 
    44 
     5 
     6  <browser:page 
     7     name="school_view" 
     8     for="...interfaces.ISchool" 
     9     class="..coursestopic.SchoolPageView" 
     10     permission="zope2.View" 
     11     /> 
    512 
    613  <browser:page 
  • enpraxis.educommons/trunk/enpraxis/educommons/configure.zcml

    r514 r632  
    6868  <i18n:registerTranslations directory="locales" /> 
    6969 
     70  <class class=".content.school.School"> 
     71    <implements interface=".interfaces.IClearCopyrightable 
     72                           .interfaces.IAccessibilityCompliantable 
     73                           .interfaces.ICourseOrderable 
     74         zope.annotation.interfaces.IAttributeAnnotatable" 
     75      /> 
     76  </class> 
     77 
    7078  <class class=".content.division.Division"> 
    7179    <implements interface=".interfaces.IClearCopyrightable 
    7280                           .interfaces.IAccessibilityCompliantable 
    7381                           .interfaces.ICourseOrderable 
    74                            zope.annotation.interfaces.IAttributeAnnotatable" 
     82         zope.annotation.interfaces.IAttributeAnnotatable" 
    7583      /> 
    7684  </class> 
     
    8088                           .interfaces.IAccessibilityCompliantable 
    8189                           .interfaces.ICourseOrderable 
    82                            zope.annotation.interfaces.IAttributeAnnotatable" 
     90         zope.annotation.interfaces.IAttributeAnnotatable" 
    8391      /> 
    8492  </class> 
     
    8896                           .interfaces.IAccessibilityCompliantable 
    8997                           .interfaces.ICourseOrderable 
    90                            zope.annotation.interfaces.IAttributeAnnotatable" 
     98         zope.annotation.interfaces.IAttributeAnnotatable" 
    9199      /> 
    92100  </class>   
     
    96104                           .interfaces.IAccessibilityCompliantable 
    97105                           .interfaces.ICourseOrderable 
    98                            zope.annotation.interfaces.IAttributeAnnotatable" 
     106         zope.annotation.interfaces.IAttributeAnnotatable" 
    99107      /> 
    100108  </class> 
     
    104112                           .interfaces.IAccessibilityCompliantable 
    105113                           .interfaces.ICourseOrderable 
    106                            zope.annotation.interfaces.IAttributeAnnotatable" 
     114         zope.annotation.interfaces.IAttributeAnnotatable" 
    107115      /> 
    108116  </class> 
     
    112120                           .interfaces.IAccessibilityCompliantable 
    113121                           .interfaces.ICourseOrderable 
    114                            zope.annotation.interfaces.IAttributeAnnotatable" 
     122         zope.annotation.interfaces.IAttributeAnnotatable" 
    115123      /> 
    116124  </class> 
     
    120128                           .interfaces.IAccessibilityCompliantable 
    121129                           .interfaces.ICourseOrderable 
    122                            zope.annotation.interfaces.IAttributeAnnotatable" 
     130         zope.annotation.interfaces.IAttributeAnnotatable" 
    123131      /> 
    124132  </class> 
     
    128136                           .interfaces.IAccessibilityCompliantable 
    129137                           .interfaces.ICourseOrderable 
    130                            zope.annotation.interfaces.IAttributeAnnotatable" 
     138         zope.annotation.interfaces.IAttributeAnnotatable" 
    131139      /> 
    132140  </class> 
     
    216224  />   
    217225 
    218 <!-- 
    219   <subscriber 
    220      for="enpraxis.educommons.interfaces.ICourse 
    221           zope.lifecycleevent.interfaces.IObjectModifiedEvent" 
    222      handler=".eventHandlers.updateZipDownload" 
    223   /> 
    224  
    225   <subscriber 
    226      for="Products.ATContentTypes.content.document.ATDocument 
    227           zope.lifecycleevent.interfaces.IObjectModifiedEvent" 
    228      handler=".eventHandlers.updateZipDownload" 
    229   /> 
    230   
    231   <subscriber 
    232      for="Products.ATContentTypes.content.file.ATFile 
    233           zope.lifecycleevent.interfaces.IObjectModifiedEvent" 
    234      handler=".eventHandlers.updateZipDownload" 
    235   />  
    236  
    237   <subscriber 
    238      for="Products.ATContentTypes.content.image.ATImage 
    239           zope.lifecycleevent.interfaces.IObjectModifiedEvent" 
    240      handler=".eventHandlers.updateZipDownload" 
    241   /> 
    242   
    243   <subscriber 
    244      for="Products.ATContentTypes.content.folder.ATFolder 
    245           zope.lifecycleevent.interfaces.IObjectModifiedEvent" 
    246      handler=".eventHandlers.updateZipDownload" 
    247   /> 
    248  
    249   <subscriber 
    250      for="Products.ATContentTypes.content.link.ATLink 
    251           zope.lifecycleevent.interfaces.IObjectModifiedEvent" 
    252      handler=".eventHandlers.updateZipDownload" 
    253   /> 
    254  
    255  
    256   <subscriber 
    257       for=".interfaces.ICourseUpdateEvent" 
    258       handler=".eventHandlers.ZipFileMaker" 
    259     /> 
    260  
    261   <subscriber 
    262       for=".interfaces.IDeleteCourseObjectEvent" 
    263       handler=".eventHandlers.deleteObjectHandler" 
    264   /> 
    265 --> 
     226  <subscriber 
     227     for="enpraxis.educommons.interfaces.ISchool 
     228          zope.app.container.interfaces.IObjectAddedEvent" 
     229     handler=".eventHandlers.syndicateFolderishObject" 
     230  /> 
     231 
    266232 
    267233  <subscriber 
  • enpraxis.educommons/trunk/enpraxis/educommons/content/division.py

    r506 r632  
    2727from Products.ATContentTypes.configuration import zconf 
    2828from Products.ATContentTypes.atct import ATFolder, ATFolderSchema 
    29 from Products.ATContentTypes.lib.historyaware import HistoryAwareMixin 
    3029from Products.ATContentTypes.content.base import registerATCT 
    3130from Products.ATContentTypes.content.schemata import finalizeATCTSchema 
    32 from zope.interface import implements 
    3331from AccessControl import ClassSecurityInfo 
    34 from Products.CMFCore.permissions import AddPortalContent 
    35 from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile 
    3632from enpraxis.educommons.interfaces import IDivision 
    3733from enpraxis.educommons.config import PROJECTNAME 
    38  
    3934from enpraxis.educommons import eduCommonsMessageFactory as _ 
    4035 
     36from zope.interface import implements 
    4137 
    4238DivisionSchema = ATFolderSchema.copy() + Schema(( 
  • enpraxis.educommons/trunk/enpraxis/educommons/content/__init__.py

    r506 r632  
    2424from division import Division 
    2525from course import Course 
     26from school import School 
    2627from feedback import Feedback 
    2728from fssfile import FSSFile 
  • enpraxis.educommons/trunk/enpraxis/educommons/eventHandlers.py

    r506 r632  
    2222 
    2323# eventHandlers.py 
    24  
    25  
    26 from enpraxis.educommons.interfaces import ICourse, IDivision 
    27 from Products.CMFDefault.SyndicationTool import SyndicationTool 
    2824from Products.CMFDefault.SyndicationInfo import SyndicationInformation 
    29 from collective.contentlicensing.utilities.interfaces import IContentLicensingUtility 
    3025from collective.zipfiletransport.utilities.interfaces import IZipFileTransportUtility 
    3126from zope.annotation.interfaces import IAnnotations 
    3227from zope.app.container.interfaces import IContainerModifiedEvent 
    3328 
    34 from zope.schema.interfaces import IVocabularyFactory 
    35 from zope.formlib.form import action 
    3629from utilities.interfaces import IECUtility 
    3730from zope.component import getUtility, queryUtility 
    38 import transaction 
    39 from xml.dom import minidom 
    40 import mimetypes 
    4131import re 
    42 from App.config import getConfiguration 
    43 import os 
    4432 
    4533 
     
    139127 
    140128 
    141  
    142  
    143129## Deprecated for 3.1.0, as auto generated Course packages have been disabled 
    144130## Replaced by Package Course functionality :: browser/packagecourseview.py 
  • enpraxis.educommons/trunk/enpraxis/educommons/events.py

    r506 r632  
    2525from zope.annotation.interfaces import IAnnotations 
    2626from plone.portlets.interfaces import IPortletManager, IPortletAssignmentMapping 
    27 from Products.CMFPlone.utils import _createObjectByType 
    28 from Products.CMFCore.utils import getToolByName 
    2927from enpraxis.educommons import portlet 
    3028from enpraxis.educommons.utilities.interfaces import IECUtility 
    31 from enpraxis.educommons.interfaces import IClearCopyrightable, IClearCopyright, ICourseUpdateEvent, IDeleteCourseObjectEvent, IAccessibilityCompliantable, IAccessibilityCompliant 
     29from enpraxis.educommons.interfaces import IClearCopyrightable, ICourseUpdateEvent, IDeleteCourseObjectEvent, IAccessibilityCompliantable 
    3230from zope.component.interfaces import ObjectEvent 
    3331from zope.interface import implements 
     
    10199 
    102100 
    103  
    104101class CourseUpdate(ObjectEvent): 
    105102    """ Set namespace information in manifest. """ 
  • enpraxis.educommons/trunk/enpraxis/educommons/interfaces.py

    r506 r632  
    2222 
    2323from zope.interface import Interface 
    24 from zope.viewlet.interfaces import IViewletManager 
    2524from zope.annotation.interfaces import IAnnotatable 
    2625from zope.app.event.interfaces import IObjectEvent 
     
    4342class IFeedback(Interface): 
    4443    """ Marker interface for Feedback object type.  """ 
     44 
     45class ISchool(Interface): 
     46    """ Marker interface for School object type. """ 
     47 
    4548 
    4649class IClearCopyrightable(IAnnotatable): 
  • enpraxis.educommons/trunk/enpraxis/educommons/portlet/configure.zcml

    r8 r632  
    7171     /> 
    7272 
     73<!-- 
     74  <utility 
     75     provides="zope.schema.interfaces.IVocabularyFactory" 
     76     component=".coursebuilderform.schoolsvocab" 
     77     name="eduCommons.schoolsvocab" 
     78     /> 
     79--> 
     80 
    7381  <utility 
    7482     provides="zope.schema.interfaces.IVocabularyFactory" 
  • enpraxis.educommons/trunk/enpraxis/educommons/portlet/coursebuilderform.py

    r506 r632  
    2525from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm 
    2626from plone.app.form.base import AddForm 
    27 from plone.app.form.validators import null_validator 
    2827from plone.app.controlpanel.widgets import MultiCheckBoxVocabularyWidget 
    29 from zope.formlib.form import FormFields, action, applyChanges 
     28from zope.formlib.form import FormFields, action 
    3029from zope.app.form.browser import DropdownWidget, FileWidget, RadioWidget 
    3130from zope.app.form.browser.widget import renderElement 
    3231from zope.app.form.interfaces import WidgetInputError 
    33 from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile 
    3432from Products.CMFPlone import PloneMessageFactory 
    3533from enpraxis.educommons import eduCommonsMessageFactory as _ 
    36 from zope.app.i18n import ZopeMessageFactory as __ 
    3734from Products.CMFCore.utils import getToolByName 
    3835from collective.imstransport.browser.importform import ZipFileLine 
     
    5148    return widget 
    5249 
     50#def schoolsvocab(context): 
     51#    """ Get the list of current divisions and return it as a vocabulary. """ 
     52#    path = {'query':('/'), } 
     53#    brains = context.portal_catalog.searchResults(path=path, Type='School', sort_on='sortable_title') 
     54#    terms = [SimpleTerm(x.getId, title=x.Title.decode('utf-8') ) for x in brains] 
     55 
     56#    return SimpleVocabulary(terms) 
     57 
    5358def divisionsvocab(context): 
    5459    """ Get the list of current divisions and return it as a vocabulary. """ 
    5560    path = {'query':('/'), } 
    5661    brains = context.portal_catalog.searchResults(path=path, Type='Division', sort_on='sortable_title') 
    57     terms = [SimpleTerm(x.getId, title=x.Title.decode('utf-8') ) for x in brains] 
     62    terms = [] 
     63    for brain in brains: 
     64        if brain.getObject().aq_parent.portal_type == 'School': 
     65            title = '%s : %s' % (brain.getObject().aq_parent.Title().decode('utf-8'), brain.Title.decode('utf-8')) 
     66        else: 
     67            title = brain.Title.decode('utf-8')             
     68        terms += [SimpleTerm(brain.getId, title=title),] 
     69    #terms = [SimpleTerm(x.getId, title=x.Title.decode('utf-8') ) for x in brains] 
     70 
    5871    return SimpleVocabulary(terms) 
    5972 
     
    122135        value = '' 
    123136        contents = [] 
    124         have_results = False 
    125137 
    126138        # Render the Drop Down 
     
    133145        contents.append(self._div('value', renderElement('input', 
    134146                                                         type='text', 
    135                                                          name='form.newdivision', 
    136                                                          id='form.division.textfield'))) 
     147                                                         name='.new'.join(self.name.split(',')), 
     148                                                         id='%s.textfield' % self.name))) 
    137149                                                       
    138150        contents.append(self._emptyMarker()) 
     
    148160                      vocabulary='eduCommons.divisionsvocab') 
    149161 
    150     coursename = TextLine(title=PloneMessageFactory(u'Title') ) 
     162#    school = Choice(title=_(u'School'), 
     163#                    required=False, 
     164#                    vocabulary='eduCommons.schoolsvocab') 
     165 
     166 
     167    coursename = TextLine(title=PloneMessageFactory(u'Course Title') ) 
    151168     
    152169    courseid = TextLine(title=_(u'Course ID'), 
     
    181198    form_fields = FormFields(ICourseBuilderForm) 
    182199    form_fields['division'].custom_widget = EitherOrWidget 
     200#    form_fields['school'].custom_widget = EitherOrWidget         
    183201    form_fields['templates'].custom_widget = MultiPreSelectCheckBoxVocabularyWidget 
    184202    form_fields['filename'].custom_widget = FileWidget 
     
    220238        divname = self.request.form['form.division'] 
    221239        newdivision = self.request.form['form.newdivision'] 
     240 
    222241        if newdivision: 
    223242            portal = self.context.portal_url 
  • enpraxis.educommons/trunk/enpraxis/educommons/portlet/simplenavportlet.py

    r506 r632  
    5858                    'getExcludeFromNav':False, 
    5959                    'sort_on':'getObjPositionInCourse'} 
    60  
    6160            brains = self.context.portal_catalog.searchResults(path) 
    6261 
     62        elif self.isDivisionObject(): 
     63            parent = self.getDivisionParent() 
     64            path = {'path':{'query':'/'.join(parent.getPhysicalPath())+'/'}, 
     65                    'getExcludeFromNav':False, 
     66                    'portal_type':'Division', 
     67                    'sort_on':'sortable_title'}             
     68            brains = self.context.portal_catalog.searchResults(path) 
     69                                                                    
    6370        else: 
    64             brains = self.context.portal_catalog.searchResults(Type='Division', 
    65                                                                sort_on='sortable_title') 
     71            brains = self.context.portal_catalog.searchResults(Type='School', 
     72                                                               sort_on='sortable_title')                                                                    
     73            if len(brains) == 0: 
     74                brains = self.context.portal_catalog.searchResults(Type='Division', 
     75                                                                   sort_on='sortable_title')                                                                    
     76                                                     
     77 
    6678        return [obj for obj in brains if not getattr(obj.aq_explicit, 'exclude_from_nav', True)] 
    6779 
     
    7082        return 'Course' == self.ecparent.Type() 
    7183 
     84    def isDivisionObject(self): 
     85        """ Check if this object is in a Division. """ 
     86        return 'Division' == self.ecparent.Type() 
     87 
     88    def getDivisionParent(self): 
     89        """ Check if parent is Division of Portal. """ 
     90        if self.aq_parent.aq_inner.aq_parent.portal_type == 'School': 
     91            return self.aq_parent.aq_inner.aq_parent         
     92        else: 
     93            return self.context.portal_url.getPortalObject() 
     94 
    7295    def isSelected(self, item): 
    73         """ Check if the navigaion item is the one being displayed. """ 
     96        """ Check if the navigation item is the one being displayed. """ 
    7497        if '/'.join(item.getPath().split('/')[1:]) == self.context.virtual_url_path(): 
    7598            return 'portletItem portletItemSelected' 
     
    82105        if self.isCourseObject(): 
    83106            return ts.translate(ecprops.course_descriptor) 
     107        elif self.isDivisionObject(): 
     108            return ecprops.division_descriptor             
    84109        else: 
    85             return ecprops.division_descriptor 
     110            brains = self.context.portal_catalog.searchResults(Type='School', 
     111                                                               sort_on='sortable_title')                                                                    
     112            if len(brains) == 0: 
     113                return ecprops.division_descriptor             
     114            return ecprops.school_descriptor 
    86115             
    87116    def get_view_url(self, item): 
  • enpraxis.educommons/trunk/enpraxis/educommons/profiles/default/propertiestool.xml

    r538 r632  
    2626 <object name="educommons_properties" meta_type="Plone Property Sheet"> 
    2727   <property name="title">eduCommons properties</property> 
     28   <property name="school_descriptor" type="string">Schools</property> 
    2829   <property name="division_descriptor" type="string">Divisions</property> 
    2930   <property name="course_descriptor" type="string" i18n:translate="">Course Contents</property> 
  • enpraxis.educommons/trunk/enpraxis/educommons/profiles/default/types.xml

    r8 r632  
    33  <object name="CoursesTopic" 
    44          meta_type="Factory-based Type Information with dynamic views"/> 
     5        <object name="School" 
     6                meta_type="Factory-based Type Information with dynamic views"/> 
    57  <object name="Division" 
    68          meta_type="Factory-based Type Information with dynamic views"/> 
  • enpraxis.educommons/trunk/enpraxis/educommons/profiles/default/workflows.xml

    r8 r632  
    55 <object name="content_workflow" meta_type="Workflow"/> 
    66 <bindings> 
    7  
     7  <type type_id="School"> 
     8   <bound-workflow workflow_id="content_workflow"/> 
     9  </type> 
    810  <type type_id="Course"> 
    911   <bound-workflow workflow_id="content_workflow"/>