Improved and generalized intra- and inter-objects navigation.

This commit is contained in:
Gaetan Delannay 2010-09-17 15:32:48 +02:00
parent 88cd4f7c46
commit c2a3551a94
12 changed files with 132 additions and 101 deletions

View file

@ -285,20 +285,16 @@ class ToolMixin(AbstractMixin):
appName = self.getProductConfig().PROJECTNAME appName = self.getProductConfig().PROJECTNAME
return self.utranslate(label, self.translationMapping, domain=appName) return self.utranslate(label, self.translationMapping, domain=appName)
def getPublishedObject(self, rootClasses): def getPublishedObject(self):
'''Gets the currently published object, if its meta_class is among '''Gets the currently published object, if its meta_class is among
p_rootClasses or if it is the corresponding tool or flavour.''' application classes.'''
rq = self.REQUEST rq = self.REQUEST
obj = rq['PUBLISHED'] obj = rq['PUBLISHED']
parent = obj.getParentNode() parent = obj.getParentNode()
if parent.id == 'skyn': if parent.id == 'skyn':
obj = parent.getParentNode() obj = parent.getParentNode()
if obj.meta_type in rootClasses: if obj.meta_type in self.getProductConfig().attributes:
return obj return obj
else:
appName = self.getAppName()
if obj.meta_type in ('%sTool' % appName, '%sFlavour' % appName):
return obj
return None return None
def getAppyClass(self, contentType): def getAppyClass(self, contentType):
@ -579,8 +575,9 @@ class ToolMixin(AbstractMixin):
label = '%s_search_%s' % (d1.split(':')[0], searchName) label = '%s_search_%s' % (d1.split(':')[0], searchName)
res['backText'] = self.translate(label) res['backText'] = self.translate(label)
else: else:
fieldName, pageName = d2.split(':')
sourceObj = self.uid_catalog(UID=d1)[0].getObject() sourceObj = self.uid_catalog(UID=d1)[0].getObject()
label = '%s_%s' % (sourceObj.meta_type, d2) label = '%s_%s' % (sourceObj.meta_type, fieldName)
res['backText'] = u'%s : %s' % (sourceObj.Title().decode('utf-8'), res['backText'] = u'%s : %s' % (sourceObj.Title().decode('utf-8'),
self.translate(label)) self.translate(label))
newNav = '%s.%s.%s.%%d.%s' % (t, d1, d2, totalNumber) newNav = '%s.%s.%s.%%d.%s' % (t, d1, d2, totalNumber)
@ -600,7 +597,6 @@ class ToolMixin(AbstractMixin):
if (nextIndex < lastIndex): lastNeeded = True if (nextIndex < lastIndex): lastNeeded = True
# Get the list of available UIDs surrounding the current object # Get the list of available UIDs surrounding the current object
if t == 'ref': # Manage navigation from a reference if t == 'ref': # Manage navigation from a reference
fieldName = d2
masterObj = self.getObject(d1) masterObj = self.getObject(d1)
batchSize = masterObj.getAppyType(fieldName).maxPerPage batchSize = masterObj.getAppyType(fieldName).maxPerPage
uids = getattr(masterObj, '_appy_%s' % fieldName) uids = getattr(masterObj, '_appy_%s' % fieldName)
@ -611,9 +607,9 @@ class ToolMixin(AbstractMixin):
startNumberKey = '%s%s_startNumber' % (masterObj.UID(), fieldName) startNumberKey = '%s%s_startNumber' % (masterObj.UID(), fieldName)
startNumber = self.computeStartNumberFrom(res['currentNumber']-1, startNumber = self.computeStartNumberFrom(res['currentNumber']-1,
res['totalNumber'], batchSize) res['totalNumber'], batchSize)
res['sourceUrl'] = '%s?%s=%s' % (masterObj.getUrl(), res['sourceUrl'] = masterObj.getUrl(**{startNumberKey:startNumber,
startNumberKey, startNumber) 'page':pageName, 'nav':''})
else: # Manage navigation from a search else: # Manage navigation from a search
contentType, flavourNumber = d1.split(':') contentType, flavourNumber = d1.split(':')
flavourNumber = int(flavourNumber) flavourNumber = int(flavourNumber)
searchName = keySuffix = d2 searchName = keySuffix = d2
@ -661,9 +657,9 @@ class ToolMixin(AbstractMixin):
if uid: if uid:
brain = self.uid_catalog(UID=uid) brain = self.uid_catalog(UID=uid)
if brain: if brain:
baseUrl = brain[0].getObject().getUrl() sibling = brain[0].getObject()
navUrl = baseUrl + '/?nav=' + newNav % (index + 1) res[urlKey] = sibling.getUrl(nav=newNav % (index + 1),
res[urlKey] = navUrl page='main')
return res return res
def tabularize(self, data, numberOfRows): def tabularize(self, data, numberOfRows):

View file

@ -91,7 +91,7 @@ class AbstractMixin:
baseUrl = self.absolute_url() baseUrl = self.absolute_url()
objId = self.generateUniqueId(rq.get('type_name')) objId = self.generateUniqueId(rq.get('type_name'))
urlBack = '%s/portal_factory/%s/%s/skyn/edit' % \ urlBack = '%s/portal_factory/%s/%s/skyn/edit' % \
(baseUrl, rq.get('type_name'), objId) (baseUrl, rq.get('type_name'), objId)
return self.goto(urlBack) return self.goto(urlBack)
def intraFieldValidation(self, errors, values): def intraFieldValidation(self, errors, values):
@ -148,10 +148,10 @@ class AbstractMixin:
# Go back to the Plone site (no better solution at present). # Go back to the Plone site (no better solution at present).
urlBack = self.portal_url.getPortalObject().absolute_url() urlBack = self.portal_url.getPortalObject().absolute_url()
else: else:
urlBack = self.absolute_url() urlBack = self.getUrl()
self.plone_utils.addPortalMessage( self.plone_utils.addPortalMessage(
self.translate('Changes canceled.', domain='plone')) self.translate('Changes canceled.', domain='plone'))
return self.goto(urlBack, True) return self.goto(urlBack)
# Object for storing validation errors # Object for storing validation errors
errors = AppyObject() errors = AppyObject()
@ -180,7 +180,7 @@ class AbstractMixin:
if rq.get('buttonOk.x', None): if rq.get('buttonOk.x', None):
# Go to the consult view for this object # Go to the consult view for this object
obj.plone_utils.addPortalMessage(msg) obj.plone_utils.addPortalMessage(msg)
return self.goto('%s/skyn/view' % obj.absolute_url(), True) return self.goto(obj.getUrl())
if rq.get('buttonPrevious.x', None): if rq.get('buttonPrevious.x', None):
# Go to the previous page for this object. # Go to the previous page for this object.
# We recompute the list of phases and pages because things # We recompute the list of phases and pages because things
@ -193,34 +193,30 @@ class AbstractMixin:
phaseInfo = self.getAppyPhases(page=currentPage) phaseInfo = self.getAppyPhases(page=currentPage)
previousPage, show = self.getPreviousPage(phaseInfo, currentPage) previousPage, show = self.getPreviousPage(phaseInfo, currentPage)
if previousPage: if previousPage:
# Return the edit or view page? # Return to the edit or view page?
if show != 'view': if show != 'view':
rq.set('page', previousPage) rq.set('page', previousPage)
return obj.skyn.edit(obj) return obj.skyn.edit(obj)
else: else:
urlBack = '%s/skyn/view?page=%s' % (obj.absolute_url(), return self.goto(obj.getUrl(page=previousPage))
previousPage)
return self.goto(urlBack)
else: else:
obj.plone_utils.addPortalMessage(msg) obj.plone_utils.addPortalMessage(msg)
return self.goto('%s/skyn/view' % obj.absolute_url()) return self.goto(obj.getUrl())
if rq.get('buttonNext.x', None): if rq.get('buttonNext.x', None):
# Go to the next page for this object # Go to the next page for this object
currentPage = rq.get('page') currentPage = rq.get('page')
phaseInfo = self.getAppyPhases(page=currentPage) phaseInfo = self.getAppyPhases(page=currentPage)
nextPage, show = self.getNextPage(phaseInfo, currentPage) nextPage, show = self.getNextPage(phaseInfo, currentPage)
if nextPage: if nextPage:
# Return the edit or view page? # Return to the edit or view page?
if show != 'view': if show != 'view':
rq.set('page', nextPage) rq.set('page', nextPage)
return obj.skyn.edit(obj) return obj.skyn.edit(obj)
else: else:
urlBack = '%s/skyn/view?page=%s' % (obj.absolute_url(), return self.goto(obj.getUrl(page=nextPage))
nextPage)
return self.goto(urlBack)
else: else:
obj.plone_utils.addPortalMessage(msg) obj.plone_utils.addPortalMessage(msg)
return self.goto('%s/skyn/view' % obj.absolute_url()) return self.goto(obj.getUrl())
return obj.skyn.edit(obj) return obj.skyn.edit(obj)
def onDelete(self): def onDelete(self):
@ -228,7 +224,7 @@ class AbstractMixin:
msg = self.translate('delete_done') msg = self.translate('delete_done')
self.delete() self.delete()
self.plone_utils.addPortalMessage(msg) self.plone_utils.addPortalMessage(msg)
self.goto(rq['HTTP_REFERER'], True) self.goto(self.getUrl(rq['HTTP_REFERER']))
def rememberPreviousData(self): def rememberPreviousData(self):
'''This method is called before updating an object and remembers, for '''This method is called before updating an object and remembers, for
@ -280,17 +276,7 @@ class AbstractMixin:
def goto(self, url, addParams=False): def goto(self, url, addParams=False):
'''Brings the user to some p_url after an action has been executed.''' '''Brings the user to some p_url after an action has been executed.'''
rq = self.REQUEST return self.REQUEST.RESPONSE.redirect(url)
if not addParams: return rq.RESPONSE.redirect(url)
# Add some context-related parameters if needed.
params = []
if rq.get('page', ''): params.append('page=%s' % rq['page'])
if rq.get('nav', ''): params.append('nav=%s' % rq['nav'])
params = '&'.join(params)
if not params: return rq.RESPONSE.redirect(url)
if url.find('?') != -1: params = '&' + params
else: params = '?' + params
return rq.RESPONSE.redirect(url+params)
def showField(self, name, layoutType='view'): def showField(self, name, layoutType='view'):
'''Must I show field named p_name on this p_layoutType ?''' '''Must I show field named p_name on this p_layoutType ?'''
@ -300,9 +286,14 @@ class AbstractMixin:
'''Returns the method named p_methodName.''' '''Returns the method named p_methodName.'''
return getattr(self, methodName, None) return getattr(self, methodName, None)
def getFieldValue(self, name): def getFieldValue(self, name, onlyIfSync=False, layoutType=None):
'''Returns the database value of field named p_name for p_self.''' '''Returns the database value of field named p_name for p_self.
return self.getAppyType(name).getValue(self) If p_onlyIfSync is True, it returns the value only if appyType can be
retrieved in synchronous mode.'''
appyType = self.getAppyType(name)
if not onlyIfSync or (onlyIfSync and appyType.sync[layoutType]):
return appyType.getValue(self)
return None
def getFormattedFieldValue(self, name, value): def getFormattedFieldValue(self, name, value):
'''Gets a nice, string representation of p_value which is a value from '''Gets a nice, string representation of p_value which is a value from
@ -759,7 +750,7 @@ class AbstractMixin:
msg = self.translate(label) msg = self.translate(label)
if (resultType == 'computation') or not successfull: if (resultType == 'computation') or not successfull:
self.plone_utils.addPortalMessage(msg) self.plone_utils.addPortalMessage(msg)
return self.goto(rq['HTTP_REFERER'], True) return self.goto(self.getUrl(rq['HTTP_REFERER']))
else: else:
# msg does not contain a message, but a complete file to show as is. # msg does not contain a message, but a complete file to show as is.
# (or, if your prefer, the message must be shown directly to the # (or, if your prefer, the message must be shown directly to the
@ -1018,9 +1009,38 @@ class AbstractMixin:
exec 'self.set%s%s([])' % (appyType.name[0].upper(), exec 'self.set%s%s([])' % (appyType.name[0].upper(),
appyType.name[1:]) appyType.name[1:])
def getUrl(self): getUrlDefaults = {'page':True, 'nav':True}
'''Returns the Appy URL for viewing this object.''' def getUrl(self, base=None, mode='view', **kwargs):
return self.absolute_url() + '/skyn/view' '''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_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
if not base: base = self.absolute_url()
# Manage default args
if not kwargs: kwargs = self.getUrlDefaults
if 'page' not in kwargs: kwargs['page'] = True
if 'nav' not in kwargs: kwargs['nav'] = True
# Create URL parameters from kwargs
params = []
for name, value in kwargs.iteritems():
if isinstance(value, basestring):
params.append('%s=%s' % (name, value))
elif self.REQUEST.get(name, ''):
params.append('%s=%s' % (name, self.REQUEST[name]))
if params:
params = '&'.join(params)
if base.find('?') != -1: params = '&' + params
else: params = '?' + params
else:
params = ''
# Return the full constructed URL
return '%s/skyn/%s%s' % (base, mode, params)
def translate(self, label, mapping={}, domain=None, default=None): def translate(self, label, mapping={}, domain=None, default=None):
'''Translates a given p_label into p_domain with p_mapping.''' '''Translates a given p_label into p_domain with p_mapping.'''
@ -1030,7 +1050,7 @@ class AbstractMixin:
domain, label, mapping, self, default=default) domain, label, mapping, self, default=default)
def getPageLayout(self, layoutType): def getPageLayout(self, layoutType):
'''Returns the layout coresponding to p_layoutType for p_self.''' '''Returns the layout corresponding to p_layoutType for p_self.'''
appyClass = self.wrapperClass.__bases__[-1] appyClass = self.wrapperClass.__bases__[-1]
if hasattr(appyClass, 'layouts'): if hasattr(appyClass, 'layouts'):
layout = appyClass.layouts[layoutType] layout = appyClass.layouts[layoutType]

View file

@ -86,14 +86,14 @@
<img tal:condition="python: repeat['columnHeader'].number() == 1" <img tal:condition="python: repeat['columnHeader'].number() == 1"
tal:attributes="src string:$portal_url/skyn/eye.png; tal:attributes="src string:$portal_url/skyn/eye.png;
title python: tool.translate('import_show_hide')" title python: tool.translate('import_show_hide')"
style="cursor:pointer" onClick="javascript:toggleViewableElements()" align="left" /> style="cursor:pointer" onClick="toggleViewableElements()" align="left" />
<span tal:replace="columnHeader"/> <span tal:replace="columnHeader"/>
</th> </th>
<th tal:content="python: tool.translate('ref_actions')"></th> <th tal:content="python: tool.translate('ref_actions')"></th>
<th width="20px"><img <th width="20px"><img
tal:attributes="src string: $portal_url/skyn/select_elems.png; tal:attributes="src string: $portal_url/skyn/select_elems.png;
title python: tool.translate('select_delesect')" title python: tool.translate('select_delesect')"
onClick="javascript:toggleCheckboxes()" style="cursor:pointer"/> onClick="toggleCheckboxes()" style="cursor:pointer"/>
</tr> </tr>
<tal:row repeat="row python: importElems[1]"> <tal:row repeat="row python: importElems[1]">
<tr tal:define="alreadyImported python: tool.isAlreadyImported(contentType, row[0]); <tr tal:define="alreadyImported python: tool.isAlreadyImported(contentType, row[0]);
@ -106,7 +106,7 @@
</td> </td>
<td> <td>
<input type="button" tal:condition="not: alreadyImported" <input type="button" tal:condition="not: alreadyImported"
tal:attributes="onClick python: 'javascript:importSingleElement(\'%s\')' % row[0]; tal:attributes="onClick python: 'importSingleElement(\'%s\')' % row[0];
value python: tool.translate('query_import')"/> value python: tool.translate('query_import')"/>
<span tal:condition="alreadyImported" tal:replace="python: tool.translate('import_already')"/> <span tal:condition="alreadyImported" tal:replace="python: tool.translate('import_already')"/>
</td> </td>
@ -118,7 +118,7 @@
</table> </table>
<tal:comment replace="nothing">Button for importing several elements at once.</tal:comment> <tal:comment replace="nothing">Button for importing several elements at once.</tal:comment>
<p align="right"><br/> <p align="right"><br/>
<input type="button" onClick="javascript:importManyElements()" <input type="button" onClick="importManyElements()"
tal:condition="python: importElems[1] and not allAreImported" tal:condition="python: importElems[1] and not allAreImported"
tal:attributes="value python:tool.translate('import_many')"/> tal:attributes="value python:tool.translate('import_many')"/>
</p> </p>

View file

@ -91,8 +91,8 @@
<tal:comment replace="nothing">Mandatory column "Title"/"Name"</tal:comment> <tal:comment replace="nothing">Mandatory column "Title"/"Name"</tal:comment>
<td id="field_title"><a <td id="field_title"><a
tal:define="navInfo python:'nav=search.%s:%d.%s.%d.%d' % (contentType, flavourNumber, searchName, repeat['obj'].number()+startNumber, totalNumber);" tal:define="navInfo python:'search.%s:%d.%s.%d.%d' % (contentType, flavourNumber, searchName, repeat['obj'].number()+startNumber, totalNumber);"
tal:content="obj/Title" tal:attributes="href python: obj.getUrl() + '/?' + navInfo"></a></td> tal:content="obj/Title" tal:attributes="href python: obj.getUrl(nav=navInfo, page='main')"></a></td>
<tal:comment replace="nothing">Columns corresponding to other fields</tal:comment> <tal:comment replace="nothing">Columns corresponding to other fields</tal:comment>
<tal:otherFields repeat="widget fieldDescrs"> <tal:otherFields repeat="widget fieldDescrs">
@ -124,8 +124,10 @@
<table class="no-style-table" cellpadding="0" cellspacing="0"> <table class="no-style-table" cellpadding="0" cellspacing="0">
<tr> <tr>
<tal:comment replace="nothing">Edit the element</tal:comment> <tal:comment replace="nothing">Edit the element</tal:comment>
<td class="noPadding"><a tal:attributes="href python: obj.absolute_url() + '/skyn/edit'" <td class="noPadding">
tal:condition="python: member.has_permission('Modify portal content', obj)"> <a tal:define="navInfo python:'search.%s:%d.%s.%d.%d' % (contentType, flavourNumber, searchName, repeat['obj'].number()+startNumber, totalNumber);"
tal:attributes="href python: obj.getUrl(mode='edit', page='main', nav=navInfo)"
tal:condition="python: member.has_permission('Modify portal content', obj)">
<img title="Edit" i18n:domain="plone" i18n:attributes="title" <img title="Edit" i18n:domain="plone" i18n:attributes="title"
tal:attributes="src string: $portal_url/skyn/edit.gif"/> tal:attributes="src string: $portal_url/skyn/edit.gif"/>
</a></td> </a></td>
@ -134,7 +136,7 @@
<img tal:condition="python: member.has_permission('Delete objects', obj)" <img tal:condition="python: member.has_permission('Delete objects', obj)"
title="Delete" i18n:domain="plone" i18n:attributes="title" style="cursor:pointer" title="Delete" i18n:domain="plone" i18n:attributes="title" style="cursor:pointer"
tal:attributes="src string: $portal_url/skyn/delete.png; tal:attributes="src string: $portal_url/skyn/delete.png;
onClick python:'javascript:onDeleteObject(\'%s\')' % obj.UID()"/> onClick python:'onDeleteObject(\'%s\')' % obj.UID()"/>
</td> </td>
</tr> </tr>
</table> </table>

View file

@ -46,7 +46,7 @@
</table> </table>
</div> </div>
<div metal:define-macro="objectNavigate" tal:condition="request/nav|nothing" align="right"> <div metal:define-macro="objectNavigate" tal:condition="request/nav|nothing">
<tal:comment replace="nothing"> <tal:comment replace="nothing">
Buttons for going to next/previous elements if this one is among bunch of referenced or searched objects. Buttons for going to next/previous elements if this one is among bunch of referenced or searched objects.
currentNumber starts with 1. currentNumber starts with 1.

View file

@ -242,7 +242,8 @@
} }
// Function that allows to generate a document from a pod template. // Function that allows to generate a document from a pod template.
function generatePodDocument(contextUid, templateUid, fieldName, podFormat) { function generatePodDocument(contextUid, templateUid, fieldName, podFormat) {
var theForm = document.forms["podTemplateForm"]; var theForm = document.getElementsByName("podTemplateForm")[0];
alert('The form =' + theForm);
theForm.objectUid.value = contextUid; theForm.objectUid.value = contextUid;
theForm.templateUid.value = templateUid; theForm.templateUid.value = templateUid;
theForm.fieldName.value = fieldName; theForm.fieldName.value = fieldName;
@ -395,7 +396,7 @@
tal:repeat="podTemplate podTemplates"> tal:repeat="podTemplate podTemplates">
<a style="cursor: pointer" <a style="cursor: pointer"
tal:define="podFormat podTemplate/getPodFormat" tal:define="podFormat podTemplate/getPodFormat"
tal:attributes="onclick python: 'javascript:generatePodDocument(\'%s\',\'%s\', \'\', \'\')' % (contextObj.UID(), podTemplate.UID())" > tal:attributes="onclick python: 'generatePodDocument(\'%s\',\'%s\', \'\', \'\')' % (contextObj.UID(), podTemplate.UID())" >
<img tal:attributes="src string: $portal_url/skyn/$podFormat.png"/> <img tal:attributes="src string: $portal_url/skyn/$podFormat.png"/>
<span tal:replace="podTemplate/Title"/> <span tal:replace="podTemplate/Title"/>
</a> </a>
@ -404,7 +405,7 @@
<select tal:condition="python: len(podTemplates)&gt;maxShownTemplates"> <select tal:condition="python: len(podTemplates)&gt;maxShownTemplates">
<option value="" tal:content="python: tool.translate('choose_a_doc')"></option> <option value="" tal:content="python: tool.translate('choose_a_doc')"></option>
<option tal:repeat="podTemplate podTemplates" tal:content="podTemplate/Title" <option tal:repeat="podTemplate podTemplates" tal:content="podTemplate/Title"
tal:attributes="onclick python: 'javascript:generatePodDocument(\'%s\',\'%s\', \'\', \'\')' % (contextObj.UID(), podTemplate.UID())" /> tal:attributes="onclick python: 'generatePodDocument(\'%s\',\'%s\', \'\', \'\')' % (contextObj.UID(), podTemplate.UID())" />
</select> </select>
</tal:podTemplates> </tal:podTemplates>
</div> </div>
@ -522,7 +523,7 @@
<td align="right" tal:repeat="transition transitions"> <td align="right" tal:repeat="transition transitions">
<input type="button" class="context" <input type="button" class="context"
tal:attributes="value python: tool.translate(transition['name']); tal:attributes="value python: tool.translate(transition['name']);
onClick python: 'javascript: triggerTransition(\'%s\')' % transition['id'];"/> onClick python: 'triggerTransition(\'%s\')' % transition['id'];"/>
</td> </td>
</tr> </tr>
</table> </table>
@ -560,7 +561,7 @@
<tal:comment replace="nothing">Creator and last modification date</tal:comment> <tal:comment replace="nothing">Creator and last modification date</tal:comment>
<tal:comment replace="nothing">Plus/minus icon for accessing history</tal:comment> <tal:comment replace="nothing">Plus/minus icon for accessing history</tal:comment>
<tal:accessHistory condition="hasHistory"> <tal:accessHistory condition="hasHistory">
<img align="left" style="cursor:pointer" onClick="javascript:toggleCookie('appyHistory')" <img align="left" style="cursor:pointer" onClick="toggleCookie('appyHistory')"
tal:attributes="src python:test(historyExpanded, 'skyn/collapse.gif', 'skyn/expand.gif');" tal:attributes="src python:test(historyExpanded, 'skyn/collapse.gif', 'skyn/expand.gif');"
id="appyHistory_img"/>&nbsp; id="appyHistory_img"/>&nbsp;
<span i18n:translate="label_history" i18n:domain="plone" class="appyHistory"></span>&nbsp; <span i18n:translate="label_history" i18n:domain="plone" class="appyHistory"></span>&nbsp;
@ -659,7 +660,7 @@
<div metal:define-macro="buttons" <div metal:define-macro="buttons"
tal:define="previousPage python: contextObj.getPreviousPage(phaseInfo, page)[0]; tal:define="previousPage python: contextObj.getPreviousPage(phaseInfo, page)[0];
nextPage python: contextObj.getNextPage(phaseInfo, page)[0]; nextPage python: contextObj.getNextPage(phaseInfo, page)[0];
isEdit python: layoutType == 'edit';"> isEdit python: layoutType == 'edit'">
<br/> <br/>
<tal:previousButton condition="previousPage"> <tal:previousButton condition="previousPage">
<tal:button condition="isEdit"> <tal:button condition="isEdit">
@ -669,7 +670,7 @@
<input type="hidden" name="previousPage" tal:attributes="value previousPage"/> <input type="hidden" name="previousPage" tal:attributes="value previousPage"/>
</tal:button> </tal:button>
<tal:link condition="not: isEdit"> <tal:link condition="not: isEdit">
<a tal:attributes="href python: contextObj.getUrl()+'?page=%s' % previousPage"> <a tal:attributes="href python: contextObj.getUrl(page=previousPage)">
<img tal:attributes="src string:$portal_url/skyn/previous.png" <img tal:attributes="src string:$portal_url/skyn/previous.png"
title="label_previous" i18n:attributes="title" i18n:domain="plone"/> title="label_previous" i18n:attributes="title" i18n:domain="plone"/>
</a> </a>
@ -689,10 +690,8 @@
</tal:cancelButton> </tal:cancelButton>
<tal:editLink condition="python: not isEdit and (phaseInfo['pageShows'][page] != 'view')"> <tal:editLink condition="python: not isEdit and (phaseInfo['pageShows'][page] != 'view')">
<img tal:define="nav request/nav|nothing; <img title="Edit" i18n:domain="plone" i18n:attributes="title" style="cursor:pointer"
nav python: test(nav, '&nav=%s' % nav, '')" tal:attributes="onClick python: 'href: window.location=\'%s\'' % contextObj.getUrl(mode='edit', page=page);
title="Edit" i18n:domain="plone" i18n:attributes="title" style="cursor:pointer"
tal:attributes="onClick python: 'href: window.location=\'%s/skyn/edit?page=%s%s\'' % (contextObj.absolute_url(), page, nav);
src string: $portal_url/skyn/editBig.png" src string: $portal_url/skyn/editBig.png"
tal:condition="python: member.has_permission('Modify portal content', contextObj)"/> tal:condition="python: member.has_permission('Modify portal content', contextObj)"/>
</tal:editLink> </tal:editLink>
@ -705,7 +704,7 @@
<input type="hidden" name="nextPage" tal:attributes="value nextPage"/> <input type="hidden" name="nextPage" tal:attributes="value nextPage"/>
</tal:button> </tal:button>
<tal:link condition="not: isEdit"> <tal:link condition="not: isEdit">
<a tal:attributes="href python: contextObj.getUrl()+'?&page=%s' % nextPage"> <a tal:attributes="href python: contextObj.getUrl(page=nextPage)">
<img tal:attributes="src string:$portal_url/skyn/next.png" <img tal:attributes="src string:$portal_url/skyn/next.png"
title="label_next" i18n:attributes="title" i18n:domain="plone"/> title="label_next" i18n:attributes="title" i18n:domain="plone"/>
</a> </a>

View file

@ -5,7 +5,7 @@
tal:define="queryUrl python: '%s/skyn/query' % appFolder.absolute_url(); tal:define="queryUrl python: '%s/skyn/query' % appFolder.absolute_url();
currentSearch request/search|nothing; currentSearch request/search|nothing;
currentType request/type_name|nothing; currentType request/type_name|nothing;
contextObj python: tool.getPublishedObject(rootClasses)"> contextObj python: tool.getPublishedObject()">
<tal:comment replace="nothing">Portlet title, with link to tool.</tal:comment> <tal:comment replace="nothing">Portlet title, with link to tool.</tal:comment>
<dt class="portletHeader"> <dt class="portletHeader">
<tal:comment replace="nothing">If there is only one flavour, clicking on the portlet <tal:comment replace="nothing">If there is only one flavour, clicking on the portlet
@ -22,7 +22,7 @@
<td align="right"> <td align="right">
<img style="cursor:pointer" <img style="cursor:pointer"
tal:condition="python: member.has_role('Manager')" tal:condition="python: member.has_role('Manager')"
tal:attributes="onClick python: 'href: window.location=\'%s/skyn/view\'' % tool.absolute_url(); tal:attributes="onClick python: 'href: window.location=\'%s\'' % tool.getUrl(page='main', nav='');
title python: tool.translate('%sTool' % appName); title python: tool.translate('%sTool' % appName);
src string:$portal_url/skyn/appyConfig.gif"/> src string:$portal_url/skyn/appyConfig.gif"/>
</td> </td>
@ -30,7 +30,7 @@
<tal:publishedObject condition="python: contextObj"> <tal:publishedObject condition="python: contextObj">
<dt class="portletAppyItem portletCurrent"> <dt class="portletAppyItem portletCurrent">
<a tal:attributes="href python: contextObj.getUrl() + '?page=main'" <a tal:attributes="href python: contextObj.getUrl(page='main')"
tal:content="contextObj/Title"></a> tal:content="contextObj/Title"></a>
</dt> </dt>
<dt class="portletAppyItem"><metal:phases use-macro="here/skyn/portlet/macros/phases"/></dt> <dt class="portletAppyItem"><metal:phases use-macro="here/skyn/portlet/macros/phases"/></dt>
@ -88,7 +88,7 @@
<img align="left" style="cursor:pointer" <img align="left" style="cursor:pointer"
tal:attributes="id python: '%s_img' % group['labelId']; tal:attributes="id python: '%s_img' % group['labelId'];
src python:test(expanded, 'skyn/collapse.gif', 'skyn/expand.gif'); src python:test(expanded, 'skyn/collapse.gif', 'skyn/expand.gif');
onClick python:'javascript:toggleCookie(\'%s\')' % group['labelId']"/>&nbsp; onClick python:'toggleCookie(\'%s\')' % group['labelId']"/>&nbsp;
<span tal:replace="group/label"/> <span tal:replace="group/label"/>
</dt> </dt>
<tal:comment replace="nothing">Group searches</tal:comment> <tal:comment replace="nothing">Group searches</tal:comment>
@ -136,9 +136,9 @@
<div align="center"> <div align="center">
<p tal:content="python: tool.translate('confirm')"></p> <p tal:content="python: tool.translate('confirm')"></p>
<input type="hidden" name="actionFormId"/> <input type="hidden" name="actionFormId"/>
<input type="button" onClick="javascript: doConfirm()" <input type="button" onClick="doConfirm()"
tal:attributes="value python:tool.translate('yes')"/> tal:attributes="value python:tool.translate('yes')"/>
<input type="button" value="No" onClick="javascript:closePopup('confirmActionPopup')" <input type="button" value="No" onClick="closePopup('confirmActionPopup')"
tal:attributes="value python:tool.translate('no')"/> tal:attributes="value python:tool.translate('no')"/>
</div> </div>
</form> </form>
@ -150,7 +150,7 @@
currently shown object, made of phases and contained pages. currently shown object, made of phases and contained pages.
</tal:comment> </tal:comment>
<metal:phases define-macro="phases"> <metal:phases define-macro="phases">
<table tal:define="phases contextObj/getAppyPhases|nothing; <table tal:define="phases contextObj/getAppyPhases|nothing;
page python: request.get('page', 'main')" page python: request.get('page', 'main')"
tal:condition="python: phases and not ((len(phases)==1) and len(phases[0]['pages'])==1)" tal:condition="python: phases and not ((len(phases)==1) and len(phases[0]['pages'])==1)"
cellspacing="1" cellpadding="2" width="100%"> cellspacing="1" cellpadding="2" width="100%">
@ -161,27 +161,38 @@
displayLink python: (phase['phaseStatus'] != 'Future') and ('/portal_factory' not in contextObj.absolute_url()) and (len(phase['pages']) == 1)" displayLink python: (phase['phaseStatus'] != 'Future') and ('/portal_factory' not in contextObj.absolute_url()) and (len(phase['pages']) == 1)"
tal:attributes="class python: (len(phases) &gt; 1) and ('appyPhase step%s' % phase['phaseStatus']) or 'appyPhase'"> tal:attributes="class python: (len(phases) &gt; 1) and ('appyPhase step%s' % phase['phaseStatus']) or 'appyPhase'">
<div class="portletGroup" tal:condition="python: len(phases) &gt; 1"> <div class="portletGroup" tal:condition="python: len(phases) &gt; 1">
<a tal:attributes="href python: '%s?page=%s' % (contextObj.getUrl(), phase['pages'][0]);"
tal:condition="displayLink" <tal:comment replace="nothing">A single page in the phase</tal:comment>
tal:content="python: tool.translate(label)"></a> <table tal:condition="displayLink" cellpadding="0" cellspacing="0" width="100%">
<tr tal:define="pageName python: phase['pages'][0]">
<td><a tal:attributes="href python: contextObj.getUrl(page=pageName)"
tal:content="python: tool.translate(label)"></a>
</td>
<td align="right">
<img title="Edit" i18n:domain="plone" i18n:attributes="title" style="cursor:pointer"
tal:attributes="onClick python: 'href: window.location=\'%s\'' % contextObj.getUrl(mode='edit', page=pageName);
src string: $portal_url/skyn/edit.gif"
tal:condition="python: member.has_permission('Modify portal content', contextObj) and phase['pageShows'][pageName] != 'view'"/>
</td>
</tr>
</table>
<tal:comment replace="nothing">Several pages in the phase</tal:comment>
<span tal:condition="not: displayLink" tal:replace="python: tool.translate(label)"/> <span tal:condition="not: displayLink" tal:replace="python: tool.translate(label)"/>
</div> </div>
<div class="portletMenu"> <div class="portletMenu">
<table width="100%" cellpadding="0" cellspacing="0" <table cellpadding="0" cellspacing="0" width="100%"
tal:condition="python: len(phase['pages']) &gt; 1"> tal:condition="python: len(phase['pages']) &gt; 1">
<tr tal:repeat="aPage phase/pages" valign="top"> <tr tal:repeat="aPage phase/pages" valign="top">
<td tal:attributes="class python: test(aPage == page, 'portletCurrent portletPageItem', 'portletPageItem')"> <td tal:attributes="class python: test(aPage == page, 'portletCurrent portletPageItem', 'portletPageItem')">
<a tal:attributes="href python: contextObj.getUrl()+'?page=%s' % aPage" <a tal:attributes="href python: contextObj.getUrl(page=aPage)"
tal:content="structure python: tool.translate('%s_page_%s' % (contextObj.meta_type, aPage))"> tal:content="structure python: tool.translate('%s_page_%s' % (contextObj.meta_type, aPage))">
</a> </a>
</td> </td>
<td align="right"> <td align="right">
<img tal:define="nav request/nav|nothing; <img title="Edit" i18n:domain="plone" i18n:attributes="title" style="cursor:pointer"
nav python: test(nav, '&nav=%s' % nav, '')" tal:attributes="onClick python: 'href: window.location=\'%s\'' % contextObj.getUrl(mode='edit', page=aPage);
title="Edit" i18n:domain="plone" i18n:attributes="title" style="cursor:pointer" src string: $portal_url/skyn/edit.gif"
tal:attributes="onClick python: 'href: window.location=\'%s/skyn/edit?page=%s%s\'' % (contextObj.absolute_url(), aPage, nav); tal:condition="python: member.has_permission('Modify portal content', contextObj) and phase['pageShows'][aPage] != 'view'"/>
src string: $portal_url/skyn/edit.gif"
tal:condition="python: member.has_permission('Modify portal content', contextObj)"/>
</td> </td>
</tr> </tr>
</table> </table>

View file

@ -9,7 +9,7 @@
<input type="hidden" name="fieldName" tal:attributes="value name"/> <input type="hidden" name="fieldName" tal:attributes="value name"/>
<input type="button" tal:condition="widget/confirm" <input type="button" tal:condition="widget/confirm"
tal:attributes="value label; tal:attributes="value label;
onClick python: 'javascript:askConfirm(\'%s\')' % formId"/> onClick python: 'askConfirm(\'%s\')' % formId"/>
<input type="submit" name="do" tal:condition="not: widget/confirm" <input type="submit" name="do" tal:condition="not: widget/confirm"
tal:attributes="value label" onClick="javascript:;"/> tal:attributes="value label" onClick="javascript:;"/>
<tal:comment replace="nothing">The previous onClick is simply used to prevent Plone <tal:comment replace="nothing">The previous onClick is simply used to prevent Plone

View file

@ -9,7 +9,7 @@
</tal:askAction> </tal:askAction>
<img tal:repeat="podFormat python:flavour.getPodInfo(contextObj, name)['formats']" <img tal:repeat="podFormat python:flavour.getPodInfo(contextObj, name)['formats']"
tal:attributes="src string: $portal_url/skyn/${podFormat}.png; tal:attributes="src string: $portal_url/skyn/${podFormat}.png;
onClick python: 'javascript:generatePodDocument(\'%s\',\'\',\'%s\',\'%s\')' % (contextObj.UID(), name, podFormat); onClick python: 'generatePodDocument(\'%s\',\'\',\'%s\',\'%s\')' % (contextObj.UID(), name, podFormat);
title podFormat/capitalize" title podFormat/capitalize"
style="cursor:pointer"/> style="cursor:pointer"/>
</metal:view> </metal:view>

View file

@ -8,10 +8,11 @@
allows to reach the correct page where the forward reference is defined. If we are allows to reach the correct page where the forward reference is defined. If we are
on a forward reference, the "nav" parameter is added to the URL for allowing to navigate on a forward reference, the "nav" parameter is added to the URL for allowing to navigate
from one object to the next/previous on skyn/view.</tal:comment> from one object to the next/previous on skyn/view.</tal:comment>
<a tal:define="viewUrl obj/getUrl; <a tal:define="includeShownInfo includeShownInfo | python:False;
includeShownInfo includeShownInfo | python:False; navInfo python:'ref.%s.%s:%s.%d.%d' % (contextObj.UID(), fieldName, appyType['page'], repeat['obj'].number()+startNumber, totalNumber);
navInfo python:'nav=ref.%s.%s.%d.%d' % (contextObj.UID(), fieldName, repeat['obj'].number()+startNumber, totalNumber); navInfo python: appyType['isBack'] and '' or navInfo;
fullUrl python: appyType['isBack'] and (viewUrl + '/?page=%s' % appyType['backd']['page']) or (viewUrl + '/?' + navInfo)" pageName python: appyType['isBack'] and appyType['backd']['page'] or 'main';
fullUrl python: obj.getUrl(page=pageName, nav=navInfo)"
tal:attributes="href fullUrl" tal:content="python: (not includeShownInfo) and obj.Title() or contextObj.getReferenceLabel(fieldName, obj.appy())"></a> tal:attributes="href fullUrl" tal:content="python: (not includeShownInfo) and obj.Title() or contextObj.getReferenceLabel(fieldName, obj.appy())"></a>
</metal:objectTitle> </metal:objectTitle>
@ -39,7 +40,9 @@
</tal:moveRef> </tal:moveRef>
</td> </td>
<tal:comment replace="nothing">Edit the element</tal:comment> <tal:comment replace="nothing">Edit the element</tal:comment>
<td class="noPadding"><a tal:attributes="href python: obj.absolute_url() + '/skyn/edit'" <td class="noPadding">
<a tal:define="navInfo python:'ref.%s.%s:%s.%d.%d' % (contextObj.UID(), fieldName, appyType['page'], repeat['obj'].number()+startNumber, totalNumber);"
tal:attributes="href python: obj.getUrl(mode='edit', page='main', nav=navInfo)"
tal:condition="python: member.has_permission('Modify portal content', obj)"> tal:condition="python: member.has_permission('Modify portal content', obj)">
<img title="label_edit" i18n:domain="plone" i18n:attributes="title" <img title="label_edit" i18n:domain="plone" i18n:attributes="title"
tal:attributes="src string: $portal_url/skyn/edit.gif"/> tal:attributes="src string: $portal_url/skyn/edit.gif"/>
@ -49,7 +52,7 @@
<img tal:condition="python: member.has_permission('Delete objects', obj)" <img tal:condition="python: member.has_permission('Delete objects', obj)"
title="Delete" i18n:domain="plone" i18n:attributes="title" style="cursor:pointer" title="Delete" i18n:domain="plone" i18n:attributes="title" style="cursor:pointer"
tal:attributes="src string: $portal_url/skyn/delete.png; tal:attributes="src string: $portal_url/skyn/delete.png;
onClick python:'javascript:onDeleteObject(\'%s\')' % obj.UID()"/> onClick python:'onDeleteObject(\'%s\')' % obj.UID()"/>
</td> </td>
</tr> </tr>
</table> </table>

View file

@ -55,8 +55,8 @@
layout python: widget['layouts'][layoutType]; layout python: widget['layouts'][layoutType];
name widget/name; name widget/name;
sync python: widget['sync'][layoutType]; sync python: widget['sync'][layoutType];
rawValue python: sync and contextObj.getFieldValue(name) or None; rawValue python: contextObj.getFieldValue(name, onlyIfSync=True, layoutType=layoutType);
value python: sync and contextObj.getFormattedFieldValue(name, rawValue) or None; value python: contextObj.getFormattedFieldValue(name, rawValue);
requestValue python: request.get(name, None); requestValue python: request.get(name, None);
inRequest python: request.has_key(name); inRequest python: request.has_key(name);
errors errors | python: (); errors errors | python: ();
@ -103,7 +103,7 @@
id tabId"> id tabId">
<a style="cursor:pointer" <a style="cursor:pointer"
tal:content="python: tool.translate('%s_col%d' % (widget['labelId'], repeat['widgetRow'].number()))" tal:content="python: tool.translate('%s_col%d' % (widget['labelId'], repeat['widgetRow'].number()))"
tal:attributes="onClick python: 'javascript:showTab(\'%s_%d_%d\')' % (widget['name'], repeat['widgetRow'].number(), len(widget['widgets']))"></a> tal:attributes="onClick python: 'showTab(\'%s_%d_%d\')' % (widget['name'], repeat['widgetRow'].number(), len(widget['widgets']))"></a>
</td> </td>
<td><img tal:attributes="src string: $portal_url/skyn/tabRight.png; <td><img tal:attributes="src string: $portal_url/skyn/tabRight.png;
id python: '%s_right' % tabId"/><td> id python: '%s_right' % tabId"/><td>

View file

@ -30,7 +30,7 @@
tal:attributes="name name; tal:attributes="name name;
id name; id name;
multiple python: isMultiple and 'multiple' or ''; multiple python: isMultiple and 'multiple' or '';
onchange python: isMaster and ('javascript:updateSlaves(getMasterValue(this), \'%s\')' % widget['id']) or ''; onchange python: isMaster and ('updateSlaves(getMasterValue(this), \'%s\')' % widget['id']) or '';
class widget/master_css; class widget/master_css;
size python: isMultiple and widget['height'] or 1"> size python: isMultiple and widget['height'] or 1">
<option tal:repeat="possibleValue possibleValues" <option tal:repeat="possibleValue possibleValues"