view MoinMoin/items/ @ 1988:490c13d072f2

remove Submit widget The Submit widget was a mistake. The buttons carry no user input, and making it part of the form screws up POST form handling. Instead of being a widget, the submit button has its label kept in the class member submit_label of the Form, and is rendered by a new macro forms.render_submit.
author Cheer Xiao <>
date Tue, 12 Feb 2013 10:28:18 +0800
parents 384555088cab
children 22441b6366e6
line wrap: on
line source
# Copyright: 2012 MoinMoin:CheerXiao
# License: GNU GPL v2 (or any later version), see LICENSE.txt for details.

MoinMoin - Ticket itemtype

from __future__ import absolute_import, division

import time

from flask import request, abort, redirect, url_for
from flask import g as flaskg

from jinja2 import Markup

from whoosh.query import Term

from MoinMoin.i18n import L_
from MoinMoin.themes import render_template
from MoinMoin.forms import (Form, OptionalText, OptionalMultilineText, SmallNatural, Tags,
                            Reference, BackReference)
from import AccessDenied
from MoinMoin.constants.keys import ITEMTYPE, CONTENTTYPE, ITEMID, CURRENT
from MoinMoin.constants.contenttypes import CONTENTTYPE_USER
from MoinMoin.items import Item, Contentful, register, BaseModifyForm
from MoinMoin.items.content import NonExistentContent



Rating = SmallNatural.using(optional=True).with_properties(lower=1, upper=5)
OptionalTicketReference =
OptionalUserReference ='(Nobody)')

class TicketMetaForm(Form):
    summary = OptionalText.using(label=L_("Summary")).with_properties(placeholder=L_("One-line summary of the item"))
    effort = Rating.using(label=L_("Effort"))
    difficulty = Rating.using(label=L_("Difficulty"))
    severity = Rating.using(label=L_("Severity"))
    priority = Rating.using(label=L_("Priority"))
    tags = Tags.using(optional=True)
    assigned_to = OptionalUserReference.using(label=L_("Assigned To"))
    superseded_by = OptionalTicketReference.using(label=L_("Superseded By"))
    depends_on = OptionalTicketReference.using(label=L_("Depends On"))

class TicketBackRefForm(Form):
    supersedes = BackReference.using(label=L_("Supersedes"))
    required_by = BackReference.using(label=L_("Required By"))
    subscribers = BackReference.using(label=L_("Subscribers"))

    def _load(self, item):
        id_ = item.meta[ITEMID]
        self['supersedes'].set(Term('superseded_by', id_))
        self['required_by'].set(Term('depends_on', id_))
        self['subscribers'].set(Term('subscribed_items', id_))

class TicketForm(BaseModifyForm):
    meta = TicketMetaForm
    backrefs = TicketBackRefForm
    message = OptionalMultilineText.using(label=L_("Message")).with_properties(rows=8, cols=80)
    submit_label = L_("Update ticket")

    def _load(self, item):
        meta = item.prepare_meta_for_modify(item.meta)
        self['meta'].set(meta, 'duck')
        # XXX need a more explicit way to test for item creation/modification
        if ITEMID in item.meta:

# XXX Ideally we should generate DOM instead of moin wiki source. But
# currently this is not very useful, since
# * DOM cannot be stored directly, it has to be converted to some markup first
# * DOM -> markup conversion is only available for moinwiki

# XXX How to do i18n on this?

def message_markup(message):
    return u'''{{{{{{#!wiki tip
%(author)s wrote on <<DateTime(%(timestamp)d)>>:

''' % dict(, timestamp=time.time(), message=message)

class Ticket(Contentful):
    itemtype = ITEMTYPE_TICKET
    display_name = L_('Ticket')
    description = L_('Ticket item')
    modify_template = 'ticket.html'

    def do_show(self, revid):
        if revid != CURRENT:
            # TODO When requesting a historical version, show a readonly view
            return self.do_modify()

    def do_modify(self):
        if request.method in ['GET', 'HEAD']:
            form = TicketForm.from_item(self)
        elif request.method == 'POST':
            form = TicketForm.from_request(request)
            if form.validate():
                meta = form['meta'].value
                    ITEMTYPE: self.itemtype,
                    # XXX support other markups
                    CONTENTTYPE: 'text/;charset=utf-8',

                if isinstance(self.content, NonExistentContent):
                    data = u''
                    data = self.content.data_storage_to_internal(
                message = form['message'].value
                if message:
                    data += message_markup(message)

                    self.modify(meta, data)
                except AccessDenied:
                    return redirect(url_for('.show_item',
        if isinstance(self.content, NonExistentContent):
            is_new = True
            # XXX suppress the "foo doesn't exist. Create it?" dummy content
            data_rendered = None
            form.submit_label = L_('Submit ticket')
            is_new = False
            data_rendered = Markup(self.content._render_data())

        return render_template(self.modify_template,