Added a new system for layouting production-ready forms without any HTML coding, many performance improvements and more independence towards Archetypes.

This commit is contained in:
Gaetan Delannay 2010-08-05 18:23:17 +02:00
parent 309ea921fa
commit bfd2357f69
84 changed files with 4663 additions and 3549 deletions

View file

@ -4,22 +4,23 @@
It can also have a parameter "action", that refers to a method that will be triggered on
contextObj before returning the result of the macro to the browser.
</tal:comment>
<tal:ajax define="page request/page;
macro request/macro;
<tal:ajax define="page request/page;
macro request/macro;
contextObj context/getParentNode;
action request/action|nothing;
response request/RESPONSE;
member context/portal_membership/getAuthenticatedMember;
portal context/portal_url/getPortalObject;
action request/action|nothing;
response request/RESPONSE;
member context/portal_membership/getAuthenticatedMember;
portal context/portal_url/getPortalObject;
portal_url context/portal_url/getPortalPath;
dummy python:response.setHeader('Content-Type','text/html;;charset=utf-8');
dummy2 python:response.setHeader('Expires', 'Mon, 11 Dec 1975 12:05:05 GMT');
dummy3 python:response.setHeader('CacheControl', 'no-cache')">
template python: contextObj.getPageTemplate(portal.skyn, page);
dummy python: response.setHeader('Content-Type','text/html;;charset=utf-8');
dummy2 python: response.setHeader('Expires', 'Mon, 11 Dec 1975 12:05:05 GMT');
dummy3 python: response.setHeader('CacheControl', 'no-cache')">
<tal:comment replace="nothing">Keys "Expires" and "CacheControl" are used for preventing IE to cache
this page. Indeed, this page is retrieved through an asynchronous XMLHttpRequest by the browser, and
IE caches this by default.</tal:comment>
<tal:executeAction condition="action">
<tal:do define="dummy python: contextObj.getAppyValue('on'+action)()" omit-tag=""/>
<tal:do define="dummy python: contextObj.getMethod('on'+action)()" omit-tag=""/>
</tal:executeAction>
<metal:callMacro use-macro="python: portal.skyn.get(page).macros.get(macro)"/>
<metal:callMacro use-macro="python: template.macros.get(macro)"/>
</tal:ajax>

BIN
gen/plone25/skin/cancel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View file

@ -12,4 +12,4 @@ else:
from Products.CMFCore.utils import getToolByName
portal = getToolByName(obj, 'portal_url').getPortalObject()
obj = portal.get('portal_%s' % obj.id.lower()) # The tool
return obj.getAppyValue('on'+action)()
return obj.getMethod('on'+action)()

View file

@ -1,24 +1,18 @@
<tal:block metal:define-macro="master"
define="contextObj python:context.getParentNode();
errors request/errors | python:{};
schematas contextObj/Schemata;
fieldsets python:[key for key in schematas.keys() if (key != 'metadata') and (schematas[key].editableFields(contextObj, visible_only=True))];
default_fieldset python:(not schematas or schematas.has_key('default')) and 'default' or fieldsets[0];
fieldset request/fieldset|options/fieldset|default_fieldset;
fields python:schematas[fieldset].editableFields(contextObj);
lockable python:hasattr(contextObj, 'wl_isLocked');
isLocked python:lockable and contextObj.wl_isLocked();
isEdit python:True;
tool contextObj/getTool;
flavour python: tool.getFlavour(contextObj);
appFolder tool/getAppFolder;
appName appFolder/id;
css python:contextObj.getUniqueWidgetAttr(fields, 'helper_css');
js python:contextObj.getUniqueWidgetAttr(fields, 'helper_js');
phaseInfo python: contextObj.getAppyPhases(fieldset=fieldset, forPlone=True);
phase request/phase|phaseInfo/name;
appyPages python: contextObj.getAppyPages(phase);
pageName python: contextObj.getAppyPage(isEdit, phaseInfo, appyPages);">
<tal:edit metal:define-macro="master"
define="contextObj python:context.getParentNode();
errors request/errors | python:{};
layoutType python:'edit';
layout python: contextObj.getPageLayout(layoutType);
tool contextObj/getTool;
flavour python: tool.getFlavour(contextObj);
appFolder tool/getAppFolder;
appName appFolder/getId;
page request/page|python:'main';
cssAndJs python: contextObj.getCssAndJs(layoutType, page);
css python: cssAndJs[0];
js python: cssAndJs[1];
phaseInfo python: contextObj.getAppyPhases(page=page);
phase phaseInfo/name">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -32,80 +26,38 @@
<div tal:define="dummy python:request.set('disable_border', 1)" />
</div>
<tal:comment replace="nothing">Archetypes stuff for managing Javascript and CSS.
If I remove this stuff, Javascript popup for dates does not work anyore.</tal:comment>
<metal:javascript_head fill-slot="javascript_head_slot">
<tal:block define="macro here/archetypes_custom_js/macros/javascript_head | nothing"
condition="macro">
<metal:block use-macro="macro" />
</tal:block>
<tal:js condition="js" repeat="item js">
<tal:comment replace="nothing">Include type-specific CSS and JS.</tal:comment>
<metal:js fill-slot="javascript_head_slot">
<tal:js condition="js" repeat="jsFile js">
<script type="text/javascript" charset="iso-8859-1"
tal:condition="python:exists('portal/%s' % item)"
tal:attributes="src string:$portal_url/$item">
tal:condition="python:exists('portal/%s' % jsFile)"
tal:attributes="src string:$portal_url/$jsFile">
</script>
</tal:js>
<tal:block define="macro edit_macros/javascript_head | nothing" condition="macro">
<metal:block use-macro="macro" />
</tal:block>
</metal:javascript_head>
</metal:js>
<metal:css fill-slot="css_slot">
<tal:css condition="css" repeat="item css">
<tal:css condition="css" repeat="cssFile css">
<style type="text/css" media="all"
tal:condition="python:exists('portal/%s' % item)"
tal:content="structure string:<!-- @import url($portal_url/$item); -->">
tal:condition="python:exists('portal/%s' % cssFile)"
tal:content="structure string:<!-- @import url($portal_url/$cssFile); -->">
</style>
</tal:css>
<tal:block define="macro edit_macros/css | nothing" condition="macro">
<metal:block use-macro="macro" />
</tal:block>
</metal:css>
<body>
<metal:fill fill-slot="main">
<div metal:use-macro="here/skyn/macros/macros/pagePrologue"/>
<div metal:use-macro="here/skyn/macros/macros/showPageHeader"/>
<metal:prologue use-macro="here/skyn/page/macros/prologue"/>
<form name="edit_form" method="post" enctype="multipart/form-data"
class="enableUnloadProtection atBaseEditForm"
tal:attributes="action python: contextObj.absolute_url()+'/skyn/do'">
<div metal:use-macro="here/skyn/macros/macros/listFields" /><br/>
<input type="hidden" name="action" value="Update"/>
<input type="hidden" name="fieldset" tal:attributes="value fieldset"/>
<input type="hidden" name="pageName" tal:attributes="value pageName"/>
<input type="hidden" name="phase" tal:attributes="value phase"/>
<input type="hidden" name="page" tal:attributes="value page"/>
<input type="hidden" name="nav" tal:attributes="value python:request.get('nav', '')"/>
<input type="hidden" name="is_new"
tal:attributes="value python: '/portal_factory/' in contextObj.absolute_url()"/>
<tal:comment replace="nothing">Buttons (Previous, Next, Save, etc)</tal:comment>
<metal:block define-slot="buttons"
tal:define="pages phaseInfo/pages;
pageIndex python:pages.index(fieldset);
numberOfPages python:len(pages)">
<tal:previousButton condition="python: pageIndex &gt; 0">
<input class="context" type="submit" name="buttonPrevious"
i18n:attributes="value label_previous;" i18n:domain="plone"
tal:attributes="disabled python:test(isLocked, 'disabled', None);"/>
<input type="hidden" name="previousPage" tal:attributes="value python: pages[pageIndex-1]"/>
</tal:previousButton>
<tal:nextButton condition="python: pageIndex &lt; numberOfPages - 1">
<input class="context" type="submit" name="buttonNext" value="Next"
i18n:attributes="value label_next;" i18n:domain="plone"
tal:attributes="disabled python:test(isLocked, 'disabled', None);"/>
<input type="hidden" name="nextPage" tal:attributes="value python: pages[pageIndex+1]"/>
</tal:nextButton>
<input class="context" type="submit" name="buttonOk"
i18n:attributes="value label_save;" i18n:domain="plone"
tal:attributes="disabled python:test(isLocked, 'disabled', None);"/>
<input class="standalone" type="submit" name="buttonCancel"
i18n:attributes="value label_cancel;" i18n:domain="plone"/>
</metal:block>
<input type="hidden" name="is_new" tal:attributes="value contextObj/checkCreationFlag"/>
<metal:show use-macro="here/skyn/page/macros/show"/>
</form>
<div metal:use-macro="here/skyn/macros/macros/showPageFooter"/>
<metal:footer use-macro="here/skyn/page/macros/footer"/>
</metal:fill>
</body>
</html>
</tal:block>
</tal:edit>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
gen/plone25/skin/help.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 B

BIN
gen/plone25/skin/help.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 735 B

View file

@ -20,7 +20,7 @@
importElems python: flavour.getImportElements(contentType);
global allAreImported python:True">
<div metal:use-macro="here/skyn/macros/macros/pagePrologue"/>
<div metal:use-macro="here/skyn/page/macros/prologue"/>
<script language="javascript">
<!--
var importedElemsShown = false;

View file

@ -1,814 +1,3 @@
<div metal:define-macro="listPodTemplates" class="appyPod" tal:condition="podTemplates"
tal:define="podTemplates python: flavour.getAvailablePodTemplates(contextObj, phase);">
<tal:podTemplates define="maxShownTemplates python: flavour.getMaxShownTemplates(contextObj)">
<tal:comment replace="nothing">Display templates as links if a few number of templates must be shown</tal:comment>
<span class="discreet" tal:condition="python: len(podTemplates)&lt;=maxShownTemplates"
tal:repeat="podTemplate podTemplates">
<a style="cursor: pointer"
tal:define="podFormat podTemplate/getPodFormat"
tal:attributes="onclick python: 'javascript:generatePodDocument(\'%s\',\'%s\', \'\', \'\')' % (contextObj.UID(), podTemplate.UID())" >
<img tal:attributes="src string: $portal_url/skyn/$podFormat.png"/>
<span tal:replace="podTemplate/Title"/>
</a>
&nbsp;</span>
<tal:comment replace="nothing">Display templates as a list if a lot of templates must be shown</tal:comment>
<select tal:condition="python: len(podTemplates)&gt;maxShownTemplates">
<option value="" tal:content="python: tool.translate('choose_a_doc')"></option>
<option tal:repeat="podTemplate podTemplates" tal:content="podTemplate/Title"
tal:attributes="onclick python: 'javascript:generatePodDocument(\'%s\',\'%s\', \'\', \'\')' % (contextObj.UID(), podTemplate.UID())" />
</select>
</tal:podTemplates>
</div>
<metal:editString define-macro="editString" tal:define="vocab python:field.Vocabulary(contextObj)">
<label tal:attributes="for fieldName" tal:condition="showLabel" tal:content="label"/>&nbsp;
<span class="fieldRequired" tal:condition="python: appyType['multiplicity'][0] &gt; 0"></span>
<div class="discreet" tal:content="structure description"/>
<select tal:attributes="name fieldName;
id fieldName;
tabindex tabindex/next;
multiple isMultiple;
onchange python: 'javascript:updateSlaves(getMasterValue(this), \'%s\')' % appyType['id'];
class python: contextObj.getCssClasses(appyType, asSlave=False)">
<option tal:repeat="item vocab" i18n:translate=""
tal:attributes="value item;
selected python:contextObj.fieldValueSelected(fieldName, value, item)"
tal:content="python:here.translate(vocab.getMsgId(item), default=vocab.getValue(item))"/>
</select>
</metal:editString>
<metal:editBoolean define-macro="editBoolean">
<input type="checkbox"
tal:attributes="tabindex tabindex/next;
name python: fieldName + '_visible';
id fieldName;
checked python:contextObj.checkboxChecked(fieldName, value);
onClick python:'toggleCheckbox(\'%s\', \'%s_hidden\');;updateSlaves(getMasterValue(this), \'%s\')' % (fieldName, fieldName, appyType['id']);
class python: 'noborder ' + contextObj.getCssClasses(appyType, asSlave=False)"/>
<input tal:attributes="name fieldName;
id string:${fieldName}_hidden;
value python: test(contextObj.checkboxChecked(fieldName, value), 'True', 'False')"
type="hidden" />
<span class="fieldRequired" tal:condition="python: appyType['multiplicity'][0] &gt; 0"></span>
<label tal:attributes="for fieldName" tal:condition="showLabel" tal:content="label"/>
<div class="discreet" tal:content="structure description"/>
</metal:editBoolean>
<div metal:define-macro="editField"
tal:define="fieldName field/getName;
isMultiple python:test(appyType['multiplicity'][1]!=1, 'multiple', '');
inError python:test(errors.has_key(fieldName), True, False);
value python:field.getAccessor(contextObj)();
defaultValue python: contextObj.getDefault(fieldName)"
tal:attributes="class python:'field ' + test(inError, ' error', '')">
<div tal:condition="inError" tal:content="python: errors[fieldName]"></div>
<tal:stringField condition="python: appyType['type'] == 'String'">
<metal:edit use-macro="here/skyn/macros/macros/editString"/>
</tal:stringField>
<tal:booleanField condition="python: appyType['type'] == 'Boolean'">
<metal:edit use-macro="here/skyn/macros/macros/editBoolean"/>
</tal:booleanField>
</div>
<div metal:define-macro="showComputedField">
<span class="appyLabel" tal:condition="showLabel" tal:content="label"></span>
<span class="formHelp" tal:content="structure description"></span>
<tal:showValue define="theValue python: contextObj.getComputedValue(appyType)">
<span tal:condition="appyType/plainText" tal:replace="theValue"/>
<span tal:condition="not: appyType/plainText" tal:replace="structure theValue"/>
</tal:showValue>
</div>
<div metal:define-macro="showInfoField">
<span class="appyLabel" tal:content="structure label"></span>
<span class="formHelp" tal:content="structure description"></span>
</div>
<div metal:define-macro="showActionField">
<form name="executeAppyAction"
tal:define="formId python: '%s_%s' % (contextObj.UID(), field.getName())"
tal:attributes="id formId; action python: contextObj.absolute_url()+'/skyn/do'">
<input type="hidden" name="action" value="ExecuteAppyAction"/>
<input type="hidden" name="objectUid" tal:attributes="value contextObj/UID"/>
<input type="hidden" name="fieldName" tal:attributes="value field/getName"/>
<input type="button" tal:condition="appyType/confirm"
tal:attributes="value label; onClick python: 'javascript:askConfirm(\'%s\')' % formId"/>
<input type="submit" name="do" tal:condition="not: appyType/confirm"
tal:attributes="value label" onClick="javascript:;"/>
<tal:comment replace="nothing">The previous onClick is simply used to prevent Plone
from adding a CSS class that displays a popup when the user triggers the form multiple
times.</tal:comment>
</form>
</div>
<metal:showDate define-macro="showDateField"
tal:define="v python: contextObj.getAppyValue(field.getName(), appyType)">
<span tal:condition="showLabel" tal:content="label" class="appyLabel"></span>
<span tal:replace="v"></span>
</metal:showDate>
<metal:showFloat define-macro="showFloatField"
tal:define="v python: contextObj.getAppyValue(field.getName(), appyType)">
<span tal:condition="showLabel" tal:content="label"
tal:attributes="class python: 'appyLabel ' + contextObj.getCssClasses(appyType, asSlave=False);
id python: v"></span>
<span tal:replace="v"></span>
</metal:showFloat>
<metal:showString define-macro="showStringField"
tal:define="v python: contextObj.getAppyValue(field.getName(), appyType);
fmt python: appyType['format'];
maxMult python: appyType['multiplicity'][1];
severalValues python: (maxMult == None) or (maxMult &gt; 1)">
<tal:simpleString condition="python: fmt in (0, 3)">
<span tal:condition="showLabel" tal:content="label" class="appyLabel"
tal:attributes="class python: 'appyLabel ' + contextObj.getCssClasses(appyType, asSlave=False);
id python: contextObj.getAppyValue(field.getName(), appyType, forMasterId=True)"></span>
<ul class="appyList" tal:condition="python: v and severalValues">
<li class="appyBullet" tal:repeat="sv v"><i tal:content="structure sv"></i></li>
</ul>
<tal:singleValue condition="python: v and not severalValues">
<span tal:condition="python: fmt != 3" tal:replace="structure v"/>
<span tal:condition="python: fmt == 3">********</span>
</tal:singleValue>
</tal:simpleString>
<tal:formattedString condition="python: fmt not in (0, 3)">
<fieldset>
<legend tal:condition="showLabel" tal:content="label"></legend>
<span tal:condition="python: v and (appyType['format'] == 1)"
tal:replace="structure python: v.replace('\n', '&lt;br&gt;')"/>
<span tal:condition="python: v and (appyType['format'] == 2)" tal:replace="structure v"/>
</fieldset>
</tal:formattedString>
</metal:showString>
<metal:showPod define-macro="showPodField"
tal:define="fieldName field/getName">
<tal:askAction condition="appyType/askAction"
define="doLabel python:'%s_askaction' % appyType['label'];
chekboxId python: '%s_%s' % (contextObj.UID(), fieldName)">
<input type="checkbox" tal:attributes="name doLabel; id chekboxId"/>
<label tal:attributes="for chekboxId" class="discreet"
tal:content="python: tool.translate(doLabel)"></label>
</tal:askAction>
<img tal:repeat="podFormat python:flavour.getPodInfo(contextObj, fieldName)['formats']"
tal:attributes="src string: $portal_url/skyn/${podFormat}.png;
title label;
onClick python: 'javascript:generatePodDocument(\'%s\',\'\',\'%s\',\'%s\')' % (contextObj.UID(), fieldName, podFormat)"
style="cursor:pointer"/>
</metal:showPod>
<div metal:define-macro="showArchetypesField"
tal:define="field fieldDescr/atField|widgetDescr/atField;
appyType fieldDescr/appyType|widgetDescr/appyType;
showLabel showLabel|python:True;
labelId field/widget/label_msgid;
label python: tool.translate(labelId);
descrId field/widget/description_msgid|python:'';
description python: tool.translate(descrId)"
tal:attributes="class python: contextObj.getCssClasses(appyType, asSlave=True)">
<tal:comment replace="nothing">For some fields we simply use the standard Archetypes
macro for showing it. Special Appy field types like Ref and Computed have their
corresponding Archetypes fields set as invisible, so they won't be shown by the following
tal:showField.</tal:comment>
<tal:showField define="mode python:test(isEdit, 'edit', 'view');"
tal:condition="python: test(isEdit, member.has_permission(field.write_permission, contextObj), member.has_permission(field.read_permission, contextObj))">
<tal:editField condition="isEdit">
<metal:editMacro use-macro="python:contextObj.widget(field.getName(), mode='edit', use_label=showLabel)" />
</tal:editField>
<tal:viewField tal:condition="not: isEdit">
<tal:fileField condition="python: (appyType['type'] == 'File')">
<span tal:condition="showLabel" tal:content="label" class="appyLabel"></span>
<metal:viewField use-macro="python: contextObj.widget(field.getName(), 'view', use_label=0)"/>
</tal:fileField>
<tal:date condition="python: appyType['type'] == 'Date'">
<metal:showDate use-macro="here/skyn/macros/macros/showDateField"/>
</tal:date>
<tal:string condition="python: appyType['type'] == 'String'">
<metal:showString use-macro="here/skyn/macros/macros/showStringField"/>
</tal:string>
<tal:float condition="python: appyType['type'] == 'Float'">
<metal:showFloat use-macro="here/skyn/macros/macros/showFloatField"/>
</tal:float>
<tal:simpleField condition="python: (appyType['type'] in ('Integer', 'Boolean'))">
<span tal:condition="showLabel" tal:content="label"
tal:attributes="class python: 'appyLabel ' + contextObj.getCssClasses(appyType, asSlave=False);
id python: field.getAccessor(contextObj)()"></span>
<metal:viewField use-macro="python: contextObj.widget(field.getName(), 'view', use_label=0)"/>
</tal:simpleField>
</tal:viewField>
</tal:showField>
<tal:comment replace="nothing">For other fields like Refs we use specific view/edit macros.</tal:comment>
<tal:viewRef condition="python: (not isEdit) and (appyType['type'] == 'Ref')">
<tal:ref define="isBack python:False;
fieldName field/getName;
innerRef innerRef|python:False">
<metal:viewRef use-macro="here/skyn/ref/macros/showReference" />
</tal:ref>
</tal:viewRef>
<tal:editRef condition="python: isEdit and (appyType['type'] == 'Ref')">
<tal:ref define="appyType fieldDescr/appyType|widgetDescr/appyType"
condition="python: appyType['link']==True">
<metal:editRef use-macro="here/skyn/ref/macros/editReference" />
</tal:ref>
</tal:editRef>
<tal:computedField condition="python: appyType['type'] == 'Computed'">
<metal:cf use-macro="here/skyn/macros/macros/showComputedField" />
</tal:computedField>
<tal:actionField condition="python: appyType['type'] == 'Action'">
<metal:af use-macro="here/skyn/macros/macros/showActionField" />
</tal:actionField>
<tal:masterString condition="python: isEdit and (appyType['type'] in ('String', 'Boolean')) and (appyType['slaves'])">
<metal:mf use-macro="here/skyn/macros/macros/editField" />
</tal:masterString>
<tal:infoField condition="python: appyType['type'] == 'Info'">
<metal:af use-macro="here/skyn/macros/macros/showInfoField" />
</tal:infoField>
<tal:podField condition="python: (not isEdit) and (appyType['type'] == 'Pod')">
<metal:af use-macro="here/skyn/macros/macros/showPodField" />
</tal:podField>
</div>
<div metal:define-macro="showBackwardField"
tal:define="isBack python:True;
appyType widgetDescr/appyType;
fieldName widgetDescr/fieldRel;
labelId python: '%s_%s_back' % (contextObj.meta_type, appyType['backd']['attribute']);
descrId python: '';
innerRef innerRef|python:False">
<div metal:use-macro="here/skyn/ref/macros/showReference" />
</div>
<metal:group define-macro="showGroup">
<fieldset class="appyGroup">
<legend><i tal:define="groupDescription python:contextObj.translate('%s_group_%s' % (contextObj.meta_type, widgetDescr['name']))"
tal:content="structure groupDescription"></i></legend>
<table tal:define="global fieldNb python:-1" width="100%">
<tr valign="top" tal:repeat="rowNb python:range(widgetDescr['rows'])">
<td tal:repeat="colNb python:range(widgetDescr['cols'])"
tal:attributes="width python: str(100.0/widgetDescr['cols']) + '%'">
<tal:showField define="global fieldNb python:fieldNb+1;
hasFieldDescr python: test(fieldNb < len(widgetDescr['fields']), True, False);"
tal:condition="hasFieldDescr">
<tal:field define="fieldDescr python:widgetDescr['fields'][fieldNb]">
<tal:archetypesField condition="python: fieldDescr['widgetType'] == 'field'">
<metal:atField use-macro="here/skyn/macros/macros/showArchetypesField"/>
</tal:archetypesField>
<tal:backwardRef tal:condition="python: (not isEdit) and (fieldDescr['widgetType'] == 'backField')">
<metal:backRef use-macro="here/skyn/macros/macros/showBackwardField" />
</tal:backwardRef>
</tal:field>
</tal:showField>
</td>
</tr>
</table>
</fieldset>
<br/>
</metal:group>
<metal:fields define-macro="listFields"
tal:repeat="widgetDescr python: contextObj.getAppyFields(isEdit, pageName)">
<tal:displayArchetypesField condition="python: widgetDescr['widgetType'] == 'field'">
<tal:atField condition="python: widgetDescr['page'] == pageName">
<metal:field use-macro="here/skyn/macros/macros/showArchetypesField" />
</tal:atField>
</tal:displayArchetypesField>
<tal:displayBackwardRef condition="python: (not isEdit) and (widgetDescr['widgetType'] == 'backField')">
<tal:backRef condition="python: widgetDescr['appyType']['backd']['page'] == pageName">
<metal:field metal:use-macro="here/skyn/macros/macros/showBackwardField" />
</tal:backRef>
</tal:displayBackwardRef>
<tal:displayGroup condition="python: widgetDescr['widgetType'] == 'group'">
<tal:displayG condition="python: widgetDescr['page'] == pageName">
<metal:group metal:use-macro="here/skyn/macros/macros/showGroup" />
</tal:displayG>
</tal:displayGroup>
</metal:fields>
<metal:history define-macro="history"
tal:define="startNumber request/startNumber|python:0;
startNumber python: int(startNumber);
historyInfo python: contextObj.getHistory(startNumber);
objs historyInfo/events;
batchSize historyInfo/batchSize;
totalNumber historyInfo/totalNumber;
ajaxHookId python:'appyHistory';
navBaseCall python: 'askObjectHistory(\'%s\',\'%s\',**v**)' % (ajaxHookId, contextObj.absolute_url());
tool contextObj/getTool">
<tal:comment replace="nothing">Table containing the history</tal:comment>
<tal:history condition="objs">
<metal:nav use-macro="here/skyn/navigate/macros/appyNavigate"/>
<table width="100%" class="listing nosort">
<tr i18n:domain="plone">
<th i18n:translate="listingheader_action"/>
<th i18n:translate="listingheader_performed_by"/>
<th i18n:translate="listingheader_date_and_time"/>
<th i18n:translate="listingheader_comment"/>
</tr>
<tal:event repeat="event objs">
<tr tal:define="odd repeat/event/odd;
rhComments event/comments|nothing;
state event/review_state|nothing;
isDataChange python: event['action'] == '_datachange_'"
tal:attributes="class python:test(odd, 'even', 'odd')" valign="top">
<td tal:condition="isDataChange" tal:content="python: tool.translate('data_change')"></td>
<td tal:condition="not: isDataChange"
tal:content="python: tool.translate(contextObj.getWorkflowLabel(event['action']))"
tal:attributes="class string:state-${state}"/>
<td tal:define="actorid python:event.get('actor');
actor python:contextObj.portal_membership.getMemberInfo(actorid);
fullname actor/fullname|nothing;
username actor/username|nothing"
tal:content="python:fullname or username or actorid"/>
<td tal:content="python:contextObj.restrictedTraverse('@@plone').toLocalizedTime(event['time'],long_format=True)"/>
<td tal:condition="not: isDataChange"><tal:comment condition="rhComments" tal:content="structure rhComments"/>
<tal:noComment condition="not: rhComments" i18n:translate="no_comments" i18n:domain="plone"/></td>
<td tal:condition="isDataChange">
<tal:comment replace="nothing">
Display the previous values of the fields whose value were modified in this change.</tal:comment>
<table class="appyChanges" width="100%">
<tr>
<th align="left" width="30%" tal:content="python: tool.translate('modified_field')"></th>
<th align="left" width="70%" tal:content="python: tool.translate('previous_value')"></th>
</tr>
<tr tal:repeat="change event/changes/items" valign="top">
<td tal:content="python: tool.translate(change[1][1])"></td>
<td tal:define="appyType python:contextObj.getAppyType(change[0]);
appyValue python: contextObj.getAppyValue(change[0], appyType, True, change[1][0]);
severalValues python: (appyType['multiplicity'][1] &gt; 1) or (appyType['multiplicity'][1] == None)">
<span tal:condition="not: severalValues" tal:replace="appyValue"></span>
<ul tal:condition="python: severalValues">
<li tal:repeat="av appyValue" tal:content="av"></li>
</ul>
</td>
</tr>
</table>
</td>
</tr>
</tal:event>
</table>
</tal:history>
</metal:history>
<div metal:define-macro="pagePrologue">
<tal:comment replace="nothing">Global elements used in every page.</tal:comment>
<tal:comment replace="nothing">Javascript messages</tal:comment>
<script language="javascript" tal:content="tool/getJavascriptMessages"></script>
<tal:comment replace="nothing">"Static" javascripts</tal:comment>
<script language="javascript">
<!--
var isIe = (navigator.appName == "Microsoft Internet Explorer");
// AJAX machinery
var xhrObjects = new Array(); // An array of XMLHttpRequest objects
function XhrObject() { // Wraps a XmlHttpRequest object
this.freed = 1; // Is this xhr object already dealing with a request or not?
this.xhr = false;
if (window.XMLHttpRequest) this.xhr = new XMLHttpRequest();
else this.xhr = new ActiveXObject("Microsoft.XMLHTTP");
this.hook = ''; /* The ID of the HTML element in the page that will be
replaced by result of executing the Ajax request. */
this.onGet = ''; /* The name of a Javascript function to call once we
receive the result. */
this.info = {}; /* An associative array for putting anything else. */
}
function getAjaxChunk(pos) {
// This function is the callback called by the AJAX machinery (see function
// askAjaxChunk below) when an Ajax response is available.
// First, find back the correct XMLHttpRequest object
if ( (typeof(xhrObjects[pos]) != 'undefined') &&
(xhrObjects[pos].freed == 0)) {
var hook = xhrObjects[pos].hook;
if (xhrObjects[pos].xhr.readyState == 1) {
// The request has been initialized: display the waiting radar
var hookElem = document.getElementById(hook);
if (hookElem) hookElem.innerHTML = "<div align=\"center\"><img src=\"skyn/waiting.gif\"/><\/div>";
}
if (xhrObjects[pos].xhr.readyState == 4) {
// We have received the HTML chunk
var hookElem = document.getElementById(hook);
if (hookElem && (xhrObjects[pos].xhr.status == 200)) {
hookElem.innerHTML = xhrObjects[pos].xhr.responseText;
// Call a custom Javascript function if required
if (xhrObjects[pos].onGet) {
xhrObjects[pos].onGet(xhrObjects[pos], hookElem);
}
}
xhrObjects[pos].freed = 1;
}
}
}
function askAjaxChunk(hook,mode,url,page,macro,params,beforeSend,onGet) {
/* This function will ask to get a chunk of HTML on the server through a
XMLHttpRequest. p_mode can be 'GET' or 'POST'. p_url is the URL of a
given server object. On this URL we will call the page "ajax.pt" that
will call a specific p_macro in a given p_page with some additional
p_params (must be an associative array) if required.
p_hook is the ID of the HTML element that will be filled with the HTML
result from the server.
p_beforeSend is a Javascript function to call before sending the request.
This function will get 2 args: the XMLHttpRequest object and the
p_params. This method can return, in a string, additional parameters to
send, ie: "&param1=blabla&param2=blabla".
p_onGet is a Javascript function to call when we will receive the answer.
This function will get 2 args, too: the XMLHttpRequest object and the
HTML node element into which the result has been inserted.
*/
// First, get a non-busy XMLHttpRequest object.
var pos = -1;
for (var i=0; i < xhrObjects.length; i++) {
if (xhrObjects[i].freed == 1) { pos = i; break; }
}
if (pos == -1) {
pos = xhrObjects.length;
xhrObjects[pos] = new XhrObject();
}
xhrObjects[pos].hook = hook;
xhrObjects[pos].onGet = onGet;
if (xhrObjects[pos].xhr) {
var rq = xhrObjects[pos];
rq.freed = 0;
// Construct parameters
var paramsFull = 'page=' + page + '&macro=' + macro;
if (params) {
for (var paramName in params)
paramsFull = paramsFull + '&' + paramName + '=' + params[paramName];
}
// Call beforeSend if required
if (beforeSend) {
var res = beforeSend(rq, params);
if (res) paramsFull = paramsFull + res;
}
// Construct the URL to call
var urlFull = url + '/skyn/ajax';
if (mode == 'GET') {
urlFull = urlFull + '?' + paramsFull;
}
// Perform the asynchronous HTTP GET or POST
rq.xhr.open(mode, urlFull, true);
if (mode == 'POST') {
// Set the correct HTTP headers
rq.xhr.setRequestHeader(
"Content-Type", "application/x-www-form-urlencoded");
rq.xhr.setRequestHeader("Content-length", paramsFull.length);
rq.xhr.setRequestHeader("Connection", "close");
rq.xhr.onreadystatechange = function(){ getAjaxChunk(pos); }
rq.xhr.send(paramsFull);
}
else if (mode == 'GET') {
rq.xhr.onreadystatechange = function() { getAjaxChunk(pos); }
if (window.XMLHttpRequest) { rq.xhr.send(null); }
else if (window.ActiveXObject) { rq.xhr.send(); }
}
}
}
/* The functions below wrap askAjaxChunk for getting specific content through
an Ajax request. */
function askQueryResult(hookId, objectUrl, contentType, flavourNumber,
searchName, startNumber, sortKey, sortOrder, filterKey) {
// Sends an Ajax request for getting the result of a query.
var params = {'type_name': contentType, 'flavourNumber': flavourNumber,
'search': searchName, 'startNumber': startNumber};
if (sortKey) params['sortKey'] = sortKey;
if (sortOrder) params['sortOrder'] = sortOrder;
if (filterKey) {
var filterWidget = document.getElementById(hookId + '_' + filterKey);
if (filterWidget && filterWidget.value) {
params['filterKey'] = filterKey;
params['filterValue'] = filterWidget.value;
}
}
askAjaxChunk(hookId,'GET',objectUrl,'macros','queryResult',params);
}
function askObjectHistory(hookId, objectUrl, startNumber) {
// Sends an Ajax request for getting the history of an object
var params = {'startNumber': startNumber};
askAjaxChunk(hookId, 'GET', objectUrl, 'macros', 'history', params);
}
function askRefField(hookId, objectUrl, fieldName, isBack, innerRef, labelId,
descrId, startNumber, action, actionParams){
// Sends an Ajax request for getting the content of a reference field.
var startKey = hookId + '_startNumber';
var params = {'fieldName': fieldName, 'isBack': isBack,
'innerRef': innerRef, 'labelId': labelId,
'descrId': descrId };
params[startKey] = startNumber;
if (action) params['action'] = action;
if (actionParams) {
for (key in actionParams) { params[key] = actionParams[key]; };
}
askAjaxChunk(hookId, 'GET', objectUrl, 'ref', 'showReferenceContent',
params);
}
// Function used by checkbox widgets for having radio-button-like behaviour
function toggleCheckbox(visibleCheckbox, hiddenBoolean) {
vis = document.getElementById(visibleCheckbox);
hidden = document.getElementById(hiddenBoolean);
if (vis.checked) hidden.value = 'True';
else hidden.value = 'False';
}
// Functions used for master/slave relationships between widgets
function getMasterValue(widget) {
// Returns an array of selected options in a select widget
res = new Array();
if (widget.type == 'checkbox') {
var mv = widget.checked + '';
mv = mv.charAt(0).toUpperCase() + mv.substr(1);
res.push(mv);
}
else { // SELECT widget
for (var i=0; i < widget.options.length; i++) {
if (widget.options[i].selected) res.push(widget.options[i].value);
}
}
return res;
}
function updateSlaves(masterValues, appyTypeId) {
// Given the value(s) selected in a master field, this function updates the
// state of all corresponding slaves.
var slaves = cssQuery('div.slave_' + appyTypeId);
for (var i=0; i< slaves.length; i++){
slaves[i].style.display = "none";
}
for (var i=0; i < masterValues.length; i++) {
var activeSlaves = cssQuery('div.slaveValue_' + appyTypeId + '_' + masterValues[i]);
for (var j=0; j < activeSlaves.length; j++){
activeSlaves[j].style.display = "";
}
}
}
// Function used for triggering a workflow transition
function triggerTransition(transitionId) {
var theForm = document.getElementById('triggerTransitionForm');
theForm.workflow_action.value = transitionId;
theForm.submit();
}
function onDeleteObject(objectUid) {
if (confirm(delete_confirm)) {
f = document.getElementById('deleteForm');
f.objectUid.value = objectUid;
f.submit();
}
}
function toggleCookie(cookieId) {
// What is the state of this boolean (expanded/collapsed) cookie?
var state = readCookie(cookieId);
if ((state != 'collapsed') && (state != 'expanded')) {
// No cookie yet, create it.
createCookie(cookieId, 'collapsed');
state = 'collapsed';
}
var hook = document.getElementById(cookieId); // The hook is the part of
// the HTML document that needs to be shown or hidden.
var displayValue = 'none';
var newState = 'collapsed';
var imgSrc = 'skyn/expand.gif';
if (state == 'collapsed') {
// Show the HTML zone
displayValue = 'block';
imgSrc = 'skyn/collapse.gif';
newState = 'expanded';
}
// Update the corresponding HTML element
hook.style.display = displayValue;
var img = document.getElementById(cookieId + '_img');
img.src = imgSrc;
// Inverse the cookie value
createCookie(cookieId, newState);
}
// Function that allows to generate a document from a pod template.
function generatePodDocument(contextUid, templateUid, fieldName, podFormat) {
var theForm = document.forms["podTemplateForm"];
theForm.objectUid.value = contextUid;
theForm.templateUid.value = templateUid;
theForm.fieldName.value = fieldName;
theForm.podFormat.value = podFormat;
theForm.askAction.value = "False";
var askActionWidget = document.getElementById(contextUid + '_' + fieldName);
if (askActionWidget && askActionWidget.checked) {
theForm.askAction.value = "True";
}
theForm.submit();
}
// Functions for opening and closing a popup
function openPopup(popupId) {
// Open the popup
var popup = document.getElementById(popupId);
// Put it at the right place on the screen
var scrollTop = window.pageYOffset || document.documentElement.scrollTop || 0;
popup.style.top = (scrollTop + 150) + 'px';
popup.style.display = "block";
// Show the greyed zone
var greyed = document.getElementById('appyGrey');
greyed.style.top = scrollTop + 'px';
greyed.style.display = "block";
}
function closePopup(popupId) {
// Close the popup
var popup = document.getElementById(popupId);
popup.style.display = "none";
// Hide the greyed zone
var greyed = document.getElementById('appyGrey');
greyed.style.display = "none";
}
// Function triggered when an action needs to be confirmed by the user
function askConfirm(formId) {
// Store the ID of the form to send if the users confirms.
var confirmForm = document.getElementById('confirmActionForm');
confirmForm.actionFormId.value = formId;
openPopup("confirmActionPopup");
}
// Function triggered when an action confirmed by the user must be performed
function doConfirm() {
// The user confirmed: retrieve the form to send and send it.
var confirmForm = document.getElementById('confirmActionForm');
var actionFormId = confirmForm.actionFormId.value;
var actionForm = document.getElementById(actionFormId);
actionForm.submit();
}
-->
</script>
<tal:comment replace="nothing">Global form for deleting an object</tal:comment>
<form id="deleteForm" method="post" action="skyn/do">
<input type="hidden" name="action" value="Delete"/>
<input type="hidden" name="objectUid"/>
</form>
<tal:comment replace="nothing">Global form for generating a document from a pod template.</tal:comment>
<form name="podTemplateForm" method="post"
tal:attributes="action python: flavour.absolute_url() + '/generateDocument'">
<input type="hidden" name="objectUid"/>
<tal:comment replace="nothing">templateUid is given if class-wide pod, fieldName and podFormat are given if podField.</tal:comment>
<input type="hidden" name="templateUid"/>
<input type="hidden" name="fieldName"/>
<input type="hidden" name="podFormat"/>
<input type="hidden" name="askAction"/>
</form>
</div>
<div metal:define-macro="showPageHeader"
tal:define="showCommonInfo python: not isEdit;
hasHistory contextObj/hasHistory;
historyExpanded python: tool.getCookieValue('appyHistory', default='collapsed') == 'expanded';
creator contextObj/Creator"
tal:condition="not: contextObj/isTemporary">
<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">
<tr valign="bottom">
<tal:comment replace="nothing">Title, edit icon and state</tal:comment>
<td width="80%">
<b class="appyTitle" tal:content="contextObj/title_or_id"></b>
<tal:comment replace="nothing">Show the phase name tied to this page</tal:comment>
<span class="discreet" tal:condition="python: phaseInfo['totalNbOfPhases']&gt;1">&minus;
<span tal:replace="python:contextObj.translate('phase')"/>:
<span tal:replace="python:tool.translate('%s_phase_%s' % (contextObj.meta_type, phase))"/>
</span>
<tal:comment replace="nothing">When no tabs are shown, we provide an edit icon.</tal:comment>
<img tal:define="editPageName python:test(pageName=='main', 'default', pageName);
nav request/nav|nothing;
nav python: test(nav, '&nav=%s' % nav, '')"
title="Edit" i18n:domain="plone" i18n:attributes="title" style="cursor:pointer"
tal:attributes="onClick python: 'href: window.location=\'%s/skyn/edit?fieldset=%s&phase=%s%s\'' % (contextObj.absolute_url(), editPageName, phase, nav);
src string: $portal_url/skyn/edit.gif"
tal:condition="python: (len(appyPages)==1) and member.has_permission('Modify portal content', contextObj)"/>
</td>
<td><metal:actions use-macro="here/document_actions/macros/document_actions"/>
</td>
</tr>
<tr tal:define="descrLabel python: contextObj.translate('%s_edit_descr' % contextObj.portal_type)"
tal:condition="descrLabel/strip" >
<tal:comment replace="nothing">Content type description</tal:comment>
<td colspan="2" class="discreet" tal:content="descrLabel"/>
</tr>
<tr>
<td class="documentByLine">
<tal:comment replace="nothing">Creator and last modification date</tal:comment>
<tal:comment replace="nothing">Plus/minus icon for accessing history</tal:comment>
<tal:accessHistory condition="hasHistory">
<img align="left" style="cursor:pointer" onClick="javascript:toggleCookie('appyHistory')"
tal:attributes="src python:test(historyExpanded, 'skyn/collapse.gif', 'skyn/expand.gif');"
id="appyHistory_img"/>&nbsp;
<span i18n:translate="label_history" i18n:domain="plone" class="appyHistory"></span>&nbsp;
</tal:accessHistory>
<tal:comment replace="nothing">Show document creator</tal:comment>
<tal:creator condition="creator"
define="author python:contextObj.portal_membership.getMemberInfo(creator)">
<span class="documentAuthor" i18n:domain="plone" i18n:translate="label_by_author">
by <a tal:attributes="href string:${portal_url}/author/${creator}"
tal:content="python:author and author['fullname'] or creator"
tal:omit-tag="not:author" i18n:name="author"/>
&mdash;
</span>
</tal:creator>
<tal:comment replace="nothing">Show last modification date</tal:comment>
<span i18n:translate="box_last_modified" i18n:domain="plone"></span>
<span tal:replace="python:contextObj.restrictedTraverse('@@plone').toLocalizedTime(contextObj.ModificationDate(),long_format=1)"></span>
</td>
<td valign="top"><metal:pod use-macro="here/skyn/macros/macros/listPodTemplates"/>
</td>
</tr>
<tal:comment replace="nothing">Object history</tal:comment>
<tr tal:condition="hasHistory">
<td colspan="2">
<span id="appyHistory"
tal:attributes="style python:test(historyExpanded, 'display:block', 'display:none')">
<div tal:define="ajaxHookId python: contextObj.UID() + '_history';"
tal:attributes="id ajaxHookId">
<script language="javascript" tal:content="python: 'askObjectHistory(\'%s\',\'%s\',0)' % (ajaxHookId, contextObj.absolute_url())">
</script>
</div>
</span>
</td>
</tr>
<tal:comment replace="nothing">Workflow-related information and actions</tal:comment>
<tr tal:condition="python: showWorkflow and contextObj.getWorkflowLabel()">
<td colspan="2" class="appyWorkflow">
<table width="100%">
<tr>
<td><metal:states use-macro="here/skyn/macros/macros/states"/></td>
<td align="right"><metal:states use-macro="here/skyn/macros/macros/transitions"/></td>
</tr>
</table>
</td>
</tr>
</table>
<metal:nav use-macro="here/skyn/navigate/macros/objectNavigate"/>
<tal:comment replace="nothing">Tabs</tal:comment>
<ul class="contentViews appyTabs" tal:condition="python: len(appyPages)&gt;1">
<li tal:repeat="thePage appyPages"
tal:attributes="class python:test(thePage == pageName, 'selected', 'plain')">
<tal:tab define="pageLabel python: tool.translate('%s_page_%s' % (contextObj.meta_type, thePage))">
<a tal:content="pageLabel"
tal:attributes="href python: contextObj.absolute_url() + '/skyn/view?phase=%s&pageName=%s' % (phase, thePage)">
</a>
<img tal:define="editPageName python:test(thePage=='main', 'default', thePage);
nav request/nav|nothing;
nav python: test(nav, '&nav=%s' % nav, '')"
title="Edit" i18n:domain="plone" i18n:attributes="title" style="cursor:pointer" class="appyPlusImg"
tal:attributes="onClick python: 'href: window.location=\'%s/skyn/edit?fieldset=%s&phase=%s%s\'' % (contextObj.absolute_url(), editPageName, phase, nav);
src string: $portal_url/skyn/edit.gif"
tal:condition="python: member.has_permission('Modify portal content', contextObj)"/>
</tal:tab>
</li>
</ul>
</div>
<div metal:define-macro="showPageFooter">
<script language="javascript">
<!--
// When the current page is loaded, we must set the correct state for all slave fields.
var masters = cssQuery('.appyMaster');
for (var i=0; i < masters.length; i++) {
var cssClasses = masters[i].className.split(' ');
for (var j=0; j < cssClasses.length; j++) {
if (cssClasses[j].indexOf('master_') == 0) {
var appyId = cssClasses[j].split('_')[1];
var masterValue = [];
if (masters[i].nodeName == 'SPAN'){
var idField = masters[i].id;
if (idField == '') {
masterValue.push(idField);
}
else {
if (idField[0] == '(') {
// There are multiple values, split it
var subValues = idField.substring(1, idField.length-1).split(',');
for (var k=0; k < subValues.length; k++){
var subValue = subValues[k].strip();
masterValue.push(subValue.substring(1, subValue.length-1));
}
}
else { masterValue.push(masters[i].id);
}
}
}
else { masterValue = getMasterValue(masters[i]);
}
updateSlaves(masterValue, appyId);
}
}
}
-->
</script>
</div>
<metal:queryResults define-macro="queryResult"
tal:define="tool python: contextObj;
contentType request/type_name;
@ -856,7 +45,7 @@
<table tal:define="fieldDescrs python: tool.getResultColumns(objs[0], contentType)"
class="listing nosort" 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 fieldDescrs is an Appy type (dict version),
excepted for workflow state (which is not a field): in this case it is simply the
string "workflow_state".</tal:comment>
@ -871,12 +60,12 @@
<tal:comment replace="nothing">Columns corresponding to other fields</tal:comment>
<tal:columnHeader repeat="fieldDescr fieldDescrs">
<th tal:define="fieldName fieldDescr/atField/getName|string:workflow_state;
sortable fieldDescr/sortable|nothing;
<th tal:define="fieldName fieldDescr/name|string:workflow_state;
sortable fieldDescr/indexed|nothing;
filterable fieldDescr/filterable|nothing;">
<tal:comment replace="nothing">Display header for a "standard" field</tal:comment>
<tal:standardField condition="python: fieldName != 'workflow_state'">
<span tal:replace="python: tool.translate(fieldDescr['atField'].widget.label_msgid)"/>
<span tal:replace="python: tool.translate(fieldDescr['labelId'])"/>
</tal:standardField>
<tal:comment replace="nothing">Display header for the workflow state</tal:comment>
<tal:workflowState condition="python: fieldName == 'workflow_state'">
@ -906,23 +95,22 @@
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:otherFields repeat="fieldDescr fieldDescrs">
<tal:standardField condition="python: fieldDescr != 'workflowState'">
<td tal:condition="fieldDescr/atField"
tal:attributes="id python:'field_%s' % fieldDescr['atField'].getName()">
<tal:otherFields repeat="widget fieldDescrs">
<tal:standardField condition="python: widget != 'workflowState'">
<td tal:condition="python: '_wrong' not in widget"
tal:attributes="id python:'field_%s' % widget['name']">
<tal:field define="contextObj python:obj;
isEdit python:False;
showLabel python:False;
layoutType python:'cell';
innerRef python:True"
condition="python: contextObj.showField(fieldDescr)">
<metal:field use-macro="here/skyn/macros/macros/showArchetypesField"/>
condition="python: contextObj.showField(widget['name'], 'view')">
<metal:field use-macro="here/skyn/widgets/show/macros/field"/>
</tal:field>
</td>
<td tal:condition="not: fieldDescr/atField" style="color:red">Field
<span tal:replace="fieldDescr/name"/> not found.
<td tal:condition="python: '_wrong' in widget" style="color:red">Field
<span tal:replace="widget/name"/> not found.
</td>
</tal:standardField>
<tal:workflowState condition="python: fieldDescr == 'workflowState'">
<tal:workflowState condition="python: widget == 'workflowState'">
<td id="field_workflow_state" tal:content="python: tool.translate(obj.getWorkflowLabel())"></td>
</tal:workflowState>
</tal:otherFields>
@ -969,70 +157,3 @@
</tal:noResult>
</metal:queryResults>
<metal:phases define-macro="phases">
<tal:comment replace="nothing">This macro displays phases defined for a given content type,
only if more than one phase is defined.</tal:comment>
<table width="100%" tal:define="phases contextObj/getAppyPhases|nothing"
tal:condition="python: phases and (len(phases)&gt;1)" cellspacing="1" cellpadding="0">
<tal:phase repeat="phase phases">
<tr>
<td tal:define="label python:'%s_phase_%s' % (contextObj.meta_type, phase['name']);
displayLink python: (phase['phaseStatus'] != 'Future') and ('/portal_factory' not in contextObj.absolute_url())"
tal:attributes="class python: 'appyPhase step' + phase['phaseStatus']">
<a tal:attributes="href python: '%s?phase=%s&pageName=%s' % (contextObj.getUrl(), phase['name'], phase['pages'][0]);" tal:condition="displayLink"
tal:content="python: tool.translate(label)"/>
<span tal:condition="not: displayLink" tal:content="python: tool.translate(label)"/>
</td>
</tr>
<tr tal:condition="python: phase['name'] != phases[-1]['name']">
<td align="center"><img tal:attributes="src string: $portal_url/skyn/nextPhase.png"/></td>
</tr>
</tal:phase>
</table>
</metal:phases>
<metal:states define-macro="states"
tal:define="showAllStatesInPhase python: flavour.getAttr('showAllStatesInPhaseFor' + contextObj.meta_type);
states python: contextObj.getAppyStates(phase, currentOnly=not showAllStatesInPhase)"
tal:condition="python: test(showAllStatesInPhase, len(states)&gt;1, True)">
<table>
<tr>
<tal:state repeat="stateInfo states">
<td tal:attributes="class python: 'appyState step' + stateInfo['stateStatus']"
tal:content="python: tool.translate(contextObj.getWorkflowLabel(stateInfo['name']))">
</td>
<td tal:condition="python: stateInfo['name'] != states[-1]['name']">
<img tal:attributes="src string: $portal_url/skyn/nextState.png"/>
</td>
</tal:state>
</tr>
</table>
</metal:states>
<metal:transitions define-macro="transitions"
tal:define="transitions contextObj/getAppyTransitions"
tal:condition="transitions">
<form id="triggerTransitionForm" method="post"
tal:attributes="action python: contextObj.absolute_url() + '/skyn/do'">
<input type="hidden" name="action" value="TriggerTransition"/>
<input type="hidden" name="workflow_action"/>
<table>
<tr>
<tal:comment replace="nothing">Input field allowing to enter a comment before triggering a transition</tal:comment>
<td tal:define="showCommentsField python:flavour.getAttr('showWorkflowCommentFieldFor'+contextObj.meta_type)"
align="right" tal:condition="showCommentsField">
<span tal:content="python: tool.translate('workflow_comment')" class="discreet"></span>
<input type="text" id="comment" name="comment" size="35"/>
</td>
<tal:comment replace="nothing">Buttons for triggering transitions</tal:comment>
<td align="right" tal:repeat="transition transitions">
<input type="button" class="context"
tal:attributes="value python: tool.translate(transition['name']);
onClick python: 'javascript: triggerTransition(\'%s\')' % transition['id'];"/>
</td>
</tr>
</table>
</form>
</metal:transitions>

BIN
gen/plone25/skin/next.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 951 B

728
gen/plone25/skin/page.pt Normal file
View file

@ -0,0 +1,728 @@
<tal:comment replace="nothing">
This macro contains global page-related Javascripts.
</tal:comment>
<div metal:define-macro="prologue">
<tal:comment replace="nothing">Global elements used in every page.</tal:comment>
<tal:comment replace="nothing">Javascript messages</tal:comment>
<script language="javascript" tal:content="tool/getJavascriptMessages"></script>
<tal:comment replace="nothing">"Static" javascripts</tal:comment>
<script language="javascript">
<!--
var isIe = (navigator.appName == "Microsoft Internet Explorer");
// AJAX machinery
var xhrObjects = new Array(); // An array of XMLHttpRequest objects
function XhrObject() { // Wraps a XmlHttpRequest object
this.freed = 1; // Is this xhr object already dealing with a request or not?
this.xhr = false;
if (window.XMLHttpRequest) this.xhr = new XMLHttpRequest();
else this.xhr = new ActiveXObject("Microsoft.XMLHTTP");
this.hook = ''; /* The ID of the HTML element in the page that will be
replaced by result of executing the Ajax request. */
this.onGet = ''; /* The name of a Javascript function to call once we
receive the result. */
this.info = {}; /* An associative array for putting anything else. */
}
function getAjaxChunk(pos) {
// This function is the callback called by the AJAX machinery (see function
// askAjaxChunk below) when an Ajax response is available.
// First, find back the correct XMLHttpRequest object
if ( (typeof(xhrObjects[pos]) != 'undefined') &&
(xhrObjects[pos].freed == 0)) {
var hook = xhrObjects[pos].hook;
if (xhrObjects[pos].xhr.readyState == 1) {
// The request has been initialized: display the waiting radar
var hookElem = document.getElementById(hook);
if (hookElem) hookElem.innerHTML = "<div align=\"center\"><img src=\"skyn/waiting.gif\"/><\/div>";
}
if (xhrObjects[pos].xhr.readyState == 4) {
// We have received the HTML chunk
var hookElem = document.getElementById(hook);
if (hookElem && (xhrObjects[pos].xhr.status == 200)) {
hookElem.innerHTML = xhrObjects[pos].xhr.responseText;
// Call a custom Javascript function if required
if (xhrObjects[pos].onGet) {
xhrObjects[pos].onGet(xhrObjects[pos], hookElem);
}
}
xhrObjects[pos].freed = 1;
}
}
}
function askAjaxChunk(hook,mode,url,page,macro,params,beforeSend,onGet) {
/* This function will ask to get a chunk of HTML on the server through a
XMLHttpRequest. p_mode can be 'GET' or 'POST'. p_url is the URL of a
given server object. On this URL we will call the page "ajax.pt" that
will call a specific p_macro in a given p_page with some additional
p_params (must be an associative array) if required.
p_hook is the ID of the HTML element that will be filled with the HTML
result from the server.
p_beforeSend is a Javascript function to call before sending the request.
This function will get 2 args: the XMLHttpRequest object and the
p_params. This method can return, in a string, additional parameters to
send, ie: "&param1=blabla&param2=blabla".
p_onGet is a Javascript function to call when we will receive the answer.
This function will get 2 args, too: the XMLHttpRequest object and the
HTML node element into which the result has been inserted.
*/
// First, get a non-busy XMLHttpRequest object.
var pos = -1;
for (var i=0; i < xhrObjects.length; i++) {
if (xhrObjects[i].freed == 1) { pos = i; break; }
}
if (pos == -1) {
pos = xhrObjects.length;
xhrObjects[pos] = new XhrObject();
}
xhrObjects[pos].hook = hook;
xhrObjects[pos].onGet = onGet;
if (xhrObjects[pos].xhr) {
var rq = xhrObjects[pos];
rq.freed = 0;
// Construct parameters
var paramsFull = 'page=' + page + '&macro=' + macro;
if (params) {
for (var paramName in params)
paramsFull = paramsFull + '&' + paramName + '=' + params[paramName];
}
// Call beforeSend if required
if (beforeSend) {
var res = beforeSend(rq, params);
if (res) paramsFull = paramsFull + res;
}
// Construct the URL to call
var urlFull = url + '/skyn/ajax';
if (mode == 'GET') {
urlFull = urlFull + '?' + paramsFull;
}
// Perform the asynchronous HTTP GET or POST
rq.xhr.open(mode, urlFull, true);
if (mode == 'POST') {
// Set the correct HTTP headers
rq.xhr.setRequestHeader(
"Content-Type", "application/x-www-form-urlencoded");
rq.xhr.setRequestHeader("Content-length", paramsFull.length);
rq.xhr.setRequestHeader("Connection", "close");
rq.xhr.onreadystatechange = function(){ getAjaxChunk(pos); }
rq.xhr.send(paramsFull);
}
else if (mode == 'GET') {
rq.xhr.onreadystatechange = function() { getAjaxChunk(pos); }
if (window.XMLHttpRequest) { rq.xhr.send(null); }
else if (window.ActiveXObject) { rq.xhr.send(); }
}
}
}
/* The functions below wrap askAjaxChunk for getting specific content through
an Ajax request. */
function askQueryResult(hookId, objectUrl, contentType, flavourNumber,
searchName, startNumber, sortKey, sortOrder, filterKey) {
// Sends an Ajax request for getting the result of a query.
var params = {'type_name': contentType, 'flavourNumber': flavourNumber,
'search': searchName, 'startNumber': startNumber};
if (sortKey) params['sortKey'] = sortKey;
if (sortOrder) params['sortOrder'] = sortOrder;
if (filterKey) {
var filterWidget = document.getElementById(hookId + '_' + filterKey);
if (filterWidget && filterWidget.value) {
params['filterKey'] = filterKey;
params['filterValue'] = filterWidget.value;
}
}
askAjaxChunk(hookId,'GET',objectUrl,'macros','queryResult',params);
}
function askObjectHistory(hookId, objectUrl, startNumber) {
// Sends an Ajax request for getting the history of an object
var params = {'startNumber': startNumber};
askAjaxChunk(hookId, 'GET', objectUrl, 'page', 'objectHistory', params);
}
function askRefField(hookId, objectUrl, fieldName, innerRef, startNumber,
action, actionParams){
// Sends an Ajax request for getting the content of a reference field.
var startKey = hookId + '_startNumber';
var params = {'fieldName': fieldName, 'innerRef': innerRef, };
params[startKey] = startNumber;
if (action) params['action'] = action;
if (actionParams) {
for (key in actionParams) { params[key] = actionParams[key]; };
}
askAjaxChunk(hookId, 'GET', objectUrl, 'widgets/ref', 'viewContent',params);
}
// Function used by checkbox widgets for having radio-button-like behaviour
function toggleCheckbox(visibleCheckbox, hiddenBoolean) {
vis = document.getElementById(visibleCheckbox);
hidden = document.getElementById(hiddenBoolean);
if (vis.checked) hidden.value = 'True';
else hidden.value = 'False';
}
// Functions used for master/slave relationships between widgets
function getMasterValue(widget) {
// Returns an array of selected options in a select widget
res = new Array();
if (widget.type == 'checkbox') {
var mv = widget.checked + '';
mv = mv.charAt(0).toUpperCase() + mv.substr(1);
res.push(mv);
}
else { // SELECT widget
for (var i=0; i < widget.options.length; i++) {
if (widget.options[i].selected) res.push(widget.options[i].value);
}
}
return res;
}
function updateSlaves(masterValues, appyTypeId) {
// Given the value(s) selected in a master field, this function updates the
// state of all corresponding slaves.
var slaves = cssQuery('table.slave_' + appyTypeId);
for (var i=0; i< slaves.length; i++){
slaves[i].style.display = "none";
}
for (var i=0; i < masterValues.length; i++) {
var activeSlaves = cssQuery('table.slaveValue_' + appyTypeId + '_' + masterValues[i]);
for (var j=0; j < activeSlaves.length; j++){
activeSlaves[j].style.display = "";
}
}
}
// Function used for triggering a workflow transition
function triggerTransition(transitionId) {
var theForm = document.getElementById('triggerTransitionForm');
theForm.workflow_action.value = transitionId;
theForm.submit();
}
function onDeleteObject(objectUid) {
if (confirm(delete_confirm)) {
f = document.getElementById('deleteForm');
f.objectUid.value = objectUid;
f.submit();
}
}
function toggleCookie(cookieId) {
// What is the state of this boolean (expanded/collapsed) cookie?
var state = readCookie(cookieId);
if ((state != 'collapsed') && (state != 'expanded')) {
// No cookie yet, create it.
createCookie(cookieId, 'collapsed');
state = 'collapsed';
}
var hook = document.getElementById(cookieId); // The hook is the part of
// the HTML document that needs to be shown or hidden.
var displayValue = 'none';
var newState = 'collapsed';
var imgSrc = 'skyn/expand.gif';
if (state == 'collapsed') {
// Show the HTML zone
displayValue = 'block';
imgSrc = 'skyn/collapse.gif';
newState = 'expanded';
}
// Update the corresponding HTML element
hook.style.display = displayValue;
var img = document.getElementById(cookieId + '_img');
img.src = imgSrc;
// Inverse the cookie value
createCookie(cookieId, newState);
}
// Function that allows to generate a document from a pod template.
function generatePodDocument(contextUid, templateUid, fieldName, podFormat) {
var theForm = document.forms["podTemplateForm"];
theForm.objectUid.value = contextUid;
theForm.templateUid.value = templateUid;
theForm.fieldName.value = fieldName;
theForm.podFormat.value = podFormat;
theForm.askAction.value = "False";
var askActionWidget = document.getElementById(contextUid + '_' + fieldName);
if (askActionWidget && askActionWidget.checked) {
theForm.askAction.value = "True";
}
theForm.submit();
}
// Functions for opening and closing a popup
function openPopup(popupId) {
// Open the popup
var popup = document.getElementById(popupId);
// Put it at the right place on the screen
var scrollTop = window.pageYOffset || document.documentElement.scrollTop || 0;
popup.style.top = (scrollTop + 150) + 'px';
popup.style.display = "block";
// Show the greyed zone
var greyed = document.getElementById('appyGrey');
greyed.style.top = scrollTop + 'px';
greyed.style.display = "block";
}
function closePopup(popupId) {
// Close the popup
var popup = document.getElementById(popupId);
popup.style.display = "none";
// Hide the greyed zone
var greyed = document.getElementById('appyGrey');
greyed.style.display = "none";
}
// Function triggered when an action needs to be confirmed by the user
function askConfirm(formId) {
// Store the ID of the form to send if the users confirms.
var confirmForm = document.getElementById('confirmActionForm');
confirmForm.actionFormId.value = formId;
openPopup("confirmActionPopup");
}
// Function triggered when an action confirmed by the user must be performed
function doConfirm() {
// The user confirmed: retrieve the form to send and send it.
var confirmForm = document.getElementById('confirmActionForm');
var actionFormId = confirmForm.actionFormId.value;
var actionForm = document.getElementById(actionFormId);
actionForm.submit();
}
// Function that shows or hides a tab. p_action is 'show' or 'hide'.
function manageTab(tabId, action) {
// Manage the tab content (show it or hide it)
var content = document.getElementById('tabcontent_' + tabId);
if (action == 'show') { content.style.display = 'table-row'; }
else { content.style.display = 'none'; }
// Manage the tab itself (show as selected or unselected)
var left = document.getElementById('tab_' + tabId + '_left');
var tab = document.getElementById('tab_' + tabId);
var right = document.getElementById('tab_' + tabId + '_right');
if (action == 'show') {
left.src = "skyn/tabLeft.png";
tab.style.backgroundImage = "url(skyn/tabBg.png)";
right.src = "skyn/tabRight.png";
}
if (action == 'hide') {
left.src = "skyn/tabLeftu.png";
tab.style.backgroundImage = "url(skyn/tabBgu.png)";
right.src = "skyn/tabRightu.png";
}
}
// Function used for displaying/hiding content of a tab
function showTab(tabId) {
// 1st, show the tab to show
manageTab(tabId, 'show');
// Compute the number of tabs.
var idParts = tabId.split('_');
var prefix = idParts[0] + '_';
// Store the currently selected tab in a cookie.
createCookie('tab_' + idParts[0], tabId);
var nbOfTabs = idParts[2]*1;
// Then, hide the other tabs.
for (var i=0; i<nbOfTabs; i++) {
var idTab = prefix + (i+1) + '_' + nbOfTabs;
if (idTab != tabId) {
manageTab(idTab, 'hide');
}
}
}
// Function that initializes the state of a tab
function initTab(cookieId, defaultValue) {
var toSelect = readCookie(cookieId);
if (!toSelect) { showTab(defaultValue) }
else { showTab(toSelect); }
}
-->
</script>
<tal:comment replace="nothing">Global form for deleting an object</tal:comment>
<form id="deleteForm" method="post" action="skyn/do">
<input type="hidden" name="action" value="Delete"/>
<input type="hidden" name="objectUid"/>
</form>
<tal:comment replace="nothing">Global form for generating a document from a pod template.</tal:comment>
<form name="podTemplateForm" method="post"
tal:attributes="action python: flavour.absolute_url() + '/generateDocument'">
<input type="hidden" name="objectUid"/>
<tal:comment replace="nothing">templateUid is given if class-wide pod, fieldName and podFormat are given if podField.</tal:comment>
<input type="hidden" name="templateUid"/>
<input type="hidden" name="fieldName"/>
<input type="hidden" name="podFormat"/>
<input type="hidden" name="askAction"/>
</form>
</div>
<tal:comment replace="nothing">
This macro shows the content of page. Because a page is a layouted object,
we simply call the macro that displays a layouted object.
contextObj The Zope object for which this page must be shown
layoutType The kind of layout: "view"? "edit"? "cell"?
layout The layout object that will dictate how object content
will be rendered.
</tal:comment>
<metal:show define-macro="show">
<metal:layout use-macro="here/skyn/widgets/show/macros/layout"/>
</metal:show>
<tal:comment replace="nothing">
This macro displays all widgets of a given page. It requires:
contextObj The Zope object for which widgets must be shown
page We show widgets of a given page
layoutType We must know if we must render the widgets in a "view",
"edit" or "cell" layout
</tal:comment>
<table metal:define-macro="widgets" cellpadding="0" cellspacing="0">
<tr tal:repeat="widget python: contextObj.getGroupedAppyTypes(layoutType, page)">
<td tal:condition="python: widget['type'] == 'group'">
<metal:call use-macro="portal/skyn/widgets/show/macros/group"/>
</td>
<td tal:condition="python: widget['type'] != 'group'">
<metal:call use-macro="portal/skyn/widgets/show/macros/field"/>
</td>
</tr>
</table>
<tal:comment replace="nothing">
This macro lists the POD templates that are available. It is used by macro "header" below.
</tal:comment>
<div metal:define-macro="listPodTemplates" class="appyPod" tal:condition="podTemplates"
tal:define="podTemplates python: flavour.getAvailablePodTemplates(contextObj, phase);">
<tal:podTemplates define="maxShownTemplates python: flavour.getMaxShownTemplates(contextObj)">
<tal:comment replace="nothing">Display templates as links if a few number of templates must be shown</tal:comment>
<span class="discreet" tal:condition="python: len(podTemplates)&lt;=maxShownTemplates"
tal:repeat="podTemplate podTemplates">
<a style="cursor: pointer"
tal:define="podFormat podTemplate/getPodFormat"
tal:attributes="onclick python: 'javascript:generatePodDocument(\'%s\',\'%s\', \'\', \'\')' % (contextObj.UID(), podTemplate.UID())" >
<img tal:attributes="src string: $portal_url/skyn/$podFormat.png"/>
<span tal:replace="podTemplate/Title"/>
</a>
&nbsp;</span>
<tal:comment replace="nothing">Display templates as a list if a lot of templates must be shown</tal:comment>
<select tal:condition="python: len(podTemplates)&gt;maxShownTemplates">
<option value="" tal:content="python: tool.translate('choose_a_doc')"></option>
<option tal:repeat="podTemplate podTemplates" tal:content="podTemplate/Title"
tal:attributes="onclick python: 'javascript:generatePodDocument(\'%s\',\'%s\', \'\', \'\')' % (contextObj.UID(), podTemplate.UID())" />
</select>
</tal:podTemplates>
</div>
<tal:comment replace="nothing">
This macro displays an object's history. It is used by macro "header" below.
</tal:comment>
<metal:history define-macro="objectHistory"
tal:define="startNumber request/startNumber|python:0;
startNumber python: int(startNumber);
historyInfo python: contextObj.getHistory(startNumber);
objs historyInfo/events;
batchSize historyInfo/batchSize;
totalNumber historyInfo/totalNumber;
ajaxHookId python:'appyHistory';
navBaseCall python: 'askObjectHistory(\'%s\',\'%s\',**v**)' % (ajaxHookId, contextObj.absolute_url());
tool contextObj/getTool">
<tal:comment replace="nothing">Table containing the history</tal:comment>
<tal:history condition="objs">
<metal:nav use-macro="here/skyn/navigate/macros/appyNavigate"/>
<table width="100%" class="listing nosort">
<tr i18n:domain="plone">
<th i18n:translate="listingheader_action"/>
<th i18n:translate="listingheader_performed_by"/>
<th i18n:translate="listingheader_date_and_time"/>
<th i18n:translate="listingheader_comment"/>
</tr>
<tal:event repeat="event objs">
<tr tal:define="odd repeat/event/odd;
rhComments event/comments|nothing;
state event/review_state|nothing;
isDataChange python: event['action'] == '_datachange_'"
tal:attributes="class python:test(odd, 'even', 'odd')" valign="top">
<td tal:condition="isDataChange" tal:content="python: tool.translate('data_change')"></td>
<td tal:condition="not: isDataChange"
tal:content="python: tool.translate(contextObj.getWorkflowLabel(event['action']))"
tal:attributes="class string:state-${state}"/>
<td tal:define="actorid python:event.get('actor');
actor python:contextObj.portal_membership.getMemberInfo(actorid);
fullname actor/fullname|nothing;
username actor/username|nothing"
tal:content="python:fullname or username or actorid"/>
<td tal:content="python:contextObj.restrictedTraverse('@@plone').toLocalizedTime(event['time'],long_format=True)"/>
<td tal:condition="not: isDataChange"><tal:comment condition="rhComments" tal:content="structure rhComments"/>
<tal:noComment condition="not: rhComments" i18n:translate="no_comments" i18n:domain="plone"/></td>
<td tal:condition="isDataChange">
<tal:comment replace="nothing">
Display the previous values of the fields whose value were modified in this change.</tal:comment>
<table class="appyChanges" width="100%">
<tr>
<th align="left" width="30%" tal:content="python: tool.translate('modified_field')"></th>
<th align="left" width="70%" tal:content="python: tool.translate('previous_value')"></th>
</tr>
<tr tal:repeat="change event/changes/items" valign="top">
<td tal:content="python: tool.translate(change[1][1])"></td>
<td tal:define="appyValue python: contextObj.getFormattedValue(change[0], useParamValue=True, value=change[1][0]);
appyType python:contextObj.getAppyType(change[0], asDict=True);
severalValues python: (appyType['multiplicity'][1] &gt; 1) or (appyType['multiplicity'][1] == None)">
<span tal:condition="not: severalValues" tal:replace="appyValue"></span>
<ul tal:condition="python: severalValues">
<li tal:repeat="av appyValue" tal:content="av"></li>
</ul>
</td>
</tr>
</table>
</td>
</tr>
</tal:event>
</table>
</tal:history>
</metal:history>
<tal:comment replace="nothing">
This macro displays an object's state(s). It is used by macro "header" below.
</tal:comment>
<metal:states define-macro="states"
tal:define="showAllStatesInPhase python: flavour.getAttr('showAllStatesInPhaseFor' + contextObj.meta_type);
states python: contextObj.getAppyStates(phase, currentOnly=not showAllStatesInPhase)"
tal:condition="python: test(showAllStatesInPhase, len(states)&gt;1, True)">
<table>
<tr>
<tal:state repeat="stateInfo states">
<td tal:attributes="class python: 'appyState step' + stateInfo['stateStatus']"
tal:content="python: tool.translate(contextObj.getWorkflowLabel(stateInfo['name']))">
</td>
<td tal:condition="python: stateInfo['name'] != states[-1]['name']">
<img tal:attributes="src string: $portal_url/skyn/nextState.png"/>
</td>
</tal:state>
</tr>
</table>
</metal:states>
<tal:comment replace="nothing">
This macro displays an object's transitions(s). It is used by macro "header" below.
</tal:comment>
<metal:transitions define-macro="transitions"
tal:define="transitions contextObj/getAppyTransitions"
tal:condition="transitions">
<form id="triggerTransitionForm" method="post"
tal:attributes="action python: contextObj.absolute_url() + '/skyn/do'">
<input type="hidden" name="action" value="TriggerTransition"/>
<input type="hidden" name="workflow_action"/>
<table>
<tr>
<tal:comment replace="nothing">Input field allowing to enter a comment before triggering a transition</tal:comment>
<td tal:define="showCommentsField python:flavour.getAttr('showWorkflowCommentFieldFor'+contextObj.meta_type)"
align="right" tal:condition="showCommentsField">
<span tal:content="python: tool.translate('workflow_comment')" class="discreet"></span>
<input type="text" id="comment" name="comment" size="35"/>
</td>
<tal:comment replace="nothing">Buttons for triggering transitions</tal:comment>
<td align="right" tal:repeat="transition transitions">
<input type="button" class="context"
tal:attributes="value python: tool.translate(transition['name']);
onClick python: 'javascript: triggerTransition(\'%s\')' % transition['id'];"/>
</td>
</tr>
</table>
</form>
</metal:transitions>
<tal:comment replace="nothing">
This macros displays the page header, containing object title,
workflow-related info, object history, etc.
</tal:comment>
<div metal:define-macro="header"
tal:define="showCommonInfo python: layoutType == 'view';
hasHistory contextObj/hasHistory;
historyExpanded python: tool.getCookieValue('appyHistory', default='collapsed') == 'expanded';
creator contextObj/Creator"
tal:condition="not: contextObj/isTemporary">
<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">
<tr valign="bottom">
<tal:comment replace="nothing">Title and state</tal:comment>
<td width="80%">
<b class="appyTitle" tal:content="contextObj/title_or_id"></b>
</td>
<td><metal:actions use-macro="here/document_actions/macros/document_actions"/>
</td>
</tr>
<tr tal:define="descrLabel python: contextObj.translate('%s_edit_descr' % contextObj.portal_type)"
tal:condition="descrLabel/strip" >
<tal:comment replace="nothing">Content type description</tal:comment>
<td colspan="2" class="discreet" tal:content="descrLabel"/>
</tr>
<tr>
<td class="documentByLine">
<tal:comment replace="nothing">Creator and last modification date</tal:comment>
<tal:comment replace="nothing">Plus/minus icon for accessing history</tal:comment>
<tal:accessHistory condition="hasHistory">
<img align="left" style="cursor:pointer" onClick="javascript:toggleCookie('appyHistory')"
tal:attributes="src python:test(historyExpanded, 'skyn/collapse.gif', 'skyn/expand.gif');"
id="appyHistory_img"/>&nbsp;
<span i18n:translate="label_history" i18n:domain="plone" class="appyHistory"></span>&nbsp;
</tal:accessHistory>
<tal:comment replace="nothing">Show document creator</tal:comment>
<tal:creator condition="creator"
define="author python:contextObj.portal_membership.getMemberInfo(creator)">
<span class="documentAuthor" i18n:domain="plone" i18n:translate="label_by_author">
by <a tal:attributes="href string:${portal_url}/author/${creator}"
tal:content="python:author and author['fullname'] or creator"
tal:omit-tag="not:author" i18n:name="author"/>
&mdash;
</span>
</tal:creator>
<tal:comment replace="nothing">Show last modification date</tal:comment>
<span i18n:translate="box_last_modified" i18n:domain="plone"></span>
<span tal:replace="python:contextObj.restrictedTraverse('@@plone').toLocalizedTime(contextObj.ModificationDate(),long_format=1)"></span>
</td>
<td valign="top"><metal:pod use-macro="here/skyn/page/macros/listPodTemplates"/>
</td>
</tr>
<tal:comment replace="nothing">Object history</tal:comment>
<tr tal:condition="hasHistory">
<td colspan="2">
<span id="appyHistory"
tal:attributes="style python:test(historyExpanded, 'display:block', 'display:none')">
<div tal:define="ajaxHookId python: contextObj.UID() + '_history';"
tal:attributes="id ajaxHookId">
<script language="javascript" tal:content="python: 'askObjectHistory(\'%s\',\'%s\',0)' % (ajaxHookId, contextObj.absolute_url())">
</script>
</div>
</span>
</td>
</tr>
<tal:comment replace="nothing">Workflow-related information and actions</tal:comment>
<tr tal:condition="python: showWorkflow and contextObj.getWorkflowLabel()">
<td colspan="2" class="appyWorkflow">
<table width="100%">
<tr>
<td><metal:states use-macro="here/skyn/page/macros/states"/></td>
<td align="right"><metal:states use-macro="here/skyn/page/macros/transitions"/></td>
</tr>
</table>
</td>
</tr>
</table>
</div>
<tal:comment replace="nothing">
The page footer.
</tal:comment>
<metal:footer define-macro="footer">
<tal:dummy define="messages putils/showPortalMessages"/>
<script language="javascript">
<!--
// When the current page is loaded, we must set the correct state for all slave fields.
var masters = cssQuery('.appyMaster');
for (var i=0; i < masters.length; i++) {
var cssClasses = masters[i].className.split(' ');
for (var j=0; j < cssClasses.length; j++) {
if (cssClasses[j].indexOf('master_') == 0) {
var appyId = cssClasses[j].split('_')[1];
var masterValue = [];
if (masters[i].nodeName == 'SPAN'){
var idField = masters[i].id;
if (idField == '') {
masterValue.push(idField);
}
else {
if (idField[0] == '(') {
// There are multiple values, split it
var subValues = idField.substring(1, idField.length-1).split(',');
for (var k=0; k < subValues.length; k++){
var subValue = subValues[k].strip();
masterValue.push(subValue.substring(1, subValue.length-1));
}
}
else { masterValue.push(masters[i].id);
}
}
}
else { masterValue = getMasterValue(masters[i]);
}
updateSlaves(masterValue, appyId);
}
}
}
-->
</script>
</metal:footer>
<tal:comment replace="nothing">
This macro shows the range of buttons (next, previous, save,...).
</tal:comment>
<div metal:define-macro="buttons"
tal:define="previousPage python: contextObj.getPreviousPage(phaseInfo, page);
nextPage python: contextObj.getNextPage(phaseInfo, page);
isEdit python: layoutType == 'edit';">
<br/>
<tal:previousButton condition="previousPage">
<tal:button condition="isEdit">
<input type="image" class="imageInput" style="cursor:pointer" name="buttonPrevious"
title="label_previous" i18n:attributes="title" i18n:domain="plone"
tal:attributes="src string:$portal_url/skyn/previous.png"/>
<input type="hidden" name="previousPage" tal:attributes="value previousPage"/>
</tal:button>
<tal:link condition="not: isEdit">
<a tal:attributes="href python: contextObj.getUrl()+'?page=%s' % previousPage">
<img tal:attributes="src string:$portal_url/skyn/previous.png"
title="label_previous" i18n:attributes="title" i18n:domain="plone"/>
</a>
</tal:link>
</tal:previousButton>
<tal:saveButton condition="isEdit">
<input type="image" class="imageInput" style="cursor:pointer" name="buttonOk"
title="label_save" i18n:attributes="title" i18n:domain="plone"
tal:attributes="src string:$portal_url/skyn/save.png"/>
</tal:saveButton>
<tal:cancelButton condition="isEdit">
<input type="image" class="imageInput" style="cursor:pointer" name="buttonCancel"
title="label_cancel" i18n:attributes="title" i18n:domain="plone"
tal:attributes="src string:$portal_url/skyn/cancel.png"/>
</tal:cancelButton>
<tal:editLink condition="not:isEdit">
<img tal:define="nav request/nav|nothing;
nav python: test(nav, '&nav=%s' % nav, '')"
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"
tal:condition="python: member.has_permission('Modify portal content', contextObj)"/>
</tal:editLink>
<tal:nextButton condition="nextPage">
<tal:button condition="isEdit">
<input type="image" class="imageInput" style="cursor:pointer" name="buttonNext"
title="label_next" i18n:attributes="title" i18n:domain="plone"
tal:attributes="src string:$portal_url/skyn/next.png"/>
<input type="hidden" name="nextPage" tal:attributes="value nextPage"/>
</tal:button>
<tal:link condition="not: isEdit">
<a tal:attributes="href python: contextObj.getUrl()+'?&page=%s' % nextPage">
<img tal:attributes="src string:$portal_url/skyn/next.png"
title="label_next" i18n:attributes="title" i18n:domain="plone"/>
</a>
</tal:link>
</tal:nextButton>
</div>
<tal:comment replace="nothing">
This macro displays the global message on the page.
</tal:comment>
<metal:message define-macro="message" i18n:domain="plone" >
<tal:comment replace="nothing">Single message from portal_status_message request key</tal:comment>
<div tal:define="msg request/portal_status_message | nothing"
tal:condition="msg" class="portalMessage" tal:content="msg" i18n:translate=""></div>
<tal:comment replace="nothing">Messages added via plone_utils</tal:comment>
<tal:messages define="messages putils/showPortalMessages" condition="messages">
<tal:msgs define="type_css_map python: {'info':'portalMessage', 'warn':'portalWarningMessage',
'stop':'portalStopMessage'};"
repeat="msg messages">
<div tal:define="mtype msg/type | nothing;"
tal:attributes="class python:mtype and type_css_map[mtype] or 'info';"
tal:content="structure msg/message | nothing" i18n:translate=""></div>
</tal:msgs>
</tal:messages>
</metal:message>

View file

@ -2,9 +2,10 @@
This macro displays the content of the application portlet.
</tal:comment>
<metal:portletContent define-macro="portletContent"
tal:define="queryUrl python: '%s/skyn/query' % appFolder.absolute_url();
currentSearch request/search|nothing;
currentType request/type_name|nothing;">
tal:define="queryUrl python: '%s/skyn/query' % appFolder.absolute_url();
currentSearch request/search|nothing;
currentType request/type_name|nothing;
contextObj python: tool.getPublishedObject(rootClasses)">
<tal:comment replace="nothing">Portlet title, with link to tool.</tal:comment>
<dt class="portletHeader">
<tal:comment replace="nothing">If there is only one flavour, clicking on the portlet
@ -27,6 +28,14 @@
</td>
</dt>
<tal:publishedObject condition="python: contextObj">
<dt class="portletAppyItem portletCurrent">
<a tal:attributes="href python: contextObj.getUrl() + '?page=main'"
tal:content="contextObj/Title"></a>
</dt>
<dt class="portletAppyItem"><metal:phases use-macro="here/skyn/portlet/macros/phases"/></dt>
</tal:publishedObject>
<tal:comment replace="nothing">TODO: implement a widget for selecting the needed flavour.</tal:comment>
<tal:comment replace="nothing">Create a section for every root class.</tal:comment>
@ -34,7 +43,7 @@
define="flavourNumber python:1;
flavour python: tool.getFlavour('Dummy_%d' % flavourNumber)">
<tal:comment replace="nothing">Section title, with action icons</tal:comment>
<dt tal:attributes="class python:test(repeat['rootClass'].number()==1, 'portletAppyItem', 'portletAppyItem portletSep')">
<dt tal:attributes="class python:test((repeat['rootClass'].number()==1) and not contextObj, 'portletAppyItem', 'portletAppyItem portletSep')">
<table width="100%" cellspacing="0" cellpadding="0" class="no-style-table">
<tr>
<td>
@ -44,7 +53,7 @@
</td>
<td align="right"
tal:define="addPermission python: '%s: Add %s' % (appName, rootClass);
userMayAdd python: member.has_permission(addPermission, appFolder);
userMayAdd python: member.has_permission(addPermission, appFolder) and tool.userMayAdd(rootClass);
createMeans python: tool.getCreateMeans(rootClass)">
<tal:comment replace="nothing">Create a new object from a web form</tal:comment>
<img style="cursor:pointer"
@ -115,11 +124,6 @@
href python:'%s?type_name=%s&flavourNumber=%d' % (queryUrl, rootClassesQuery, flavourNumber)"></a>
</dt-->
<dt class="portletAppyItem" tal:define="contextObj tool/getPublishedObject"
tal:condition="python: contextObj.meta_type in rootClasses">
<metal:phases use-macro="here/skyn/macros/macros/phases"/>
</dt>
<tal:comment replace="nothing">
Greyed transparent zone that is deployed on the
whole screen when a popup is displayed.
@ -140,3 +144,52 @@
</form>
</div>
</metal:portletContent>
<tal:comment replace="nothing">
This macro displays, within the portlet, the navigation tree for the
currently shown object, made of phases and contained pages.
</tal:comment>
<metal:phases define-macro="phases">
<table tal:define="phases contextObj/getAppyPhases|nothing;
page python: request.get('page', 'main')"
tal:condition="python: phases and not ((len(phases)==1) and len(phases[0]['pages'])==1)"
cellspacing="1" cellpadding="0" width="100%">
<tal:phase repeat="phase phases">
<tal:comment replace="nothing">The box containing phase-related information</tal:comment>
<tr>
<td tal:define="label python:'%s_phase_%s' % (contextObj.meta_type, phase['name']);
displayLink python: (phase['phaseStatus'] != 'Future') and ('/portal_factory' not in contextObj.absolute_url()) and (len(phase['pages']) == 1)"
tal:attributes="class python: 'appyPhase step' + phase['phaseStatus']">
<span 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:content="python: tool.translate(label)"></a>
<span tal:condition="not: displayLink" tal:replace="python: tool.translate(label)"/>
</span>
<table width="100%" cellpadding="0" cellspacing="0"
tal:condition="python: len(phase['pages']) &gt; 1">
<tr tal:repeat="aPage phase/pages" valign="top">
<td tal:attributes="class python: test(aPage == page, 'portletCurrent portletPageItem', 'portletPageItem')">
<a tal:attributes="href python: contextObj.getUrl()+'?page=%s' % aPage"
tal:content="structure python: tool.translate('%s_page_%s' % (contextObj.meta_type, aPage))">
</a>
</td>
<td>
<img tal:define="nav request/nav|nothing;
nav python: test(nav, '&nav=%s' % nav, '')"
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(), aPage, nav);
src string: $portal_url/skyn/edit.gif"
tal:condition="python: member.has_permission('Modify portal content', contextObj)"/>
</td>
</tr>
</table>
</td>
</tr>
<tal:comment replace="nothing">The down arrow pointing to the next phase (if any)</tal:comment>
<tr tal:condition="python: phase['name'] != phases[-1]['name']">
<td>&nbsp;&nbsp;<img tal:attributes="src string: $portal_url/skyn/nextPhase.png"/></td>
</tr>
</tal:phase>
</table>
</metal:phases>

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

View file

@ -20,7 +20,7 @@
flavourNumber python:int(context.REQUEST.get('flavourNumber'));
searchName python:context.REQUEST.get('search', '')">
<div metal:use-macro="here/skyn/macros/macros/pagePrologue"/>
<div metal:use-macro="here/skyn/page/macros/prologue"/>
<tal:comment replace="nothing">Query result</tal:comment>
<div id="queryResult"></div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 B

BIN
gen/plone25/skin/save.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -32,13 +32,13 @@
<table class="no-style-table" cellpadding="0" cellspacing="0" width="100%"
tal:define="numberOfColumns python: flavour.getAttr('numberOfSearchColumnsFor%s' % contentType)">
<tr tal:repeat="searchRow python: tool.tabularize(searchableFields, numberOfColumns)" valign="top">
<td tal:repeat="searchField searchRow" tal:attributes="width python:'%d%%' % (100/numberOfColumns)">
<tal:field condition="searchField">
<tal:showSearchField define="fieldName python:searchField[0];
appyType python:searchField[1];
widgetName python: 'w_%s' % fieldName">
<metal:searchField use-macro="python: appFolder.skyn.widgets.macros.get('search%s' % searchField[1]['type'])"/>
</tal:showSearchField>
<td tal:repeat="widget searchRow" tal:attributes="width python:'%d%%' % (100/numberOfColumns)">
<tal:field condition="widget">
<tal:show define="name widget/name;
widgetName python: 'w_%s' % name;
macroPage python: widget['type'].lower()">
<metal:call use-macro="python: appFolder.skyn.widgets.get(macroPage).macros.get('search')"/>
</tal:show>
</tal:field><br class="discreet"/>
</td>
</tr>

BIN
gen/plone25/skin/space.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 B

BIN
gen/plone25/skin/tabBg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 B

BIN
gen/plone25/skin/tabBgu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 B

View file

@ -18,20 +18,19 @@
tal:define="contextObj python:context.getParentNode();
portal_type python:here.getPortalTypeName().lower().replace(' ', '_');
errors python:request.get('errors', {});
isEdit python:False;
layoutType python:'view';
layout python: contextObj.getPageLayout(layoutType);
tool contextObj/getTool;
flavour python: tool.getFlavour(contextObj);
appFolder tool/getAppFolder;
appName appFolder/id;
phaseInfo python: contextObj.getAppyPhases(currentOnly=True, forPlone=False);
phase request/phase|phaseInfo/name;
appyPages python: contextObj.getAppyPages(phase);
pageName python: contextObj.getAppyPage(isEdit, phaseInfo, appyPages);
appName appFolder/getId;
page request/page|python:'main';
phaseInfo python: contextObj.getAppyPhases(page=page);
phase phaseInfo/name;
showWorkflow python: flavour.getAttr('showWorkflowFor' + contextObj.meta_type)">
<metal:prologue use-macro="here/skyn/macros/macros/pagePrologue"/>
<metal:header use-macro="here/skyn/macros/macros/showPageHeader"/>
<metal:fields use-macro="here/skyn/macros/macros/listFields" />
<metal:footer use-macro="here/skyn/macros/macros/showPageFooter"/>
<metal:prologue use-macro="here/skyn/page/macros/prologue"/>
<metal:show use-macro="here/skyn/page/macros/show"/>
<metal:footer use-macro="here/skyn/page/macros/footer"/>
</metal:fill>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 400 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 B

View file

@ -1,142 +0,0 @@
<metal:searchInteger define-macro="searchInteger">
<label tal:content="python: tool.translate(appyType['label'])"></label><br>&nbsp;&nbsp;
<tal:from define="fromName python: '%s*int' % widgetName">
<label tal:attributes="for fromName" tal:content="python: tool.translate('search_from')"></label>
<input type="text" tal:attributes="name fromName" size="4"/>
</tal:from>
<tal:to define="toName python: '%s_to' % fieldName">
<label tal:attributes="for toName" tal:content="python: tool.translate('search_to')"></label>
<input type="text" tal:attributes="name toName" size="4"/>
</tal:to><br/>
</metal:searchInteger>
<metal:searchFloat define-macro="searchFloat">
<label tal:content="python: tool.translate(appyType['label'])"></label><br>&nbsp;&nbsp;
<tal:from define="fromName python: '%s*float' % widgetName">
<label tal:attributes="for fromName" tal:content="python: tool.translate('search_from')"></label>
<input type="text" tal:attributes="name fromName" size="4"/>
</tal:from>
<tal:to define="toName python: '%s_to' % fieldName">
<label tal:attributes="for toName" tal:content="python: tool.translate('search_to')"></label>
<input type="text" tal:attributes="name toName" size="4"/>
</tal:to><br/>
</metal:searchFloat>
<metal:searchString define-macro="searchString">
<label tal:attributes="for widgetName" tal:content="python: tool.translate(appyType['label'])"></label><br>&nbsp;&nbsp;
<tal:comment replace="nothing">Show a simple search field for most String fields.</tal:comment>
<tal:simpleSearch condition="not: appyType/isSelect">
<input type="text" tal:attributes="name python: '%s*string-%s' % (widgetName, appyType['transform']);
style python: 'text-transform:%s' % appyType['transform']"/>
</tal:simpleSearch>
<tal:comment replace="nothing">Show a multi-selection box for fields whose validator defines a list of values, with a "AND/OR" checkbox.</tal:comment>
<tal:selectSearch condition="appyType/isSelect">
<tal:comment replace="nothing">The "and" / "or" radio buttons</tal:comment>
<tal:operator define="operName python: 'o_%s' % fieldName;
orName python: '%s_or' % operName;
andName python: '%s_and' % operName;"
condition="python: appyType['multiplicity'][1]!=1">
<input type="radio" class="noborder" tal:attributes="name operName; id orName" checked="checked" value="or"/>
<label tal:attributes="for orName" tal:content="python: tool.translate('search_or')"></label>
<input type="radio" class="noborder" tal:attributes="name operName; id andName" value="and"/>
<label tal:attributes="for andName" tal:content="python: tool.translate('search_and')"></label><br/>
</tal:operator>
<tal:comment replace="nothing">The list of values</tal:comment>
<select tal:attributes="name widgetName" multiple="multiple" size="5">
<option tal:repeat="v python:tool.getSelectValues(appyType)"
tal:attributes="value python:v[0]" tal:content="python: v[1]">
</option>
</select>
</tal:selectSearch><br/>
</metal:searchString>
<metal:searchBoolean define-macro="searchBoolean"
tal:define="typedWidget python:'%s*bool' % widgetName">
<label tal:attributes="for widgetName" tal:content="python: tool.translate(appyType['label'])"></label><br>&nbsp;&nbsp;
<tal:yes define="valueId python:'%s_yes' % fieldName">
<input type="radio" class="noborder" value="True" tal:attributes="name typedWidget; id valueId"/>
<label tal:attributes="for valueId" i18n:translate="yes" i18n:domain="plone"></label>
</tal:yes>
<tal:no define="valueId python:'%s_no' % fieldName">
<input type="radio" class="noborder" value="False" tal:attributes="name typedWidget; id valueId"/>
<label tal:attributes="for valueId" i18n:translate="no" i18n:domain="plone"></label>
</tal:no>
<tal:whatever define="valueId python:'%s_whatever' % fieldName">
<input type="radio" class="noborder" value="" tal:attributes="name typedWidget; id valueId" checked="checked"/>
<label tal:attributes="for valueId" tal:content="python: tool.translate('whatever')"></label>
</tal:whatever><br/>
</metal:searchBoolean>
<metal:searchDate define-macro="searchDate">
<label tal:content="python: tool.translate(appyType['label'])"></label>
<table cellpadding="0" cellspacing="0">
<tal:comment replace="nothing">From</tal:comment>
<tr tal:define="fromName python: '%s*date' % widgetName">
<td width="10px">&nbsp;</td>
<td>
<label tal:content="python: tool.translate('search_from')"></label>
</td>
<td>
<select tal:attributes="name fromName">
<option value="">--</option>
<option tal:repeat="value python:range(appyType['startYear'], appyType['endYear']+1)"
tal:content="value" tal:attributes="value value"></option>
</select> /
<select tal:attributes="name python: '%s_from_month' % fieldName">
<option value="">--</option>
<option tal:repeat="value python: [str(v).zfill(2) for v in range(1, 13)]"
tal:content="python:tool.getMonthName(value)" tal:attributes="value value"></option>
</select> /
<select tal:attributes="name python: '%s_from_day' % fieldName">
<option value="">--</option>
<option tal:repeat="value python: [str(v).zfill(2) for v in range(1, 32)]"
tal:content="value" tal:attributes="value value"></option>
</select>
</td>
</tr>
<tal:comment replace="nothing">To</tal:comment>
<tr>
<td></td>
<td>
<label tal:content="python: tool.translate('search_to')"></label>
</td>
<td>
<select tal:attributes="name python: '%s_to_year' % fieldName">
<option value="">--</option>
<option tal:repeat="value python:range(appyType['startYear'], appyType['endYear']+1)"
tal:content="value" tal:attributes="value value"></option>
</select> /
<select tal:attributes="name python: '%s_to_month' % fieldName">
<option value="">--</option>
<option tal:repeat="value python: [str(v).zfill(2) for v in range(1, 13)]"
tal:content="python:tool.getMonthName(value)" tal:attributes="value value"></option>
</select> /
<select tal:attributes="name python: '%s_to_day' % fieldName">
<option value="">--</option>
<option tal:repeat="value python: [str(v).zfill(2) for v in range(1, 32)]"
tal:content="value" tal:attributes="value value"></option>
</select>
</td>
</tr>
</table>
</metal:searchDate>
<metal:searchFile define-macro="searchFile">
<p tal:content="fieldName"></p>
</metal:searchFile>
<metal:searchRef define-macro="searchRef">
<p tal:content="fieldName"></p>
</metal:searchRef>
<metal:searchComputed define-macro="searchComputed">
<p tal:content="fieldName"></p>
</metal:searchComputed>
<metal:searchAction define-macro="searchAction">
<p tal:content="fieldName"></p>
</metal:searchAction>
<metal:searchInfo define-macro="searchInfo">
<p tal:content="fieldName"></p>
</metal:searchInfo>

View file

@ -0,0 +1,30 @@
<tal:comment replace="nothing">View macro for an Action.</tal:comment>
<metal:view define-macro="view">
<form name="executeAppyAction"
tal:define="formId python: '%s_%s' % (contextObj.UID(), name);
label python: contextObj.translate(widget['labelId'])"
tal:attributes="id formId; action python: contextObj.absolute_url()+'/skyn/do'">
<input type="hidden" name="action" value="ExecuteAppyAction"/>
<input type="hidden" name="objectUid" tal:attributes="value contextObj/UID"/>
<input type="hidden" name="fieldName" tal:attributes="value name"/>
<input type="button" tal:condition="widget/confirm"
tal:attributes="value label;
onClick python: 'javascript:askConfirm(\'%s\')' % formId"/>
<input type="submit" name="do" tal:condition="not: widget/confirm"
tal:attributes="value label" onClick="javascript:;"/>
<tal:comment replace="nothing">The previous onClick is simply used to prevent Plone
from adding a CSS class that displays a popup when the user triggers the form multiple
times.</tal:comment>
</form>
</metal:view>
<tal:comment replace="nothing">Edit macro for an Action.</tal:comment>
<metal:edit define-macro="edit"></metal:edit>
<tal:comment replace="nothing">Cell macro for an Action.</tal:comment>
<metal:cell define-macro="cell">
<metal:call use-macro="portal/skyn/widgets/action/macros/view"/>
</metal:cell>
<tal:comment replace="nothing">Search macro for an Action.</tal:comment>
<metal:search define-macro="search"></metal:search>

View file

@ -0,0 +1,39 @@
<tal:comment replace="nothing">View macro for a Boolean.</tal:comment>
<metal:view define-macro="view"><span tal:replace="value"/></metal:view>
<tal:comment replace="nothing">Edit macro for an Boolean.</tal:comment>
<metal:edit define-macro="edit">
<input type="checkbox"
tal:attributes="name python: name + '_visible';
id name;
checked python:contextObj.checkboxChecked(name);
onClick python:'toggleCheckbox(\'%s\', \'%s_hidden\');;updateSlaves(getMasterValue(this), \'%s\')' % (name, name, widget['id']);
class python: 'noborder ' + widget['master_css']"/>
<input tal:attributes="name name;
id string:${name}_hidden;
value python: test(contextObj.checkboxChecked(name), 'True', 'False')"
type="hidden" />&nbsp;
</metal:edit>
<tal:comment replace="nothing">Cell macro for an Boolean.</tal:comment>
<metal:cell define-macro="cell">
<metal:call use-macro="portal/skyn/widgets/boolean/macros/view"/>
</metal:cell>
<tal:comment replace="nothing">Search macro for an Boolean.</tal:comment>
<metal:search define-macro="search"
tal:define="typedWidget python:'%s*bool' % widgetName">
<label tal:attributes="for widgetName" tal:content="python: tool.translate(widget['labelId'])"></label><br>&nbsp;&nbsp;
<tal:yes define="valueId python:'%s_yes' % name">
<input type="radio" class="noborder" value="True" tal:attributes="name typedWidget; id valueId"/>
<label tal:attributes="for valueId" i18n:translate="yes" i18n:domain="plone"></label>
</tal:yes>
<tal:no define="valueId python:'%s_no' % name">
<input type="radio" class="noborder" value="False" tal:attributes="name typedWidget; id valueId"/>
<label tal:attributes="for valueId" i18n:translate="no" i18n:domain="plone"></label>
</tal:no>
<tal:whatever define="valueId python:'%s_whatever' % name">
<input type="radio" class="noborder" value="" tal:attributes="name typedWidget; id valueId" checked="checked"/>
<label tal:attributes="for valueId" tal:content="python: tool.translate('whatever')"></label>
</tal:whatever><br/>
</metal:search>

View file

@ -0,0 +1,18 @@
<tal:comment replace="nothing">View macro for a Computed.</tal:comment>
<metal:view define-macro="view">
<span tal:condition="widget/plainText" tal:replace="value"/>
<span tal:condition="not: widget/plainText" tal:replace="structure value"/>
</metal:view>
<tal:comment replace="nothing">Edit macro for a Computed.</tal:comment>
<metal:edit define-macro="edit">
<metal:call use-macro="portal/skyn/widgets/computed/macros/view"/>
</metal:edit>
<tal:comment replace="nothing">Cell macro for a Computed.</tal:comment>
<metal:cell define-macro="cell">
<metal:call use-macro="portal/skyn/widgets/computed/macros/view"/>
</metal:cell>
<tal:comment replace="nothing">Search macro for a Computed.</tal:comment>
<metal:search define-macro="search"></metal:search>

View file

@ -0,0 +1,132 @@
<tal:comment replace="nothing">View macro for a Date.</tal:comment>
<metal:view define-macro="view"><span tal:replace="value"/></metal:view>
<tal:comment replace="nothing">Edit macro for an Date.</tal:comment>
<metal:edit define-macro="edit"
tal:define="years python:range(widget['startYear'], widget['endYear']+1);
dummyName python: '_d_ummy_%s' % name">
<tal:comment replace="nothing">This field is not used but required by the Javascript popup.</tal:comment>
<input type="hidden" tal:attributes="name dummyName; id dummyName"/>
<tal:comment replace="nothing">Day</tal:comment>
<select tal:define="days python:range(1,32)"
tal:attributes="name string:${name}_day;
id string:${name}_day;">
<option value="">-</option>
<tal:days repeat="day days">
<option tal:define="zDay python: str(day).zfill(2)"
tal:attributes="value zDay;
selected python:contextObj.dateValueSelected(name, 'day', day)"
tal:content="zDay"></option>
</tal:days>
</select>
<tal:comment replace="nothing">Month</tal:comment>
<select tal:define="months python:range(1,13)"
tal:attributes="name string:${name}_month;
id string:${name}_month;">
<option value="">-</option>
<tal:months repeat="month months">
<option tal:define="zMonth python: str(month).zfill(2)"
tal:attributes="value zMonth;
selected python:contextObj.dateValueSelected(name, 'month', month)"
tal:content="zMonth"></option>
</tal:months>
</select>
<tal:comment replace="nothing">Year</tal:comment>
<select tal:attributes="name string:${name}_year;
id string:${name}_year;">
<option value="">-</option>
<option tal:repeat="year years"
tal:attributes="value year;
selected python:contextObj.dateValueSelected(name, 'year', year)"
tal:content="year"></option>
</select>
<tal:comment replace="nothing">The icon for displaying the date chooser</tal:comment>
<a tal:attributes="onclick python: 'return showJsCalendar(\'%s_month\', \'%s\', \'%s_year\', \'%s_month\', \'%s_day\', null, null, %d, %d)' % (name, dummyName, name, name, name, years[0], years[-1])"><img tal:attributes="src string: $portal_url/popup_calendar.gif"/></a>
<tal:hour condition="python: widget['format'] == 0">
<select tal:define="hours python:range(0,24);"
tal:attributes="name string:${name}_hour;
id string:${name}_hour;">
<option value="">-</option>
<tal:hours repeat="hour hours">
<option tal:define="zHour python: str(hour).zfill(2)"
tal:attributes="value zHour;
selected python:contextObj.dateValueSelected(name, 'hour', hour)"
tal:content="zHour"></option>
</tal:hours>
</select> :
<select tal:define="minutes python:range(0,60,5);"
tal:attributes="name string:${name}_minute;
id string:${name}_minute;">
<option value="">-</option>
<tal:minutes repeat="minute minutes">
<option tal:define="zMinute python: str(minute).zfill(2)"
tal:attributes="value zMinute;
selected python:contextObj.dateValueSelected(name, 'minute', minute)"
tal:content="zMinute"></option>
</tal:minutes>
</select>
</tal:hour>
</metal:edit>
<tal:comment replace="nothing">Cell macro for an Date.</tal:comment>
<metal:cell define-macro="cell">
<metal:call use-macro="portal/skyn/widgets/date/macros/view"/>
</metal:cell>
<tal:comment replace="nothing">Search macro for an Date.</tal:comment>
<metal:search define-macro="search">
<label tal:content="python: tool.translate(widget['labelId'])"></label>
<table cellpadding="0" cellspacing="0">
<tal:comment replace="nothing">From</tal:comment>
<tr tal:define="fromName python: '%s*date' % widgetName">
<td width="10px">&nbsp;</td>
<td>
<label tal:content="python: tool.translate('search_from')"></label>
</td>
<td>
<select tal:attributes="name fromName">
<option value="">--</option>
<option tal:repeat="value python:range(widget['startYear'], widget['endYear']+1)"
tal:content="value" tal:attributes="value value"></option>
</select> /
<select tal:attributes="name python: '%s_from_month' % name">
<option value="">--</option>
<option tal:repeat="value python: [str(v).zfill(2) for v in range(1, 13)]"
tal:content="python:tool.getMonthName(value)" tal:attributes="value value"></option>
</select> /
<select tal:attributes="name python: '%s_from_day' % name">
<option value="">--</option>
<option tal:repeat="value python: [str(v).zfill(2) for v in range(1, 32)]"
tal:content="value" tal:attributes="value value"></option>
</select>
</td>
</tr>
<tal:comment replace="nothing">To</tal:comment>
<tr>
<td></td>
<td>
<label tal:content="python: tool.translate('search_to')"></label>
</td>
<td>
<select tal:attributes="name python: '%s_to_year' % name">
<option value="">--</option>
<option tal:repeat="value python:range(widget['startYear'], widget['endYear']+1)"
tal:content="value" tal:attributes="value value"></option>
</select> /
<select tal:attributes="name python: '%s_to_month' % name">
<option value="">--</option>
<option tal:repeat="value python: [str(v).zfill(2) for v in range(1, 13)]"
tal:content="python:tool.getMonthName(value)" tal:attributes="value value"></option>
</select> /
<select tal:attributes="name python: '%s_to_day' % name">
<option value="">--</option>
<option tal:repeat="value python: [str(v).zfill(2) for v in range(1, 32)]"
tal:content="value" tal:attributes="value value"></option>
</select>
</td>
</tr>
</table>
</metal:search>

View file

@ -0,0 +1,73 @@
<tal:comment replace="nothing">View macro for a File.</tal:comment>
<metal:view define-macro="view"
tal:define="empty python: not value or not value.size;
imageSrc string:${contextObj/absolute_url}/download?name=$name">
<tal:file condition="python: not empty and not widget['isImage']">
<img tal:define="icon value/getBestIcon"
tal:condition="icon" tal:attributes="src string: $portal_url/$icon"/>
<a tal:attributes="href imageSrc"
tal:content="value/filename">
</a>&nbsp;&nbsp;-
<i class="discreet" tal:content="python:'%sKb' % (value.size / 1024)"></i>
</tal:file>
<tal:image condition="python: not empty and widget['isImage']">
<img tal:attributes="src python: imageSrc" />
</tal:image>
<tal:nothing tal:condition="empty">-</tal:nothing>
</metal:view>
<tal:comment replace="nothing">Edit macro for an File.</tal:comment>
<metal:edit define-macro="edit">
<tal:showFile condition="python: value and value.size">
<metal:call use-macro="portal/skyn/widgets/file/macros/view"/><br/>
</tal:showFile>
<tal:editButtons condition="python: value and value.size">
<tal:comment replace="nothing">Keep the file untouched.</tal:comment>
<input class="noborder" type="radio" value="nochange"
tal:attributes="checked python:test(value.size!=0, 'checked', None);
name string:${name}_delete;
id string:${name}_nochange;
onclick string:document.getElementById('${name}_file').disabled=true;"/>
<label tal:attributes="for string:${name}_nochange"
i18n:translate="nochange_file" i18n:domain="plone">
</label>
<br/>
<tal:comment replace="nothing">Delete the file.</tal:comment>
<tal:delete condition="not: widget/required">
<input class="noborder" type="radio" value="delete"
tal:attributes="name string:${name}_delete;
id string:${name}_delete;
onclick string:document.getElementById('${name}_file').disabled=true;"/>
<label tal:attributes="for string:${name}_delete"
i18n:translate="delete_file" i18n:domain="plone">
</label>
<br/>
</tal:delete>
<tal:comment replace="nothing">Replace with a new file.</tal:comment>
<input class="noborder" type="radio" value=""
tal:attributes="checked python:test(value.size==0, 'checked', None);
name string:${name}_delete;
id string:${name}_upload;
onclick string:document.getElementById('${name}_file').disabled=false"/>
<label tal:attributes="for string:${name}_upload;"
i18n:translate="upload_file" i18n:domain="plone">
</label>
<br/>
</tal:editButtons>
<tal:comment replace="nothing">The upload field.</tal:comment>
<input type="file" size="30"
tal:attributes="name string:${name}_file;
id string:${name}_file;"/>
<script type="text/javascript"
tal:define="isDisabled python:test(value and value.size, 'true', 'false')"
tal:content="string: document.getElementById('${name}_file').disabled=$isDisabled;">
</script>
</metal:edit>
<tal:comment replace="nothing">Cell macro for an File.</tal:comment>
<metal:cell define-macro="cell">
<metal:call use-macro="portal/skyn/widgets/file/macros/view"/>
</metal:cell>
<tal:comment replace="nothing">Search macro for an File.</tal:comment>
<metal:search define-macro="search"></metal:search>

View file

@ -0,0 +1,29 @@
<tal:comment replace="nothing">View macro for a Float.</tal:comment>
<metal:view define-macro="view">
<span tal:content="value"
tal:attributes="id value; class widget/master_css"></span>
</metal:view>
<tal:comment replace="nothing">Edit macro for an Float.</tal:comment>
<metal:edit define-macro="edit">
<input tal:attributes="id name; name name; size widget/width;
value python: test(inRequest, requestValue, value)" type="text"/>
</metal:edit>
<tal:comment replace="nothing">Cell macro for an Float.</tal:comment>
<metal:cell define-macro="cell">
<metal:call use-macro="portal/skyn/widgets/float/macros/view"/>
</metal:cell>
<tal:comment replace="nothing">Search macro for an Float.</tal:comment>
<metal:search define-macro="search">
<label tal:content="python: tool.translate(widget['labelId'])"></label><br>&nbsp;&nbsp;
<tal:from define="fromName python: '%s*float' % widgetName">
<label tal:attributes="for fromName" tal:content="python: tool.translate('search_from')"></label>
<input type="text" tal:attributes="name fromName" size="4"/>
</tal:from>
<tal:to define="toName python: '%s_to' % name">
<label tal:attributes="for toName" tal:content="python: tool.translate('search_to')"></label>
<input type="text" tal:attributes="name toName" size="4"/>
</tal:to><br/>
</metal:search>

View file

@ -0,0 +1,11 @@
<tal:comment replace="nothing">View macro for an Info.</tal:comment>
<metal:view define-macro="view"><tal:comment replace="nothing">Shows nothing more.</tal:comment></metal:view>
<tal:comment replace="nothing">Edit macro for an Info.</tal:comment>
<metal:edit define-macro="edit"></metal:edit>
<tal:comment replace="nothing">Cell macro for an Info.</tal:comment>
<metal:cell define-macro="cell"></metal:cell>
<tal:comment replace="nothing">Search macro for an Info.</tal:comment>
<metal:search define-macro="search"></metal:search>

View file

@ -0,0 +1,28 @@
<tal:comment replace="nothing">View macro for an Integer.</tal:comment>
<metal:view define-macro="view">
<span tal:content="value" tal:attributes="id value; class widget/master_css"></span>
</metal:view>
<tal:comment replace="nothing">Edit macro for an Integer.</tal:comment>
<metal:edit define-macro="edit">
<input tal:attributes="id name; name name; size widget/width;
value python: test(inRequest, requestValue, value)" type="text"/>
</metal:edit>
<tal:comment replace="nothing">Cell macro for an Integer.</tal:comment>
<metal:cell define-macro="cell">
<metal:call use-macro="portal/skyn/widgets/integer/macros/view"/>
</metal:cell>
<tal:comment replace="nothing">Search macro for an Integer.</tal:comment>
<metal:search define-macro="search">
<label tal:content="python: tool.translate(widget['labelId'])"></label><br>&nbsp;&nbsp;
<tal:from define="fromName python: '%s*int' % widgetName">
<label tal:attributes="for fromName" tal:content="python: tool.translate('search_from')"></label>
<input type="text" tal:attributes="name fromName" size="4"/>
</tal:from>
<tal:to define="toName python: '%s_to' % name">
<label tal:attributes="for toName" tal:content="python: tool.translate('search_to')"></label>
<input type="text" tal:attributes="name toName" size="4"/>
</tal:to><br/>
</metal:search>

View file

@ -0,0 +1,26 @@
<tal:comment replace="nothing">View macro for a Pod.</tal:comment>
<metal:view define-macro="view">
<tal:askAction condition="widget/askAction"
define="doLabel python:'%s_askaction' % widget['labelId'];
chekboxId python: '%s_%s' % (contextObj.UID(), name)">
<input type="checkbox" tal:attributes="name doLabel; id chekboxId"/>
<label tal:attributes="for chekboxId" class="discreet"
tal:content="python: tool.translate(doLabel)"></label>
</tal:askAction>
<img tal:repeat="podFormat python:flavour.getPodInfo(contextObj, name)['formats']"
tal:attributes="src string: $portal_url/skyn/${podFormat}.png;
onClick python: 'javascript:generatePodDocument(\'%s\',\'\',\'%s\',\'%s\')' % (contextObj.UID(), name, podFormat);
title podFormat/capitalize"
style="cursor:pointer"/>
</metal:view>
<tal:comment replace="nothing">Edit macro for a Pod.</tal:comment>
<metal:edit define-macro="edit"></metal:edit>
<tal:comment replace="nothing">Cell macro for a Pod.</tal:comment>
<metal:cell define-macro="cell">
<metal:call use-macro="portal/skyn/widgets/pod/macros/view"/>
</metal:cell>
<tal:comment replace="nothing">Search macro for a Pod.</tal:comment>
<metal:search define-macro="search"></metal:search>

View file

@ -1,5 +1,6 @@
<tal:comment replace="nothing"> We begin with some sub-macros used within
macro "showReference" defined below.</tal:comment>
<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
@ -9,7 +10,7 @@
from one object to the next/previous on skyn/view.</tal:comment>
<a tal:define="viewUrl obj/getUrl;
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)"
fullUrl python: test(appyType['isBack'], viewUrl + '/?page=%s' % appyType['page'], viewUrl + '/?' + navInfo)"
tal:attributes="href fullUrl" tal:content="obj/Title"></a>
</metal:objectTitle>
@ -77,42 +78,28 @@
onClick python: ajaxBaseCall.replace('**v**', 'True')"/>
</metal:sortIcons>
<tal:comment replace="nothing">
This macro shows a reference field. More precisely, it shows nothing, but calls
a Javascript function that will asynchonously call (via a XmlHttpRequest object) the
macro 'showReferenceContent' defined below, that will really show content.
It requires:
- isBack (bool) Is the reference a backward or forward reference?
- fieldName (string) The name of the reference field (if it is a forward reference)
or the name of the Archetypes relationship (if it is a backward reference)
- innerRef (bool) Are we rendering a reference within a reference or not?
- contextObj (object) the object from which the reference starts
- labelId (string) the i18n id of the reference field label
- descrId (string) the i18n id of the reference field description
</tal:comment>
<div metal:define-macro="showReference"
tal:define="ajaxHookId python: contextObj.UID() + fieldName"
tal:attributes="id ajaxHookId">
<tal:comment replace="nothing">View macro for a Ref.</tal:comment>
<div metal:define-macro="view"
tal:define= "innerRef innerRef|python:False;
ajaxHookId python: contextObj.UID() + name"
tal:attributes = "id ajaxHookId">
<script language="javascript"
tal:content="python: 'askRefField(\'%s\',\'%s\',\'%s\',\'%s\',\'%s\',\'%s\',\'%s\',0)' % (ajaxHookId, contextObj.absolute_url(), fieldName, isBack, innerRef, labelId, descrId)">
tal:content="python: 'askRefField(\'%s\',\'%s\',\'%s\',\'%s\',0)' % (ajaxHookId, contextObj.absolute_url(), name, innerRef)">
</script>
</div>
<tal:comment replace="nothing">
This macro is called by a XmlHttpRequest for displaying the paginated referred objects
of a reference field.
This macro is called by a XmlHttpRequest for displaying the paginated
referred objects of a reference field.
</tal:comment>
<div metal:define-macro="showReferenceContent"
<div metal:define-macro="viewContent"
tal:define="fieldName request/fieldName;
isBack python: test(request['isBack']=='True', True, False);
appyType python: contextObj.getAppyType(fieldName, asDict=True);
innerRef python: test(request['innerRef']=='True', True, False);
labelId request/labelId;
descrId request/descrId;
ajaxHookId python: contextObj.UID()+fieldName;
startNumber python: int(request.get('%s_startNumber' % ajaxHookId, 0));
appyType python: contextObj.getAppyType(fieldName, not isBack);
tool contextObj/getTool;
refObjects python:contextObj.getAppyRefs(fieldName, not isBack, startNumber);
refObjects python:contextObj.getAppyRefs(appyType, startNumber);
objs refObjects/objects;
totalNumber refObjects/totalNumber;
batchSize refObjects/batchSize;
@ -120,14 +107,14 @@
flavour python:tool.getFlavour(contextObj);
linkedPortalType python:flavour.getPortalType(appyType['klass']);
addPermission python: '%s: Add %s' % (tool.getAppName(), linkedPortalType);
canWrite python: not isBack and member.has_permission(contextObj.getField(fieldName).write_permission, contextObj);
multiplicity python:test(isBack, appyType['backd']['multiplicity'], appyType['multiplicity']);
canWrite python: not appyType['isBack'] and member.has_permission(appyType['writePermission'], contextObj);
multiplicity appyType/multiplicity;
maxReached python:(multiplicity[1] != None) and (len(objs) >= multiplicity[1]);
showPlusIcon python:not isBack and appyType['add'] and not maxReached and member.has_permission(addPermission, folder) and canWrite;
showPlusIcon python:not appyType['isBack'] and appyType['add'] and not maxReached and member.has_permission(addPermission, folder) and canWrite;
atMostOneRef python: (multiplicity[1] == 1) and (len(objs)&lt;=1);
label python: tool.translate(labelId);
description python: tool.translate(descrId);
navBaseCall python: 'askRefField(\'%s\',\'%s\',\'%s\',\'%s\',\'%s\',\'%s\',\'%s\',**v**)' % (ajaxHookId, contextObj.absolute_url(), fieldName, isBack, innerRef, labelId, descrId)">
label python: tool.translate(appyType['labelId']);
description python: tool.translate(appyType['descrId']);
navBaseCall python: 'askRefField(\'%s\',\'%s\',\'%s\',\'%s\',**v**)' % (ajaxHookId, contextObj.absolute_url(), fieldName, innerRef)">
<tal:comment replace="nothing">This macro displays the Reference widget on a "consult" page.
@ -139,20 +126,20 @@
<tal:comment replace="nothing">Display a simplified widget if maximum number of
referenced objects is 1.</tal:comment>
<table class="no-style-table" cellpadding="0" cellspacing="0"><tr valign="top">
<td><span class="appyLabel" tal:condition="not: innerRef" tal:content="label"></span></td>
<td><span class="appyLabel" tal:condition="not: innerRef" tal:content="structure label"></span></td>
<tal:comment replace="nothing">If there is no object...</tal:comment>
<tal:noObject condition="not:objs">
<td tal:content="python: tool.translate('no_ref')"></td>
<td><metal:plusIcon use-macro="here/skyn/ref/macros/plusIcon"/></td>
<td><metal:plusIcon use-macro="portal/skyn/widgets/ref/macros/plusIcon"/></td>
</tal:noObject>
<tal:comment replace="nothing">If there is an object...</tal:comment>
<tal:objectIsPresent condition="python: len(objs) == 1">
<tal:obj repeat="obj objs">
<td><metal:showObjectTitle use-macro="here/skyn/ref/macros/objectTitle" /></td>
<td tal:condition="not: isBack">
<metal:showObjectActions use-macro="here/skyn/ref/macros/objectActions" />
<td><metal:showObjectTitle use-macro="portal/skyn/widgets/ref/macros/objectTitle" /></td>
<td tal:condition="not: appyType/isBack">
<metal:showObjectActions use-macro="portal/skyn/widgets/ref/macros/objectActions" />
</td>
</tal:obj>
</tal:objectIsPresent>
@ -165,12 +152,12 @@
<legend tal:condition="python: not innerRef or showPlusIcon">
<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="portal/skyn/widgets/ref/macros/plusIcon"/>
</legend>
<tal:comment replace="nothing">Object description</tal:comment>
<p tal:condition="python: not innerRef and description.strip()"
tal:content="description" class="discreet" ></p>
<!--p tal:condition="python: not innerRef and description.strip()"
tal:content="description" class="discreet" ></p-->
<tal:comment replace="nothing">Appy (top) navigation</tal:comment>
<metal:nav use-macro="here/skyn/navigate/macros/appyNavigate"/>
@ -184,35 +171,29 @@
<tal:comment replace="nothing">Show backward reference(s)</tal:comment>
<table class="no-style-table" cellspacing="0" cellpadding="0"
tal:condition="python: isBack and objs">
tal:condition="python: appyType['isBack'] and objs">
<tr tal:repeat="obj objs">
<td><metal:showObjectTitle use-macro="here/skyn/ref/macros/objectTitle" />
<td><metal:showObjectTitle use-macro="portal/skyn/widgets/ref/macros/objectTitle" />
</td>
</tr>
</table>
<tal:comment replace="nothing">Show forward reference(s)</tal:comment>
<table tal:attributes="class python:test(innerRef, '', 'listing nosort');
width python:test(innerRef, '100%', test(appyType['wide'], '100%', ''))"
align="right" tal:condition="python: not isBack and objs" cellpadding="0" cellspacing="0">
width python:test(innerRef, '100%', appyType['layouts']['view']['width']);"
align="right" tal:condition="python: not appyType['isBack'] and objs" cellpadding="0" cellspacing="0">
<tal:widgets define="widgets python: objs[0].getAppyTypesFromNames(appyType['shownInfo'])">
<tr tal:condition="appyType/showHeaders">
<th tal:condition="python: 'title' not in appyType['shownInfo']"
tal:define="shownField python:'title'">
<span tal:content="python: tool.translate('ref_name')"></span>
<metal:sortIcons use-macro="here/skyn/ref/macros/sortIcons" />
<metal:sortIcons use-macro="portal/skyn/widgets/ref/macros/sortIcons" />
</th>
<th tal:repeat="shownField appyType/shownInfo">
<tal:showHeader condition="python: objs[0].getField(shownField)">
<tal:titleHeader condition="python: shownField == 'title'">
<span tal:content="python: tool.translate('ref_name')"></span>
<metal:sortIcons use-macro="here/skyn/ref/macros/sortIcons" />
</tal:titleHeader>
<tal:otherHeader condition="python: shownField != 'title'"
define="labelId python: objs[0].getField(shownField).widget.label_msgid">
<span tal:content="python: tool.translate(labelId)"></span>
<metal:sortIcons use-macro="here/skyn/ref/macros/sortIcons" />
</tal:otherHeader>
</tal:showHeader>
<th tal:repeat="widget widgets">
<tal:header define="shownField widget/name">
<span tal:content="python: tool.translate(widget['labelId'])"></span>
<metal:sortIcons use-macro="portal/skyn/widgets/ref/macros/sortIcons" />
</tal:header>
</th>
<th tal:content="python: tool.translate('ref_actions')"></th>
</tr>
@ -222,41 +203,27 @@
<tal:comment replace="nothing">Object title, shown here if not specified somewhere
else in appyType.shownInfo.</tal:comment>
<td tal:condition="python: 'title' not in appyType['shownInfo']"><metal:showObjectTitle
use-macro="here/skyn/ref/macros/objectTitle"/>&nbsp;
use-macro="portal/skyn/widgets/ref/macros/objectTitle"/>&nbsp;
</td>
<tal:comment replace="nothing">Additional fields that must be shown</tal:comment>
<td tal:repeat="shownField appyType/shownInfo">
<tal:showTitle condition="python: shownField == 'title'">
<metal:showObjectTitle use-macro="here/skyn/ref/macros/objectTitle"/>
<td tal:repeat="widget widgets">
<tal:showTitle condition="python: widget['name'] == 'title'">
<metal:showObjectTitle use-macro="portal/skyn/widgets/ref/macros/objectTitle"/>
</tal:showTitle>
<tal:showOtherField define="appyType python: obj.getAppyType(shownField);
field python:obj.getField(shownField);
contextObj python:obj;"
condition="python: appyType and (shownField != 'title')">
<tal:showNormalField condition="python: appyType['type'] not in ('Ref', 'Computed', 'Action')">
<metal:viewField use-macro="python: obj.widget(shownField, 'view', use_label=0)"/>
</tal:showNormalField>
<tal:showRef condition="python: appyType['type'] == 'Ref'">
<tal:ref tal:define="isBack python:appyType['isBack'];
fieldName python: test(isBack, field.relationship, field.getName());
innerRef python:True">
<metal:showField use-macro="here/skyn/ref/macros/showReference" />
</tal:ref>
</tal:showRef>
<tal:showComputed condition="python: appyType['type'] == 'Computed'">
<tal:computed content="python: obj.getComputedValue(appyType)"/>
</tal:showComputed>
<tal:showAction condition="python: appyType['type'] == 'Action'">
<metal:action use-macro="here/skyn/macros/macros/showActionField" />
</tal:showAction>
<tal:showOtherField define="contextObj python:obj;
layoutType python: 'cell';
innerRef python:True"
condition="python: widget['name'] != 'title'">
<metal:showField use-macro="portal/skyn/widgets/show/macros/field" />
</tal:showOtherField>&nbsp;
</td>
<tal:comment replace="nothing">Actions</tal:comment>
<td align="right">
<metal:showObjectActions use-macro="here/skyn/ref/macros/objectActions" />
<metal:showObjectActions use-macro="portal/skyn/widgets/ref/macros/objectActions" />
</td>
</tr>
</tal:row>
</tal:widgets>
</table>
</td></tr>
@ -272,18 +239,17 @@
</tal:anyNumberOfReferences>
</div>
<div metal:define-macro="editReference"
tal:define="refPortalType python:here.getAppyRefPortalType(field.getName());
appyType python:here.getAppyType(field.getName());
<tal:comment replace="nothing">Edit macro for an Ref.</tal:comment>
<div define-macro="edit"
tal:condition="widget/link"
tal:define="refPortalType python: contextObj.getAppyRefPortalType(name);
allBrains python:here.uid_catalog(portal_type=refPortalType);
brains python:here.callAppySelect(appyType['select'], allBrains);
refUids python: [o.UID() for o in here.getAppyRefs(field.getName())['objects']];
isMultiple python:test(appyType['multiplicity'][1]!=1, 'multiple', '');
appyFieldName python: 'appy_ref_%s' % field.getName();
inError python:test(errors.has_key(field.getName()), True, False);
defaultValue python: contextObj.getDefault(field.getName());
defaultValueUID defaultValue/UID|nothing;
isBeingCreated python: contextObj.portal_factory.isTemporary(contextObj) or ('/portal_factory/' in contextObj.absolute_url())"
brains python:contextObj.callAppySelect(widget['select'], allBrains);
refUids python: [o.UID() for o in here.getAppyRefs(name)['objects']];
isMultiple python:test(widget['multiplicity'][1]!=1, 'multiple', '');
appyFieldName python: 'appy_ref_%s' % name;
inError python:test(errors.has_key(name), True, False);
isBeingCreated python: contextObj.isTemporary() or ('/portal_factory/' in contextObj.absolute_url())"
tal:attributes="class python:'appyRefEdit field' + test(inError, ' error', '')">
<tal:comment replace="nothing">This macro displays the Reference widget on an "edit" page</tal:comment>
@ -301,3 +267,11 @@
selected python:test((valueIsInReq and (brain.UID in request.get(appyFieldName, []))) or (not valueIsInReq and ((brain.UID in refUids) or (isBeingCreated and (brain.UID==defaultValueUID)))), True, False)"/>
</select>
</div>
<tal:comment replace="nothing">Cell macro for a Ref.</tal:comment>
<metal:cell define-macro="cell">
<metal:call use-macro="portal/skyn/widgets/ref/macros/view"/>
</metal:cell>
<tal:comment replace="nothing">Search macro for a Ref.</tal:comment>
<metal:search define-macro="search"></metal:search>

View file

@ -0,0 +1,203 @@
<tal:comment replace="nothing">
This macro shows the content of a layouted object, like a page or widget.
It requires:
contextObj The Zope object on which we are working
layoutType The kind of layout: "view"? "edit"? "cell"?
layout The layout object that will dictate how object content
will be rendered.
Options:
contextMacro The base on folder containing the macros to call for
rendering the elements within the layout.
Defaults to portal.skyn
</tal:comment>
<metal:show define-macro="layout"
tal:define="contextMacro contextMacro| python: portal.skyn">
<table tal:attributes="cellpadding layout/cellpadding;
cellspacing layout/cellspacing;
width layout/width;
align layout/align;
class layout/css_class;
style layout/style">
<tal:comment replace="nothing">The table header row</tal:comment>
<tr tal:condition="layout/headerRow" tal:attributes="valign layout/headerRow/valign">
<th tal:repeat="cell layout/headerRow/cells"
tal:attributes="align cell/align; width cell/width;">
</th>
</tr>
<tal:comment replace="nothing">The table content</tal:comment>
<tr tal:repeat="row layout/rows" tal:attributes="valign row/valign">
<td tal:repeat="cell row/cells"
tal:attributes="align cell/align; colspan cell/colspan;
style python: test(repeat['cell'].end, '', 'padding-right: 0.4em')">
<tal:content repeat="elem cell/content">
<tal:field condition="python: elem == '?'">
<metal:call use-macro="python: contextMacro.get(widget['type'].lower()).macros.get(layoutType)"/>
</tal:field>
<tal:other condition="python: elem != '?'">
<metal:call use-macro="python: contextMacro.get(elem[0]).macros.get(elem[1])"/>
</tal:other>
<img tal:condition="not: repeat/elem/end" tal:attributes="src string: $portal_url/skyn/space.gif"/>
</tal:content>
</td>
</tr>
</table>
</metal:show>
<tal:comment replace="nothing">
This macro displays the widget corresponding to a given field. It requires:
contextObj The Zope object for which this widget must be rendered
page The page where the widget lies
layoutType "edit"? "view"? "cell?"
widget The widget to render
</tal:comment>
<metal:field define-macro="field"
tal:define="contextMacro python: portal.skyn.widgets;
layout python: widget['layouts'][layoutType];
name widget/name;
value python: contextObj.getFormattedValue(name);
requestValue python: request.get(name, None);
inRequest python: request.has_key(name);
errors errors | python: ();
inError python: test(widget['name'] in errors, True, False)">
<metal:layout use-macro="here/skyn/widgets/show/macros/layout"/>
</metal:field>
<tal:comment replace="nothing">
This macro displays the widget corresponding to a group of widgets.
It requires:
contextObj The Zope object for which this widget must be rendered
page The page where the widget lies
layoutType "edit"? "view"? "cell?"
widget The widget to render
</tal:comment>
<metal:group define-macro="group">
<fieldset tal:condition="python: widget['style'] == 'fieldset'">
<legend tal:condition="widget/hasLabel">
<i tal:content="structure python: contextObj.translate(widget['labelId'])"></i>
<tal:help condition="widget/hasHelp">
<metal:call use-macro="portal/skyn/widgets/show/macros/help"/>
</tal:help>
</legend>
<div tal:condition="widget/hasDescr" class="discreet"
tal:content="structure python: contextObj.translate(widget['descrId'])"></div>
<metal:content use-macro="portal/skyn/widgets/show/macros/groupContent"/>
</fieldset>
<tal:asSection condition="python: widget['style'] not in ('fieldset', 'tabs')">
<metal:content use-macro="portal/skyn/widgets/show/macros/groupContent"/>
</tal:asSection>
<tal:asTabs condition="python: widget['style'] == 'tabs'">
<table cellpadding="0" cellspacing="0" tal:attributes="width python: test(widget['wide'], '100%', '')">
<tal:comment replace="nothing">First row: the tabs.</tal:comment>
<tr><td style="border-bottom: 1px solid #ff8040">
<table cellpadding="0" cellspacing="0" style="position:relative; bottom:-1px;">
<tr valign="bottom">
<tal:tab repeat="widgetRow widget/widgets">
<tal:id define="tabId python:'tab_%s_%d_%d' % (widget['name'], repeat['widgetRow'].number(), len(widget['widgets']))">
<td><img tal:attributes="src string: $portal_url/skyn/tabLeft.png;
id python: '%s_left' % tabId"/><td>
<td tal:attributes="style python:'background-image: url(%s/skyn/tabBg.png)' % portal_url;
id tabId">
<a style="cursor:pointer"
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>
</td>
<td><img tal:attributes="src string: $portal_url/skyn/tabRight.png;
id python: '%s_right' % tabId"/><td>
</tal:id>
</tal:tab>
</tr>
</table>
</td></tr>
<tal:comment replace="nothing">Other rows: the widgets.</tal:comment>
<tr tal:repeat="widgetRow widget/widgets"
tal:attributes="id python: 'tabcontent_%s_%d_%d' % (widget['name'], repeat['widgetRow'].number(), len(widget['widgets']));
style python: test(repeat['widgetRow'].number()==1, 'display:table-row', 'display:none')">
<td tal:define="widget python: widgetRow[0]">
<tal:group condition="python: widget['type'] == 'group'">
<metal:call use-macro="portal/skyn/widgets/show/macros/group"/>
</tal:group>
<tal:field condition="python: widget['type'] != 'group'">
<metal:call use-macro="portal/skyn/widgets/show/macros/field"/>
</tal:field>
</td>
</tr>
</table>
<script language="javascript"
tal:content="python: 'initTab(\'tab_%s\', \'%s_1_%d\')' % (widget['name'], widget['name'], len(widget['widgets']))"></script>
</tal:asTabs>
</metal:group>
<tal:comment replace="nothing">
This macro displays the content of a group of widgets.
It is exclusively called by macro "group" above.
</tal:comment>
<table metal:define-macro="groupContent" align="center"
tal:attributes="width python: test(widget['wide'], '100%', '')">
<tal:comment replace="nothing">Display the title of the group if it is not rendered a fieldset.</tal:comment>
<tr tal:condition="python: (widget['style'] != 'fieldset') and widget['hasLabel']">
<td tal:attributes="colspan python: len(widget['columnsWidths']);
class widget/style">
<span tal:replace="structure python: contextObj.translate(widget['labelId'])"/>
<tal:help condition="widget/hasHelp">
<metal:call use-macro="portal/skyn/widgets/show/macros/help"/>
</tal:help>
</td>
</tr>
<tr tal:condition="python: (widget['style'] != 'fieldset') and widget['hasDescr']">
<td tal:attributes="colspan python: len(widget['columnsWidths'])" class="discreet"
tal:content="structure python: contextObj.translate(widget['descrId'])">
</td>
</tr>
<tr> <tal:comment replace="nothing">The column headers</tal:comment>
<th tal:repeat="colNb python:range(len(widget['columnsWidths']))"
tal:attributes="width python:widget['columnsWidths'][colNb];
align python:widget['columnsAligns'][colNb]"
tal:content="structure python: test(widget['hasHeaders'], contextObj.translate('%s_col%d' % (widget['labelId'], colNb+1)), '')">
</th>
</tr>
<tal:comment replace="nothing">The rows of widgets</tal:comment>
<tr valign="top" tal:repeat="widgetRow widget/widgets">
<td tal:repeat="widget widgetRow"
tal:attributes="colspan widget/colspan|python:1;
style python: test(repeat['widget'].number() != len(widgetRow), 'padding-right: 0.6em', '')">
<tal:showWidget condition="widget">
<tal:group condition="python: widget['type'] == 'group'">
<metal:call use-macro="portal/skyn/widgets/show/macros/group"/>
</tal:group>
<tal:field condition="python: widget['type'] != 'group'">
<metal:call use-macro="portal/skyn/widgets/show/macros/field"/>
</tal:field>
</tal:showWidget>
</td>
</tr>
</table>
<tal:comment replace="nothing">Displays a field label.</tal:comment>
<tal:label metal:define-macro="label" condition="widget/hasLabel">
<label tal:attributes="for widget/name"
tal:condition="python: widget['type'] not in ('Action', 'Ref')"
tal:content="structure python: contextObj.translate(widget['labelId'])"></label>
</tal:label>
<tal:comment replace="nothing">Displays a field description.</tal:comment>
<tal:description metal:define-macro="description" condition="widget/hasDescr">
<span class="discreet" tal:content="structure python: contextObj.translate(widget['descrId'])"></span>
</tal:description>
<tal:comment replace="nothing">Displays a field help.</tal:comment>
<tal:help metal:define-macro="help">
<acronym tal:attributes="title python: contextObj.translate(widget['helpId'])">
<img tal:attributes="src string: $portal_url/skyn/help.png"/>
</acronym>
</tal:help>
<tal:comment replace="nothing">Displays validation-error-related info about a field.</tal:comment>
<tal:validation metal:define-macro="validation">
<acronym tal:condition="inError" tal:attributes="title python: errors[name]">
<img tal:attributes="src string: $portal_url/skyn/warning.png"/>
</acronym>
<img tal:condition="not: inError" tal:attributes="src string: $portal_url/skyn/warning_no.png"/>
</tal:validation>
<tal:comment replace="nothing">Displays the fact that a field is required.</tal:comment>
<tal:required metal:define-macro="required"><img tal:attributes="src string: $portal_url/skyn/required.png"/></tal:required>

View file

@ -0,0 +1,102 @@
<tal:comment replace="nothing">View macro for a String.</tal:comment>
<metal:view define-macro="view"
tal:define="fmt widget/format;
maxMult python: widget['multiplicity'][1];
severalValues python: (maxMult == None) or (maxMult &gt; 1)">
<span tal:condition="python: fmt in (0, 3)"
tal:attributes="class widget/master_css;
id python: contextObj.getFormattedValue(name, forMasterId=True)">
<ul class="appyList" tal:condition="python: value and severalValues">
<li class="appyBullet" tal:repeat="sv value"><i tal:content="structure sv"></i></li>
</ul>
<tal:singleValue condition="python: value and not severalValues">
<span tal:condition="python: fmt != 3" tal:replace="structure value"/>
<span tal:condition="python: fmt == 3">********</span>
</tal:singleValue>
</span>
<tal:formattedString condition="python: fmt not in (0, 3)">
<span tal:condition="python: value and (fmt == 1)"
tal:replace="structure python: value.replace('\n', '&lt;br&gt;')"/>
<span tal:condition="python: value and (fmt == 2)" tal:replace="structure value"/>
</tal:formattedString>
</metal:view>
<tal:comment replace="nothing">Edit macro for a String.</tal:comment>
<metal:edit define-macro="edit"
tal:define="fmt widget/format;
isSelect widget/isSelect;
isMaster widget/slaves;
isOneLine python: fmt in (0,3)">
<tal:choice condition="isSelect">
<select tal:define="possibleValues python:contextObj.getPossibleValues(name, withTranslations=True, withBlankValue=True)"
tal:attributes="name name;
id name;
multiple python: test(widget['multiplicity'][1] != 1, 'multiple', '');
onchange python: test(isMaster, 'javascript:updateSlaves(getMasterValue(this), \'%s\')' % widget['id'], '');
class widget/master_css">
<option tal:repeat="possibleValue possibleValues"
tal:attributes="value python: possibleValue[0];
selected python:contextObj.fieldValueSelected(name, possibleValue[0])"
tal:content="python:tool.truncateValue(possibleValue[1], widget)"></option>
</select>
</tal:choice>
<tal:line condition="python: isOneLine and not isSelect">
<input tal:attributes="id name; name name; size widget/width;
value python: test(inRequest, requestValue, value)" type="text"/>
</tal:line>
<tal:textarea condition="python: fmt == 1">
<textarea tal:attributes="id name; name name;
cols widget/width;
rows widget/height;"
tal:content="python: test(inRequest, requestValue, value)">
</textarea>
<input type="hidden" value="text/plain" originalvalue="text/plain"
tal:attributes="name python: '%s_text_format' % name"/>
</tal:textarea>
<tal:rich condition="python: fmt == 2">
<tal:editor define="editor python: member.getProperty('wysiwyg_editor','').lower();
macrosFile python: path('nocall:here/%s_wysiwyg_support' % editor);
fieldName name;
inputname name;
inputvalue python: test(inRequest, requestValue, value);
dummy python: request.set('%s_text_format' % name, 'text/html')">
<metal:box use-macro="macrosFile/macros/wysiwygEditorBox"/>
</tal:editor>
</tal:rich>
</metal:edit>
<tal:comment replace="nothing">Cell macro for a String.</tal:comment>
<metal:cell define-macro="cell">
<metal:call use-macro="portal/skyn/widgets/string/macros/view"/>
</metal:cell>
<tal:comment replace="nothing">Search macro for a String.</tal:comment>
<metal:search define-macro="search">
<label tal:attributes="for widgetName" tal:content="python: tool.translate(widget['labelId'])"></label><br>&nbsp;&nbsp;
<tal:comment replace="nothing">Show a simple search field for most String fields.</tal:comment>
<tal:simpleSearch condition="not: widget/isSelect">
<input type="text" tal:attributes="name python: '%s*string-%s' % (widgetName, widget['transform']);
style python: 'text-transform:%s' % widget['transform']"/>
</tal:simpleSearch>
<tal:comment replace="nothing">Show a multi-selection box for fields whose
validator defines a list of values, with a "AND/OR" checkbox.</tal:comment>
<tal:selectSearch condition="widget/isSelect">
<tal:comment replace="nothing">The "and" / "or" radio buttons</tal:comment>
<tal:operator define="operName python: 'o_%s' % fieldName;
orName python: '%s_or' % operName;
andName python: '%s_and' % operName;"
condition="python: widget['multiplicity'][1]!=1">
<input type="radio" class="noborder" tal:attributes="name operName; id orName" checked="checked" value="or"/>
<label tal:attributes="for orName" tal:content="python: tool.translate('search_or')"></label>
<input type="radio" class="noborder" tal:attributes="name operName; id andName" value="and"/>
<label tal:attributes="for andName" tal:content="python: tool.translate('search_and')"></label><br/>
</tal:operator>
<tal:comment replace="nothing">The list of values</tal:comment>
<select tal:attributes="name widgetName" multiple="multiple" size="5">
<option tal:repeat="v python:tool.getPossibleValues(name, withTranslations=True, withBlankValue=False, className=contentType)"
tal:attributes="value python:v[0]" tal:content="python: v[1]">
</option>
</select>
</tal:selectSearch><br/>
</metal:search>