diff --git a/gen/plone25/mixins/ToolMixin.py b/gen/plone25/mixins/ToolMixin.py
index 0f123a8..8cee75b 100644
--- a/gen/plone25/mixins/ToolMixin.py
+++ b/gen/plone25/mixins/ToolMixin.py
@@ -47,6 +47,10 @@ class ToolMixin(BaseMixin):
res['action'] = appyType.action
return res
+ def getSiteUrl(self):
+ '''Returns the absolute URL of this site.'''
+ return self.portal_url.getPortalObject().absolute_url()
+
def generateDocument(self):
'''Generates the document from field-related info. UID of object that
is the template target is given in the request.'''
diff --git a/gen/plone25/mixins/__init__.py b/gen/plone25/mixins/__init__.py
index 0291387..24a6b52 100644
--- a/gen/plone25/mixins/__init__.py
+++ b/gen/plone25/mixins/__init__.py
@@ -18,7 +18,7 @@ class BaseMixin:
_appy_meta_type = 'Class'
def get_o(self):
- '''In some cases, we wand the Zope object, we don't know if the current
+ '''In some cases, we want the Zope object, we don't know if the current
object is a Zope or Appy object. By defining this property,
"someObject.o" produces always the Zope object, be someObject an Appy
or Zope object.'''
@@ -79,6 +79,18 @@ class BaseMixin:
'''This methods is self's suicide.'''
self.getParentNode().manage_delObjects([self.id])
+ def onDelete(self):
+ rq = self.REQUEST
+ self.delete()
+ if self.getUrl(rq['HTTP_REFERER'],mode='raw') ==self.getUrl(mode='raw'):
+ # We were consulting the object that has been deleted. Go back to
+ # the main page.
+ urlBack = self.getTool().getSiteUrl()
+ else:
+ urlBack = self.getUrl(rq['HTTP_REFERER'])
+ self.plone_utils.addPortalMessage(self.translate('delete_done'))
+ self.goto(urlBack)
+
def onCreate(self):
'''This method is called when a user wants to create a root object in
the application folder or an object through a reference field.'''
@@ -152,6 +164,7 @@ class BaseMixin:
the "final" object in the database. If the object is not a temporary
one, this method updates its fields in the database.'''
rq = self.REQUEST
+ tool = self.getTool()
errorMessage = self.translate(
'Please correct the indicated errors.', domain='plone')
isNew = rq.get('is_new') == 'True'
@@ -161,12 +174,12 @@ class BaseMixin:
if rq.get('nav', ''):
# We can go back to the initiator page.
splitted = rq['nav'].split('.')
- initiator = self.getTool().getObject(splitted[1])
+ initiator = tool.getObject(splitted[1])
initiatorPage = splitted[2].split(':')[1]
urlBack = initiator.getUrl(page=initiatorPage, nav='')
else:
# Go back to the root of the site.
- urlBack = self.portal_url.getPortalObject().absolute_url()
+ urlBack = tool.getSiteUrl()
else:
urlBack = self.getUrl()
self.plone_utils.addPortalMessage(
@@ -192,12 +205,21 @@ class BaseMixin:
self.plone_utils.addPortalMessage(errorMessage)
return self.skyn.edit(self)
+ # Before saving data, must we ask a confirmation by the user ?
+ appyObj = self.appy()
+ saveConfirmed = rq.get('confirmed') == 'True'
+ if hasattr(appyObj, 'confirm') and not saveConfirmed:
+ msg = appyObj.confirm(values)
+ if msg:
+ rq.set('confirmMsg', msg.replace("'", "\\'"))
+ return self.skyn.edit(self)
+
# Create or update the object in the database
obj = self.createOrUpdate(isNew, values)
# Redirect the user to the appropriate page
msg = obj.translate('Changes saved.', domain='plone')
- if rq.get('buttonOk.x', None):
+ if rq.get('buttonOk.x', None) or saveConfirmed:
# Go to the consult view for this object
obj.plone_utils.addPortalMessage(msg)
return self.goto(obj.getUrl())
@@ -237,13 +259,6 @@ class BaseMixin:
return self.goto(obj.getUrl())
return obj.skyn.edit(obj)
- def onDelete(self):
- rq = self.REQUEST
- msg = self.translate('delete_done')
- self.delete()
- self.plone_utils.addPortalMessage(msg)
- self.goto(self.getUrl(rq['HTTP_REFERER']))
-
def rememberPreviousData(self):
'''This method is called before updating an object and remembers, for
every historized field, the previous value. Result is a dict
@@ -754,17 +769,11 @@ class BaseMixin:
rq = self.REQUEST
self.portal_workflow.doActionFor(self, rq['workflow_action'],
comment = rq.get('comment', ''))
- # Where to redirect the user back ?
- urlBack = rq['HTTP_REFERER']
- if urlBack.find('?') != -1:
- # Remove params; this way, the user may be redirected to correct
- # phase when relevant.
- urlBack = urlBack[:urlBack.find('?')]
- msg = self.translate(u'Your content\'s status has been modified.',
- domain='plone')
- self.plone_utils.addPortalMessage(msg)
self.reindexObject()
- return self.goto(urlBack)
+ # Where to redirect the user back ?
+ # TODO (?): remove the "phase" param for redirecting the user to the
+ # next phase when relevant.
+ return self.goto(self.getUrl(rq['HTTP_REFERER']))
def fieldValueSelected(self, fieldName, vocabValue, dbValue):
'''When displaying a selection box (ie a String with a validator being a
@@ -916,15 +925,28 @@ class BaseMixin:
'''Returns a Appy URL.
* If p_base is None, it will be the base URL for this object
(ie, self.absolute_url()).
- * p_mode can de "edit" or "view".
+ * p_mode can be "edit", "view" or "raw" (a non-param, base URL)
* p_kwargs can store additional parameters to add to the URL.
In this dict, every value that is a string will be added to the
URL as-is. Every value that is True will be replaced by the value
in the request for the corresponding key (if existing; else, the
param will not be included in the URL at all).'''
- # Define base URL if ommitted
+ # Define the URL suffix
+ suffix = ''
+ if mode != 'raw': suffix = '/skyn/%s' % mode
+ # Define base URL if omitted
if not base:
- base = '%s/skyn/%s' % (self.absolute_url(), mode)
+ base = self.absolute_url() + suffix
+ # If a raw URL is asked, remove any param and suffix.
+ if mode == 'raw':
+ if '?' in base: base = base[:base.index('?')]
+ base = base.strip('/')
+ for mode in ('view', 'edit'):
+ suffix = 'skyn/%s' % mode
+ if base.endswith(suffix):
+ base = base[:-len(suffix)].strip('/')
+ break
+ return base
# Manage default args
if not kwargs: kwargs = self.getUrlDefaults
if 'page' not in kwargs: kwargs['page'] = True
diff --git a/gen/plone25/skin/edit.pt b/gen/plone25/skin/edit.pt
index 9971906..d43178f 100644
--- a/gen/plone25/skin/edit.pt
+++ b/gen/plone25/skin/edit.pt
@@ -11,7 +11,8 @@
page request/page|python:'main';
cssAndJs python: contextObj.getCssAndJs(layoutType, page);
css python: cssAndJs[0];
- js python: cssAndJs[1]">
+ js python: cssAndJs[1];
+ confirmMsg request/confirmMsg | nothing;">
-
+
diff --git a/gen/plone25/skin/page.pt b/gen/plone25/skin/page.pt
index cb77e19..b4b5002 100644
--- a/gen/plone25/skin/page.pt
+++ b/gen/plone25/skin/page.pt
@@ -46,8 +46,13 @@
if (xhrObjects[pos].onGet) {
xhrObjects[pos].onGet(xhrObjects[pos], hookElem);
}
+ // Eval inner scripts if any.
+ var innerScripts = document.getElementsByName("appyHook");
+ for (var i=0; iView macro for a Ref.
-
@@ -148,9 +147,6 @@
|
-
-
- |
diff --git a/gen/plone25/workflow.py b/gen/plone25/workflow.py
index 35bc18d..f01e048 100644
--- a/gen/plone25/workflow.py
+++ b/gen/plone25/workflow.py
@@ -142,6 +142,7 @@ def do(transitionName, stateChange, logger):
ploneObj = stateChange.object
workflow = ploneObj.getWorkflow()
transition = workflow._transitionsMapping[transitionName]
+ msg = ''
# Must I execute transition-related actions and notifications?
doAction = False
if transition.action:
@@ -161,11 +162,25 @@ def do(transitionName, stateChange, logger):
if doAction or doNotify:
obj = ploneObj.appy()
if doAction:
+ msg = ''
if type(transition.action) in (tuple, list):
# We need to execute a list of actions
- for act in transition.action: act(workflow, obj)
+ for act in transition.action:
+ msgPart = act(workflow, obj)
+ if msgPart: msg += msgPart
else: # We execute a single action only.
- transition.action(workflow, obj)
+ msgPart = transition.action(workflow, obj)
+ if msgPart: msg += msgPart
if doNotify:
notifier.sendMail(obj, transition, transitionName, workflow, logger)
+ # Produce a message to the user
+ if hasattr(ploneObj, '_v_appy_do') and not ploneObj._v_appy_do['doSay']:
+ # We do not produce any message if the transition was triggered
+ # programmatically.
+ return
+ # Produce a default message if no transition has given a custom one.
+ if not msg:
+ msg = ploneObj.translate(u'Your content\'s status has been modified.',
+ domain='plone')
+ ploneObj.plone_utils.addPortalMessage(msg)
# ------------------------------------------------------------------------------
diff --git a/gen/plone25/wrappers/__init__.py b/gen/plone25/wrappers/__init__.py
index 5c1aca7..b21a14d 100644
--- a/gen/plone25/wrappers/__init__.py
+++ b/gen/plone25/wrappers/__init__.py
@@ -90,6 +90,8 @@ class AbstractWrapper:
typeName = property(get_typeName)
def get_id(self): return self.o.id
id = property(get_id)
+ def get_uid(self): return self.o.UID()
+ uid = property(get_uid)
def get_state(self):
return self.o.portal_workflow.getInfoFor(self.o, 'review_state')
state = property(get_state)
@@ -238,7 +240,8 @@ class AbstractWrapper:
# Set in a versatile attribute details about what to execute or not
# (actions, notifications) after the transition has been executed by DC
# workflow.
- self.o._v_appy_do = {'doAction': doAction, 'doNotify': doNotify}
+ self.o._v_appy_do = {'doAction': doAction, 'doNotify': doNotify,
+ 'doSay': False}
if not doHistory:
comment = '_invisible_' # Will not be displayed.
# At first sight, I wanted to remove the entry from