285 lines
16 KiB
XML
285 lines
16 KiB
XML
<tal:comment replace="nothing">
|
|
We begin with some sub-macros used within macro "show" defined below.
|
|
</tal:comment>
|
|
|
|
<metal:objectTitle define-macro="objectTitle">
|
|
<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
|
|
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 ui/view.</tal:comment>
|
|
<tal:icons replace="structure obj/getIcons"/>
|
|
<a tal:define="includeShownInfo includeShownInfo | python:False;
|
|
navInfo python:'ref.%s.%s:%s.%d.%d' % (contextObj.UID(), fieldName, appyType['pageName'], repeat['obj'].number()+startNumber, totalNumber);
|
|
navInfo python: test(appyType['isBack'], '', navInfo);
|
|
pageName python: appyType['isBack'] and appyType['backd']['pageName'] 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>
|
|
</metal:objectTitle>
|
|
|
|
<metal:objectActions define-macro="objectActions">
|
|
<tal:comment replace="nothing">Displays icons for triggering actions on a given
|
|
referenced object (edit, delete, etc).</tal:comment>
|
|
<table class="noStyle"
|
|
tal:define="isBack appyType/isBack">
|
|
<tr>
|
|
<tal:comment replace="nothing">Workflow transitions</tal:comment>
|
|
<td tal:condition="python: obj.showTransitions('result')">
|
|
<tal:def define="targetObj python: obj">
|
|
<metal:transitions use-macro="app/ui/page/macros/transitions"/>
|
|
</tal:def>
|
|
</td>
|
|
<tal:comment replace="nothing">Edit</tal:comment>
|
|
<td tal:condition="python: not appyType['noForm'] and obj.mayEdit() and appyType['delete']">
|
|
<a tal:define="navInfo python:'ref.%s.%s:%s.%d.%d' % (contextObj.UID(), fieldName, appyType['pageName'], repeat['obj'].number()+startNumber, totalNumber);"
|
|
tal:attributes="href python: obj.getUrl(mode='edit', page='main', nav=navInfo)">
|
|
<img tal:attributes="src string: $appUrl/ui/edit.png;
|
|
title python: _('object_edit')"/>
|
|
</a>
|
|
</td>
|
|
<tal:comment replace="nothing">Delete</tal:comment>
|
|
<td tal:condition="python: not isBack and appyType['delete'] and canWrite and obj.mayDelete()">
|
|
<img style="cursor:pointer"
|
|
tal:attributes="src string: $appUrl/ui/delete.png;
|
|
onClick python:'onDeleteObject(\'%s\')' % obj.UID();
|
|
title python: _('object_delete')"/>
|
|
</td>
|
|
<tal:comment replace="nothing">Unlink</tal:comment>
|
|
<td tal:condition="python: not isBack and appyType['unlink'] and canWrite">
|
|
<img style="cursor:pointer"
|
|
tal:attributes="src string: $appUrl/ui/unlink.png;
|
|
onClick python:'onUnlinkObject(\'%s\',\'%s\',\'%s\')' % (contextObj.UID(), appyType['name'], obj.UID());
|
|
title python: _('object_unlink')"/>
|
|
</td>
|
|
<tal:comment replace="nothing">Arrows for moving objects up or down</tal:comment>
|
|
<td tal:condition="python: not isBack and (len(objs)>1) and changeOrder and canWrite">
|
|
<tal:moveRef define="objectIndex python: contextObj.getAppyRefIndex(fieldName, obj);
|
|
ajaxBaseCall python: navBaseCall.replace('**v**', '\'%s\',\'ChangeRefOrder\', {\'refObjectUid\':\'%s\', \'move\':\'**v**\'}' % (startNumber, obj.UID()))">
|
|
<img tal:condition="python: objectIndex > 0" style="cursor:pointer"
|
|
tal:attributes="src string: $appUrl/ui/arrowUp.png;
|
|
title python: _('move_up');
|
|
onClick python: ajaxBaseCall.replace('**v**', 'up')"/><img style="cursor:pointer"
|
|
tal:condition="python: objectIndex < (totalNumber-1)"
|
|
tal:attributes="src string: $appUrl/ui/arrowDown.png;
|
|
title python: _('move_down');
|
|
onClick python: ajaxBaseCall.replace('**v**', 'down')"/>
|
|
</tal:moveRef>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</metal:objectActions>
|
|
|
|
<metal:plusIcon define-macro="plusIcon">
|
|
<tal:comment replace="nothing">Displays the "plus" icon that allows to add new object
|
|
through a reference widget. Indeed, If field was declared as "addable", we must provide
|
|
an icon for creating a new linked object (at least if multiplicities allow it).</tal:comment>
|
|
<img style="cursor:pointer" tal:condition="showPlusIcon"
|
|
tal:define="navInfo python:'ref.%s.%s:%s.%d.%d' % (contextObj.UID(), fieldName, appyType['pageName'], 0, totalNumber);
|
|
formCall python:'window.location=\'%s/do?action=Create&className=%s&nav=%s\'' % (folder.absolute_url(), linkedPortalType, navInfo);
|
|
formCall python: test(appyType['addConfirm'], 'askConfirm(\'script\', "%s", "%s")' % (formCall, addConfirmMsg), formCall);
|
|
noFormCall python: navBaseCall.replace('**v**', '%d, \'CreateWithoutForm\'' % startNumber);
|
|
noFormCall python: test(appyType['addConfirm'], 'askConfirm(\'script\', "%s", "%s")' % (noFormCall, addConfirmMsg), noFormCall)"
|
|
tal:attributes="src string:$appUrl/ui/plus.png;
|
|
title python: _('add_ref');
|
|
onClick python: test(appyType['noForm'], noFormCall, formCall)"/>
|
|
</metal:plusIcon>
|
|
|
|
<tal:comment replace="nothing">
|
|
This macro displays, in a cell header from a ref table, icons for sorting the
|
|
ref field according to the field that corresponds to this column.
|
|
</tal:comment>
|
|
<metal:sortIcons define-macro="sortIcons"
|
|
tal:define="ajaxBaseCall python: navBaseCall.replace('**v**', '\'%s\',\'SortReference\', {\'sortKey\':\'%s\', \'reverse\':\'**v**\'}' % (startNumber, widget['name']))"
|
|
tal:condition="python: changeOrder and canWrite and tool.isSortable(widget['name'], objs[0].meta_type, 'ref')">
|
|
<img style="cursor:pointer"
|
|
tal:attributes="src string:$appUrl/ui/sortAsc.png;
|
|
onClick python: ajaxBaseCall.replace('**v**', 'False')"/>
|
|
<img style="cursor:pointer"
|
|
tal:attributes="src string:$appUrl/ui/sortDesc.png;
|
|
onClick python: ajaxBaseCall.replace('**v**', 'True')"/>
|
|
</metal:sortIcons>
|
|
|
|
<tal:comment replace="nothing">View macro for a Ref.</tal:comment>
|
|
<metal:view define-macro="view"
|
|
tal:define="dummy python: request.set('fieldName', widget['name'])">
|
|
<metal:ref use-macro="app/ui/widgets/ref/macros/viewContent"/>
|
|
</metal:view>
|
|
|
|
<tal:comment replace="nothing">
|
|
This macro is called by a XmlHttpRequest (or directly by the macro above)
|
|
for displaying the referred objects of a reference field.
|
|
</tal:comment>
|
|
<div metal:define-macro="viewContent"
|
|
tal:define="fieldName request/fieldName;
|
|
appyType python: contextObj.getAppyType(fieldName, asDict=True);
|
|
innerRef python: test(request.get('innerRef', False)=='True', True, False);
|
|
ajaxHookId python: contextObj.UID()+fieldName;
|
|
startNumber python: int(request.get('%s_startNumber' % ajaxHookId, 0));
|
|
tool contextObj/getTool;
|
|
_ python: tool.translate;
|
|
refObjects python:contextObj.getAppyRefs(fieldName, startNumber);
|
|
objs refObjects/objects;
|
|
totalNumber refObjects/totalNumber;
|
|
batchSize refObjects/batchSize;
|
|
folder contextObj/getCreateFolder;
|
|
linkedPortalType python: tool.getPortalType(appyType['klass']);
|
|
canWrite python: not appyType['isBack'] and contextObj.allows(appyType['writePermission']);
|
|
showPlusIcon python: contextObj.mayAddReference(fieldName);
|
|
atMostOneRef python: (appyType['multiplicity'][1] == 1) and (len(objs)<=1);
|
|
addConfirmMsg python: appyType['addConfirm'] and _('%s_addConfirm' % appyType['labelId']) or '';
|
|
navBaseCall python: 'askRefField(\'%s\',\'%s\',\'%s\',\'%s\',**v**)' % (ajaxHookId, contextObj.absolute_url(), fieldName, innerRef);
|
|
changeOrder python: contextObj.callField(fieldName, 'changeOrderEnabled', contextObj);
|
|
showSubTitles python: request.get('showSubTitles', 'true') == 'true'"
|
|
tal:attributes="id ajaxHookId">
|
|
|
|
<tal:comment replace="nothing">This macro displays the Reference widget on a "view" page.
|
|
|
|
The definition of "atMostOneRef" above may sound strange: we shouldn't check the actual number
|
|
of referenced objects. But for back references people often forget to specify multiplicities.
|
|
So concretely, multiplicities (0,None) are coded as (0,1).</tal:comment>
|
|
<tal:atMostOneReference condition="atMostOneRef">
|
|
<tal:comment replace="nothing">Display a simplified widget if maximum number of
|
|
referenced objects is 1.</tal:comment>
|
|
<table><tr valign="top">
|
|
<tal:comment replace="nothing">If there is no object...</tal:comment>
|
|
<tal:noObject condition="not:objs">
|
|
<td class="discreet" tal:content="python: _('no_ref')"></td>
|
|
<td><metal:plusIcon use-macro="app/ui/widgets/ref/macros/plusIcon"/></td>
|
|
</tal:noObject>
|
|
|
|
<tal:comment replace="nothing">If there is an object...</tal:comment>
|
|
<tal:objectIsPresent condition="python: objs">
|
|
<tal:obj repeat="obj objs">
|
|
<td tal:define="includeShownInfo python:True"><metal:showObjectTitle use-macro="app/ui/widgets/ref/macros/objectTitle" /></td>
|
|
</tal:obj>
|
|
</tal:objectIsPresent>
|
|
</tr></table>
|
|
</tal:atMostOneReference>
|
|
|
|
<tal:comment replace="nothing">Display a table in all other cases.</tal:comment>
|
|
<tal:anyNumberOfReferences condition="not: atMostOneRef">
|
|
<div tal:condition="python: not innerRef or showPlusIcon">
|
|
(<span tal:replace="totalNumber"/>)
|
|
<metal:plusIcon use-macro="app/ui/widgets/ref/macros/plusIcon"/>
|
|
<tal:comment replace="nothing">The search icon if field is queryable</tal:comment>
|
|
<a tal:condition="python: objs and appyType['queryable']"
|
|
tal:attributes="href python: '%s/ui/search?className=%s&ref=%s:%s' % (tool.absolute_url(), linkedPortalType, contextObj.UID(), appyType['name'])">
|
|
<img tal:attributes="title python: _('search_title');
|
|
src string: $appUrl/ui/search.gif"/></a>
|
|
</div>
|
|
|
|
<tal:comment replace="nothing">Appy (top) navigation</tal:comment>
|
|
<metal:nav use-macro="here/ui/navigate/macros/appyNavigate"/>
|
|
|
|
<tal:comment replace="nothing">No object is present</tal:comment>
|
|
<p class="discreet" tal:condition="not:objs" tal:content="python: _('no_ref')"></p>
|
|
|
|
<table width="100%" tal:condition="python: objs"
|
|
tal:attributes="class python:test(innerRef, 'innerAppyTable', '')">
|
|
<tr valign="bottom"><td>
|
|
|
|
<tal:comment replace="nothing">Show forward or backward reference(s)</tal:comment>
|
|
<table tal:attributes="class python:test(innerRef, '', 'list');
|
|
width python:test(innerRef, '100%', appyType['layouts']['view']['width']);">
|
|
<tal:infos define="columns python: objs[0].getColumnsSpecifiers(appyType['shownInfo'], dir)">
|
|
<tr tal:condition="appyType/showHeaders">
|
|
<th tal:repeat="column columns"
|
|
tal:attributes="width column/width; align column/align">
|
|
<tal:def define="widget column/field">
|
|
<span tal:content="python: _(widget['labelId'])"></span>
|
|
<metal:sortIcons use-macro="app/ui/widgets/ref/macros/sortIcons" />
|
|
<tal:sd define="className linkedPortalType">
|
|
<metal:details use-macro="context/ui/navigate/macros/showDetails"/>
|
|
</tal:sd>
|
|
</tal:def>
|
|
</th>
|
|
</tr>
|
|
<tal:row repeat="obj objs">
|
|
<tr valign="top" tal:define="odd repeat/obj/odd"
|
|
tal:attributes="class python:test(odd, 'even', 'odd')">
|
|
<td tal:repeat="column columns"
|
|
tal:attributes="width column/width; align column/align">
|
|
<tal:def define="widget column/field">
|
|
<tal:title condition="python: widget['name'] == 'title'">
|
|
<metal:showObjectTitle use-macro="app/ui/widgets/ref/macros/objectTitle"/>
|
|
<div name="subTitle" tal:content="structure obj/getSubTitle"
|
|
tal:attributes="style python: showSubTitles and 'display:block' or 'display:none'"></div>
|
|
<div tal:attributes="align dright" tal:condition="obj/mayAct">
|
|
<metal:showObjectActions use-macro="app/ui/widgets/ref/macros/objectActions" />
|
|
</div>
|
|
</tal:title>
|
|
<tal:other condition="python: widget['name'] != 'title'">
|
|
<tal:field define="contextObj python:obj;
|
|
layoutType python: 'cell';
|
|
innerRef python:True"
|
|
condition="python: obj.showField(widget['name'], layoutType='result')">
|
|
<metal:field use-macro="app/ui/widgets/show/macros/field" />
|
|
</tal:field>
|
|
</tal:other>
|
|
</tal:def>
|
|
</td>
|
|
</tr>
|
|
</tal:row>
|
|
</tal:infos>
|
|
</table>
|
|
</td></tr>
|
|
</table>
|
|
|
|
<tal:comment replace="nothing">Appy (bottom) navigation</tal:comment>
|
|
<metal:nav use-macro="context/ui/navigate/macros/appyNavigate"/>
|
|
</tal:anyNumberOfReferences>
|
|
</div>
|
|
|
|
<tal:comment replace="nothing">Edit macro for an Ref.</tal:comment>
|
|
<metal:editRef define-macro="edit"
|
|
tal:condition="widget/link"
|
|
tal:define="requestValue python: request.get(name, []);
|
|
inRequest python: request.has_key(name);
|
|
allObjects python: contextObj.getSelectableAppyRefs(name);
|
|
refUids python: [o.UID() for o in contextObj.getAppyRefs(name)['objects']];
|
|
isBeingCreated python: contextObj.isTemporary() or ('/portal_factory/' in contextObj.absolute_url())">
|
|
|
|
<select tal:attributes="name name;
|
|
size python: test(isMultiple, widget['height'], '');
|
|
multiple python: test(isMultiple, 'multiple', '')">
|
|
<option value="" tal:condition="not: isMultiple" tal:content="python: _('choose_a_value')"></option>
|
|
<tal:ref repeat="refObj allObjects">
|
|
<option tal:define="uid python: contextObj.getReferenceUid(refObj)"
|
|
tal:content="python: contextObj.getReferenceLabel(name, refObj)"
|
|
tal:attributes="value uid;
|
|
selected python:(inRequest and (uid in requestValue) or (not inRequest and ((uid in refUids)))) and True or False">
|
|
</option>
|
|
</tal:ref>
|
|
</select>
|
|
</metal:editRef>
|
|
|
|
<tal:comment replace="nothing">Cell macro for a Ref.</tal:comment>
|
|
<metal:cell define-macro="cell">
|
|
<metal:call use-macro="app/ui/widgets/ref/macros/view"/>
|
|
</metal:cell>
|
|
|
|
<tal:comment replace="nothing">Search macro for a Ref.</tal:comment>
|
|
<metal:search define-macro="search">
|
|
<label tal:attributes="for widgetName" tal:content="python: _(widget['labelId'])"></label><br>
|
|
<tal:comment replace="nothing">The "and" / "or" radio buttons</tal:comment>
|
|
<tal:operator define="operName python: 'o_%s' % name;
|
|
orName python: '%s_or' % operName;
|
|
andName python: '%s_and' % operName;"
|
|
condition="python: widget['multiplicity'][1]!=1">
|
|
<input type="radio" tal:attributes="name operName; id orName" checked="checked" value="or"/>
|
|
<label tal:attributes="for orName" tal:content="python: _('search_or')"></label>
|
|
<input type="radio" tal:attributes="name operName; id andName" value="and"/>
|
|
<label tal:attributes="for andName" tal:content="python: _('search_and')"></label><br/>
|
|
</tal:operator>
|
|
<tal:comment replace="nothing">The list of values</tal:comment>
|
|
<select tal:attributes="name widgetName; size widget/sheight" multiple="multiple">
|
|
<tal:option repeat="v python: tool.getSearchValues(name, className)">
|
|
<option tal:define="uid python: v[0];
|
|
title python: tool.getReferenceLabel(name, v[1], className)"
|
|
tal:attributes="value uid; title title"
|
|
tal:content="python: tool.truncateValue(title, widget['swidth'])">
|
|
</option>
|
|
</tal:option>
|
|
</select>
|
|
</metal:search>
|