Inter-object navigation.
This commit is contained in:
parent
7cdc3c1ed6
commit
d9484b104e
|
@ -124,6 +124,7 @@ class Generator(AbstractGenerator):
|
||||||
msg('goto_previous', '', msg.GOTO_PREVIOUS),
|
msg('goto_previous', '', msg.GOTO_PREVIOUS),
|
||||||
msg('goto_next', '', msg.GOTO_NEXT),
|
msg('goto_next', '', msg.GOTO_NEXT),
|
||||||
msg('goto_last', '', msg.GOTO_LAST),
|
msg('goto_last', '', msg.GOTO_LAST),
|
||||||
|
msg('goto_source', '', msg.GOTO_SOURCE),
|
||||||
]
|
]
|
||||||
# Create basic files (config.py, Install.py, etc)
|
# Create basic files (config.py, Install.py, etc)
|
||||||
self.generateTool()
|
self.generateTool()
|
||||||
|
|
|
@ -98,9 +98,15 @@ class ToolMixin(AbstractMixin):
|
||||||
def showPortlet(self):
|
def showPortlet(self):
|
||||||
return not self.portal_membership.isAnonymousUser()
|
return not self.portal_membership.isAnonymousUser()
|
||||||
|
|
||||||
|
def getObject(self, uid, appy=False):
|
||||||
|
'''Allows to retrieve an object from its p_uid.'''
|
||||||
|
res = self.uid_catalog(UID=uid)
|
||||||
|
if res: return res[0].getObject()
|
||||||
|
return None
|
||||||
|
|
||||||
_sortFields = {'title': 'sortable_title'}
|
_sortFields = {'title': 'sortable_title'}
|
||||||
def executeQuery(self, contentType, flavourNumber=1, searchName=None,
|
def executeQuery(self, contentType, flavourNumber=1, searchName=None,
|
||||||
startNumber=0, search=None):
|
startNumber=0, search=None, remember=False):
|
||||||
'''Executes a query on a given p_contentType (or several, separated
|
'''Executes a query on a given p_contentType (or several, separated
|
||||||
with commas) in Plone's portal_catalog. Portal types are from the
|
with commas) in Plone's portal_catalog. Portal types are from the
|
||||||
flavour numbered p_flavourNumber. If p_searchName is specified, it
|
flavour numbered p_flavourNumber. If p_searchName is specified, it
|
||||||
|
@ -147,6 +153,21 @@ class ToolMixin(AbstractMixin):
|
||||||
brains = self.portal_catalog.searchResults(**params)
|
brains = self.portal_catalog.searchResults(**params)
|
||||||
res = SomeObjects(brains, self.getNumberOfResultsPerPage(), startNumber)
|
res = SomeObjects(brains, self.getNumberOfResultsPerPage(), startNumber)
|
||||||
res.brainsToObjects()
|
res.brainsToObjects()
|
||||||
|
# In some cases (p_remember=True), we need to keep some information
|
||||||
|
# about the query results in the current user's session, allowing him
|
||||||
|
# to navigate within elements without re-triggering the query every
|
||||||
|
# time a page for an element is consulted.
|
||||||
|
if remember:
|
||||||
|
if not searchName:
|
||||||
|
# It is the global search for all objects pf p_contentType
|
||||||
|
searchName = contentType
|
||||||
|
s = self.REQUEST.SESSION
|
||||||
|
uids = {}
|
||||||
|
i = -1
|
||||||
|
for obj in res.objects:
|
||||||
|
i += 1
|
||||||
|
uids[startNumber+i] = obj.UID()
|
||||||
|
s['search_%s_%s' % (flavourNumber, searchName)] = uids
|
||||||
return res.__dict__
|
return res.__dict__
|
||||||
|
|
||||||
def getResultColumnsNames(self, contentType):
|
def getResultColumnsNames(self, contentType):
|
||||||
|
@ -373,12 +394,122 @@ class ToolMixin(AbstractMixin):
|
||||||
if cookieValue: return cookieValue.value
|
if cookieValue: return cookieValue.value
|
||||||
return default
|
return default
|
||||||
|
|
||||||
def getQueryUrl(self, contentType, flavourNumber, searchName):
|
def getQueryUrl(self, contentType, flavourNumber, searchName, ajax=True,
|
||||||
|
startNumber=None):
|
||||||
'''This method creates the URL that allows to perform an ajax GET
|
'''This method creates the URL that allows to perform an ajax GET
|
||||||
request for getting queried objects from a search named p_searchName
|
request for getting queried objects from a search named p_searchName
|
||||||
on p_contentType from flavour numbered p_flavourNumber.'''
|
on p_contentType from flavour numbered p_flavourNumber. If p_ajax
|
||||||
return self.getAppFolder().absolute_url() + '/skyn/ajax?objectUid=%s' \
|
is False, it returns the non-ajax URL.'''
|
||||||
'&page=macros¯o=queryResult&contentType=%s&flavourNumber=%s' \
|
baseUrl = self.getAppFolder().absolute_url() + '/skyn'
|
||||||
'&searchName=%s&startNumber=' % (self.UID(), contentType,
|
baseParams = 'type_name=%s&flavourNumber=%s'%(contentType,flavourNumber)
|
||||||
flavourNumber, searchName)
|
# Manage start number
|
||||||
|
rq = self.REQUEST
|
||||||
|
if startNumber != None:
|
||||||
|
baseParams += '&startNumber=%s' % startNumber
|
||||||
|
elif rq.has_key('startNumber'):
|
||||||
|
baseParams += '&startNumber=%s' % rq['startNumber']
|
||||||
|
# Manage search name
|
||||||
|
if searchName or ajax: baseParams += '&search=%s' % searchName
|
||||||
|
if ajax:
|
||||||
|
return '%s/ajax?objectUid=%s&page=macros¯o=queryResult&%s' % \
|
||||||
|
(baseUrl, self.UID(), baseParams)
|
||||||
|
else:
|
||||||
|
return '%s/query?%s' % (baseUrl, baseParams)
|
||||||
|
|
||||||
|
def computeStartNumberFrom(self, currentNumber, totalNumber, batchSize):
|
||||||
|
'''Returns the number (start at 0) of the first element in a list
|
||||||
|
containing p_currentNumber (starts at 0) whose total number is
|
||||||
|
p_totalNumber and whose batch size is p_batchSize.'''
|
||||||
|
startNumber = 0
|
||||||
|
res = startNumber
|
||||||
|
while (startNumber < totalNumber):
|
||||||
|
if (currentNumber < startNumber + batchSize):
|
||||||
|
return startNumber
|
||||||
|
else:
|
||||||
|
startNumber += batchSize
|
||||||
|
return startNumber
|
||||||
|
|
||||||
|
def getNavigationInfo(self):
|
||||||
|
'''Extracts navigation information from request/nav and returns a dict
|
||||||
|
with the info that a page can use for displaying object
|
||||||
|
navigation.'''
|
||||||
|
res = {}
|
||||||
|
t,d1,d2,currentNumber,totalNumber = self.REQUEST.get('nav').split('.')
|
||||||
|
res['currentNumber'] = int(currentNumber)
|
||||||
|
res['totalNumber'] = int(totalNumber)
|
||||||
|
newNav = '%s.%s.%s.%%d.%s' % (t, d1, d2, totalNumber)
|
||||||
|
# Among, first, previous, next and last, which one do I need?
|
||||||
|
previousNeeded = False # Previous ?
|
||||||
|
previousIndex = res['currentNumber'] - 2
|
||||||
|
if (previousIndex > -1) and (res['totalNumber'] > previousIndex):
|
||||||
|
previousNeeded = True
|
||||||
|
nextNeeded = False # Next ?
|
||||||
|
nextIndex = res['currentNumber']
|
||||||
|
if nextIndex < res['totalNumber']: nextNeeded = True
|
||||||
|
firstNeeded = False # First ?
|
||||||
|
firstIndex = 0
|
||||||
|
if previousIndex > 0: firstNeeded = True
|
||||||
|
lastNeeded = False # Last ?
|
||||||
|
lastIndex = res['totalNumber'] - 1
|
||||||
|
if (nextIndex < lastIndex): lastNeeded = True
|
||||||
|
# Get the list of available UIDs surrounding the current object
|
||||||
|
if t == 'ref': # Manage navigation from a reference
|
||||||
|
fieldName = d2
|
||||||
|
masterObj = self.getObject(d1)
|
||||||
|
batchSize = masterObj.getAppyType(fieldName)['maxPerPage']
|
||||||
|
uids = getattr(masterObj, '_appy_%s' % fieldName)
|
||||||
|
# In the case of a reference, we retrieve ALL surrounding objects.
|
||||||
|
|
||||||
|
# Display the reference widget at the page where the current object
|
||||||
|
# lies.
|
||||||
|
startNumberKey = '%s%s_startNumber' % (masterObj.UID(), fieldName)
|
||||||
|
startNumber = self.computeStartNumberFrom(res['currentNumber']-1,
|
||||||
|
res['totalNumber'], batchSize)
|
||||||
|
res['sourceUrl'] = '%s?%s=%s' % (masterObj.getUrl(),
|
||||||
|
startNumberKey, startNumber)
|
||||||
|
else: # Manage navigation from a search
|
||||||
|
contentType, flavourNumber = d1.split(':')
|
||||||
|
flavourNumber = int(flavourNumber)
|
||||||
|
searchName = keySuffix = d2
|
||||||
|
batchSize = self.getNumberOfResultsPerPage()
|
||||||
|
if not searchName: keySuffix = contentType
|
||||||
|
s = self.REQUEST.SESSION
|
||||||
|
searchKey = 'search_%s_%s' % (flavourNumber, keySuffix)
|
||||||
|
if s.has_key(searchKey): uids = s[searchKey]
|
||||||
|
else: uids = {}
|
||||||
|
# In the case of a search, we retrieve only a part of all
|
||||||
|
# surrounding objects, those that are stored in the session.
|
||||||
|
if (previousNeeded and not uids.has_key(previousIndex)) or \
|
||||||
|
(nextNeeded and not uids.has_key(nextIndex)):
|
||||||
|
# I do not have this UID in session. I will need to
|
||||||
|
# retrigger the query by querying all objects surrounding
|
||||||
|
# this one.
|
||||||
|
newStartNumber = (res['currentNumber']-1) - (batchSize / 2)
|
||||||
|
if newStartNumber < 0: newStartNumber = 0
|
||||||
|
self.executeQuery(contentType, flavourNumber,
|
||||||
|
searchName=searchName, startNumber=newStartNumber,
|
||||||
|
remember=True)
|
||||||
|
uids = s[searchKey]
|
||||||
|
# For the moment, for first and last, we get them only if we have
|
||||||
|
# them in session.
|
||||||
|
if not uids.has_key(0): firstNeeded = False
|
||||||
|
if not uids.has_key(lastIndex): lastNeeded = False
|
||||||
|
# Compute URL of source object
|
||||||
|
startNumber = self.computeStartNumberFrom(res['currentNumber']-1,
|
||||||
|
res['totalNumber'], batchSize)
|
||||||
|
res['sourceUrl'] = self.getQueryUrl(contentType, flavourNumber,
|
||||||
|
searchName, ajax=False, startNumber=startNumber)
|
||||||
|
# Compute URLs
|
||||||
|
for urlType in ('previous', 'next', 'first', 'last'):
|
||||||
|
exec 'needIt = %sNeeded' % urlType
|
||||||
|
urlKey = '%sUrl' % urlType
|
||||||
|
res[urlKey] = None
|
||||||
|
if needIt:
|
||||||
|
exec 'index = %sIndex' % urlType
|
||||||
|
brain = self.uid_catalog(UID=uids[index])
|
||||||
|
if brain:
|
||||||
|
baseUrl = brain[0].getObject().getUrl()
|
||||||
|
navUrl = baseUrl + '/?nav=' + newNav % (index + 1)
|
||||||
|
res['%sUrl' % urlType] = navUrl
|
||||||
|
return res
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -1079,11 +1079,15 @@ class AbstractMixin:
|
||||||
'''This method returns various URLs about this object.'''
|
'''This method returns various URLs about this object.'''
|
||||||
baseUrl = self.absolute_url()
|
baseUrl = self.absolute_url()
|
||||||
params = ''
|
params = ''
|
||||||
|
rq = self.REQUEST
|
||||||
for k, v in kwargs.iteritems(): params += '&%s=%s' % (k, v)
|
for k, v in kwargs.iteritems(): params += '&%s=%s' % (k, v)
|
||||||
params = params[1:]
|
params = params[1:]
|
||||||
if t == 'showRef':
|
if t == 'showRef':
|
||||||
chunk = '/skyn/ajax?objectUid=%s&page=ref&' \
|
chunk = '/skyn/ajax?objectUid=%s&page=ref&' \
|
||||||
'macro=showReferenceContent&' % self.UID()
|
'macro=showReferenceContent&' % self.UID()
|
||||||
|
startKey = '%s%s_startNumber' % (self.UID(), kwargs['fieldName'])
|
||||||
|
if rq.has_key(startKey) and not kwargs.has_key(startKey):
|
||||||
|
params += '&%s=%s' % (startKey, rq[startKey])
|
||||||
return baseUrl + chunk + params
|
return baseUrl + chunk + params
|
||||||
else: # We consider t=='view'
|
else: # We consider t=='view'
|
||||||
return baseUrl + '/skyn/view' + params
|
return baseUrl + '/skyn/view' + params
|
||||||
|
|
BIN
gen/plone25/skin/gotoSource.png
Normal file
BIN
gen/plone25/skin/gotoSource.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 225 B |
|
@ -475,7 +475,7 @@
|
||||||
<div metal:define-macro="showPageHeader"
|
<div metal:define-macro="showPageHeader"
|
||||||
tal:define="appyPages python: contextObj.getAppyPages(phase);
|
tal:define="appyPages python: contextObj.getAppyPages(phase);
|
||||||
showCommonInfo python: not isEdit"
|
showCommonInfo python: not isEdit"
|
||||||
tal:condition="python: not contextObj.portal_factory.isTemporary(contextObj)">
|
tal:condition="not: contextObj/isTemporary">
|
||||||
|
|
||||||
<tal:comment replace="nothing">Information that is common to all tabs (object title, state, etc)</tal:comment>
|
<tal:comment replace="nothing">Information that is common to all tabs (object title, state, etc)</tal:comment>
|
||||||
<table width="100%" tal:condition="showCommonInfo" class="appyCommonInfo">
|
<table width="100%" tal:condition="showCommonInfo" class="appyCommonInfo">
|
||||||
|
@ -499,7 +499,7 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr tal:define="descrLabel python: contextObj.translate('%s_edit_descr' % contextObj.portal_type)"
|
<tr tal:define="descrLabel python: contextObj.translate('%s_edit_descr' % contextObj.portal_type)"
|
||||||
tal:condition="descrLabel" >
|
tal:condition="descrLabel/strip" >
|
||||||
<tal:comment replace="nothing">Content type description</tal:comment>
|
<tal:comment replace="nothing">Content type description</tal:comment>
|
||||||
<td colspan="2" class="discreet" tal:content="descrLabel"/>
|
<td colspan="2" class="discreet" tal:content="descrLabel"/>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -526,6 +526,7 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
<metal:nav use-macro="here/skyn/macros/macros/objectNavigate"/>
|
||||||
|
|
||||||
<tal:comment replace="nothing">Tabs</tal:comment>
|
<tal:comment replace="nothing">Tabs</tal:comment>
|
||||||
<ul class="contentViews appyTabs" tal:condition="python: len(appyPages)>1">
|
<ul class="contentViews appyTabs" tal:condition="python: len(appyPages)>1">
|
||||||
|
@ -585,26 +586,41 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<metal:queryResults define-macro="queryResult"
|
<metal:queryResults define-macro="queryResult"
|
||||||
tal:define="tool python: contextObj;
|
tal:define="tool python: contextObj;
|
||||||
contentType request/contentType;
|
contentType request/type_name;
|
||||||
flavourNumber python: int(request['flavourNumber']);
|
flavourNumber python: int(request['flavourNumber']);
|
||||||
startNumber python:test(request['startNumber']=='', '0', request['startNumber']);
|
startNumber request/startNumber|python:'0';
|
||||||
startNumber python: int(startNumber);
|
startNumber python: int(startNumber);
|
||||||
searchName request/searchName;
|
searchName request/search;
|
||||||
severalTypes python: contentType and (contentType.find(',') != -1);
|
searchLabel python: '%s_search_%s' % (contentType, searchName);
|
||||||
queryResult python: tool.executeQuery(contentType, flavourNumber, searchName, startNumber);
|
searchDescr python: '%s_descr' % searchLabel;
|
||||||
objs queryResult/objects;
|
severalTypes python: contentType and (contentType.find(',') != -1);
|
||||||
totalNumber queryResult/totalNumber;
|
queryResult python: tool.executeQuery(contentType, flavourNumber, searchName, startNumber, remember=True);
|
||||||
batchSize queryResult/batchSize;
|
objs queryResult/objects;
|
||||||
ajaxHookId python:'queryResult';
|
totalNumber queryResult/totalNumber;
|
||||||
baseUrl python: tool.getQueryUrl(contentType, flavourNumber, searchName)">
|
batchSize queryResult/batchSize;
|
||||||
|
ajaxHookId python:'queryResult';
|
||||||
|
baseUrl python: tool.getQueryUrl(contentType, flavourNumber, searchName, startNumber='**v**')">
|
||||||
|
|
||||||
<tal:result condition="objs">
|
<tal:result condition="objs">
|
||||||
|
|
||||||
<tal:comment replace="nothing">Appy (top) navigation</tal:comment>
|
<fieldset>
|
||||||
<metal:nav use-macro="here/skyn/macros/macros/appyNavigate"/>
|
<legend>
|
||||||
|
<span tal:replace="structure python: test(searchName, tool.translate(searchLabel), test(severalTypes, tool.translate(tool.getAppName()), tool.translate('%s_plural' % contentType)))"/>
|
||||||
|
(<span tal:replace="totalNumber"/>)
|
||||||
|
</legend>
|
||||||
|
|
||||||
<table tal:define="fieldDescrs python: tool.getResultColumns(objs[0], contentType)"
|
<table cellpadding="0" cellspacing="0" width="100%"><tr>
|
||||||
|
<td><span class="discreet" tal:define="descr python: tool.translate(searchDescr)"
|
||||||
|
tal:condition="python: searchName and descr" tal:content="descr"></span><br/><br/>
|
||||||
|
</td>
|
||||||
|
<td align="right">
|
||||||
|
<tal:comment replace="nothing">Appy (top) navigation</tal:comment>
|
||||||
|
<metal:nav use-macro="here/skyn/macros/macros/appyNavigate"/>
|
||||||
|
</td>
|
||||||
|
</tr></table>
|
||||||
|
|
||||||
|
<table tal:define="fieldDescrs python: tool.getResultColumns(objs[0], contentType)"
|
||||||
class="vertical listing" width="100%" cellpadding="0" cellspacing="0">
|
class="vertical listing" width="100%" cellpadding="0" cellspacing="0">
|
||||||
<tal:comment replace="nothing">Every item in fieldDescr is a FieldDescr instance,
|
<tal:comment replace="nothing">Every item in fieldDescr is a FieldDescr instance,
|
||||||
excepted for workflow state (which is not a field): in this case it is simply the
|
excepted for workflow state (which is not a field): in this case it is simply the
|
||||||
|
@ -662,7 +678,9 @@
|
||||||
<tr tal:repeat="obj objs" id="query_row">
|
<tr tal:repeat="obj objs" id="query_row">
|
||||||
|
|
||||||
<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 tal:content="obj/Title" tal:attributes="href obj/getUrl"></a></td>
|
<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:content="obj/Title" tal:attributes="href python: obj.getUrl() + '/?' + navInfo"></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="fieldDescr fieldDescrs">
|
<tal:otherFields repeat="fieldDescr fieldDescrs">
|
||||||
|
@ -709,10 +727,11 @@
|
||||||
</table>
|
</table>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<tal:comment replace="nothing">Appy (bottom) navigation</tal:comment>
|
<tal:comment replace="nothing">Appy (bottom) navigation</tal:comment>
|
||||||
<metal:nav use-macro="here/skyn/macros/macros/appyNavigate"/>
|
<metal:nav use-macro="here/skyn/macros/macros/appyNavigate"/>
|
||||||
|
</fieldset>
|
||||||
</tal:result>
|
</tal:result>
|
||||||
|
|
||||||
<span tal:condition="not: objs"
|
<span tal:condition="not: objs"
|
||||||
|
@ -932,13 +951,13 @@
|
||||||
<td><img style="cursor:pointer" tal:condition="python: (startNumber != 0) and (startNumber != batchSize)"
|
<td><img style="cursor:pointer" tal:condition="python: (startNumber != 0) and (startNumber != batchSize)"
|
||||||
tal:attributes="src string: $portal_url/skyn/arrowLeftDouble.png;
|
tal:attributes="src string: $portal_url/skyn/arrowLeftDouble.png;
|
||||||
title python: tool.translate('goto_first');
|
title python: tool.translate('goto_first');
|
||||||
onClick python: 'askAjaxChunk(\'%s\', \'%s\')' % (ajaxHookId, baseUrl+'0')"/></td>
|
onClick python: 'askAjaxChunk(\'%s\', \'%s\')' % (ajaxHookId, baseUrl.replace('**v**', '0'))"/></td>
|
||||||
<tal:comment replace="nothing">Go to the previous page</tal:comment>
|
<tal:comment replace="nothing">Go to the previous page</tal:comment>
|
||||||
<td><img style="cursor:pointer" tal:condition="python: startNumber != 0"
|
<td><img style="cursor:pointer" tal:condition="python: startNumber != 0"
|
||||||
tal:define="sNumber python: startNumber - batchSize"
|
tal:define="sNumber python: startNumber - batchSize"
|
||||||
tal:attributes="src string: $portal_url/skyn/arrowLeftSimple.png;
|
tal:attributes="src string: $portal_url/skyn/arrowLeftSimple.png;
|
||||||
title python: tool.translate('goto_previous');
|
title python: tool.translate('goto_previous');
|
||||||
onClick python: 'askAjaxChunk(\'%s\', \'%s\')' % (ajaxHookId, baseUrl+str(sNumber))"/></td>
|
onClick python: 'askAjaxChunk(\'%s\', \'%s\')' % (ajaxHookId, baseUrl.replace('**v**', str(sNumber)))"/></td>
|
||||||
<tal:comment replace="nothing">Explain which elements are currently shown</tal:comment>
|
<tal:comment replace="nothing">Explain which elements are currently shown</tal:comment>
|
||||||
<td class="discreet" valign="middle">
|
<td class="discreet" valign="middle">
|
||||||
<span tal:replace="python: startNumber+1"/>
|
<span tal:replace="python: startNumber+1"/>
|
||||||
|
@ -946,13 +965,12 @@
|
||||||
<span tal:replace="python: startNumber+len(objs)"/> <b>//</b>
|
<span tal:replace="python: startNumber+len(objs)"/> <b>//</b>
|
||||||
<span tal:replace="python: totalNumber"/>
|
<span tal:replace="python: totalNumber"/>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<tal:comment replace="nothing">Go to the next page</tal:comment>
|
<tal:comment replace="nothing">Go to the next page</tal:comment>
|
||||||
<td><img style="cursor:pointer" tal:condition="python: sNumber < totalNumber"
|
<td><img style="cursor:pointer" tal:condition="python: sNumber < totalNumber"
|
||||||
tal:define="sNumber python: startNumber + batchSize"
|
tal:define="sNumber python: startNumber + batchSize"
|
||||||
tal:attributes="src string: $portal_url/skyn/arrowRightSimple.png;
|
tal:attributes="src string: $portal_url/skyn/arrowRightSimple.png;
|
||||||
title python: tool.translate('goto_next');
|
title python: tool.translate('goto_next');
|
||||||
onClick python: 'askAjaxChunk(\'%s\', \'%s\')' % (ajaxHookId, baseUrl+str(sNumber))"/></td>
|
onClick python: 'askAjaxChunk(\'%s\', \'%s\')' % (ajaxHookId, baseUrl.replace('**v**', str(sNumber)))"/></td>
|
||||||
<tal:comment replace="nothing">Go to the last page</tal:comment>
|
<tal:comment replace="nothing">Go to the last page</tal:comment>
|
||||||
<td><img style="cursor:pointer" tal:condition="python: (startNumber != sNumber) and (startNumber != sNumber-batchSize)"
|
<td><img style="cursor:pointer" tal:condition="python: (startNumber != sNumber) and (startNumber != sNumber-batchSize)"
|
||||||
tal:define="lastPageIsIncomplete python: totalNumber % batchSize;
|
tal:define="lastPageIsIncomplete python: totalNumber % batchSize;
|
||||||
|
@ -961,7 +979,51 @@
|
||||||
sNumber python: (nbOfCountedPages*batchSize)"
|
sNumber python: (nbOfCountedPages*batchSize)"
|
||||||
tal:attributes="src string: $portal_url/skyn/arrowRightDouble.png;
|
tal:attributes="src string: $portal_url/skyn/arrowRightDouble.png;
|
||||||
title python: tool.translate('goto_last');
|
title python: tool.translate('goto_last');
|
||||||
onClick python: 'askAjaxChunk(\'%s\', \'%s\')' % (ajaxHookId, baseUrl+str(sNumber))"/></td>
|
onClick python: 'askAjaxChunk(\'%s\', \'%s\')' % (ajaxHookId, baseUrl.replace('**v**', str(sNumber)))"/></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div metal:define-macro="objectNavigate" tal:condition="request/nav|nothing" align="right">
|
||||||
|
<tal:comment replace="nothing">
|
||||||
|
Buttons for going to next/previous elements if this one is among bunch of referenced or searched objects.
|
||||||
|
currentNumber starts with 1.
|
||||||
|
</tal:comment>
|
||||||
|
<table cellpadding="0" cellspacing="0"
|
||||||
|
tal:define="navInfo tool/getNavigationInfo;
|
||||||
|
currentNumber navInfo/currentNumber;
|
||||||
|
totalNumber navInfo/totalNumber;
|
||||||
|
firstUrl navInfo/firstUrl;
|
||||||
|
previousUrl navInfo/previousUrl;
|
||||||
|
nextUrl navInfo/nextUrl;
|
||||||
|
lastUrl navInfo/lastUrl;
|
||||||
|
sourceUrl navInfo/sourceUrl">
|
||||||
|
<tr>
|
||||||
|
<tal:comment replace="nothing">Go to the source URL (search or referred object)</tal:comment>
|
||||||
|
<td><a tal:condition="sourceUrl" tal:attributes="href sourceUrl"><img style="cursor:pointer"
|
||||||
|
tal:attributes="src string: $portal_url/skyn/gotoSource.png;
|
||||||
|
title python: tool.translate('goto_source')"/></a></td>
|
||||||
|
<tal:comment replace="nothing">Go to the first page</tal:comment>
|
||||||
|
<td><a tal:condition="firstUrl" tal:attributes="href firstUrl"><img style="cursor:pointer"
|
||||||
|
tal:attributes="src string: $portal_url/skyn/arrowLeftDouble.png;
|
||||||
|
title python: tool.translate('goto_first')"/></a></td>
|
||||||
|
<tal:comment replace="nothing">Go to the previous page</tal:comment>
|
||||||
|
<td><a tal:condition="previousUrl" tal:attributes="href previousUrl"><img style="cursor:pointer"
|
||||||
|
tal:attributes="src string: $portal_url/skyn/arrowLeftSimple.png;
|
||||||
|
title python: tool.translate('goto_previous')"/></a></td>
|
||||||
|
<tal:comment replace="nothing">Explain which element is currently shown</tal:comment>
|
||||||
|
<td class="discreet" valign="middle">
|
||||||
|
<span tal:replace="python: currentNumber"/> <b>//</b>
|
||||||
|
<span tal:replace="python: totalNumber"/>
|
||||||
|
</td>
|
||||||
|
<tal:comment replace="nothing">Go to the next page</tal:comment>
|
||||||
|
<td><a tal:condition="python: nextUrl" tal:attributes="href nextUrl"><img style="cursor:pointer"
|
||||||
|
tal:attributes="src string: $portal_url/skyn/arrowRightSimple.png;
|
||||||
|
title python: tool.translate('goto_next')"/></a></td>
|
||||||
|
<tal:comment replace="nothing">Go to the last page</tal:comment>
|
||||||
|
<td><a tal:condition="lastUrl" tal:attributes="href lastUrl"><img style="cursor:pointer"
|
||||||
|
tal:attributes="src string: $portal_url/skyn/arrowRightDouble.png;
|
||||||
|
title python: tool.translate('goto_last')"/></a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -17,10 +17,7 @@
|
||||||
tool python: portal.get('portal_%s' % appName.lower());
|
tool python: portal.get('portal_%s' % appName.lower());
|
||||||
contentType python:context.REQUEST.get('type_name');
|
contentType python:context.REQUEST.get('type_name');
|
||||||
flavourNumber python:int(context.REQUEST.get('flavourNumber'));
|
flavourNumber python:int(context.REQUEST.get('flavourNumber'));
|
||||||
searchName python:context.REQUEST.get('search', '');
|
searchName python:context.REQUEST.get('search', '')">
|
||||||
searchLabel python: '%s_search_%s' % (contentType, searchName);
|
|
||||||
searchDescr python: '%s_descr' % searchLabel;
|
|
||||||
severalTypes python: contentType and (contentType.find(',') != -1)">
|
|
||||||
|
|
||||||
<div metal:use-macro="here/skyn/macros/macros/pagePrologue"/>
|
<div metal:use-macro="here/skyn/macros/macros/pagePrologue"/>
|
||||||
<script language="javascript">
|
<script language="javascript">
|
||||||
|
@ -143,11 +140,6 @@
|
||||||
-->
|
-->
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<tal:comment replace="nothing">Query title and description</tal:comment>
|
|
||||||
<h1 tal:content="structure python: test(searchName, tool.translate(searchLabel), test(severalTypes, tool.translate(appName), tool.translate('%s_plural' % contentType)))"></h1>
|
|
||||||
<div class="discreet" tal:condition="searchName"
|
|
||||||
tal:content="structure python: tool.translate(searchDescr)+'<br/><br/>'"></div>
|
|
||||||
|
|
||||||
<tal:comment replace="nothing">Query result</tal:comment>
|
<tal:comment replace="nothing">Query result</tal:comment>
|
||||||
<div id="queryResult"></div>
|
<div id="queryResult"></div>
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,12 @@
|
||||||
<metal:objectTitle define-macro="objectTitle">
|
<metal:objectTitle define-macro="objectTitle">
|
||||||
<tal:comment replace="nothing">Displays the title of a referenced object, with a link on
|
<tal:comment replace="nothing">Displays the title of a referenced object, with a link on
|
||||||
it to reach the consult view for this object. If we are on a back reference, the link
|
it to reach the consult view for this object. If we are on a back reference, the link
|
||||||
allows to reach the correct page where the forward reference is defined.</tal:comment>
|
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
|
||||||
|
from one object to the next/previous on skyn/view.</tal:comment>
|
||||||
<a tal:define="viewUrl obj/getUrl;
|
<a tal:define="viewUrl obj/getUrl;
|
||||||
fullUrl python: test(isBack, viewUrl + '/?pageName=%s&phase=%s' % (appyType['page'], appyType['phase']), viewUrl)"
|
navInfo python:'nav=ref.%s.%s.%d.%d' % (contextObj.UID(), fieldName, repeat['obj'].number()+startNumber, totalNumber);
|
||||||
|
fullUrl python: test(isBack, viewUrl + '/?pageName=%s&phase=%s' % (appyType['page'], appyType['phase']), viewUrl + '/?' + navInfo)"
|
||||||
tal:attributes="href fullUrl" tal:content="obj/Title"></a>
|
tal:attributes="href fullUrl" tal:content="obj/Title"></a>
|
||||||
</metal:objectTitle>
|
</metal:objectTitle>
|
||||||
|
|
||||||
|
@ -72,7 +75,7 @@
|
||||||
- descrId (string) the i18n id of the reference field description
|
- descrId (string) the i18n id of the reference field description
|
||||||
</tal:comment>
|
</tal:comment>
|
||||||
<div metal:define-macro="showReference"
|
<div metal:define-macro="showReference"
|
||||||
tal:define="ajaxHookId python: contextObj.UID()+fieldName;
|
tal:define="ajaxHookId python: contextObj.UID() + fieldName;
|
||||||
ajaxUrl python: contextObj.getUrl('showRef', **{'fieldName': fieldName, 'isBack': isBack, 'innerRef': innerRef, 'labelId': labelId, 'descrId': descrId})"
|
ajaxUrl python: contextObj.getUrl('showRef', **{'fieldName': fieldName, 'isBack': isBack, 'innerRef': innerRef, 'labelId': labelId, 'descrId': descrId})"
|
||||||
tal:attributes="id ajaxHookId">
|
tal:attributes="id ajaxHookId">
|
||||||
<script language="javascript"
|
<script language="javascript"
|
||||||
|
@ -108,7 +111,7 @@
|
||||||
atMostOneRef python: (multiplicity[1] == 1) and (len(objs)<=1);
|
atMostOneRef python: (multiplicity[1] == 1) and (len(objs)<=1);
|
||||||
label python: tool.translate(labelId);
|
label python: tool.translate(labelId);
|
||||||
description python: tool.translate(descrId);
|
description python: tool.translate(descrId);
|
||||||
baseUrl python: contextObj.getUrl('showRef', **{'fieldName': fieldName, 'isBack': isBack, 'innerRef': innerRef, 'labelId': labelId, 'descrId': descrId}) + '&%s_startNumber=' % ajaxHookId">
|
baseUrl python: contextObj.getUrl('showRef', **{'fieldName': fieldName, 'isBack': isBack, 'innerRef': innerRef, 'labelId': labelId, 'descrId': descrId, '%s_startNumber' % ajaxHookId: '**v**'})">
|
||||||
|
|
||||||
<tal:comment replace="nothing">This macro displays the Reference widget on a "consult" page.
|
<tal:comment replace="nothing">This macro displays the Reference widget on a "consult" page.
|
||||||
|
|
||||||
|
@ -130,7 +133,7 @@
|
||||||
|
|
||||||
<tal:comment replace="nothing">If there is an object...</tal:comment>
|
<tal:comment replace="nothing">If there is an object...</tal:comment>
|
||||||
<tal:objectIsPresent condition="python: len(objs) == 1">
|
<tal:objectIsPresent condition="python: len(objs) == 1">
|
||||||
<tal:obj define="obj python:objs[0]">
|
<tal:obj repeat="obj objs">
|
||||||
<td><metal:showObjectTitle use-macro="here/skyn/ref/macros/objectTitle" /></td>
|
<td><metal:showObjectTitle use-macro="here/skyn/ref/macros/objectTitle" /></td>
|
||||||
<td tal:condition="not: isBack">
|
<td tal:condition="not: isBack">
|
||||||
<metal:showObjectActions use-macro="here/skyn/ref/macros/objectActions" />
|
<metal:showObjectActions use-macro="here/skyn/ref/macros/objectActions" />
|
||||||
|
@ -145,6 +148,7 @@
|
||||||
<fieldset tal:attributes="class python:test(innerRef, 'innerAppyFieldset', '')">
|
<fieldset tal:attributes="class python:test(innerRef, 'innerAppyFieldset', '')">
|
||||||
<legend tal:condition="python: not innerRef or showPlusIcon">
|
<legend tal:condition="python: not innerRef or showPlusIcon">
|
||||||
<span tal:condition="not: innerRef" tal:content="label"/>
|
<span tal:condition="not: innerRef" tal:content="label"/>
|
||||||
|
(<span tal:replace="totalNumber"/>)
|
||||||
<metal:plusIcon use-macro="here/skyn/ref/macros/plusIcon"/>
|
<metal:plusIcon use-macro="here/skyn/ref/macros/plusIcon"/>
|
||||||
</legend>
|
</legend>
|
||||||
|
|
||||||
|
|
|
@ -113,7 +113,7 @@
|
||||||
background-color: &dtml-evenRowBackgroundColor;;
|
background-color: &dtml-evenRowBackgroundColor;;
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-width: 2px;
|
border-width: 2px;
|
||||||
margin-bottom: 1em;
|
margin-bottom: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.appyWorkflow {
|
.appyWorkflow {
|
||||||
|
|
|
@ -9,4 +9,8 @@ class ToolWrapper:
|
||||||
if initiatorUid:
|
if initiatorUid:
|
||||||
res = self.o.uid_catalog(UID=initiatorUid)[0].getObject().appy()
|
res = self.o.uid_catalog(UID=initiatorUid)[0].getObject().appy()
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
def getObject(self, uid):
|
||||||
|
'''Allow to retrieve an object from its unique identifier p_uid.'''
|
||||||
|
return self.o.getObject(uid, appy=True)
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -85,6 +85,7 @@ class PoMessage:
|
||||||
GOTO_PREVIOUS = 'Go to previous'
|
GOTO_PREVIOUS = 'Go to previous'
|
||||||
GOTO_NEXT = 'Go to next'
|
GOTO_NEXT = 'Go to next'
|
||||||
GOTO_LAST = 'Go to end'
|
GOTO_LAST = 'Go to end'
|
||||||
|
GOTO_SOURCE = 'Go back'
|
||||||
|
|
||||||
def __init__(self, id, msg, default, fuzzy=False, comments=[]):
|
def __init__(self, id, msg, default, fuzzy=False, comments=[]):
|
||||||
self.id = id
|
self.id = id
|
||||||
|
|
Loading…
Reference in a new issue