This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
glasnost/shared/web/CardsWeb.py

842 lines
31 KiB
Python

# -*- coding: iso-8859-15 -*-
# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
# Romain Chantereau <rchantereau@entrouvert.com>
# Nicolas Clapiès <nclapies@easter-eggs.org>
# Pierre-Antoine Dejace <padejace@entrouvert.be>
# Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com>
# Cédric Musso <cmusso@easter-eggs.org>
# Frédéric Péters <fpeters@entrouvert.be>
# Benjamin Poussin <poussin@codelutin.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
# Sébastien Régnier <regnier@codelutin.com>
# Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
# Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
# Régnier, Emmanuel Saracco, Théridion & Vecam
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
__doc__ = """Glasnost Cards Web"""
__version__ = '$Revision$'[11:-2]
import cPickle
import glasnost.common.context as context
import glasnost.common.faults as faults
from glasnost.common.ObjectsCommon import ObjectCommon
import glasnost.common.slots as slots
import glasnost.common.system as system
import glasnost.common.tools_new as commonTools
import glasnost.common.xhtmlgenerator as X
from glasnost.proxy.CardsProxy import *
from ObjectsWeb import register, AdminMixin, BaseObjectWebMixin, ObjectsWebMixin
import properties
import things
from tools import *
class Command:
action = None
nextModeName = None
nextObjectId = None
def getNextUrl(self):
return X.idUrl(self.nextObjectId, action = self.nextModeName)
class AdminCards(AdminMixin, AdminCards):
pass
register(AdminCards)
class AbstractCard(BaseObjectWebMixin, Card):
def getEditModeUsersSet(self):
if self.editModeUsersSet is not None:
return self.editModeUsersSet
prototypes = self.getC3PrototypeLinearization()
for prototype in prototypes:
if prototype.editModeUsersSet is not None:
return prototype.editModeUsersSet
return [system.generalPublicId]
def getRequiredFieldSlotNames(self, fields, parentSlot = None):
allSlotNames = ObjectCommon.getSlotNames(self, parentSlot = parentSlot)
orderedSlotNames = self.getOrderedFieldSlotNames(
fields, parentSlot = parentSlot)
slotNames = []
for slotName in orderedSlotNames:
if not slotName in allSlotNames:
continue
slotNames.append(slotName)
for slotName in allSlotNames:
if slotName in slotNames:
continue
slotNames.append(slotName)
return slotNames
def getRequiredLayoutSlotNames(self, fields, parentSlot = None):
# Skip properties slots.
allSlotNames = ObjectCommon.getSlotNames(self, parentSlot = parentSlot)
orderedSlotNames = self.getOrderedLayoutSlotNames(
parentSlot = parentSlot)
slotNames = []
for slotName in orderedSlotNames:
if not slotName in allSlotNames:
continue
slotNames.append(slotName)
for slotName in allSlotNames:
if slotName in slotNames:
continue
slotNames.append(slotName)
return slotNames
def getViewModeUsersSet(self):
if self.viewModeUsersSet is not None:
return self.viewModeUsersSet
prototypes = self.getC3PrototypeLinearization()
for prototype in prototypes:
if prototype.viewModeUsersSet is not None:
return prototype.viewModeUsersSet
return [system.generalPublicId]
class Card(AbstractCard):
pass
register(Card)
class CardForDefinition(AbstractCard):
thingName = 'Card'
def getFieldSlotNames(self, fields, parentSlot = None):
allSlotNames = ObjectCommon.getSlotNames(self, parentSlot = parentSlot)
orderedSlotNames = self.getOrderedFieldSlotNames(
fields, parentSlot = parentSlot)
slotNames = []
for slotName in orderedSlotNames:
if not slotName in allSlotNames:
continue
slotNames.append(slotName)
for slotName in allSlotNames:
if slotName in slotNames:
continue
slotNames.append(slotName)
return slotNames
def getLayoutSlotNames(self, fields, parentSlot = None):
# Skip properties slots.
allSlotNames = ObjectCommon.getSlotNames(self, parentSlot = parentSlot)
orderedSlotNames = self.getOrderedLayoutSlotNames(
parentSlot = parentSlot)
slotNames = []
for slotName in orderedSlotNames:
if not slotName in allSlotNames:
continue
slotNames.append(slotName)
for slotName in allSlotNames:
if slotName in slotNames:
continue
slotNames.append(slotName)
return slotNames
## def getSlotNames(self, parentSlot = None):
## return ObjectCommon.getSlotNames(self, parentSlot = parentSlot)
def getSlotToModifyNames(self, parentSlot = None):
return ObjectCommon.getSlotNames(self, parentSlot = parentSlot)
def makeContentTitle(self, contentSlot, contentLabel):
return X.a(href = X.idUrl(
self.id, 'definition/%s' % contentSlot.getPath()))(
contentLabel)
class CardForUse(AbstractCard):
_c3PrototypeLinearization = None
class defaultImplementModeName_kindClass(
AbstractCard.defaultImplementModeName_kindClass):
importExport = 'from-server-only'
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
class defaultListModeName_kindClass(
AbstractCard.defaultListModeName_kindClass):
importExport = 'from-server-only'
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
class defaultModeName_kindClass(AbstractCard.defaultModeName_kindClass):
importExport = 'from-server-only'
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
draftKey = None
class draftKey_kindClass:
_kindName = 'PythonIdentifier'
importExport = 'private'
isRequiredInEditMode = 1
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
class editMode_kindClass(AbstractCard.editMode_kindClass):
importExport = 'from-server-only'
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
class editModeUsersSet_kindClass(AbstractCard.editModeUsersSet_kindClass):
importExport = 'from-server-only'
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
class modes_kindClass(AbstractCard.modes_kindClass):
importExport = 'from-server-only'
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
properties_kind_importExport = 'from-server-only'
properties_kind_stateInEditMode = 'hidden'
properties_kind_stateInViewMode = 'hidden'
# prototypeIds is modified for new implementations.
# prototypeIds_kind_importExport = 'from-server-only'
prototypeIds_kind_stateInEditMode = 'hidden'
prototypeIds_kind_stateInViewMode = 'hidden'
thingName = 'Card'
class viewMode_kindClass(AbstractCard.viewMode_kindClass):
importExport = 'from-server-only'
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
class viewModeUsersSet_kindClass(AbstractCard.viewModeUsersSet_kindClass):
importExport = 'from-server-only'
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
def getC3PrototypeLinearization(self):
if self._c3PrototypeLinearization is None:
self._c3PrototypeLinearization = \
AbstractCard.getC3PrototypeLinearization(self)
return self._c3PrototypeLinearization
def getSlotToModifyNames(self, parentSlot = None):
return self.getPropertyNames()
# To do later...
## def makeContentTitle(self, contentSlot, contentLabel):
## return X.a(href = X.idUrl(
## self.id, 'content/%s' % contentSlot.getPath()))(
## contentLabel)
class CardsWeb(ObjectsWebMixin, CardsProxy):
def definition(self, id, contentPath = ''):
if not self.hasObject(id):
return pageNotFound()
object = self.getObject(id)
object.__class__ = CardForDefinition # Important.
rememberObject(id)
try:
contentSlot = object.getSlotByPath(contentPath)
except: # FIXME.
if context.getVar('debug'):
raise
return pageNotFound()
if contentSlot is None:
contentSlot = slots.Root(object)
content = contentSlot.getValue()
contentKind = contentSlot.getKind()
contentWidget = contentKind.getModelWidget(
contentSlot, forceEmbedding = 1)
layout = X.array()
if contentSlot.parent is not None:
# Add the public path to the layout.
# FIXME: quick & dirty.
contentPublicPath = []
slot = contentSlot
while slot.parent is not None and slot.parent.parent is not None:
if slot.parent.parent.parent is None:
contentPublicPath.append(object.makeContentTitle(
slot, slot.parent.getLabel()))
else:
contentPublicPath.append(
object.makeContentTitle(slot, slot.getLabel()))
slot = slot.parent
contentPublicPath.reverse()
publicPath = X.array()
publicPath.append(object.makeContentTitle(
slots.Root(object), object.getLabel()))
for itemTitle in contentPublicPath:
publicPath.append(' / ')
publicPath.append(itemTitle)
layout += X.div(_class = 'public-path')(publicPath)
layout += contentWidget.getModelPageBodyLayout(contentSlot, None)
buttonsBar = X.div(_class = 'buttons-bar')
layout += buttonsBar
navigationButtonsBar = X.span(_class = 'navigation-buttons-bar')
buttonsBar += navigationButtonsBar
if object.getDefaultModeName() != 'view':
navigationButtonsBar += X.buttonStandalone('use', X.idUrl(id))
navigationButtonsBar += X.buttonStandalone('view', X.idUrl(id, 'view'))
if self.canModifyObject(object.id):
buttonsBar += X.span(_class = 'action-buttons-bar')(
X.buttonStandalone(
'edit',
X.idUrl(id, 'editDefinition/%s' % contentPath)))
return writePageLayout(
layout, _('Definition of Card "%s"') % object.getLabel())
definition.isPublicForWeb = 1
def edit(self, *arguments, **keywords):
pass
edit.isPublicForWeb = 0 # Important, so that self.parseHttpPathAction is
# called.
def editDefinition(self, id, contentPath = ''):
if id and not self.hasObject(id):
return pageNotFound()
if id:
if not self.canModifyObject(id):
return accessForbidden()
object = self.getObject(id)
rememberObject(id)
else:
if not self.canAddObject():
return accessForbidden()
object = self.newObject(None)
object.__class__ = CardForDefinition # Important.
return self.editDefinitionObject(object, id, contentPath)
editDefinition.isPublicForWeb = 1
def editDefinitionObject(self, object, id = '', contentPath = ''):
try:
contentSlot = object.getSlotByPath(contentPath)
except: # FIXME.
if context.getVar('debug'):
raise
return pageNotFound()
if contentSlot is None:
contentSlot = slots.Root(object)
content = contentSlot.getValue()
contentKind = contentSlot.getKind()
contentWidget = contentKind.getModelWidget(
contentSlot, forceEmbedding = 1)
if not id:
headerTitle = _(self.newObjectNameCapitalized)
else:
headerTitle = _('Editing Definition of Card "%s"') \
% object.getLabel()
context.push(_level = 'editDefinition',
isCreateEditMode = not id,
layoutMode = 'edit')
try:
layout = X.array()
if contentSlot.parent is not None:
# Add the public path to the layout.
# FIXME: quick & dirty.
contentPublicPath = []
slot = contentSlot
while slot.parent is not None \
and slot.parent.parent is not None:
if slot.parent.parent.parent is None:
contentPublicPath.append(slot.parent.getLabel())
else:
contentPublicPath.append(slot.getLabel())
slot = slot.parent
contentPublicPath.reverse()
publicPath = X.array()
publicPath.append(object.getLabel())
for itemTitle in contentPublicPath:
publicPath.append(' / ')
publicPath.append(itemTitle)
layout += X.div(_class = 'public-path')(publicPath)
if context.getVar('error'):
layout += object.getErrorLayout()
form = X.form(action = X.actionUrl('submitDefinition'),
enctype= 'multipart/form-data', method = 'post')
layout += form
if content != object:
form += X.input(name = 'id', type = 'hidden', value = id)
form += X.input(name = 'contentPath', type = 'hidden',
value = contentPath)
form += contentWidget.getModelPageBodyLayout(contentSlot, None)
buttonsBar = X.div(_class = 'buttons-bar')
form += buttonsBar
actionButtonsBar = X.span(_class = 'action-buttons-bar')
buttonsBar += actionButtonsBar
if not id:
actionButtonsBar += X.buttonInForm('create', 'createButton')
else:
actionButtonsBar += X.buttonInForm('modify', 'modifyButton')
return writePageLayout(layout, headerTitle)
finally:
context.pull(_level = 'editDefinition')
def getViewAllActionButtonsBarLayout(self):
layout = X.array()
if self.canAddObject():
layout += X.buttonStandalone(
'new', X.actionUrl('editDefinition').add('id', ''))
return layout
def getViewNavigationButtonsBarLayout(self, object, fields):
layout = X.array()
if object.getDefaultModeName() != 'view':
layout += X.buttonStandalone('use', X.idUrl(object.id))
layout += ObjectsWebMixin.getViewNavigationButtonsBarLayout(
self, object, fields)
userToken = context.getVar('userToken', default = '')
if userToken:
layout += X.buttonStandalone(
'view-definition', X.idUrl(object.id, 'definition'))
return layout
def getViewOtherActionButtonsBarLayout(self, object, fields):
layout = X.array()
layout += ObjectsWebMixin.getViewOtherActionButtonsBarLayout(
self, object, fields)
if self.canAddObject():
layout += X.buttonStandalone(
'implement', X.idUrl(object.id, 'new'))
return layout
def implementations(self, id, slotNames = None):
if type(slotNames) is not types.ListType:
slotNames = None
if not self.hasObject(id):
return pageNotFound()
if not self.canGetObject(id):
return accessForbidden()
object = self.getObject(id)
object.__class__ = CardForUse # Important.
rememberObject(id)
#object.execute('onImplementations')
if not self.canGetObjects():
return accessForbidden()
objects = self.getImplementations(id)
layout = X.array()
leadIn = self.getViewAllLeadIn()
if leadIn:
layout += X.enclose(leadIn, _class = 'lead-in')
ids = self.getSortedIds(objects)
layout += self.getObjectsLayout(objects, ids, slotNames = slotNames)
buttonsBar = X.div(_class = 'buttons-bar')
layout += buttonsBar
buttonsBar += X.span(_class = 'action-buttons-bar')(
X.buttonStandalone('new', X.idUrl(id, 'new')))
headerTitle = _('"%s" Implementations' % object.getLabelTranslated(
context.getVar('readLanguages')))
return writePageLayout(layout, headerTitle)
implementations.isPublicForWeb = 1
def index(self, id, modeName = '', *arguments, **keywords):
localId = commonTools.extractLocalId(id)
if localId.startswith('draft/'):
draftKey = localId
session = context.getVar('session')
if session is None or not session.has_key(draftKey):
return pageNotFound()
object = cPickle.loads(session[draftKey])
else:
if not self.hasObject(id):
return pageNotFound()
if not self.canGetObject(id):
return accessForbidden()
object = self.getObject(id)
object.__class__ = CardForUse # Important.
if not modeName:
modeName = object.getDefaultModeName()
elif not object.hasMode(modeName):
# modeName is not a mode name, but an action.
arguments = [modeName] + list(arguments)
modeName = object.getDefaultModeName()
if not object.hasMode(modeName):
return pageNotFound()
mode = object.getMode(modeName)
identitiesProxy = getProxyForServerRole('identities')
if not identitiesProxy.setContainsUser(
mode.getModelUsersSet(object)):
return accessForbidden()
command = None
if arguments:
action = arguments[0]
if action == 'new':
prototypeId = id
id = ''
if not self.canAddObject():
return accessForbidden()
object = self.newObject(keywords)
object.__class__ = CardForUse # Important.
object.prototypeIds = [prototypeId]
command = Command()
command.action = 'create'
if id:
rememberObject(id)
return self.indexObject(object, mode, command)
index.isPublicForWeb = 1
def indexObject(self, object, mode, command):
modeName = mode.getName()
if modeName == 'edit':
layoutMode = 'edit'
elif modeName == 'view':
layoutMode = 'view'
else:
layoutMode = 'use'
create = 0
if command and (command.action == 'create' or
command.action == 'submit' and not object.id):
create = 1
prototypeId = object.prototypeIds[0]
context.push(_level = 'index', layoutMode = layoutMode)
try:
headerTitle, pageBodyLayout, buttonsBarLayout, inForm = \
mode.getModelLayoutInfos(object, None, create)
layout = X.array()
if inForm:
if context.getVar('error'):
layout += object.getErrorLayout()
form = X.form(action = X.actionUrl('submit'),
enctype = 'multipart/form-data', method = 'post')
layout += form
if modeName:
form += X.input(name = 'modeName', type = 'hidden',
value = modeName)
if create:
form += X.input(name = 'prototypeId', type = 'hidden',
value = prototypeId)
form += pageBodyLayout
if buttonsBarLayout:
form += buttonsBarLayout
else:
layout += pageBodyLayout
if buttonsBarLayout:
layout += buttonsBarLayout
context.push(
currentObject = WebAPI.GlasnostObject(object = object))
layout = writePageLayout(layout, headerTitle)
context.pull()
return layout
finally:
context.pull(_level = 'index')
def parseHttpPathAction(self, remaining):
context.push()
try:
if not remaining:
remaining = [] # Duplicate it for the insert below.
modeName = None
else:
modeName = remaining[0]
remaining = remaining[1:]
id = context.getVar('objectId')
localId = commonTools.extractLocalId(id)
if localId.startswith('draft/'):
draftKey = localId
session = context.getVar('session')
if session is None or not session.has_key(draftKey):
return pageNotFound()
object = cPickle.loads(session[draftKey])
else:
if not self.hasObject(id):
return None
if not self.canGetObject(id):
return None
object = self.getObject(id)
object.__class__ = CardForUse # Important.
if not modeName:
modeName = object.getDefaultModeName()
elif modeName == 'new':
modeName = object.getDefaultImplementModeName()
remaining.insert(0, 'new')
if not object.hasMode(modeName):
return None
context.setVar('function', self.index)
remaining.insert(0, modeName)
return context.getVar('application').parseHttpPathArguments(
remaining)
finally:
context.pull()
def parseHttpPathId(self, remaining):
context.push()
try:
assert context.getVar('objectId') is None
assert context.getVar('serverRole') is not None
if not remaining:
return None
if remaining[0] == 'draft':
if len(remaining) < 2:
return None
localId = '%s/%s' % (remaining[0], remaining[1])
remaining = remaining[2:]
else:
localId = remaining[0]
remaining = remaining[1:]
objectId = '%s/%s/%s' % (
context.getVar('dispatcherId'),
context.getVar('serverRole'),
localId)
context.setVar('objectId', objectId)
result = context.getVar('application').parseHttpPathAction(
remaining)
if result is not None:
return result
return None
finally:
context.pull()
def submit(self, id = '', modeName = '', prototypeId = '', **keywords):
if keywords is None:
keywords = {}
keywords['id'] = id # FIXME: not sure it is still useful
if isButtonSelected('applyButton', keywords):
context.setVar('again', 1)
context.setVar('hideErrors', 1)
removeDraft = 0
if id:
localId = commonTools.extractLocalId(id)
if localId.startswith('draft/'):
draftKey = localId
session = context.getVar('session')
if session is None or not session.has_key(draftKey):
if context.getVar('debug'):
raise
return accessForbidden()
object = cPickle.loads(session[draftKey])
removeDraft = 1
else:
object = self.getObject(id)
object.__class__ = CardForUse # Important.
else:
if not prototypeId:
return accessForbidden()
object = self.newObject(keywords)
object.prototypeIds = [prototypeId]
object.__class__ = CardForUse # Important.
mode = object.getMode(modeName)
identitiesProxy = getProxyForServerRole('identities')
if not identitiesProxy.setContainsUser(
mode.getModelUsersSet(object)):
return accessForbidden()
command = Command()
command.action = 'submit'
command.nextObjectId = id
context.push(_level = 'submit',
command = command)
try:
mode.submitModelFields(object, keywords)
finally:
# I don't like this; why is the submit in its own context ?
again = context.getVar('again')
error = context.getVar('error')
command = context.getVar('command')
context.pull(_level = 'submit')
if again:
context.setVar('again', 1)
if error:
context.setVar('error', 1)
if context.getVar('again'):
return self.indexObject(object, mode, command)
mode.executeModel(object, 'onSubmit', command)
action = command.action
if action == 'create' or action == 'submit' and not id:
try:
id = self.addObject(object)
except faults.Fault:
if context.getVar('debug'):
raise
return accessForbidden()
elif action == 'modify' or action == 'submit' and id:
slotToModifyNames = mode.getModelSlotToModifyNames(object)
if slotToModifyNames:
# The previous test is needed because modifyPartialObject
# modifies every slot when slotToModifyNames is empty.
try:
self.modifyPartialObject(object, slotToModifyNames)
except faults.WrongVersion:
context.setVar('again', 1)
context.setVar('error', 1)
object.setError('version', 1)
return self.indexObject(object, mode, command)
except:
if context.getVar('debug'):
raise
return accessForbidden()
elif action == 'delete':
try:
self.deleteObject(id)
except faults.Fault:
if context.getVar('debug'):
raise
return accessForbidden()
elif action == 'draft':
session = context.getVar('session')
if session is None:
if context.getVar('debug'):
raise
return accessForbidden()
if object.draftKey is not None \
and session.has_key(object.draftKey):
draftKey = object.draftKey
else:
if session.has_key('lastDraftNumber'):
# A session can store only two drafts.
draftNumber = (session['lastDraftNumber'] + 1) % 2
else:
draftNumber = 0
session['lastDraftNumber'] = draftNumber
draftKey = 'draft/%d' % draftNumber
session[draftKey] = cPickle.dumps(object)
session['isDirty'] = 1
defaultDispatcherId = context.getVar('defaultDispatcherId')
id = '%s/%s' % (commonTools.makeApplicationId(
defaultDispatcherId, self.serverRole),
draftKey)
removeDraft = 0
elif action:
if context.getVar('debug'):
raise faults.UnknownCommandAction(action)
return accessForbidden()
else:
# Accept empty action.
pass
if removeDraft and object.draftKey is not None:
session = context.getVar('session')
if session is not None and session.has_key(object.draftKey):
del session[draftKey]
session['isDirty'] = 1
# FIXME: To improve.
if not command.nextObjectId:
command.nextObjectId = id
return redirect(command.getNextUrl())
submit.isPublicForWeb = 1
def submitDefinition(self, id, contentPath = '', **keywords):
if keywords is None:
keywords = {}
keywords['id'] = id
keywords['contentPath'] = contentPath
if isButtonSelected('applyButton', keywords):
context.setVar('again', 1)
context.setVar('hideErrors', 1)
if id:
object = self.getObject(id)
else:
object = self.newObject(keywords)
object.__class__ = CardForDefinition # Important.
try:
contentSlot = object.getSlotByPath(contentPath)
except: # FIXME.
if context.getVar('debug'):
raise
return pageNotFound()
if contentSlot is None:
contentSlot = slots.Root(object)
content = contentSlot.getValue()
contentKind = contentSlot.getKind()
contentWidget = contentSlot.getWidget()
contentWidget.submitEmbedded(contentSlot, keywords)
if context.getVar('again'):
return self.editDefinitionObject(object, contentPath)
if not id:
try:
id = self.addObject(object)
except faults.Fault:
if context.getVar('debug'):
raise
return accessForbidden()
else:
try:
self.modifyPartialObject(object, object.getSlotToModifyNames())
except faults.WrongVersion:
context.setVar('again', 1)
context.setVar('error', 1)
object.setError('version', 1)
return self.editDefinitionObject(object, contentPath)
except:
if context.getVar('debug'):
raise
return accessForbidden()
return redirect(X.idUrl(id, 'definition/%s' % contentPath))
submitDefinition.isPublicForWeb = 1
def use(self, *arguments, **keywords):
pass
use.isPublicForWeb = 0 # Important, so that self.parseHttpPathAction is
# called.
def view(self, *arguments, **keywords):
pass
view.isPublicForWeb = 0 # Important, so that self.parseHttpPathAction is
# called.