示例#1
0
class ISession(model.Schema):
    """A conference session. Sessions are managed inside Programs.
    """

    title = schema.TextLine(
        title=_(u"Title"),
        description=_(u"Session title"),
    )

    description = schema.Text(
        title=_(u"Session summary"),
    )

    model.primary('details')
    details = RichText(
        title=_(u"Session details"),
        required=False
    )

    # use an autocomplete selection widget instead of the default content tree
    form.widget(presenter=AutocompleteFieldWidget)
    presenter = RelationChoice(
        title=_(u"Presenter"),
        source=ObjPathSourceBinder(
            object_provides=IPresenter.__identifier__),
        required=False,
    )

    dexterity.write_permission(track='example.conference.ModifyTrack')
    track = schema.Choice(
        title=_(u"Track"),
        source=possibleTracks,
        required=False,
    )
示例#2
0
class ISector(form.Schema, IUser, IBasic):
    """Sector object.

    A sector is a national organisation for a specific type of
    industry.
    """

    form.order_before(title="*")
    dexterity.write_permission(title="euphorie.content.ManageCountry")

    form.order_after(login="******")
    dexterity.write_permission(login="******")

    form.order_before(password="******")

    form.order_after(locked="password")
    dexterity.write_permission(locked="euphorie.content.ManageCountry")

    contact_name = schema.TextLine(title=_("label_contact_name",
                                           default=u"Contact name"),
                                   required=True)

    form.order_after(contact_email="contact_name")

    logo = filefield.NamedBlobImage(
        title=_("label_logo", default=u"Logo"),
        description=_(
            "help_image_upload",
            default=u"Upload an image. Make sure your image is of format "
            u"png, jpg or gif and does not contain any special "
            u"characters."),
        required=False)

    main_colour = colour.Colour(title=_("label_main_colour",
                                        default=u"Main colour"),
                                required=False)

    support_colour = colour.Colour(title=_("label_support_colour",
                                           default=u"Support colour"),
                                   required=False)
示例#3
0
文件: user.py 项目: EU-OSHA/Euphorie
class IUser(form.Schema):
    title = schema.TextLine(
            title=_("label_user_title", default=u"Name"),
            required=True)

    contact_email = schema.TextLine(
            title=_("label_contact_email", default=u"Contact email address"),
            required=True)

    login = LoginField(
            title=_("label_login_name", default=u"Login name"),
            required=True,
            constraint=validLoginValue)
    dexterity.write_permission(login="******")

    password = schema.Password(
            title=_("label_password", default=u"Password"),
            required=True)

    locked = schema.Bool(
            title=_("label_account_locked", default=u"Account is locked"),
            required=False,
            default=False)
    dexterity.write_permission(locked="euphorie.content.ManageCountry")
示例#4
0
class IPeriodicFormInstance(form.Schema, IAttributeUUID):
    """Base form instance interface"""

    form.fieldset('Review', label=u"Review information", fields=['notes'])

    title = schema.TextLine(
        title=_(u'Title'),
        description=_(u'Title for form instance; usually contains the '
                      u'name of a calendar period.'),
        required=True,
    )

    start = schema.Date(
        title=_(u'Start date'),
        description=_(u'Start date for reporting period.'),
        required=False,
    )

    end = schema.Date(
        title=_(u'End date'),
        description=_(u'End date for reporting period.'),
        required=False,
    )

    process_changes = schema.Text(
        title=_(u'Process changes'),
        description=_(u'Notes about changes in goals, process, '
                      u'expectations for period of form.'),
        required=False,
    )

    dexterity.read_permission(notes='cmf.ReviewPortalContent')
    dexterity.write_permission(notes='cmf.ReviewPortalContent')
    notes = schema.Text(
        title=_(u'Notes'),
        description=_(u'Administrative, review notes about form instance.'),
        required=False,
    )

    @invariant
    def validate_start_end(obj):
        if not (obj.start is None or obj.end is None) and obj.start > obj.end:
            raise Invalid(_(u"Start date cannot be after end date."))
示例#5
0
class IOrgangovern(form.Schema):
    """ Organ de Govern
    """

    fieldset('organ',
             label=_(u'Tab organ'),
             fields=[
                 'title', 'acronim', 'descripcioOrgan', 'fromMail',
                 'organType', 'logoOrgan', 'visiblefields', 'eventsColor',
                 'estatsLlista', 'FAQmembres'
             ])

    fieldset(
        'assistents',
        label=_(u'Assistents'),
        fields=['membresOrgan', 'convidatsPermanentsOrgan', 'adrecaLlista'])

    fieldset(
        'afectats',
        label=_(u'Afectats'),
        fields=['adrecaAfectatsLlista'],
    )

    fieldset(
        'plantilles',
        label=_(u'Plantilles'),
        fields=['bodyMailconvoquing', 'bodyMailSend', 'footerMail', 'footer'],
    )

    dexterity.write_permission(title='genweb.webmaster')
    dexteritytextindexer.searchable('title')
    title = schema.TextLine(title=_(u'Organ Title'), required=True)

    dexterity.write_permission(acronim='genweb.webmaster')
    dexteritytextindexer.searchable('acronim')
    acronim = schema.TextLine(title=_(u'Acronym'),
                              description=_(u"Acronym Description"),
                              required=True)

    dexteritytextindexer.searchable('descripcioOrgan')
    directives.widget(descripcioOrgan=WysiwygFieldWidget)
    descripcioOrgan = schema.Text(
        title=_(u"Organ Govern description"),
        description=_(u"Organ Govern description help"),
        required=False,
    )

    dexterity.write_permission(organType='genweb.webmaster')
    organType = schema.Choice(
        title=_(u"Organ Govern type"),
        vocabulary=types,
        default=_(u'open_organ'),
        required=True,
    )

    directives.widget(membresOrgan=WysiwygFieldWidget)
    membresOrgan = schema.Text(
        title=_(u"Organ Govern members"),
        description=_(u"Organ Govern members Description"),
        required=False,
    )

    directives.widget(convidatsPermanentsOrgan=WysiwygFieldWidget)
    convidatsPermanentsOrgan = schema.Text(
        title=_(u"Invited members"),
        description=_(u"Organ permanently invited people description."),
        required=False,
    )

    fromMail = schema.TextLine(
        title=_(u'From mail'),
        description=_(u'Enter the from used in the mail form'),
        required=True,
        constraint=checkEmailAddress)

    adrecaLlista = schema.Text(
        title=_(u"mail address"),
        description=_(u"Mail address help"),
        required=True,
    )

    adrecaAfectatsLlista = schema.Text(
        title=_(u"Stakeholders mail address"),
        description=_(u"Stakeholders mail address help."),
        required=False,
    )

    logoOrgan = NamedBlobImage(
        title=_(u"Organ logo"),
        description=_(u'Logo description'),
        required=False,
    )

    eventsColor = schema.TextLine(
        title=_(u"Color del esdeveniments"),
        description=_(u"Events color help"),
        required=False,
    )

    dexterity.write_permission(estatsLlista='genweb.webmaster')
    directives.widget(estatsLlista=WysiwygFieldWidget)
    estatsLlista = schema.Text(
        title=_(u"Agreement and document labels"),
        description=_(u"Enter labels, separated by commas."),
        default=defaultEstats,
        required=False,
    )

    directives.widget(bodyMailconvoquing=WysiwygFieldWidget)
    bodyMailconvoquing = schema.Text(
        title=_(u"Body Mail"),
        description=_(u"Body Mail convoquing description"),
        required=False,
    )

    directives.widget(bodyMailSend=WysiwygFieldWidget)
    bodyMailSend = schema.Text(
        title=_(u"Body Mail send"),
        description=_(u"Body Mail send description"),
        required=False,
    )

    directives.widget(footerMail=WysiwygFieldWidget)
    footerMail = schema.Text(
        title=_(u"footerMail"),
        description=_(u"footerMail description"),
        required=False,
    )

    directives.widget(footer=WysiwygFieldWidget)
    dexteritytextindexer.searchable('footer')
    footer = schema.Text(
        title=_(u"Footer"),
        description=_(u"Footer help"),
        required=False,
    )

    directives.read_permission(visiblefields='genweb.organs.add.organs')
    directives.write_permission(visiblefields='genweb.organs.add.organs')
    visiblefields = schema.Bool(
        title=_(u"Visible fields"),
        description=
        _(u"Make the sessions and composition members fields visibles to everyone, omitting the security systems."
          ),
        required=False,
    )

    FAQmembres = RichTextField(
        title=_(u"FAQ membres"),
        description=_(u'Preguntes freqüents de membres'),
        required=False,
    )
示例#6
0
class ITalk(form.Schema):
    """A conference talk. Talks are managed inside tracks of the Program.
    """

    length = SimpleVocabulary([
        SimpleTerm(value=u'30', title=_(u'30 minutes')),
        SimpleTerm(value=u'45', title=_(u'45 minutes')),
        SimpleTerm(value=u'60', title=_(u'60 minutes'))
    ])

    #    talktrack = SimpleVocabulary(
    #       [SimpleTerm(value=u'UX', title=_(u'Usability')),
    #        SimpleTerm(value=u'Core-Development', title=_(u'Development in the Core')),
    #        SimpleTerm(value=u'Extension-Development', title=_(u'Development of Extensions')),]
    #        )

    title = schema.TextLine(
        title=_(u"Title"),
        description=_(u"Talk title"),
    )

    description = schema.Text(title=_(u"Talk summary"), )

    form.primary('details')
    details = RichText(title=_(u"Talk details"), required=True)

    # use an autocomplete selection widget instead of the default content tree
    form.widget(speaker=AutocompleteFieldWidget)
    speaker = RelationChoice(
        title=_(u"Presenter"),
        source=ObjPathSourceBinder(object_provides=ISpeaker.__identifier__),
        required=False,
    )
    form.widget(speaker=AutocompleteFieldWidget)
    speaker2 = RelationChoice(
        title=_(u"Co-Presenter"),
        source=ObjPathSourceBinder(object_provides=ISpeaker.__identifier__),
        required=False,
    )
    form.widget(track=AutocompleteFieldWidget)
    track = RelationChoice(
        title=_(u"Track"),
        source=ObjPathSourceBinder(object_provides=ITrack.__identifier__),
        required=False,
    )

    #
    #    start = schema.Datetime(
    #            title=_(u"Startdate"),
    #            description =_(u"Start date"),
    #            required=False,
    #        )
    #
    #    end = schema.Datetime(
    #            title=_(u"Enddate"),
    #            description =_(u"End date"),
    #            required=False,
    #        )
    #    talktrack= schema.Choice(
    #               title=_(u"Choose the Track for the Talk"),
    #               vocabulary=talktrack,
    #               required=True,
    #               )

    length = schema.Choice(
        title=_(u"Length"),
        vocabulary=length,
        required=True,
    )
    dexterity.write_permission(order='collective.conference.ModifyTrack')
    order = schema.Int(
        title=_(u"Orderintrack"),
        description=_(u"Order in the track: write in an Integer from 1 to 12"),
        min=1,
        max=12,
        required=False,
    )

    slides = NamedBlobFile(
        title=_(u"Presentation slides"),
        description=_(u"Please upload your presentation"),
        required=False,
    )

    creativecommonslicense = schema.Bool(
        title=_(
            u'label_creative_commons_license',
            default=
            u'License is Creative Commons Attribution-Share Alike 3.0 License.'
        ),
        description=_(
            u'help_creative_commons_license',
            default=
            u'You agree that your talk and slides are provided under the Creative Commons Attribution-Share Alike 3.0 License.'
        ),
        default=True)

    dexterity.read_permission(reviewNotes='cmf.ReviewPortalContent')
    dexterity.write_permission(reviewNotes='cmf.ReviewPortalContent')
    reviewNotes = schema.Text(
        title=u"Review notes",
        required=False,
    )
示例#7
0
class IPlayer(Interface):

    title = schema.TextLine(
        title=_(u"Title"),
        required=True,
    )

    dexterity.write_permission(played='cmf.ManagePortal')
    played = schema.Text(
        title=_(u"Played players, JSON format"),
        default=u"{}",
        required=False,
    )

    awardRate = schema.Float(
        title=_(u"Award Rate"),
        default=0.01,
        required=True,
    )

    maxAward_100 = schema.Int(
        title=_(u"Max Award 100"),
        default=300,
        required=True,
    )

    dailyAward_100 = schema.Int(
        title=_(u"Daily Award 100"),
        default=10,
        required=True,
    )

    dexterity.write_permission(awarder_100='cmf.ManagePortal')
    awarder_100 = schema.Text(
        title=_(u"Awarder 100, JSON format"),
        default=u"{}",
        required=False,
    )

    maxAward_50 = schema.Int(
        title=_(u"Max Award 50"),
        default=1500,
        required=True,
    )

    dailyAward_50 = schema.Int(
        title=_(u"Daily Award 50"),
        default=50,
        required=True,
    )

    dexterity.write_permission(awarder_50='cmf.ManagePortal')
    awarder_50 = schema.Text(
        title=_(u"Awarder 50, JSON format"),
        default=u"{}",
        required=False,
    )

    dateStart = schema.Date(
        title=_("Date Start"),
        required=True,
    )

    dateEnd = schema.Date(
        title=_("Date End"),
        required=True,
    )

    dexterity.write_permission(hashkey='cmf.ManagePortal')
    hashkey = schema.TextLine(
        title=_(u"Hash Key"),
        required=True,
    )
示例#8
0
class IScoreTable(model.Schema):
    """
       Marker/Form interface for ScoreTable
    """

    form.fieldset(
        _(u'Score'),
        label=_(u"Score table"),
        fields=[
            'scoreR1Q1',
            'scoreR1Q2',
            'scoreR1Q3',
            'scoreR1Q4',
            'scoreR2Q1',
            'scoreR2Q2',
            'scoreR2Q3',
            'scoreR2Q4',
            'scoreR3Q1',
            'scoreR3Q2',
            'scoreR3Q3',
            'scoreR3Q4',
        ],
    )

    dexterity.write_permission(scoreR1Q1='ntpu.content.IsExternalReviewer')
    dexterity.read_permission(scoreR1Q1='ntpu.content.IsSuperEditor')
    #form.widget(scoreR1Q1=RadioFieldWidget)
    #    form.mode(scoreR1Q1='hidden')
    scoreR1Q1 = schema.Choice(
        title=_(u'Research value'),
        vocabulary=Score,
        required=False,
    )

    dexterity.write_permission(scoreR1Q2='ntpu.content.IsExternalReviewer')
    dexterity.read_permission(scoreR1Q2='ntpu.content.IsSuperEditor')
    #form.widget(scoreR1Q2=RadioFieldWidget)
    #    form.mode(scoreR1Q2='hidden')
    scoreR1Q2 = schema.Choice(
        title=_(u'Research Transcend'),
        vocabulary=Score,
        required=False,
    )

    dexterity.write_permission(scoreR1Q3='ntpu.content.IsExternalReviewer')
    dexterity.read_permission(scoreR1Q3='ntpu.content.IsSuperEditor')
    #    form.mode(scoreR1Q3='hidden')
    #form.widget(scoreR1Q3=RadioFieldWidget)
    scoreR1Q3 = schema.Choice(
        title=_(u'Research Design and Data Processing'),
        vocabulary=Score,
        required=False,
    )

    dexterity.write_permission(scoreR1Q4='ntpu.content.IsExternalReviewer')
    dexterity.read_permission(scoreR1Q4='ntpu.content.IsSuperEditor')
    #form.widget(scoreR1Q4=RadioFieldWidget)
    #    form.mode(scoreR1Q4='hidden')
    scoreR1Q4 = schema.Choice(
        title=_(u'Diction smooth and chart product value'),
        vocabulary=Score,
        required=False,
    )

    dexterity.write_permission(scoreR2Q1='ntpu.content.IsExternalReviewer')
    dexterity.read_permission(scoreR2Q1='ntpu.content.IsSuperEditor')
    #form.widget(scoreR2Q1=RadioFieldWidget)
    #    form.mode(scoreR2Q1='hidden')
    scoreR2Q1 = schema.Choice(
        title=_(u'Research value'),
        vocabulary=Score,
        required=False,
    )

    dexterity.write_permission(scoreR2Q2='ntpu.content.IsExternalReviewer')
    dexterity.read_permission(scoreR2Q2='ntpu.content.IsSuperEditor')
    #form.widget(scoreR2Q2=RadioFieldWidget)
    #    form.mode(scoreR2Q2='hidden')
    scoreR2Q2 = schema.Choice(
        title=_(u'Research Transcend'),
        vocabulary=Score,
        required=False,
    )

    dexterity.write_permission(scoreR2Q3='ntpu.content.IsExternalReviewer')
    dexterity.read_permission(scoreR2Q3='ntpu.content.IsSuperEditor')
    #    form.mode(scoreR2Q3='hidden')
    #form.widget(scoreR2Q3=RadioFieldWidget)
    scoreR2Q3 = schema.Choice(
        title=_(u'Research Design and Data Processing'),
        vocabulary=Score,
        required=False,
    )

    dexterity.write_permission(scoreR2Q4='ntpu.content.IsExternalReviewer')
    dexterity.read_permission(scoreR2Q4='ntpu.content.IsSuperEditor')
    #form.widget(scoreR2Q4=RadioFieldWidget)
    #    form.mode(scoreR2Q4='hidden')
    scoreR2Q4 = schema.Choice(
        title=_(u'Diction smooth and chart product value'),
        vocabulary=Score,
        required=False,
    )

    dexterity.write_permission(scoreR3Q1='ntpu.content.IsExternalReviewer')
    dexterity.read_permission(scoreR3Q1='ntpu.content.IsSuperEditor')
    #form.widget(scoreR3Q1=RadioFieldWidget)
    #    form.mode(scoreR3Q1='hidden')
    scoreR3Q1 = schema.Choice(
        title=_(u'Research value'),
        vocabulary=Score,
        required=False,
    )

    dexterity.write_permission(scoreR3Q2='ntpu.content.IsExternalReviewer')
    dexterity.read_permission(scoreR3Q2='ntpu.content.IsSuperEditor')
    #form.widget(scoreR3Q2=RadioFieldWidget)
    #    form.mode(scoreR3Q2='hidden')
    scoreR3Q2 = schema.Choice(
        title=_(u'Research Transcend'),
        vocabulary=Score,
        required=False,
    )

    dexterity.write_permission(scoreR3Q3='ntpu.content.IsExternalReviewer')
    dexterity.read_permission(scoreR3Q3='ntpu.content.IsSuperEditor')
    #    form.mode(scoreR3Q3='hidden')
    #form.widget(scoreR3Q3=RadioFieldWidget)
    scoreR3Q3 = schema.Choice(
        title=_(u'Research Design and Data Processing'),
        vocabulary=Score,
        required=False,
    )

    dexterity.write_permission(scoreR3Q4='ntpu.content.IsExternalReviewer')
    dexterity.read_permission(scoreR3Q4='ntpu.content.IsSuperEditor')
    #form.widget(scoreR3Q4=RadioFieldWidget)
    #    form.mode(scoreR3Q4='hidden')
    scoreR3Q4 = schema.Choice(
        title=_(u'Diction smooth and chart product value'),
        vocabulary=Score,
        required=False,
    )
示例#9
0
class IArticle(form.Schema, IImageScaleTraversable):
    """
    Contribute article
    """
    form.fieldset(
        _(u'Review State'),
        label=_(u"Review State"),
        fields=[
            'blindSetup',
            'assignInternalReviewer',
            'retractReason',
            'reviewFeedbackText',
            'reviewFeedback',
            'assignExternalReviewer1',
            'invitEmail1',
            'acceptInvit1',
            'acceptOrReject1',
            'externalReviewerComment1',
            'reviewCommentAttached1',
            'reviewConfirm1',
            'assignExternalReviewer2',
            'invitEmail2',
            'acceptInvit2',
            'acceptOrReject2',
            'externalReviewerComment2',
            'reviewCommentAttached2',
            'reviewConfirm2',
            'assignExternalReviewer3',
            'invitEmail3',
            'acceptInvit3',
            'acceptOrReject3',
            'externalReviewerComment3',
            'reviewCommentAttached3',
            'reviewConfirm3',
        ],
    )

    dexterity.write_permission(sn='ntpu.content.IsSiteAdministrator')
    dexterity.read_permission(sn='ntpu.content.IsSiteAdministrator')
    form.mode(sn='hidden')
    sn = schema.Int(
        title=_('sn'),
        required=False,
    )

    dexterity.write_permission(blindSetup='ntpu.content.IsSuperEditor')
    dexterity.read_permission(blindSetup='ntpu.content.IsSuperEditor')
    blindSetup = schema.Choice(
        title=_(u'Blind setup'),
        description=_(u'Recommend using double-blind review'),
        vocabulary=BlindSetup,
        default=True,
        required=True,
    )

    dexterity.write_permission(
        assignInternalReviewer='ntpu.content.IsSuperEditor')
    dexterity.read_permission(
        assignInternalReviewer='ntpu.content.IsSuperEditor')
    form.widget(assignInternalReviewer=AutocompleteFieldWidget)
    assignInternalReviewer = RelationChoice(
        title=_(u'Assign internal reviewer'),
        description=
        _(u'Double click or press down key to show selection, or input user name.'
          ),
        source=availableInternalReviewer,
        #        vocabulary=u"plone.principalsource.Users",
        default=None,
        #        required=True,
        required=False,
    )

    dexterity.write_permission(
        reviewFeedbackText='ntpu.content.IsInternalReviewer')
    #    dexterity.read_permission(assignExternalReviewer1='ntpu.content.IsInternalReviewer')
    #    form.mode(reviewFeedback='hidden')
    reviewFeedbackText = schema.Text(
        title=_(u'Review comment file'),
        required=False,
    )

    dexterity.write_permission(
        reviewFeedback='ntpu.content.IsInternalReviewer')
    #    dexterity.read_permission(assignExternalReviewer1='ntpu.content.IsInternalReviewer')
    #    form.mode(reviewFeedback='hidden')
    reviewFeedback = NamedBlobFile(
        title=_(u'Review comment file'),
        required=False,
    )

    dexterity.write_permission(
        retractReason='ntpu.content.IsSiteAdministrator')
    dexterity.read_permission(retractReason='ntpu.content.IsOwner')
    form.mode(retractReason='input')
    retractReason = schema.Text(
        title=_(u'Retract Reason'),
        required=False,
    )

    #### external reviewer 1
    dexterity.write_permission(
        assignExternalReviewer1='ntpu.content.IsInternalReviewer')
    dexterity.read_permission(
        assignExternalReviewer1='ntpu.content.IsInternalReviewer')
    form.widget(assignExternalReviewer1=AutocompleteFieldWidget)
    assignExternalReviewer1 = RelationChoice(
        title=_(u'Assign first external reviewer'),
        description=
        _(u'Double click or press down key to show selection, or input user name.'
          ),
        source=availableExternalReviewer,
        required=False,
    )

    dexterity.write_permission(invitEmail1='ntpu.content.IsInternalReviewer')
    form.mode(invitEmail1='hidden')
    invitEmail1 = schema.TextLine(
        title=_(u'Invit email'),
        default=None,
        required=False,
    )

    dexterity.write_permission(acceptInvit1='ntpu.content.IsExternalReviewer')
    form.omitted('acceptInvit1')
    acceptInvit1 = schema.Bool(
        title=_(u'Accept invitation'),
        description=_(u'Accept the invitation to review'),
        default=None,
        required=False,
    )

    dexterity.write_permission(
        acceptOrReject1='ntpu.content.IsExternalReviewer')
    acceptOrReject1 = schema.Choice(
        title=_(u'Result of Review'),
        vocabulary=AcceptOrReject,
        default=None,
        required=False,
    )

    dexterity.write_permission(
        externalReviewerComment1='ntpu.content.IsExternalReviewer')
    externalReviewerComment1 = schema.Text(
        title=_(u'External reviewer comment'),
        required=False,
    )

    dexterity.write_permission(
        reviewCommentAttached1='ntpu.content.IsExternalReviewer')
    reviewCommentAttached1 = NamedBlobFile(
        title=_(u'External reviewer comment attached file'),
        required=False,
    )

    dexterity.write_permission(
        reviewConfirm1='ntpu.content.IsExternalReviewer')
    form.mode(reviewConfirm1='hidden')
    reviewConfirm1 = schema.Choice(
        title=_(u'Review confirm'),
        vocabulary=ReviewConfirm,
        default=None,
        required=False,
    )

    #### external reviewer 2
    dexterity.write_permission(
        assignExternalReviewer2='ntpu.content.IsInternalReviewer')
    dexterity.read_permission(
        assignExternalReviewer2='ntpu.content.IsInternalReviewer')
    form.widget(assignExternalReviewer2=AutocompleteFieldWidget)
    assignExternalReviewer2 = RelationChoice(
        title=_(u'Assign second external reviewer'),
        description=
        _(u'Double click or press down key to show selection, or input user name.'
          ),
        source=availableExternalReviewer,
        required=False,
    )

    dexterity.write_permission(invitEmail2='ntpu.content.IsInternalReviewer')
    form.mode(invitEmail2='hidden')
    invitEmail2 = schema.TextLine(
        title=_(u'Invit email'),
        default=None,
        required=False,
    )

    dexterity.write_permission(acceptInvit2='ntpu.content.IsExternalReviewer')
    form.omitted('acceptInvit2')
    acceptInvit2 = schema.Bool(
        title=_(u'Accept invitation'),
        description=_(u'Accept the invitation to review'),
        default=None,
        required=False,
    )

    dexterity.write_permission(
        acceptOrReject2='ntpu.content.IsExternalReviewer')
    acceptOrReject2 = schema.Choice(
        title=_(u'Result of Review'),
        vocabulary=AcceptOrReject,
        default=None,
        required=False,
    )

    dexterity.write_permission(
        externalReviewerComment2='ntpu.content.IsExternalReviewer')
    externalReviewerComment2 = schema.Text(
        title=_(u'External reviewer comment'),
        required=False,
    )

    dexterity.write_permission(
        reviewCommentAttached2='ntpu.content.IsExternalReviewer')
    reviewCommentAttached2 = NamedBlobFile(
        title=_(u'External reviewer comment attached file'),
        required=False,
    )

    dexterity.write_permission(
        reviewConfirm2='ntpu.content.IsExternalReviewer')
    form.mode(reviewConfirm2='hidden')
    reviewConfirm2 = schema.Choice(
        title=_(u'Review confirm'),
        vocabulary=ReviewConfirm,
        default=None,
        required=False,
    )

    #### external reviewer 3
    dexterity.write_permission(
        assignExternalReviewer3='ntpu.content.IsInternalReviewer')
    dexterity.read_permission(
        assignExternalReviewer3='ntpu.content.IsInternalReviewer')
    form.widget(assignExternalReviewer3=AutocompleteFieldWidget)
    assignExternalReviewer3 = RelationChoice(
        title=_(u'Assign third external reviewer'),
        description=
        _(u'Double click or press down key to show selection, or input user name.'
          ),
        source=availableExternalReviewer,
        required=False,
    )

    dexterity.write_permission(invitEmail3='ntpu.content.IsInternalReviewer')
    form.mode(invitEmail3='hidden')
    invitEmail3 = schema.TextLine(
        title=_(u'Invit email'),
        default=None,
        required=False,
    )

    dexterity.write_permission(acceptInvit3='ntpu.content.IsExternalReviewer')
    form.omitted('acceptInvit3')
    acceptInvit3 = schema.Bool(
        title=_(u'Accept invitation'),
        description=_(u'Accept the invitation to review'),
        default=None,
        required=False,
    )

    dexterity.write_permission(
        acceptOrReject3='ntpu.content.IsExternalReviewer')
    acceptOrReject3 = schema.Choice(
        title=_(u'Result of Review'),
        vocabulary=AcceptOrReject,
        default=None,
        required=False,
    )

    dexterity.write_permission(
        externalReviewerComment3='ntpu.content.IsExternalReviewer')
    externalReviewerComment3 = schema.Text(
        title=_(u'External reviewer comment'),
        required=False,
    )

    dexterity.write_permission(
        reviewCommentAttached3='ntpu.content.IsExternalReviewer')
    reviewCommentAttached3 = NamedBlobFile(
        title=_(u'External reviewer comment attached file'),
        required=False,
    )

    dexterity.write_permission(
        reviewConfirm3='ntpu.content.IsExternalReviewer')
    form.mode(reviewConfirm3='hidden')
    reviewConfirm3 = schema.Choice(
        title=_(u'Review confirm'),
        vocabulary=ReviewConfirm,
        default=None,
        required=False,
    )

    form.fieldset(
        _(u'Manuscript Metadata'),
        label=_(u"Manuscript Metadata"),
        fields=[
            'submittingFrom', 'articleLanguage', 'articleType', 'articleTitle',
            'engTitle', 'runningTitle', 'keywords', 'engKeywords', 'abstract',
            'engAbstract', 'category', 'coverLetter'
        ],
        description=_(
            u"Submit a new manuscript(fields in RED DOT are Required)"),
    )

    dexterity.write_permission(submittingFrom='ntpu.content.IsOwner')
    submittingFrom = schema.Choice(
        title=_(u'Submitting from'),
        description=_(u'I am submitting from'),
        vocabulary=CountryList,
        default=_(u"Taiwan"),
        required=True,
    )

    dexterity.write_permission(articleLanguage='ntpu.content.IsOwner')
    articleLanguage = schema.Choice(
        title=_(u'Language'),
        vocabulary=ArticleLanguage,
        default=_(u"zh-tw"),
        required=True,
    )

    dexterity.write_permission(articleType='ntpu.content.IsOwner')
    articleType = schema.Choice(
        title=_(u'Article type'),
        vocabulary=ArticleType,
        default=_(u'Original paper'),
        required=True,
    )

    dexteritytextindexer.searchable('articleTitle')
    dexterity.write_permission(articleTitle='ntpu.content.IsOwner')
    articleTitle = schema.TextLine(
        title=_(u'Article title'),
        required=True,
    )

    dexteritytextindexer.searchable('engTitle')
    dexterity.write_permission(engTitle='ntpu.content.IsOwner')
    engTitle = schema.TextLine(
        title=_(u'English title'),
        #default=u' ',
        required=True,
    )

    dexterity.write_permission(runningTitle='ntpu.content.IsOwner')
    runningTitle = schema.TextLine(
        title=_(u'Running title'),
        required=False,
    )

    dexteritytextindexer.searchable('keywords')
    dexterity.write_permission(keywords='ntpu.content.IsOwner')
    keywords = schema.TextLine(
        title=_(u'Keywords'),
        description=_(u'Maximum 5 keywords, separated with commas.'),
        required=True,
    )

    dexteritytextindexer.searchable('engKeywords')
    dexterity.write_permission(engKeywords='ntpu.content.IsOwner')
    engKeywords = schema.TextLine(
        title=_(u'English keywords'),
        description=_(u'Maximum 5 keywords, separated with commas.'),
        required=False,
    )

    dexteritytextindexer.searchable('abstract')
    dexterity.write_permission(abstract='ntpu.content.IsOwner')
    abstract = schema.Text(
        title=_(u'Abstract'),
        description=_(
            u'Please limit the number of words in 500 words or less'),
        required=True,
    )

    dexteritytextindexer.searchable('engAbstract')
    dexterity.write_permission(engAbstract='ntpu.content.IsOwner')
    engAbstract = schema.Text(
        title=_(u'English abstract'),
        #default=u' ',
        required=True,
    )

    dexterity.write_permission(category='ntpu.content.IsOwner')
    category = schema.Choice(
        title=_(u'Category'),
        vocabulary=Category,
        default=None,
        required=True,
    )

    dexteritytextindexer.searchable('coverLetter')
    dexterity.write_permission(coverLetter='ntpu.content.IsOwner')
    coverLetter = schema.Text(
        title=_(u'Cover letter'),
        description=_(u'help_coverLetter',
                      default=u'Enter your cover letter here. \
                      DO NOT include your cover letter \
                      in the manuscript file that you \
                      will upload.The word limit of this \
                      column is 1024 characters.'),
        max_length=1024,
        required=False,
    )

    form.fieldset(
        _(u'Authors'),
        label=_(u"Authors"),
        fields=['authors', 'corresponging', 'allAuthorConsent', 'license'],
        description=_(
            u"help_authors",
            default=u"Select authors and order, first is main author,\
                                second is 2'nd author...<br> \
                                Note: Before submitting, you mustbe agree 'All author consent' \
                                , 'Exclusive or non-exclusive license' and check them."
        ),
    )

    dexterity.write_permission(authors='ntpu.content.IsOwner')
    authors = schema.List(
        title=_(u'Authors'),
        description=_(u'Please select authors'),
        value_type=schema.Choice(
            title=_(u'name'),
            source=availableAuthor,
            required=False,
        ),
        #        min_length=1,
        required=False,
    )

    dexterity.write_permission(corresponging='ntpu.content.IsOwner')
    corresponging = schema.List(
        title=_(u'Corresponding authors'),
        description=_(u'Select at least one corresponding author.'),
        value_type=schema.Choice(
            title=_(u'name'),
            source=availableAuthor,
            required=False,
        ),
        max_length=1,
        required=False,
    )

    dexterity.write_permission(allAuthorConsent='ntpu.content.IsOwner')
    allAuthorConsent = schema.Bool(
        title=_(u'All author consent'),
        description=_(
            u'help_allAuthorConsent',
            default='I confirm this manuscript has not been accepted \
                          for publication elsewhere, is not being considered \
                          for publication elsewhere and does not duplicate material \
                          already published. I confirm all authors consent to \
                          publication of this manuscript.'),
        default=False,
        required=True,
    )

    dexterity.write_permission(license='ntpu.content.IsOwner')
    license = schema.Bool(
        title=_(u'Exclusive or non-exclusive license'),
        description=_(
            u'help_license',
            default='I have read and agreed with the following statements: \
                          1. I am authorized by all co-author(s) to submit this article \
                          on their behalf and as the contact for the Editorial process. \
                          I am responsible for communicating with the other authors about \
                          progress, submissions of revisions and final approval of proofs. \
                          2. All authors agree with the Personal Information Collection \
                          Statement , and the staff of the journal will be using the \
                          personal information that I provided in the APSERS system for \
                          the sole purpose of contacting me concerning the publishing of \
                          the Article. \
                          3. The article I have submitted to the journal for review is \
                          original, has been written by the stated authors and has not been \
                          published elsewhere. Also, the Article is not currently being \
                          considered for publication by any other journal and will not be \
                          submitted for such review while under review by this journal.'
        ),
        default=False,
        required=True,
    )

    form.omitted('logText')
    logText = schema.Text(
        title=_(u'Log'),
        required=False,
    )

    @invariant
    def checkAuthor(data):
        portal = api.portal.get()
        request = portal.REQUEST
        message = _(u"Corresponging must select from authors.")

        if data.authors == [] and data.corresponging == []:
            return
        if data.authors and not data.corresponging:
            api.portal.show_message(message=message,
                                    request=request,
                                    type='error')
            raise Invalid(message)
        if not data.authors and data.corresponging:
            api.portal.show_message(message=message,
                                    request=request,
                                    type='error')
            raise Invalid(message)
        if data.corresponging[0] not in data.authors:
            api.portal.show_message(message=message,
                                    request=request,
                                    type='error')
            raise Invalid(message)

    @invariant
    def validateExternalReviewer(data):
        if data.assignExternalReviewer1 == data.assignExternalReviewer2 and data.assignExternalReviewer1 is not None:
            raise Invalid(_(u"This External reviewer already selected."))
        if data.assignExternalReviewer2 == data.assignExternalReviewer3 and data.assignExternalReviewer2 is not None:
            raise Invalid(_(u"This External reviewer already selected."))
        if data.assignExternalReviewer1 == data.assignExternalReviewer3 and data.assignExternalReviewer1 is not None:
            raise Invalid(_(u"This External reviewer already selected."))
示例#10
0
class IAttachedFile(model.Schema):
    """
       Marker/Form interface for AttachedFile
    """
    form.fieldset(
        _(u'Manuscript file'),
        label=_(u"Manuscript file"),
        fields=[
            'attachFile',
            'commentReply',
            'attachImage1',
            'attachImage2',
            'attachImage3',
            'attachImage4',
            'attachImage5',
            'attachImage6',
            'attachImage7',
            'attachImage8',
            'attachImage9',
            'attachImage10',
        ],
        #        description=_(u'Please upload Manuscript file, and you can upload images after submitting.'),
    )

    dexterity.write_permission(attachFile='ntpu.content.IsOwner')
    attachFile = NamedBlobFile(
        title=_(u'Manuscript file'),
        required=False,
    )

    dexterity.write_permission(attachFile='ntpu.content.IsOwner')
    form.mode(commentReply='hidden')
    commentReply = NamedBlobFile(
        title=_('Comment reply'),
        required=False,
    )

    dexterity.write_permission(attachImage1='ntpu.content.IsOwner')
    attachImage1 = NamedBlobImage(
        title=_(u'First attach image'),
        required=False,
    )

    dexterity.write_permission(attachImage2='ntpu.content.IsOwner')
    attachImage2 = NamedBlobImage(
        title=_(u'Second attach image'),
        required=False,
    )

    dexterity.write_permission(attachImage3='ntpu.content.IsOwner')
    attachImage3 = NamedBlobImage(
        title=_(u'Third attach image'),
        required=False,
    )

    dexterity.write_permission(attachImage4='ntpu.content.IsOwner')
    attachImage4 = NamedBlobImage(
        title=_(u'4th attach image'),
        required=False,
    )

    dexterity.write_permission(attachImage5='ntpu.content.IsOwner')
    attachImage5 = NamedBlobImage(
        title=_(u'5th attach image'),
        required=False,
    )

    dexterity.write_permission(attachImage6='ntpu.content.IsOwner')
    attachImage6 = NamedBlobImage(
        title=_(u'6th attach image'),
        required=False,
    )

    dexterity.write_permission(attachImage7='ntpu.content.IsOwner')
    attachImage7 = NamedBlobImage(
        title=_(u'7th attach image'),
        required=False,
    )

    dexterity.write_permission(attachImage8='ntpu.content.IsOwner')
    attachImage8 = NamedBlobImage(
        title=_(u'8th attach image'),
        required=False,
    )

    dexterity.write_permission(attachImage9='ntpu.content.IsOwner')
    attachImage9 = NamedBlobImage(
        title=_(u'9th attach image'),
        required=False,
    )

    dexterity.write_permission(attachImage10='ntpu.content.IsOwner')
    attachImage10 = NamedBlobImage(
        title=_(u'10th attach image'),
        required=False,
    )

    @invariant
    def checkFileType(data):
        if data.attachFile is None:
            return
        subFileName = data.attachFile.filename.split('.')[-1].lower()
        if subFileName in [u'doc', u'docx']:
            return
        else:
            portal = api.portal.get()
            request = portal.REQUEST
            message = _(u'Please upload *.doc or *.docx file.')
            api.portal.show_message(message=message,
                                    request=request,
                                    type='error')
            raise Invalid(message)
示例#11
0
class IUlearnControlPanelSettings(model.Schema):
    """ Global Ulearn settings. This describes records stored in the
    configuration registry and obtainable via plone.registry.
    """

    model.fieldset('General',
                   _(u'General'),
                   fields=[
                       'campus_url', 'library_url', 'people_literal',
                       'threshold_winwin1', 'threshold_winwin2',
                       'threshold_winwin3', 'stats_button', 'info_servei',
                       'activate_news', 'activate_sharedwithme',
                       'buttonbar_selected'
                   ])

    model.fieldset('Specific',
                   _(u'Specific'),
                   fields=[
                       'main_color', 'secondary_color', 'background_property',
                       'background_color', 'buttons_color_primary',
                       'buttons_color_secondary', 'maxui_form_bg',
                       'alt_gradient_start_color', 'alt_gradient_end_color',
                       'color_community_closed',
                       'color_community_organizative', 'color_community_open'
                   ])

    model.fieldset('Visibility', _(u'Visibility'), fields=['nonvisibles'])

    model.fieldset(
        'Quick Links',
        _(u'QuickLinks'),
        fields=['quicklinks_literal', 'quicklinks_icon', 'quicklinks_table'])

    model.fieldset('UPCnet only',
                   _(u'UPCnet only'),
                   fields=[
                       'language', 'activity_view', 'url_forget_password',
                       'show_news_in_app'
                   ])

    campus_url = schema.TextLine(
        title=_(u'campus_url', default=_(u'URL del campus')),
        description=_(
            u'help_campus_url',
            default=_(
                u'Afegiu la URL del campus associat a aquestes comunitats.')),
        required=False,
        default=u'',
    )

    library_url = schema.TextLine(
        title=_(u'library_url', default=_(u'URL de la biblioteca')),
        description=_(
            u'help_library_url',
            default=
            _(u'Afegiu la URL de la biblioteca associada a aquestes comunitats.'
              )),
        required=False,
        default=u'',
    )

    threshold_winwin1 = schema.TextLine(
        title=_(u'llindar_winwin1', default=_(u'Llindar del winwin 1')),
        description=_(u'help_llindar_winwin1',
                      default=_(u'Aquest és el llindar del winwin #1.')),
        required=False,
        default=u'50',
    )

    threshold_winwin2 = schema.TextLine(
        title=_(u'llindar_winwin2', default=_(u'Llindar del winwin 2')),
        description=_(u'help_llindar_winwin2',
                      default=_(u'Aquest és el llindar del winwin #2.')),
        required=False,
        default=u'100',
    )

    threshold_winwin3 = schema.TextLine(
        title=_(u'llindar_winwin3', default=_(u'Llindar del winwin 3')),
        description=_(u'help_llindar_winwin3',
                      default=_(u'Aquest és el llindar del winwin #3.')),
        required=False,
        default=u'500',
    )

    stats_button = schema.Bool(
        title=_(u'stats_button',
                default=_(u"Mostrar botó d'accés a estadístiques diàries")),
        description=_(
            u'help_stats_button',
            default=
            _(u"Mostra o no el botó d'accés a estadístiques diàries a stats/activity i stats/chats"
              )),
        required=False,
        default=False,
    )

    info_servei = schema.TextLine(
        title=_(u'info_servei', default=_(u'Informació del servei')),
        description=_(u'help_info_servei',
                      default=_(u'Aquest és l\'enllaç al servei.')),
        required=False,
    )

    activate_news = schema.Bool(
        title=_(u'activate_news',
                default=_(u"Mostra les noticies a les que estic subscrit")),
        description=_(
            u'help_activate_news',
            default=
            _(u"Mostra o no el botó de Noticies a la tile central de les comunitats"
              )),
        required=False,
        default=False,
    )

    activate_sharedwithme = schema.Bool(
        title=_(u'activate_sharedwithme',
                default=_(u"Mostra el que hi ha compartit amb mi")),
        description=_(
            u'help_activate_sharedwithme',
            default=
            _(u"Mostra o no el botó del que hi ha compartit amb mi i el que hi ha compartit a les comunitats"
              )),
        required=False,
        default=False,
    )

    buttonbar_selected = schema.Choice(
        title=_(u'buttonbar_selected'),
        description=_(u'Select the active button in the button bar.'),
        values=['stream', 'news', 'mycommunities', 'sharedwithme'],
        required=True,
        default='stream')

    main_color = schema.TextLine(
        title=_(u'main_color', default=_(u'Color principal')),
        description=_(u'help_main_color',
                      default=_(u'Aquest és el color principal de l\'espai.')),
        required=True,
        default=u'#f58d3d',
    )

    secondary_color = schema.TextLine(
        title=_(u'secondary_color', default=_(u'Color secundari')),
        description=_(u'help_secondary_color',
                      default=_(u'Aquest és el color secundari de l\'espai.')),
        required=True,
        default=u'#f58d3d',
    )

    maxui_form_bg = schema.TextLine(
        title=_(u'maxui_form_bg',
                default=_(u'Color del fons del widget de MAX.')),
        description=_(
            u'help_maxui_form_bg',
            default=_(u'Aquest és el color del fons del widget de MAX.')),
        required=True,
        default=u'#34495c',
    )

    alt_gradient_start_color = schema.TextLine(
        title=_(u'alt_gradient_start_color',
                default=_(u'Color inicial dels gradients.')),
        description=_(
            u'help_alt_gradient_start_color',
            default=_(u'Aquest és el color inicial dels gradients.')),
        required=True,
        default=u'#f58d3d',
    )

    alt_gradient_end_color = schema.TextLine(
        title=_(u'alt_gradient_end_color',
                default=_(u'Color final dels gradients')),
        description=_(u'help_alt_gradient_end_color',
                      default=_(u'Aquest és el color final dels gradients.')),
        required=True,
        default=u'#f58d3d',
    )

    background_property = schema.TextLine(
        title=_(u'background_property',
                default=_(u'Propietat de fons global')),
        description=_(
            u'help_background_property',
            default=_(u'Aquest és la propietat de CSS de background.')),
        required=True,
        default=u'transparent',
    )

    background_color = schema.TextLine(
        title=_(u'background_color', default=_(u'Color de fons global')),
        description=_(
            u'help_background_color',
            default=
            _(u'Aquest és el color de fons global o la propietat corresponent.'
              )),
        required=True,
        default=u'#eae9e4',
    )

    buttons_color_primary = schema.TextLine(
        title=_(u'buttons_color_primary',
                default=_(u'Color primari dels botons')),
        description=_(u'help_buttons_color_primary',
                      default=_(u'Aquest és el color primari dels botons.')),
        required=True,
        default=u'#34495E',
    )

    buttons_color_secondary = schema.TextLine(
        title=_(u'buttons_color_secondary',
                default=_(u'Color secundari dels botons')),
        description=_(u'help_buttons_color_secondary',
                      default=_(u'Aquest és el color secundari dels botons.')),
        required=True,
        default=u'#34495E',
    )

    color_community_closed = schema.TextLine(
        title=_(u'color_community_closed',
                default=_(u'Color comunitat tancada')),
        description=_(
            u'help_color_community_closed',
            default=_(u'Aquest és el color per les comunitats tancades.')),
        required=True,
        default=u'#f58d3d',
    )

    color_community_organizative = schema.TextLine(
        title=_(u'color_community_organizative',
                default=_(u'Color comunitat organitzativa')),
        description=_(
            u'help_color_community_organizative',
            default=_(
                u'Aquest és el color per les comunitats organitzatives.')),
        required=True,
        default=u'#b5c035',
    )

    color_community_open = schema.TextLine(
        title=_(u'color_community_open', default=_(u'Color comunitat oberta')),
        description=_(
            u'help_color_community_open',
            default=_(u'Aquest és el color per les comunitats obertes.')),
        required=True,
        default=u'#888888',
    )

    dexterity.write_permission(language='zope2.ViewManagementScreens')
    language = schema.Choice(
        title=_(u'language', default=_(u'Idioma de l\'espai')),
        description=_(
            u'help_language',
            default=
            _(u'Aquest és l\'idioma de l\'espai, que es configura quan el paquet es reinstala.'
              )),
        required=True,
        values=['ca', 'es', 'en'],
        default='es',
    )

    form.widget(nonvisibles=Select2MAXUserInputFieldWidget)
    nonvisibles = schema.List(
        title=_(u'no_visibles'),
        description=
        _(u'Llista amb les persones que no han de sortir a les cerques i que tenen accés restringit per les demés persones.'
          ),
        value_type=schema.TextLine(),
        required=False,
        default=[])

    people_literal = schema.Choice(
        title=_(u'people_literal'),
        description=
        _(u'Literals que identifiquen als usuaris de les comunitats i les seves aportacions.'
          ),
        values=['thinnkers', 'persones', 'participants'],
        required=False,
        default='persones')

    form.widget(quicklinks_literal=DataGridFieldFactory)
    quicklinks_literal = schema.List(
        title=_(u'Text Quick Links'),
        description=_(u'help_quicklinks_table'),
        value_type=DictRow(schema=ILiteralQuickLinks))

    quicklinks_icon = schema.TextLine(
        title=_(u'quicklinks_icon', default='icon-link'),
        description=_(
            u'help_quicklinks_icon',
            default=_(
                u'Afegiu la icona del Font Awesome que voleu que es mostri')),
        required=False,
        default=u'',
    )

    form.widget(quicklinks_table=DataGridFieldFactory)
    quicklinks_table = schema.List(title=_(u'QuickLinks'),
                                   description=_(u'help_quicklinks_literal'),
                                   value_type=DictRow(schema=ITableQuickLinks))

    activity_view = schema.Choice(title=_(u'activity_view'),
                                  description=_(u'help_activity_view'),
                                  vocabulary=u'ulearn.core.activity_view',
                                  required=True,
                                  default=_(u'Darreres activitats'))

    url_forget_password = schema.TextLine(
        title=_(u'url_forget_password',
                default=_(u'URL contrasenya oblidada')),
        description=_(
            u'help_url_forget_password',
            default=
            _(u'Url per defecte: "/mail_password_form?userid=". Per a dominis externs indiqueu la url completa, "http://www.domini.cat"'
              )),
        required=True,
        default=_(u'/mail_password_form?userid='))

    show_news_in_app = schema.Bool(
        title=_(u'show_news_in_app', default=_(u"Show News Items in App")),
        description=_(
            u'help_show_news_in_app',
            default=
            _(u"If selected, then gives the option to show the News Items in Mobile App."
              )),
        required=False,
        default=False,
    )
示例#12
0
class IFormSeries(form.Schema, IPeriodicSeries):
    """
    A time-series container of related periodic forms, may contain
    shared metadata about that group of forms.
    """

    form.fieldset('Display',
                  label=u"Form display metadata",
                  fields=['contact', 'logo', 'form_css'])

    form.fieldset('Review', label=u"Review information", fields=['notes'])

    title = schema.TextLine(
        title=_(u'Title'),
        description=_(u'Series title or heading; displayed on forms.'),
        required=True,
    )

    subhead = schema.TextLine(
        title=_(u'Sub-heading'),
        description=_(u'Second-level title/heading for form display.'),
        required=False,
    )

    description = schema.Text(
        title=u'Description',
        description=_(u'Series description; may be displayed on forms.'),
        required=False,
    )

    contact = RichText(
        title=_(u'Contact'),
        description=_(u'Project manager or coordinator contact information.'),
        required=False,
    )

    series_info = RichText(
        title=_(u'Series info'),
        description=_(
            u'Series information for display on series summary page.'),
        required=False,
    )

    logo = NamedImage(
        title=_(u'Logo'),
        description=_(u'Optionally upload a logo image for display on the '
                      u'form.  If present, overrides any logo from form '
                      u'definitions on the display of contained forms'),
        required=False,
    )

    form.widget(form_css=TextAreaFieldWidget)
    form_css = schema.Bytes(
        title=_(u'Form styles'),
        description=_(u'Additional CSS stylesheet rules for forms contained '
                      u'within this series (optional).'),
        required=False,
    )

    dexterity.read_permission(notes='cmf.ReviewPortalContent')
    dexterity.write_permission(notes='cmf.ReviewPortalContent')
    notes = schema.Text(
        title=_(u'Notes'),
        description=_(u'Administrative, review notes about series.'),
        required=False,
    )

    form.order_after(frequency='description')
    form.order_after(start='frequency')
    form.order_after(end='start')
    form.order_after(active_weekdays='end')

    @invariant
    def validate_start_end(obj):
        if not (obj.start is None or obj.end is None) and obj.start > obj.end:
            raise Invalid(_(u"Start date cannot be after end date."))