Initial import
228
gen/plone25/templates/AppyReference.pt
Executable file
|
@ -0,0 +1,228 @@
|
|||
<tal:comment replace="nothing"> We begin with some sub-macros used within
|
||||
macro "showReference" defined below.</tal:comment>
|
||||
|
||||
<metal:objectTitle define-macro="objectTitle" i18n:domain="<!applicationName!>">
|
||||
<tal:comment replace="nothing">Displays the title of a referenced object, with a link on
|
||||
it to reach the consult view for this object. If we are on a back reference, the link
|
||||
allows to reach the correct page where the forward reference is defined.</tal:comment>
|
||||
<a tal:define="viewUrl obj/absolute_url;
|
||||
fullUrl python: test(isBack, viewUrl + '/?pageName=%s&phase=%s' % (appyType['page'], appyType['phase']), viewUrl)"
|
||||
tal:attributes="href fullUrl" tal:content="obj/Title"></a>
|
||||
</metal:objectTitle>
|
||||
|
||||
<metal:objectActions define-macro="objectActions" i18n:domain="<!applicationName!>">
|
||||
<tal:comment replace="nothing">Displays icons for triggering actions on a given
|
||||
referenced object (edit, delete, etc).</tal:comment>
|
||||
<table class="no-style-table" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<tal:comment replace="nothing">Edit the element</tal:comment>
|
||||
<td class="noPadding"><a tal:attributes="href python: obj.absolute_url() + '/edit'"
|
||||
tal:condition="python: member.has_permission('Modify portal content', obj)">
|
||||
<img src="edit.gif" title="label_edit" i18n:domain="plone" i18n:attributes="title" />
|
||||
</a></td>
|
||||
<tal:comment replace="nothing">Delete the element</tal:comment>
|
||||
<td class="noPadding"><a tal:attributes="href python: obj.absolute_url() + '/delete_confirmation'"
|
||||
tal:condition="python: member.has_permission('Delete objects', obj)">
|
||||
<img src="delete_icon.gif" title="label_remove" i18n:domain="plone" i18n:attributes="title" />
|
||||
</a></td>
|
||||
<tal:comment replace="nothing">Arrows for moving objects up or down</tal:comment>
|
||||
<td class="noPadding" tal:condition="python: len(objs)>1">
|
||||
<form tal:condition="python: member.has_permission('Modify portal content', obj)"
|
||||
tal:attributes="action python: contextObj.absolute_url() + '/<!applicationName!>_do'"
|
||||
tal:define="objectIndex python:contextObj.getAppyRefIndex(field.getName(), obj)">
|
||||
<input type="hidden" name="actionType" value="changeRefOrder"/>
|
||||
<input type="hidden" name="fieldName" tal:attributes="value field/getName"/>
|
||||
<input type="hidden" name="objectUid" tal:attributes="value obj/UID"/>
|
||||
<tal:comment replace="nothing">Arrow up</tal:comment>
|
||||
<span tal:condition="python: objectIndex > 0">
|
||||
<input type="image" name="moveUp" tal:attributes="src python: contextObj.absolute_url() + '/arrowUp.png'"
|
||||
title="move_up" i18n:attributes="title" class="imageInput"/>
|
||||
</span>
|
||||
<tal:comment replace="nothing">Arrow down</tal:comment>
|
||||
<span tal:condition="python: objectIndex < (len(objs)-1)">
|
||||
<input type="image" name="moveDown" tal:attributes="src python: contextObj.absolute_url() + '/arrowDown.png'"
|
||||
title="move_down" i18n:attributes="title" class="imageInput"/>
|
||||
</span>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</metal:objectActions>
|
||||
|
||||
<metal:plusIcon define-macro="plusIcon" i18n:domain="<!applicationName!>">
|
||||
<tal:comment replace="nothing">Displays the "plus" icon that allows to add new object
|
||||
through a reference widget. Indeed, If field was declared as "addable", we must provide
|
||||
an icon for creating a new linked object (at least if multiplicities allow it).</tal:comment>
|
||||
<img src="plus.png" i18n:attributes="title" style="cursor:pointer"
|
||||
tal:condition="showPlusIcon" title="add_ref"
|
||||
tal:attributes="onClick python: 'href: window.location=\'%s/createAppyObject?initiator=%s&field=%s&type_name=%s\'' % (folder.absolute_url(), contextObj.UID(), field.getName(), linkedPortalType)"/>
|
||||
</metal:plusIcon>
|
||||
|
||||
<div metal:define-macro="showReference" i18n:domain="<!applicationName!>"
|
||||
tal:define="tool python: contextObj.<!toolInstanceName!>;
|
||||
flavour python:tool.getFlavour(contextObj);
|
||||
folder python: test(contextObj.isPrincipiaFolderish, contextObj, contextObj.getParentNode());
|
||||
linkedPortalType python:flavour.getPortalType(appyType['klass']);
|
||||
addPermission python: '<!applicationName!>: Add %s' % linkedPortalType;
|
||||
multiplicity python:test(isBack, appyType['backd']['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);
|
||||
atMostOneRef python: (multiplicity[1] == 1) and (len(objs)<=1)">
|
||||
|
||||
<tal:comment replace="nothing">This macro displays the Reference widget on a "consult" page.
|
||||
|
||||
The definition of "atMostOneRef" above may sound strange: we shouldn't check the actual number
|
||||
of referenced objects. But for back references people often forget to specify multiplicities.
|
||||
So concretely, multiplicities (0,None) are coded as (0,1).</tal:comment>
|
||||
|
||||
<tal:atMostOneReference condition="atMostOneRef">
|
||||
<tal:comment replace="nothing">Display a simplified widget if maximum number of
|
||||
referenced objects is 1.</tal:comment>
|
||||
<table class="no-style-table" cellpadding="0" cellspacing="0"><tr valign="top">
|
||||
<td><span class="appyLabel" tal:condition="not: innerRef"
|
||||
i18n:translate="" tal:content="labelMsgId"></span></td>
|
||||
|
||||
<tal:comment replace="nothing">If there is no object...</tal:comment>
|
||||
<tal:noObject condition="not:objs">
|
||||
<td i18n:translate="">no_ref</td>
|
||||
<td><metal:plusIcon use-macro="here/<!applicationName!>AppyReference/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 define="obj python:objs[0]">
|
||||
<td><metal:showObjectTitle use-macro="here/<!applicationName!>AppyReference/macros/objectTitle" /></td>
|
||||
<td tal:condition="not: isBack">
|
||||
<metal:showObjectActions use-macro="here/<!applicationName!>AppyReference/macros/objectActions" />
|
||||
</td>
|
||||
</tal:obj>
|
||||
</tal:objectIsPresent>
|
||||
</tr></table>
|
||||
</tal:atMostOneReference>
|
||||
|
||||
<tal:comment replace="nothing">Display a fieldset in all other cases.</tal:comment>
|
||||
<tal:anyNumberOfReferences condition="not: atMostOneRef">
|
||||
<fieldset tal:attributes="class python:test(innerRef, 'innerAppyFieldset', '')">
|
||||
<legend tal:condition="python: not innerRef or showPlusIcon">
|
||||
<span tal:condition="not: innerRef" i18n:translate="" tal:content="labelMsgId"/>
|
||||
<metal:plusIcon use-macro="here/<!applicationName!>AppyReference/macros/plusIcon"/>
|
||||
</legend>
|
||||
|
||||
<tal:comment replace="nothing">Object description</tal:comment>
|
||||
<p tal:define="descr python:contextObj.utranslate(descrMsgId, domain='<!applicationName!>')"
|
||||
tal:condition="python: not innerRef and descr.strip()" tal:content="descr" class="discreet" ></p>
|
||||
|
||||
<tal:comment replace="nothing">No object is present</tal:comment>
|
||||
<p tal:condition="not:objs" i18n:translate="">no_ref</p>
|
||||
|
||||
<table width="100%" cellspacing="0" cellpadding="0" tal:condition="objs"
|
||||
tal:attributes="class python:test(innerRef, 'innerAppyTable', '')">
|
||||
<tr valign="bottom"><td>
|
||||
|
||||
<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">
|
||||
<tr tal:repeat="obj objs">
|
||||
<td><metal:showObjectTitle use-macro="here/<!applicationName!>AppyReference/macros/objectTitle" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<tal:comment replace="nothing">Show forward reference(s)</tal:comment>
|
||||
<table tal:attributes="class python:test(innerRef, '', 'vertical listing');
|
||||
width python:test(innerRef, '100%', test(appyType['wide'], '100%', ''))"
|
||||
align="right" tal:condition="python: not isBack and objs" cellpadding="0" cellspacing="0">
|
||||
<tr tal:condition="appyType/showHeaders">
|
||||
<th tal:condition="python: 'title' not in appyType['shownInfo']" i18n:translate="ref_name"></th>
|
||||
<th tal:repeat="shownField appyType/shownInfo">
|
||||
<tal:showHeader condition="python: objs[0].getField(shownField)">
|
||||
<tal:titleHeader condition="python: shownField == 'title'" i18n:translate="ref_name"/>
|
||||
<tal:otherHeader condition="python: shownField != 'title'"
|
||||
define="labelId python: objs[0].getField(shownField).widget.label_msgid"
|
||||
content="labelId" i18n:translate=""/>
|
||||
</tal:showHeader>
|
||||
</th>
|
||||
<th i18n:translate="ref_actions"></th>
|
||||
</tr>
|
||||
<tr tal:repeat="obj objs" valign="top">
|
||||
<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/<!applicationName!>AppyReference/macros/objectTitle"/>
|
||||
</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/<!applicationName!>AppyReference/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'];
|
||||
fieldRel python:field.relationship;
|
||||
objs python:contextObj.getAppyRefs(field.getName());
|
||||
labelMsgId field/widget/label_msgid;
|
||||
descrMsgId field/widget/description_msgid;
|
||||
innerRef python:True">
|
||||
<metal:showField use-macro="here/<!applicationName!>AppyReference/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/<!macros!>/macros/showActionField" />
|
||||
</tal:showAction>
|
||||
</tal:showOtherField>
|
||||
</td>
|
||||
<tal:comment replace="nothing">Actions</tal:comment>
|
||||
<td align="right">
|
||||
<metal:showObjectActions use-macro="here/<!applicationName!>AppyReference/macros/objectActions" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td></tr>
|
||||
</table>
|
||||
</fieldset>
|
||||
<tal:comment replace="nothing">A carriage return needed in some cases.</tal:comment>
|
||||
<br tal:define="widgetDescr widgetDescr|nothing"
|
||||
tal:condition="python: not widgetDescr or (widgetDescr['widgetType'] != 'group')"/>
|
||||
</tal:anyNumberOfReferences>
|
||||
</div>
|
||||
|
||||
<div metal:define-macro="editReference" i18n:domain="<!applicationName!>"
|
||||
tal:define="refPortalType python:here.getAppyRefPortalType(field.getName());
|
||||
appyType python:here.getAppyType(field.getName());
|
||||
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())];
|
||||
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: here.getDefault(field.getName());
|
||||
defaultValueUID defaultValue/UID|nothing;
|
||||
isBeingCreated python: context.portal_factory.isTemporary(context) or ('/portal_factory/' in context.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>
|
||||
|
||||
<label tal:attributes="for python:appyFieldName"
|
||||
i18n:translate="" tal:content="field/widget/label_msgid"></label>
|
||||
<span class="fieldRequired" tal:condition="python: appyType['multiplicity'][0]>0"></span><br/>
|
||||
<div tal:condition="inError" tal:content="python: errors[field.getName()]"></div>
|
||||
<select tal:define="valueIsInReq python:test(request.get(appyFieldName, None) != None, True, False)"
|
||||
tal:attributes="name python:'appy_ref_%s' % field.getName();
|
||||
multiple isMultiple">
|
||||
<option tal:condition="not: isMultiple" value="" i18n:translate="choose_a_value"/>
|
||||
<option tal:repeat="brain brains"
|
||||
tal:content="python: here.<!toolInstanceName!>.getReferenceLabel(brain, appyType)"
|
||||
tal:attributes="value brain/UID;
|
||||
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>
|
34
gen/plone25/templates/ArchetypesTemplate.py
Executable file
|
@ -0,0 +1,34 @@
|
|||
<!codeHeader!>
|
||||
from AccessControl import ClassSecurityInfo
|
||||
from Products.Archetypes.atapi import *
|
||||
import Products.<!applicationName!>.config
|
||||
from Extensions.appyWrappers import <!genClassName!>_Wrapper
|
||||
from appy.gen.plone25.mixins.ClassMixin import ClassMixin
|
||||
<!imports!>
|
||||
|
||||
schema = Schema((<!fields!>
|
||||
),)
|
||||
fullSchema = <!baseSchema!>.copy() + schema.copy()
|
||||
|
||||
class <!genClassName!>(<!parents!>):
|
||||
'''<!classDoc!>'''
|
||||
security = ClassSecurityInfo()
|
||||
__implements__ = <!implements!>
|
||||
archetype_name = '<!genClassName!>'
|
||||
meta_type = '<!genClassName!>'
|
||||
portal_type = '<!genClassName!>'
|
||||
allowed_content_types = []
|
||||
filter_content_types = 0
|
||||
global_allow = 1
|
||||
immediate_view = '<!applicationName!>_appy_view'
|
||||
default_view = '<!applicationName!>_appy_view'
|
||||
suppl_views = ()
|
||||
typeDescription = '<!genClassName!>'
|
||||
typeDescMsgId = '<!genClassName!>_edit_descr'
|
||||
_at_rename_after_creation = True
|
||||
i18nDomain = '<!applicationName!>'
|
||||
schema = fullSchema
|
||||
wrapperClass = <!genClassName!>_Wrapper
|
||||
<!commonMethods!>
|
||||
<!methods!>
|
||||
<!register!>
|
38
gen/plone25/templates/FlavourTemplate.py
Executable file
|
@ -0,0 +1,38 @@
|
|||
<!codeHeader!>
|
||||
from AccessControl import ClassSecurityInfo
|
||||
from Products.Archetypes.atapi import *
|
||||
import Products.<!applicationName!>.config
|
||||
from appy.gen.plone25.mixins.FlavourMixin import FlavourMixin
|
||||
from Extensions.appyWrappers import <!wrapperClass!>
|
||||
|
||||
predefinedSchema = Schema((<!predefinedFields!>
|
||||
),)
|
||||
schema = Schema((<!fields!>
|
||||
),)
|
||||
fullSchema = OrderedBaseFolderSchema.copy() + predefinedSchema.copy() + schema.copy()
|
||||
|
||||
class <!flavourName!>(OrderedBaseFolder, FlavourMixin):
|
||||
'''Configuration flavour class for <!applicationName!>.'''
|
||||
security = ClassSecurityInfo()
|
||||
__implements__ = (getattr(OrderedBaseFolderSchema,'__implements__',()),)
|
||||
archetype_name = '<!flavourName!>'
|
||||
meta_type = '<!flavourName!>'
|
||||
portal_type = '<!flavourName!>'
|
||||
allowed_content_types = []
|
||||
filter_content_types = 0
|
||||
global_allow = 1
|
||||
#content_icon = '<!flavourName!>.gif'
|
||||
immediate_view = '<!applicationName!>_appy_view'
|
||||
default_view = '<!applicationName!>_appy_view'
|
||||
suppl_views = ()
|
||||
typeDescription = "<!flavourName!>"
|
||||
typeDescMsgId = '<!flavourName!>_edit_descr'
|
||||
i18nDomain = '<!applicationName!>'
|
||||
schema = fullSchema
|
||||
allMetaTypes = <!metaTypes!>
|
||||
wrapperClass = <!wrapperClass!>
|
||||
_at_rename_after_creation = True
|
||||
<!commonMethods!>
|
||||
<!predefinedMethods!>
|
||||
<!methods!>
|
||||
registerType(<!flavourName!>, '<!applicationName!>')
|
36
gen/plone25/templates/Install.py
Executable file
|
@ -0,0 +1,36 @@
|
|||
<!codeHeader!>
|
||||
from zExceptions import BadRequest
|
||||
from Products.ExternalMethod.ExternalMethod import ExternalMethod
|
||||
from Products.Archetypes.Extensions.utils import installTypes
|
||||
from Products.Archetypes.Extensions.utils import install_subskin
|
||||
from Products.Archetypes.config import TOOL_NAME as ARCHETYPETOOLNAME
|
||||
from Products.Archetypes.atapi import listTypes
|
||||
from Products.<!applicationName!>.config import applicationRoles,defaultAddRoles
|
||||
from Products.<!applicationName!>.config import product_globals as GLOBALS
|
||||
import appy.gen
|
||||
from appy.gen.plone25.installer import PloneInstaller
|
||||
<!imports!>
|
||||
catalogMap = {}
|
||||
<!catalogMap!>
|
||||
appClasses = <!appClasses!>
|
||||
appClassNames = [<!appClassNames!>]
|
||||
allClassNames = [<!allClassNames!>]
|
||||
workflows = {<!workflows!>}
|
||||
# ------------------------------------------------------------------------------
|
||||
def install(self, reinstall=False):
|
||||
'''Installation of product "<!applicationName!>"'''
|
||||
ploneInstaller = PloneInstaller(reinstall, "<!applicationName!>", self,
|
||||
<!minimalistPlone!>, appClasses, appClassNames, allClassNames,
|
||||
catalogMap, applicationRoles, defaultAddRoles, workflows,
|
||||
<!appFrontPage!>, globals())
|
||||
return ploneInstaller.install()
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
def uninstall(self, reinstall=False):
|
||||
'''Uninstallation of product "<!applicationName!>"'''
|
||||
ploneInstaller = PloneInstaller(reinstall, "<!applicationName!>", self,
|
||||
<!minimalistPlone!>, appClasses, appClassNames, allClassNames,
|
||||
catalogMap, applicationRoles, defaultAddRoles, workflows,
|
||||
<!appFrontPage!>, globals())
|
||||
return ploneInstaller.uninstall()
|
||||
# ------------------------------------------------------------------------------
|
765
gen/plone25/templates/Macros.pt
Executable file
|
@ -0,0 +1,765 @@
|
|||
<div metal:define-macro="listPodTemplates" i18n:domain="<!applicationName!>" class="appyPod"
|
||||
tal:define="flavour python: context.<!toolInstanceName!>.getFlavour(context);
|
||||
podTemplates python: flavour.getAvailablePodTemplates(context, phase);"
|
||||
tal:condition="podTemplates">
|
||||
<script language="javascript">
|
||||
<!--
|
||||
// Function that allows to generate a meeting document containing selected items.
|
||||
function generatePodDocument(contextUid, templateUid) {
|
||||
var theForm = document.forms["podTemplateForm"];
|
||||
theForm.objectUid.value = contextUid;
|
||||
theForm.templateUid.value = templateUid;
|
||||
theForm.submit();
|
||||
}
|
||||
-->
|
||||
</script>
|
||||
|
||||
<tal:comment replace="nothing">Form submitted when an object needs to be generated as a document.</tal:comment>
|
||||
<form name="podTemplateForm" method="post"
|
||||
tal:attributes="action python: context.absolute_url() + '/generateDocument'">
|
||||
<input type="hidden" name="objectUid"/>
|
||||
<input type="hidden" name="templateUid"/>
|
||||
</form>
|
||||
|
||||
<tal:podTemplates define="maxShownTemplates python: flavour.getMaxShownTemplates(context)">
|
||||
|
||||
<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)<=maxShownTemplates"
|
||||
tal:repeat="podTemplate podTemplates">
|
||||
<a style="cursor: pointer"
|
||||
tal:define="podFormat podTemplate/getPodFormat"
|
||||
tal:attributes="onclick python: 'javascript:generatePodDocument(\'%s\',\'%s\')' % (context.UID(), podTemplate.UID())" >
|
||||
<img tal:attributes="src string: $portal_url/$podFormat.png"/>
|
||||
<span tal:replace="podTemplate/Title"/>
|
||||
</a>
|
||||
</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)>maxShownTemplates">
|
||||
<option value="" i18n:translate="">choose_a_doc</option>
|
||||
<option tal:repeat="podTemplate podTemplates" tal:content="podTemplate/Title"
|
||||
tal:attributes="onclick python: 'javascript:generatePodDocument(\'%s\',\'%s\')' % (context.UID(), podTemplate.UID())" />
|
||||
</select>
|
||||
</tal:podTemplates>
|
||||
</div>
|
||||
|
||||
<metal:editString define-macro="editString" i18n:domain="<!applicationName!>"
|
||||
tal:define="vocab python:field.Vocabulary(contextObj);">
|
||||
<label tal:attributes="for fieldName" tal:condition="showLabel" tal:content="label"/>
|
||||
<div class="discreet" tal:content="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" i18n:domain="<!applicationName!>">
|
||||
<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" />
|
||||
<label tal:attributes="for fieldName" tal:condition="showLabel" tal:content="label"/>
|
||||
<div class="discreet" tal:content="description"/>
|
||||
</metal:editBoolean>
|
||||
|
||||
<div metal:define-macro="editField" i18n:domain="<!applicationName!>"
|
||||
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);
|
||||
label python: contextObj.utranslate(field.widget.label_msgid, domain='<!applicationName!>');
|
||||
description python: contextObj.utranslate(field.widget.description_msgid, domain='<!applicationName!>')"
|
||||
tal:attributes="class python:'field ' + test(inError, ' error', '')">
|
||||
<span class="fieldRequired" tal:condition="python: appyType['multiplicity'][0]>0"></span>
|
||||
<div tal:condition="inError" tal:content="python: errors[fieldName]"></div>
|
||||
<tal:stringField condition="python: appyType['type'] == 'String'">
|
||||
<metal:edit use-macro="here/<!macros!>/macros/editString"/>
|
||||
</tal:stringField>
|
||||
<tal:booleanField condition="python: appyType['type'] == 'Boolean'">
|
||||
<metal:edit use-macro="here/<!macros!>/macros/editBoolean"/>
|
||||
</tal:booleanField>
|
||||
</div>
|
||||
|
||||
<div metal:define-macro="showComputedField" i18n:domain="<!applicationName!>">
|
||||
<span class="appyLabel" tal:condition="showLabel"
|
||||
tal:content="field/widget/label_msgid" i18n:translate=""></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" i18n:domain="<!applicationName!>">
|
||||
<span class="appyLabel" tal:content="field/widget/label_msgid" i18n:translate=""></span>
|
||||
<span tal:content="field/widget/description_msgid" i18n:translate=""></span>
|
||||
</div>
|
||||
|
||||
<div metal:define-macro="showActionField" i18n:domain="<!applicationName!>">
|
||||
<form name="executeAppyAction" action="<!applicationName!>_do" method="POST">
|
||||
<input type="hidden" name="actionType" value="appyAction"/>
|
||||
<input type="hidden" name="objectUid" tal:attributes="value contextObj/UID"/>
|
||||
<input type="hidden" name="fieldName" tal:attributes="value field/getName"/>
|
||||
<input type="submit" name="do" i18n:attributes="value"
|
||||
tal:attributes="value field/widget/label_msgid"/>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div metal:define-macro="showArchetypesField" i18n:domain="<!applicationName!>"
|
||||
tal:define="field fieldDescr/atField|widgetDescr/atField;
|
||||
appyType fieldDescr/appyType|widgetDescr/appyType;
|
||||
showLabel showLabel|python:True;"
|
||||
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:defField>
|
||||
<tal:fileField condition="python: (appyType['type'] == 'File')">
|
||||
<span tal:condition="showLabel" tal:content="field/widget/label_msgid" i18n:translate=""></span>
|
||||
<metal:viewField use-macro="python: contextObj.widget(field.getName(), 'view', use_label=0)"/>
|
||||
</tal:fileField>
|
||||
<tal:simpleField condition="python: (appyType['type'] in ('Integer', 'Float', 'Date', 'Boolean')) or (appyType['type'] == 'String' and (appyType['format'] == 0))">
|
||||
<span tal:condition="showLabel" tal:content="field/widget/label_msgid" i18n:translate=""
|
||||
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:formattedString condition="python: (appyType['type'] == 'String' and (appyType['format'] != 0))">
|
||||
<fieldset tal:define="value python:field.getAccessor(contextObj)()">
|
||||
<legend tal:condition="showLabel" i18n:translate="" tal:content="field/widget/label_msgid"></legend>
|
||||
<span tal:condition="python: appyType['format'] == 1"
|
||||
tal:replace="structure python: value.replace('\n', '<br>')"/>
|
||||
<span tal:condition="python: appyType['format'] == 2" tal:replace="structure value"/>
|
||||
</fieldset>
|
||||
</tal:formattedString>
|
||||
</tal:defField>
|
||||
</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;
|
||||
fieldRel python:field.relationship;
|
||||
objs python:contextObj.getAppyRefs(field.getName());
|
||||
labelMsgId field/widget/label_msgid;
|
||||
descrMsgId field/widget/description_msgid;
|
||||
innerRef innerRef|python:False">
|
||||
<metal:viewRef use-macro="here/<!applicationName!>AppyReference/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/<!applicationName!>AppyReference/macros/editReference" />
|
||||
</tal:ref>
|
||||
</tal:editRef>
|
||||
<tal:computedField condition="python: (not isEdit) and (appyType['type'] == 'Computed')">
|
||||
<metal:cf use-macro="here/<!macros!>/macros/showComputedField" />
|
||||
</tal:computedField>
|
||||
<tal:actionField condition="python: (not isEdit) and (appyType['type'] == 'Action')">
|
||||
<metal:af use-macro="here/<!macros!>/macros/showActionField" />
|
||||
</tal:actionField>
|
||||
<tal:masterString condition="python: isEdit and (appyType['type'] in ('String', 'Boolean')) and (appyType['slaves'])">
|
||||
<metal:mf use-macro="here/<!macros!>/macros/editField" />
|
||||
</tal:masterString>
|
||||
<tal:infoField condition="python: (not isEdit) and (appyType['type'] == 'Info')">
|
||||
<metal:af use-macro="here/<!macros!>/macros/showInfoField" />
|
||||
</tal:infoField>
|
||||
</div>
|
||||
|
||||
<div metal:define-macro="showBackwardField" i18n:domain="<!applicationName!>"
|
||||
tal:define="isBack python:True;
|
||||
appyType widgetDescr/appyType;
|
||||
fieldRel widgetDescr/fieldRel;
|
||||
objs python:contextObj.getBRefs(fieldRel);
|
||||
labelMsgId python:'%s_%s_back' % (contextObj.meta_type, appyType['backd']['attribute']);
|
||||
descrMsgId python:'';
|
||||
innerRef innerRef|python:False">
|
||||
<div metal:use-macro="here/<!applicationName!>AppyReference/macros/showReference" />
|
||||
</div>
|
||||
|
||||
<span metal:define-macro="showGroup" i18n:domain="<!applicationName!>">
|
||||
<fieldset class="appyGroup">
|
||||
<legend><i i18n:translate=""
|
||||
tal:content="python: '%s_group_%s' % (contextObj.meta_type, widgetDescr['name'])"></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/<!macros!>/macros/showArchetypesField"/>
|
||||
</tal:archetypesField>
|
||||
<tal:backwardRef tal:condition="python: (not isEdit) and (fieldDescr['widgetType'] == 'backField')">
|
||||
<metal:backRef use-macro="here/<!macros!>/macros/showBackwardField" />
|
||||
</tal:backwardRef>
|
||||
</tal:field>
|
||||
</tal:showField>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</fieldset>
|
||||
<br/>
|
||||
</span>
|
||||
|
||||
<div metal:define-macro="listFields" i18n:domain="<!applicationName!>"
|
||||
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/<!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/<!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/<!macros!>/macros/showGroup" />
|
||||
</tal:displayG>
|
||||
</tal:displayGroup>
|
||||
</div>
|
||||
|
||||
<span metal:define-macro="byline" i18n:domain="<!applicationName!>"
|
||||
tal:condition="python: site_properties.allowAnonymousViewAbout or not isAnon"
|
||||
tal:define="creator here/Creator;" class="documentByLine">
|
||||
<tal:name tal:condition="creator"
|
||||
tal:define="author python:context.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"/>
|
||||
—
|
||||
</span>
|
||||
</tal:name>
|
||||
<span class="documentModified">
|
||||
<span i18n:translate="box_last_modified" i18n:domain="plone"/>
|
||||
<span tal:replace="python:toLocalizedTime(here.ModificationDate(),long_format=1)"/>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<span metal:define-macro="workflowHistory" i18n:domain="<!applicationName!>" class="reviewHistory"
|
||||
tal:define="history context/getWorkflowHistory" tal:condition="history">
|
||||
<dl id="history" class="collapsible inline collapsedOnLoad">
|
||||
<dt class="collapsibleHeader" i18n:translate="label_history" i18n:domain="plone">History</dt>
|
||||
<dd class="collapsibleContent">
|
||||
<table width="100%" class="listing nosort" i18n:attributes="summary summary_review_history"
|
||||
tal:define="review_history python:context.portal_workflow.getInfoFor(context, 'review_history', []);
|
||||
review_history python:[review for review in review_history if review.get('action','')]"
|
||||
tal:condition="review_history">
|
||||
<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>
|
||||
<metal:block tal:define="review_history python: portal.reverseList(review_history);"
|
||||
tal:repeat="items review_history">
|
||||
<tr tal:define="odd repeat/items/odd;
|
||||
rhComments items/comments|nothing;
|
||||
state items/review_state|nothing"
|
||||
tal:attributes="class python:test(odd, 'even', 'odd')" tal:condition="items/action">
|
||||
<td i18n:translate="" tal:content="python: context.getWorkflowLabel(items['action'])"
|
||||
tal:attributes="class string:state-${state}"/>
|
||||
<td tal:define="actorid python:items.get('actor');
|
||||
actor python:context.portal_membership.getMemberInfo(actorid);
|
||||
fullname actor/fullname|nothing;
|
||||
username actor/username|nothing"
|
||||
tal:content="python:fullname or username or actorid"/>
|
||||
<td tal:content="python:toLocalizedTime(items['time'],long_format=True)"/>
|
||||
<td> <tal:comment condition="rhComments" tal:content="rhComments"/>
|
||||
<tal:noComment condition="not: rhComments" i18n:translate="no_comments" i18n:domain="plone"/>
|
||||
</td>
|
||||
</tr>
|
||||
</metal:block>
|
||||
</table>
|
||||
</dd>
|
||||
</dl>
|
||||
</span>
|
||||
|
||||
<div metal:define-macro="showPagePrologue" i18n:domain="<!applicationName!>">
|
||||
<tal:comment replace="nothing">Global Javascript functions, used in edit and
|
||||
consult views, are defined gere.</tal:comment>
|
||||
|
||||
<script language="javascript">
|
||||
<!--
|
||||
// This function turns a checkbox into a radio button... sort of
|
||||
function toggleCheckbox(visibleCheckbox, hiddenBoolean) {
|
||||
vis = document.getElementById(visibleCheckbox);
|
||||
hidden = document.getElementById(hiddenBoolean);
|
||||
if (vis.checked) hidden.value = 'True';
|
||||
else hidden.value = 'False';
|
||||
}
|
||||
// Returns an array of selected options in a select widget
|
||||
function getMasterValue(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;
|
||||
}
|
||||
// Given the value(s) selected in a master field, this function updates the
|
||||
// state of all corresponding slaves.
|
||||
function updateSlaves(masterValues, appyTypeId) {
|
||||
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 = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
// Triggers a workflow transition
|
||||
function triggerTransition(transitionId) {
|
||||
var theForm = document.getElementById('triggerTransitionForm');
|
||||
theForm.workflow_action.value = transitionId;
|
||||
theForm.submit();
|
||||
}
|
||||
-->
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<div metal:define-macro="showPageHeader" i18n:domain="<!applicationName!>"
|
||||
tal:define="appyPages python: context.getAppyPages(phase);
|
||||
showCommonInfo python: not isEdit"
|
||||
tal:condition="python: not context.portal_factory.isTemporary(context)">
|
||||
|
||||
<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="title_string | here/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']>1">−
|
||||
<span i18n:translate="phase"></span>:
|
||||
<span tal:define="label python:'%s_phase_%s' % (context.meta_type, phase)"
|
||||
tal:content="label" i18n:translate=""></span>
|
||||
</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)"
|
||||
src="edit.gif" title="Edit" i18n:domain="plone" i18n:attributes="title"
|
||||
style="cursor:pointer"
|
||||
tal:attributes="onClick python: 'href: window.location=\'%s/<!applicationName!>_appy_edit?fieldset=%s&phase=%s\'' % (context.absolute_url(), editPageName, phase)"
|
||||
tal:condition="python: (len(appyPages)==1) and member.has_permission('Modify portal content', context)"/>
|
||||
</td>
|
||||
<td><metal:actions use-macro="here/document_actions/macros/document_actions"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr tal:define="descrLabel python: here.utranslate('%s_edit_descr' % here.portal_type, domain='<!applicationName!>')" tal:condition="descrLabel/strip" >
|
||||
<tal:comment replace="nothing">Content type description</tal:comment>
|
||||
<td colspan="2" class="discreet" tal:content="descrLabel"/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<metal:byLine use-macro="here/<!macros!>/macros/byline"/>
|
||||
<tal:showWorkflow condition="showWorkflow">
|
||||
<metal:workflowHistory use-macro="here/<!macros!>/macros/workflowHistory"/>
|
||||
</tal:showWorkflow>
|
||||
</td>
|
||||
<td valign="top"><metal:pod use-macro="here/<!macros!>/macros/listPodTemplates"/>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tal:comment replace="nothing">Workflow-related information and actions</tal:comment>
|
||||
<tr tal:condition="python: showWorkflow and context.getWorkflowLabel()">
|
||||
<td colspan="2" class="appyWorkflow">
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td><metal:states use-macro="here/<!macros!>/macros/states"/></td>
|
||||
<td align="right"><metal:states use-macro="here/<!macros!>/macros/transitions"/></td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<tal:comment replace="nothing">Tabs</tal:comment>
|
||||
<ul class="contentViews appyTabs" tal:condition="python: len(appyPages)>1">
|
||||
<li tal:repeat="thePage appyPages"
|
||||
tal:attributes="class python:test(thePage == pageName, 'selected', 'plain')">
|
||||
<tal:tab define="pageLabel python: '%s_page_%s' % (here.meta_type, thePage)">
|
||||
<a i18n:translate="" tal:content="pageLabel"
|
||||
tal:attributes="href python: here.absolute_url() + '/<!applicationName!>_appy_view?phase=%s&pageName=%s' % (phase, thePage)">
|
||||
</a>
|
||||
<img tal:define="editPageName python:test(thePage=='main', 'default', thePage)"
|
||||
src="edit.gif" title="Edit" i18n:domain="plone" i18n:attributes="title"
|
||||
style="cursor:pointer" class="appyPlusImg"
|
||||
tal:attributes="onClick python: 'href: window.location=\'%s/<!applicationName!>_appy_edit?fieldset=%s&phase=%s\'' % (context.absolute_url(), editPageName, phase)"
|
||||
tal:condition="python: member.has_permission('Modify portal content', context)"/>
|
||||
</tal:tab>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div metal:define-macro="showPageFooter" i18n:domain="<!applicationName!>">
|
||||
<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>
|
||||
|
||||
<div metal:define-macro="queryResult" i18n:domain="<!applicationName!>">
|
||||
|
||||
<script language="javascript">
|
||||
<!--
|
||||
function getSortValue(row, fieldName) {
|
||||
// Find, from p_fieldName, the cell that is used for sorting.
|
||||
var cellId = "field_" + fieldName;
|
||||
var cells = row.cells;
|
||||
for (var i=0; i < cells.length; i++) {
|
||||
if (cells[i].id == cellId) {
|
||||
// Ok we have the cell on which we must sort.
|
||||
// Now get the cell content.
|
||||
// If the cell contains links, content is the 1st link content
|
||||
var innerLinks = cells[i].getElementsByTagName("a");
|
||||
if (innerLinks.length > 0) {
|
||||
return innerLinks[0].innerHTML;
|
||||
} else {
|
||||
return cells[i].innerHTML;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function sortRows(fieldName, ascending) {
|
||||
var queryRows = cssQuery('#query_row');
|
||||
// Create a wrapper for sorting
|
||||
var RowWrapper = function(row, fieldName) {
|
||||
this.value = getSortValue(row, fieldName);
|
||||
this.cloned_node = row.cloneNode(true);
|
||||
this.toString = function() {
|
||||
if (this.value.toString) {
|
||||
return this.value.toString();
|
||||
} else {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Wrap nodes
|
||||
var items = new Array();
|
||||
for (var i=0; i<queryRows.length; i++) {
|
||||
items.push(new RowWrapper(queryRows[i], fieldName));
|
||||
}
|
||||
// Sort nodes
|
||||
items.sort();
|
||||
if (!ascending) {
|
||||
items.reverse();
|
||||
}
|
||||
// Reorder nodes
|
||||
for (var i=0; i<items.length; i++) {
|
||||
var dest = queryRows[i];
|
||||
dest.parentNode.replaceChild(items[i].cloned_node, dest);
|
||||
}
|
||||
};
|
||||
|
||||
function onSort(fieldName){
|
||||
// First, switch the sort arrow (up->down or down->up)
|
||||
var arrow = document.getElementById("arrow_" + fieldName);
|
||||
var sortAscending = (arrow.src.indexOf('arrowDown.gif') != -1);
|
||||
if (sortAscending){
|
||||
// Display "up" image
|
||||
arrow.src = arrow.src.replace('arrowDown.gif', 'arrowUp.gif')
|
||||
}
|
||||
else { // Display "down" image
|
||||
arrow.src = arrow.src.replace('arrowUp.gif', 'arrowDown.gif')
|
||||
}
|
||||
// Then, sort the rows on column "fieldName".
|
||||
sortRows(fieldName, sortAscending);
|
||||
}
|
||||
|
||||
function cellMatches(cell, searchValue) {
|
||||
// This function returns true if the HTML p_cell contains p_searchValue
|
||||
var innerLinks = cell.getElementsByTagName("a");
|
||||
// If the cell contains links, we search within the link contents
|
||||
for (var i=0; i < innerLinks.length; i++){
|
||||
var linkContent = innerLinks[i].innerHTML.toLowerCase();
|
||||
if (linkContent.indexOf(searchValue) != -1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// If we are here, we still have no match. Let's search directly within
|
||||
// the cell.
|
||||
var cellContent = cell.innerHTML.toLowerCase();
|
||||
if (cellContent.indexOf(searchValue) != -1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function onTextEntered(fieldName) {
|
||||
// Is called whenever text is entered into field named p_fieldName.
|
||||
var cellId = "field_" + fieldName
|
||||
var field = document.getElementById("filter_" + fieldName);
|
||||
var fieldValue = field.value.toLowerCase();
|
||||
if (fieldValue.length >= 3) {
|
||||
// Browse all rows and check if it should be visible or not.
|
||||
var queryRows = cssQuery('#query_row');
|
||||
for (var i=0; i < queryRows.length; i++) {
|
||||
// Find the value of the cell.
|
||||
var queryCells = queryRows[i].cells;
|
||||
for (var j=0; j < queryCells.length; j++) {
|
||||
if (queryCells[j].id == cellId) {
|
||||
if (cellMatches(queryCells[j], fieldValue)) {
|
||||
queryRows[i].style.display = "";
|
||||
}
|
||||
else {
|
||||
queryRows[i].style.display = "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Show all rows
|
||||
var queryRows = cssQuery('#query_row');
|
||||
for (var i=0; i < queryRows.length; i++) {
|
||||
queryRows[i].style.display = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
-->
|
||||
</script>
|
||||
|
||||
<table class="vertical listing" width="100%"
|
||||
tal:define="fieldDescrs python: context.<!toolInstanceName!>.getResultColumns(queryResult[0].getObject(), queryName);">
|
||||
|
||||
<tal:comment replace="nothing">Every item in fieldDescr is a FieldDescr instance,
|
||||
excepted for workflow state (which is not a field): in thi case it is simply string
|
||||
"workflowState".</tal:comment>
|
||||
|
||||
<tal:comment replace="nothing">Headers, with filters and sort arrows</tal:comment>
|
||||
<tr>
|
||||
<tal:comment replace="nothing">Mandatory column "Title"/"Name"</tal:comment>
|
||||
<th><img tal:attributes= "src python: '%s/arrowDown.gif' % context.absolute_url();
|
||||
onClick python:'javascript:onSort(\'title\')';"
|
||||
id="arrow_title" style="cursor:pointer"/>
|
||||
<span i18n:translate="ref_name"/>
|
||||
<input id="filter_title" type="text" size="10" onkeyup="javascript:onTextEntered('title')"/>
|
||||
</th>
|
||||
|
||||
<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">
|
||||
<img tal:attributes= "src string: '$portal_url/arrowDown.gif;
|
||||
onClick python:'javascript:onSort(\'%s\')' % fieldName;
|
||||
id python: 'arrow_%s' % fieldName"
|
||||
style="cursor:pointer"/>
|
||||
<tal:comment replace="nothing">Display header for a "standard" field</tal:comment>
|
||||
<tal:standardField condition="python: fieldName != 'workflow_state'">
|
||||
<span i18n:translate="" tal:content="fieldDescr/atField/widget/label_msgid"/>
|
||||
</tal:standardField>
|
||||
<tal:comment replace="nothing">Display header for the workflow state</tal:comment>
|
||||
<tal:workflowState condition="python: fieldName == 'workflow_state'">
|
||||
<span i18n:translate="workflow_state"/>
|
||||
</tal:workflowState>
|
||||
<input type="text" size="10"
|
||||
tal:attributes="id python: 'filter_%s' % fieldName;
|
||||
onkeyup python:'javascript:onTextEntered(\'%s\')' % fieldName"/>
|
||||
</th>
|
||||
</tal:columnHeader>
|
||||
|
||||
<tal:comment replace="nothing">Column "Object type", shown if we are on tab "consult all"</tal:comment>
|
||||
<th tal:condition="mainTabSelected"><img
|
||||
tal:attributes= "src string: $portal_url/arrowDown.gif;
|
||||
onClick python:'javascript:onSort(\'root_type\')';"
|
||||
id = "arrow_root_type" style="cursor:pointer"/>
|
||||
<span i18n:translate="root_type"/>
|
||||
<input type="text" size="10" id="filter_root_type"
|
||||
tal:attributes="onkeyup python:'javascript:onTextEntered(\'root_type\')'"/>
|
||||
</th>
|
||||
|
||||
<tal:comment replace="nothing">Column "Actions"</tal:comment>
|
||||
<th i18n:translate="ref_actions"></th>
|
||||
</tr>
|
||||
|
||||
<tal:comment replace="nothing">Results</tal:comment>
|
||||
<tr tal:repeat="brain queryResult" id="query_row">
|
||||
<tal:row define="obj brain/getObject">
|
||||
|
||||
<tal:comment replace="nothing">Mandatory column "Title"/"Name"</tal:comment>
|
||||
<td id="field_title"><a tal:content="brain/Title"
|
||||
tal:attributes="href python: obj.absolute_url()"></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:attributes="id python:'field_%s' % fieldDescr['atField'].getName()">
|
||||
<tal:field define="contextObj python:obj;
|
||||
isEdit python:False;
|
||||
showLabel python:False;
|
||||
innerRef python:True"
|
||||
condition="python: contextObj.showField(fieldDescr)">
|
||||
<metal:field use-macro="here/<!macros!>/macros/showArchetypesField"/>
|
||||
</tal:field>
|
||||
</td>
|
||||
</tal:standardField>
|
||||
<tal:workflowState condition="python: fieldDescr == 'workflowState'">
|
||||
<td id="field_workflow_state" i18n:translate="" tal:content="obj/getWorkflowLabel"></td>
|
||||
</tal:workflowState>
|
||||
</tal:otherFields>
|
||||
|
||||
<tal:comment replace="nothing">Column "Object type", shown if we are on tab "consult all"</tal:comment>
|
||||
<td tal:condition="mainTabSelected" tal:content="obj/portal_type"
|
||||
i18n:translate="" id="field_root_type"></td>
|
||||
|
||||
<tal:comment replace="nothing">Column "Actions"</tal:comment>
|
||||
<td align="right">
|
||||
<table class="no-style-table" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<tal:comment replace="nothing">Edit the element</tal:comment>
|
||||
<td class="noPadding"><a tal:attributes="href python: obj.absolute_url() + '/edit'"
|
||||
tal:condition="python: member.has_permission('Modify portal content', obj)">
|
||||
<img src="edit.gif" title="Edit" i18n:domain="plone" i18n:attributes="title" />
|
||||
</a></td>
|
||||
<tal:comment replace="nothing">Delete the element</tal:comment>
|
||||
<td class="noPadding"><a tal:attributes="href python: obj.absolute_url() + '/delete_confirmation'"
|
||||
tal:condition="python: member.has_permission('Delete objects', obj)">
|
||||
<img src="delete_icon.gif" title="Delete" i18n:domain="plone" i18n:attributes="title" />
|
||||
</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tal:row>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div metal:use-macro="context/batch_macros/macros/navigation" />
|
||||
</div>
|
||||
|
||||
<metal:phases define-macro="phases" i18n:domain="<!applicationName!>">
|
||||
<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 context/getAppyPhases|nothing"
|
||||
tal:condition="python: phases and (len(phases)>1)" cellspacing="1" cellpadding="0">
|
||||
<tal:phase repeat="phase phases">
|
||||
<tr>
|
||||
<td tal:define="label python:'%s_phase_%s' % (context.meta_type, phase['name']);
|
||||
displayLink python: (phase['phaseStatus'] != 'Future') and ('/portal_factory' not in context.absolute_url())"
|
||||
tal:attributes="class python: 'appyPhase step' + phase['phaseStatus']">
|
||||
<a tal:attributes="href python: '%s?phase=%s&pageName=%s' % (context.absolute_url(), phase['name'], phase['pages'][0]);" tal:condition="displayLink"
|
||||
i18n:translate="" tal:content="label"/>
|
||||
<span tal:condition="not: displayLink" i18n:translate="" tal:content="label"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr tal:condition="python: phase['name'] != phases[-1]['name']">
|
||||
<td align="center"><img tal:attributes="src string: $portal_url/nextPhase.png"/></td>
|
||||
</tr>
|
||||
</tal:phase>
|
||||
</table>
|
||||
</metal:phases>
|
||||
|
||||
<metal:states define-macro="states" i18n:domain="<!applicationName!>"
|
||||
tal:define="showAllStatesInPhase python: flavour.getAttr('showAllStatesInPhaseFor' + contextObj.meta_type);
|
||||
states python: context.getAppyStates(phase, currentOnly=not showAllStatesInPhase)"
|
||||
tal:condition="python: test(showAllStatesInPhase, len(states)>1, True)">
|
||||
<table>
|
||||
<tr>
|
||||
<tal:state repeat="stateInfo states">
|
||||
<td tal:attributes="class python: 'appyState step' + stateInfo['stateStatus']"
|
||||
tal:content="python: context.getWorkflowLabel(stateInfo['name'])" i18n:translate="">
|
||||
</td>
|
||||
<td tal:condition="python: stateInfo['name'] != states[-1]['name']">
|
||||
<img tal:attributes="src string: $portal_url/nextState.png"/>
|
||||
</td>
|
||||
</tal:state>
|
||||
</tr>
|
||||
</table>
|
||||
</metal:states>
|
||||
|
||||
<metal:transitions define-macro="transitions" i18n:domain="<!applicationName!>"
|
||||
tal:define="transitions python: contextObj.portal_workflow.getTransitionsFor(contextObj);"
|
||||
tal:condition="transitions">
|
||||
<form id="triggerTransitionForm" method="post"
|
||||
tal:attributes="action python: contextObj.absolute_url() + '/<!applicationName!>_do'">
|
||||
<input type="hidden" name="actionType" 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'+context.meta_type)"
|
||||
align="right" tal:condition="showCommentsField">
|
||||
<span i18n: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" i18n:attributes="value" class="context"
|
||||
tal:attributes="value python: transition['name'];
|
||||
onClick python: 'javascript: triggerTransition(\'%s\')' % transition['id']"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</metal:transitions>
|
34
gen/plone25/templates/PodTemplate.py
Executable file
|
@ -0,0 +1,34 @@
|
|||
<!codeHeader!>
|
||||
from AccessControl import ClassSecurityInfo
|
||||
from Products.Archetypes.atapi import *
|
||||
import Products.<!applicationName!>.config
|
||||
from appy.gen.plone25.mixins.PodTemplateMixin import PodTemplateMixin
|
||||
from Extensions.appyWrappers import <!wrapperClass!>
|
||||
|
||||
schema = Schema((<!fields!>
|
||||
),)
|
||||
fullSchema = BaseSchema.copy() + schema.copy()
|
||||
|
||||
class <!applicationName!>PodTemplate(BaseContent, PodTemplateMixin):
|
||||
'''POD template.'''
|
||||
security = ClassSecurityInfo()
|
||||
__implements__ = (getattr(BaseContent,'__implements__',()),)
|
||||
|
||||
archetype_name = '<!applicationName!>PodTemplate'
|
||||
meta_type = '<!applicationName!>PodTemplate'
|
||||
portal_type = '<!applicationName!>PodTemplate'
|
||||
allowed_content_types = []
|
||||
filter_content_types = 0
|
||||
global_allow = 1
|
||||
#content_icon = '<!applicationName!>PodTemplate.gif'
|
||||
immediate_view = '<!applicationName!>_appy_view'
|
||||
default_view = '<!applicationName!>_appy_view'
|
||||
suppl_views = ()
|
||||
typeDescription = "<!applicationName!>PodTemplate"
|
||||
typeDescMsgId = '<!applicationName!>_edit_descr'
|
||||
_at_rename_after_creation = True
|
||||
wrapperClass = <!wrapperClass!>
|
||||
schema = fullSchema
|
||||
<!commonMethods!>
|
||||
<!methods!>
|
||||
registerType(<!applicationName!>PodTemplate, '<!applicationName!>')
|
45
gen/plone25/templates/Portlet.pt
Executable file
|
@ -0,0 +1,45 @@
|
|||
<html xmlns:tal="http://xml.zope.org/namespaces/tal"
|
||||
xmlns:metal="http://xml.zope.org/namespaces/metal"
|
||||
i18n:domain="<!applicationName!>">
|
||||
<body>
|
||||
|
||||
<div metal:define-macro="portlet"
|
||||
tal:define="tool python: context.<!toolInstanceName!>"
|
||||
tal:condition="tool/showPortlet">
|
||||
|
||||
<metal:block metal:use-macro="here/global_defines/macros/defines" />
|
||||
|
||||
<dl class="portlet"
|
||||
tal:define="rootClasses python:[<!rootClasses!>];
|
||||
appFolder tool/getAppFolder">
|
||||
|
||||
<tal:comment replace="nothing">Portlet title, with link to tool.</tal:comment>
|
||||
<dt class="portletHeader">
|
||||
<span i18n:translate="" tal:content="python: '<!applicationName!>'">
|
||||
</span>
|
||||
<img i18n:attributes="title" style="cursor:pointer" title="<!applicationName!>Tool"
|
||||
tal:condition="python: member.has_role('Manager')"
|
||||
tal:attributes="onClick python: 'href: window.location=\'%s/\'' % tool.absolute_url();
|
||||
src python: here.<!toolInstanceName!>.absolute_url() + '/appyConfig.gif'"/>
|
||||
</dt>
|
||||
|
||||
<tal:comment replace="nothing">Links to flavours</tal:comment>
|
||||
<dt class="portletAppyItem" tal:repeat="flavourInfo tool/getFlavoursInfo">
|
||||
<a tal:define="flavourNumber flavourInfo/number;
|
||||
rootTypes python: test(flavourNumber==1, rootClasses, ['%s_%s' % (rc, flavourNumber) for rc in rootClasses]);
|
||||
rootClassesQuery python:','.join(rootTypes)"
|
||||
tal:content="flavourInfo/title"
|
||||
i18n:translate="" title="query_consult_all" i18n:attributes="title"
|
||||
tal:attributes="href python:'%s/<!queryName!>?query=%s&flavourNumber=%d' % (appFolder.absolute_url(), rootClassesQuery, flavourNumber)"></a>
|
||||
</dt>
|
||||
|
||||
<dt class="portletAppyItem" tal:condition="python: context.meta_type in rootClasses">
|
||||
<metal:phases use-macro="here/<!macros!>/macros/phases"/>
|
||||
</dt>
|
||||
|
||||
</dl>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
19
gen/plone25/templates/ProfileInit.py
Executable file
|
@ -0,0 +1,19 @@
|
|||
# ------------------------------------------------------------------------------
|
||||
from Products.CMFCore.utils import getToolByName
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
def installProduct(context):
|
||||
'''Installs the necessary products for running PloneMeeting.'''
|
||||
portal = context.getSite()
|
||||
qi = getToolByName(portal, 'portal_quickinstaller')
|
||||
if not qi.isProductInstalled('Archetypes'):
|
||||
qi.installProduct('Archetypes')
|
||||
if not qi.isProductInstalled('<!applicationName!>'):
|
||||
qi.installProduct('<!applicationName!>')
|
||||
return "Product <!applicationName!> installed."
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
def install_default(context):
|
||||
# Installation function of default profile.
|
||||
installProduct(context)
|
||||
# ------------------------------------------------------------------------------
|
63
gen/plone25/templates/Query.pt
Executable file
|
@ -0,0 +1,63 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
|
||||
metal:use-macro="here/main_template/macros/master"
|
||||
i18n:domain="<!applicationName!>">
|
||||
|
||||
<!-- This page presents results of queries -->
|
||||
<body>
|
||||
<div metal:fill-slot="top_slot">
|
||||
<metal:block metal:use-macro="here/global_defines/macros/defines" />
|
||||
<div tal:define="dummy python:request.set('disable_border', 1)" />
|
||||
</div>
|
||||
|
||||
<div metal:fill-slot="main"
|
||||
tal:define="tool python: context.<!toolInstanceName!>;
|
||||
queryName python:context.REQUEST.get('query');
|
||||
flavourNumber python:context.REQUEST.get('flavourNumber');
|
||||
rootClasses python:[<!rootClasses!>];
|
||||
rootTypes python: test(flavourNumber=='1', rootClasses, ['%s_%s' % (rc, flavourNumber) for rc in rootClasses]);
|
||||
rootClassesQuery python:','.join(rootClasses);
|
||||
mainTabSelected python: queryName.find(',') != -1;
|
||||
appFolder tool/getAppFolder">
|
||||
|
||||
<span tal:condition="python: queryName and (queryName != 'none')">
|
||||
<span tal:define="queryResult python: context.<!toolInstanceName!>.executeQuery(queryName, int(flavourNumber));
|
||||
batch queryResult">
|
||||
|
||||
<!-- Tabs -->
|
||||
<ul class="contentViews appyTabs">
|
||||
|
||||
<!-- Tab "All objects" -->
|
||||
<li tal:define="selected python:mainTabSelected"
|
||||
tal:attributes="class python:test(selected, 'selected', 'plain')"
|
||||
tal:condition="python: len(rootClasses)>1">
|
||||
|
||||
<a tal:attributes="href python: '%s/<!queryName!>?query=%s&flavourNumber=%s' % (appFolder.absolute_url(), rootClassesQuery, flavourNumber)"
|
||||
i18n:translate="">query_consult_all</a>
|
||||
</li>
|
||||
<!-- One tab for each root content type -->
|
||||
<tal:tab repeat="rootContentType rootTypes">
|
||||
<li tal:define="selected python:queryName == rootContentType"
|
||||
tal:attributes="class python:test(selected, 'selected', 'plain')">
|
||||
<a i18n:translate="" tal:content="rootContentType"
|
||||
tal:attributes="href python: '%s/<!queryName!>?query=%s&flavourNumber=%s' % (appFolder.absolute_url(), rootContentType, flavourNumber)"/>
|
||||
<img i18n:attributes="title" style="cursor:pointer" title="query_create" class="appyPlusImg"
|
||||
tal:define="addPermission python: '<!applicationName!>: Add %s' % rootContentType"
|
||||
tal:attributes="onClick python: 'href: window.location=\'%s/createObject?type_name=%s\'' % (appFolder.absolute_url(), rootContentType);
|
||||
src python: here.<!toolInstanceName!>.absolute_url() + '/plus.png'"
|
||||
tal:condition="python: member.has_permission(addPermission, appFolder)"/>
|
||||
</li>
|
||||
</tal:tab>
|
||||
</ul>
|
||||
<br/>
|
||||
|
||||
<!-- Query result -->
|
||||
<span tal:condition="queryResult">
|
||||
<span metal:use-macro="here/<!macros!>/macros/queryResult"></span>
|
||||
</span>
|
||||
<span tal:condition="not: queryResult"
|
||||
i18n:translate="query_no_result">No result.</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
264
gen/plone25/templates/Styles.css.dtml
Executable file
|
@ -0,0 +1,264 @@
|
|||
/* <dtml-var "enableHTTPCompression(request=REQUEST, debug=1, css=1)"> (this is for http compression) */
|
||||
/* <dtml-with base_properties> (do not remove this :) */
|
||||
/* <dtml-call "REQUEST.set('portal_url', portal_url())"> (not this either :) */
|
||||
|
||||
#portal-breadcrumbs {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.appyPod {
|
||||
float:right;
|
||||
}
|
||||
|
||||
.appyTabs {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.appyTabs li a {
|
||||
border-bottom:1px solid transparent;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
.appyTabs li a:visited {
|
||||
color: #578308;
|
||||
}
|
||||
|
||||
.appyTitle {
|
||||
padding-top: 0.5em;
|
||||
font-size: 110%;
|
||||
}
|
||||
|
||||
.appyLabel {
|
||||
font-weight: bold;
|
||||
padding-right: 0.4em;
|
||||
}
|
||||
|
||||
.appyPhase {
|
||||
border-style: solid;
|
||||
border-width: thin;
|
||||
text-align: center;
|
||||
padding: 0 1em 0 1.3em;
|
||||
}
|
||||
|
||||
.appyState {
|
||||
font-size: 85%;
|
||||
font-style: normal;
|
||||
border-style: solid;
|
||||
border-width: thin;
|
||||
text-align: center;
|
||||
padding: 0.1em 1em 0.1em 1.3em;
|
||||
}
|
||||
|
||||
/* stepxx classes are used for displaying status of a phase or state. */
|
||||
.stepDone {
|
||||
background-color: #cde2a7;
|
||||
background-image: url(&dtml-portal_url;/done.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center left;
|
||||
}
|
||||
|
||||
.stepCurrent {
|
||||
background-color: #ffce7b;
|
||||
background-image: url(&dtml-portal_url;/current.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center left;
|
||||
}
|
||||
|
||||
.stepFuture {
|
||||
background-color: #ffffff;
|
||||
color: #C8C8C8;
|
||||
border-style: dashed;
|
||||
}
|
||||
|
||||
.stepUnselected {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.appyPlusImg {
|
||||
vertical-align: top;
|
||||
position: relative;
|
||||
left: -1.4em;
|
||||
top: -0.55em;
|
||||
}
|
||||
|
||||
.appyRefEdit {
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
.appyCommonInfo {
|
||||
border-color: #ffa500;
|
||||
background-color: &dtml-evenRowBackgroundColor;;
|
||||
border-style: solid;
|
||||
border-width: 2px;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.appyWorkflow {
|
||||
text-align: center;
|
||||
background-color: &dtml-globalBackgroundColor;;
|
||||
}
|
||||
|
||||
dl.expandedInlineCollapsible dt.collapsibleHeader, dl.expandedBlockCollapsible dt.collapsibleHeader {
|
||||
background:#dee7ec url(treeExpanded.gif) no-repeat scroll 6px 50%;
|
||||
border-width 1px;
|
||||
border-color: #8cacbb;
|
||||
border-style: solid;
|
||||
border-width: thin;
|
||||
}
|
||||
|
||||
/* With fields layout in columns, standard error frame is too large */
|
||||
.error {
|
||||
padding: 0.4em;
|
||||
}
|
||||
|
||||
/* Table styles */
|
||||
.no-style-table {
|
||||
border: 0 !important;
|
||||
padding: 0 !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.no-style-table td {
|
||||
border: 0 !important;
|
||||
padding-left: 0 !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
/* Minor layout changes in fieldsets and tables */
|
||||
fieldset {
|
||||
margin: 0em 0em;
|
||||
line-height: 1.0em;
|
||||
}
|
||||
|
||||
/* Group fieldsets */
|
||||
.appyGroup {
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
.imageInput {
|
||||
border-width: 0px;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.noPadding {
|
||||
padding-right: 0em !important;
|
||||
padding-left: 0em !important;
|
||||
padding-top: 0em !important;
|
||||
padding-bottom: 0em !important;
|
||||
}
|
||||
|
||||
.appyButton {
|
||||
background: &dtml-globalBackgroundColor; url(&dtml-portal_url;/linkOpaque.gif) 5px 1px no-repeat;
|
||||
cursor: pointer;
|
||||
font-size: &dtml-fontSmallSize;;
|
||||
padding: 1px 1px 1px 12px;
|
||||
text-transform: &dtml-textTransform;;
|
||||
/* overflow: visible; IE produces ugly results with this */
|
||||
}
|
||||
|
||||
.listing {
|
||||
margin: 0em 0em;
|
||||
}
|
||||
|
||||
.listing td, .stx table td {
|
||||
padding-right: 0.1em;
|
||||
padding-left: 0.3em;
|
||||
padding-top: 0.3em;
|
||||
padding-bottom: 0em;
|
||||
}
|
||||
|
||||
.vertical td {
|
||||
padding-left: 0.3em;
|
||||
}
|
||||
|
||||
.innerAppyTable {
|
||||
border-width: 0px;
|
||||
}
|
||||
|
||||
.innerAppyTable td {
|
||||
border-top: 0px;
|
||||
border-bottom: 1px solid #8CACBB;
|
||||
border-right: 0px;
|
||||
padding: 0.4em 0em 0em 0em;
|
||||
border-collapse: separate;
|
||||
}
|
||||
|
||||
.innerAppyTable th {
|
||||
border-right: 0px;
|
||||
}
|
||||
|
||||
.innerAppyFieldset {
|
||||
margin: 0em 1em;
|
||||
line-height: 1.0em;
|
||||
}
|
||||
|
||||
/* Portlet elements */
|
||||
.portletAppyItem {
|
||||
margin: 0;
|
||||
padding: 1px 0.5em;
|
||||
border-left: 1px solid #8cacbb;
|
||||
border-right: 1px solid #8cacbb;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
/* Uncomment this if you want to hide breadcrumbs */
|
||||
/*
|
||||
#portal-breadcrumbs {
|
||||
display: none;
|
||||
}
|
||||
*/
|
||||
|
||||
/* </dtml-with> */
|
||||
|
||||
/* image-right, but without border */
|
||||
.image-right {
|
||||
border:0px solid Black;
|
||||
clear:both;
|
||||
float:right;
|
||||
margin:0.5em;
|
||||
}
|
||||
|
||||
/* DOCUMENTATION ON PRE-DEFINED PROPERTIES FROM PLONE */
|
||||
|
||||
/* You can insert colors and other variables from Plone's
|
||||
base_properties by doing:
|
||||
& dtml-variableName ; (without the spaces, excluded here to not make it render)
|
||||
|
||||
Example:
|
||||
myLink {
|
||||
color: & dtml-fontColor ; (again, without the spaces)
|
||||
}
|
||||
This means you can generate your own elements that use Plone's defaults,
|
||||
and respect any customizations people have done. See base_properties for
|
||||
the default values.
|
||||
|
||||
These are the available properties:
|
||||
logoName - the file name of the portal logo.
|
||||
fontFamily - the font family used for all text that is not headers
|
||||
fontBaseSize - the base font size that everything is calculated from
|
||||
fontColor - the main font color
|
||||
backgroundColor - the background color
|
||||
linkColor - the color used on normal links
|
||||
linkActiveColor - color used on active links
|
||||
linkVisitedColor - color used on visited links
|
||||
borderWidth - the width of most borders in Plone
|
||||
borderStyle - the style of the border lines, normally solid
|
||||
borderStyleAnnotations - style of border lines on comments etc
|
||||
globalBorderColor - the border color used on the main tabs, the portlets etc
|
||||
globalBackgroundColor - background color for the selected tabs, portlet headings etc
|
||||
globalFontColor - the color of the font in the tabs and in portlet headings
|
||||
headingFontFamily - font family for h1/h2/h3/h4/h5/h6 headlines.
|
||||
headingFontBaseSize - the base size used when calculating the different headline sizes
|
||||
contentViewBorderColor - the content view tabs border color
|
||||
contentViewBackgroundColor - the content view tabs background color
|
||||
contentViewFontColor - the font color used in the content view tabs
|
||||
textTransform - whether to lowercase text in portlets, tabs etc.
|
||||
evenRowBackgroundColor - the background color of even rows in listings
|
||||
oddRowBackgroundColor - the background color of even rows in listings
|
||||
notifyBorderColor - border color of notification elements like the status message, the calendar focus
|
||||
notifyBackgroundColor - background color of notification elements like the status message, the calendar focus
|
||||
discreetColor:string=#999999
|
||||
helpBackgroundColor:string=#ffffe1
|
||||
*/
|
||||
|
||||
|
49
gen/plone25/templates/ToolTemplate.py
Executable file
|
@ -0,0 +1,49 @@
|
|||
<!codeHeader!>
|
||||
from AccessControl import ClassSecurityInfo
|
||||
from Products.Archetypes.atapi import *
|
||||
from Products.CMFCore.utils import UniqueObject
|
||||
import Products.<!applicationName!>.config
|
||||
from appy.gen.plone25.mixins.ToolMixin import ToolMixin
|
||||
from Extensions.appyWrappers import AbstractWrapper, <!wrapperClass!>
|
||||
|
||||
predefinedSchema = Schema((<!predefinedFields!>
|
||||
),)
|
||||
schema = Schema((<!fields!>
|
||||
),)
|
||||
fullSchema = OrderedBaseFolderSchema.copy() + predefinedSchema.copy() + schema.copy()
|
||||
|
||||
class <!toolName!>(UniqueObject, OrderedBaseFolder, ToolMixin):
|
||||
'''Tool for <!applicationName!>.'''
|
||||
security = ClassSecurityInfo()
|
||||
__implements__ = (getattr(UniqueObject,'__implements__',()),) + (getattr(OrderedBaseFolder,'__implements__',()),)
|
||||
|
||||
archetype_name = '<!toolName!>'
|
||||
meta_type = '<!toolName!>'
|
||||
portal_type = '<!toolName!>'
|
||||
allowed_content_types = ()
|
||||
filter_content_types = 0
|
||||
global_allow = 0
|
||||
#content_icon = '<!toolName!>.gif'
|
||||
immediate_view = '<!applicationName!>_appy_view'
|
||||
default_view = '<!applicationName!>_appy_view'
|
||||
suppl_views = ()
|
||||
typeDescription = "<!toolName!>"
|
||||
typeDescMsgId = '<!toolName!>_edit_descr'
|
||||
i18nDomain = '<!applicationName!>'
|
||||
wrapperClass = <!wrapperClass!>
|
||||
_at_rename_after_creation = True
|
||||
schema = fullSchema
|
||||
schema["id"].widget.visible = False
|
||||
schema["title"].widget.visible = False
|
||||
# When browsing into the tool, the 'configure' portlet should be dislayed.
|
||||
left_slots = ['here/portlet_prefs/macros/portlet']
|
||||
right_slots = []
|
||||
|
||||
# Tool constructor has no id argument, the id is fixed.
|
||||
def __init__(self, id=None):
|
||||
OrderedBaseFolder.__init__(self, '<!toolInstanceName!>')
|
||||
self.setTitle('<!applicationName!>')
|
||||
<!commonMethods!>
|
||||
<!predefinedMethods!>
|
||||
<!methods!>
|
||||
registerType(<!toolName!>, '<!applicationName!>')
|
23
gen/plone25/templates/__init__.py
Executable file
|
@ -0,0 +1,23 @@
|
|||
<!codeHeader!>
|
||||
from config import *
|
||||
import logging
|
||||
try:
|
||||
import CustomizationPolicy
|
||||
except ImportError:
|
||||
CustomizationPolicy = None
|
||||
from Products.CMFCore import utils as cmfutils
|
||||
from Products.CMFCore import DirectoryView
|
||||
from Products.CMFPlone.utils import ToolInit
|
||||
from Products.Archetypes.atapi import *
|
||||
from Products.Archetypes import listTypes
|
||||
from appy.gen.plone25.installer import ZopeInstaller
|
||||
logger = logging.getLogger(PROJECTNAME)
|
||||
|
||||
def initialize(context):
|
||||
<!imports!>
|
||||
# I need to do those imports here; else, types and add permissions will not
|
||||
# be registered.
|
||||
ZopeInstaller(context, PROJECTNAME,
|
||||
<!applicationName!>Tool.<!applicationName!>Tool,
|
||||
DEFAULT_ADD_CONTENT_PERMISSION, ADD_CONTENT_PERMISSIONS,
|
||||
logger, globals()).install()
|
BIN
gen/plone25/templates/appyConfig.gif
Executable file
After Width: | Height: | Size: 899 B |
21
gen/plone25/templates/appyWrappers.py
Executable file
|
@ -0,0 +1,21 @@
|
|||
# ------------------------------------------------------------------------------
|
||||
from appy.gen import *
|
||||
from appy.gen.plone25.wrappers import AbstractWrapper
|
||||
from appy.gen.plone25.wrappers.ToolWrapper import ToolWrapper
|
||||
from appy.gen.plone25.wrappers.FlavourWrapper import FlavourWrapper
|
||||
from appy.gen.plone25.wrappers.PodTemplateWrapper import PodTemplateWrapper
|
||||
<!imports!>
|
||||
|
||||
class PodTemplate(PodTemplateWrapper):
|
||||
'''This class represents a POD template for this application.'''
|
||||
<!podTemplateBody!>
|
||||
class Flavour(FlavourWrapper):
|
||||
'''This class represents the Appy class used for defining a flavour.'''
|
||||
folder=True
|
||||
<!flavourBody!>
|
||||
class Tool(ToolWrapper):
|
||||
'''This class represents the tool for this application.'''
|
||||
folder=True
|
||||
<!toolBody!>
|
||||
<!wrappers!>
|
||||
# ------------------------------------------------------------------------------
|
155
gen/plone25/templates/appy_edit.cpt
Executable file
|
@ -0,0 +1,155 @@
|
|||
<tal:block metal:define-macro="master"
|
||||
define="errors options/state/getErrors | nothing;
|
||||
Iterator python:modules['Products.Archetypes'].IndexIterator;
|
||||
schematas here/Schemata;
|
||||
fieldsets python:[key for key in schematas.keys() if (key != 'metadata') and (schematas[key].editableFields(here, 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(here);
|
||||
dummy python:here.at_isEditable(fields);
|
||||
portal_type python:here.getPortalTypeName().lower().replace(' ', '_');
|
||||
type_name here/getPortalTypeName|here/archetype_name;
|
||||
lockable python:hasattr(here, 'wl_isLocked');
|
||||
isLocked python:lockable and here.wl_isLocked();
|
||||
tabindex tabindex|python:Iterator(pos=7000);
|
||||
isEdit python:True;
|
||||
contextObj python:context;
|
||||
css python:here.getUniqueWidgetAttr(fields, 'helper_css');
|
||||
js python:here.getUniqueWidgetAttr(fields, 'helper_js');
|
||||
phaseInfo python: context.getAppyPhases(fieldset=fieldset, forPlone=True);
|
||||
phase request/phase|phaseInfo/name;
|
||||
pageName python: context.getAppyPage(isEdit, phaseInfo);">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
|
||||
xmlns:tal="http://xml.zope.org/namespaces/tal"
|
||||
xmlns:metal="http://xml.zope.org/namespaces/metal"
|
||||
xmlns:i18n="http://xml.zope.org/namespaces/i18n"
|
||||
metal:use-macro="here/main_template/macros/master">
|
||||
|
||||
<!-- Disable the Standard Plone green tab -->
|
||||
<div metal:fill-slot="top_slot">
|
||||
<metal:block metal:use-macro="here/global_defines/macros/defines" />
|
||||
<div tal:define="dummy python:request.set('disable_border', 1)" />
|
||||
</div>
|
||||
|
||||
<!-- Archetypes stuff for managing Javascript and CSS. If I remove this stuff,
|
||||
Javascript popup for dates does not work anyore -->
|
||||
<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">
|
||||
<script type="text/javascript" charset="iso-8859-1"
|
||||
tal:condition="python:exists('portal/%s' % item)"
|
||||
tal:attributes="src string:$portal_url/$item">
|
||||
</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:css fill-slot="css_slot">
|
||||
<tal:css condition="css" repeat="item css">
|
||||
<style type="text/css" media="all"
|
||||
tal:condition="python:exists('portal/%s' % item)"
|
||||
tal:content="structure string:<!-- @import url($portal_url/$item); -->">
|
||||
</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/<!macros!>/macros/showPagePrologue"/>
|
||||
<div metal:use-macro="here/<!macros!>/macros/showPageHeader"/>
|
||||
|
||||
<form name="edit_form" method="post" enctype="multipart/form-data"
|
||||
class="enableUnloadProtection atBaseEditForm"
|
||||
tal:attributes="action python:here.absolute_url()+'/'+template.id;
|
||||
id string:${portal_type}-base-edit">
|
||||
|
||||
<div metal:use-macro="here/<!macros!>/macros/listFields" />
|
||||
|
||||
<div class="formControls">
|
||||
<input type="hidden" name="fieldset" value="default" tal:attributes="value fieldset"/>
|
||||
<input type="hidden" name="form.submitted" value="1"/>
|
||||
<input type="hidden" name="add_reference.field:record" value=""/>
|
||||
<input type="hidden" name="add_reference.type:record" value=""/>
|
||||
<input type="hidden" name="add_reference.destination:record" value=""/>
|
||||
|
||||
<tal:env define="env request/controller_state/kwargs">
|
||||
<tal:loop repeat="varname python:('reference_source_url', 'reference_source_field', 'reference_source_fieldset')">
|
||||
<tal:reference define="items python:env.get(varname, request.get(varname))"
|
||||
condition="items">
|
||||
<input tal:repeat="item items" type="hidden"
|
||||
tal:attributes="value item;
|
||||
name string:form_env.${varname}:list:record"/>
|
||||
</tal:reference>
|
||||
</tal:loop>
|
||||
</tal:env>
|
||||
|
||||
<tal:comment replace="nothing">Turn 'persistent_' variables from controller_state persistent
|
||||
</tal:comment>
|
||||
<tal:env repeat="env request/controller_state/kwargs/items">
|
||||
<input type="hidden"
|
||||
tal:define="key python:env[0];
|
||||
value python:env[1]"
|
||||
tal:condition="python:key.startswith('persistent_')"
|
||||
tal:attributes="name string:form_env.${key}:record;
|
||||
value value"/>
|
||||
</tal:env>
|
||||
|
||||
<tal:comment replace="nothing">Turn 'persistent_' variables from forms (GET/POST) persistent
|
||||
</tal:comment>
|
||||
<tal:env repeat="env request/form">
|
||||
<input type="hidden"
|
||||
tal:define="key env;
|
||||
value request/?env"
|
||||
tal:condition="python:key.startswith('persistent_')"
|
||||
tal:attributes="name string:form_env.${key}:record;
|
||||
value value"/>
|
||||
</tal:env>
|
||||
|
||||
<tal:comment replace="nothing">Store referrer to remember where to go back
|
||||
</tal:comment>
|
||||
<input type="hidden" name="last_referer"
|
||||
tal:define="last_referer python:here.session_restore_value('HTTP_REFERER', request.form.get('last_referer', request.get('HTTP_REFERER')))"
|
||||
tal:attributes="value python:(last_referer and '%s/%s' % (here.absolute_url(), template.id) not in last_referer) and last_referer or (here.getParentNode() and here.getParentNode().absolute_url())"/>
|
||||
|
||||
<tal:comment replace="nothing">Buttons (Previous, Next, Save, etc)</tal:comment>
|
||||
<metal:block define-slot="buttons"
|
||||
tal:define="fieldset_index python:fieldsets.index(fieldset);
|
||||
n_fieldsets python:len(fieldsets)">
|
||||
|
||||
<input tal:condition="python:(fieldset_index > 0) and (fieldsets[fieldset_index-1] in phaseInfo['pages'])"
|
||||
class="context" type="submit" name="form_previous" value="Previous"
|
||||
i18n:attributes="value label_previous;" i18n:domain="plone"
|
||||
tal:attributes="tabindex tabindex/next;
|
||||
disabled python:test(isLocked, 'disabled', None);"/>
|
||||
<input tal:condition="python:(fieldset_index < n_fieldsets - 1) and (fieldsets[fieldset_index+1] in phaseInfo['pages'])"
|
||||
class="context" type="submit" name="form_next" value="Next"
|
||||
i18n:attributes="value label_next;" i18n:domain="plone"
|
||||
tal:attributes="tabindex tabindex/next;
|
||||
disabled python:test(isLocked, 'disabled', None);"/>
|
||||
<input class="context" type="submit" name="form_submit" value="Save"
|
||||
i18n:attributes="value label_save;" i18n:domain="plone"
|
||||
tal:attributes="tabindex tabindex/next;
|
||||
disabled python:test(isLocked, 'disabled', None);"/>
|
||||
<input class="standalone" type="submit" name="form.button.cancel" value="Cancel"
|
||||
i18n:attributes="value label_cancel;" i18n:domain="plone"
|
||||
tal:attributes="tabindex tabindex/next"/>
|
||||
</metal:block>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
<div metal:use-macro="here/<!macros!>/macros/showPageFooter"/>
|
||||
</metal:fill>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
</tal:block>
|
13
gen/plone25/templates/appy_edit.cpt.metadata
Executable file
|
@ -0,0 +1,13 @@
|
|||
[default]
|
||||
title = Edit
|
||||
|
||||
[validators]
|
||||
validators = validate_base
|
||||
validators..form_add =
|
||||
validators..cancel =
|
||||
|
||||
[actions]
|
||||
action.success = traverse_to:string:content_edit
|
||||
action.success..form_add = traverse_to:string:add_reference
|
||||
action.success..cancel = traverse_to:string:go_back
|
||||
action.failure = traverse_to_action:string:edit
|
35
gen/plone25/templates/appy_view.pt
Executable file
|
@ -0,0 +1,35 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"
|
||||
i18n:domain="<!applicationName!>"
|
||||
lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal"
|
||||
xmlns:metal="http://xml.zope.org/namespaces/metal"
|
||||
xmlns:i18n="http://xml.zope.org/namespaces/i18n"
|
||||
metal:use-macro="here/main_template/macros/master">
|
||||
|
||||
<head><title></title></head>
|
||||
|
||||
<tal:comment replace="nothing">Disable standard Plone green tabs</tal:comment>
|
||||
<div metal:fill-slot="top_slot">
|
||||
<metal:block metal:use-macro="here/global_defines/macros/defines" />
|
||||
<div tal:define="dummy python:request.set('disable_border', 1)" />
|
||||
</div>
|
||||
|
||||
<tal:comment replace="nothing">Fill main slot of Plone main_template</tal:comment>
|
||||
<body>
|
||||
<metal:fill fill-slot="main"
|
||||
tal:define="contextObj python:context;
|
||||
portal_type python:here.getPortalTypeName().lower().replace(' ', '_');
|
||||
errors python:request.get('errors', {});
|
||||
isEdit python:False;
|
||||
tool contextObj/getTool;
|
||||
flavour python: tool.getFlavour(contextObj);
|
||||
phaseInfo python: contextObj.getAppyPhases(currentOnly=True, forPlone=False);
|
||||
phase request/phase|phaseInfo/name;
|
||||
pageName python: contextObj.getAppyPage(isEdit, phaseInfo);
|
||||
showWorkflow python: flavour.getAttr('showWorkflowFor' + contextObj.meta_type)">
|
||||
<div metal:use-macro="here/<!macros!>/macros/showPagePrologue"/>
|
||||
<div metal:use-macro="here/<!macros!>/macros/showPageHeader"/>
|
||||
<div metal:use-macro="here/<!macros!>/macros/listFields" />
|
||||
<div metal:use-macro="here/<!macros!>/macros/showPageFooter"/>
|
||||
</metal:fill>
|
||||
</body>
|
||||
</html>
|
BIN
gen/plone25/templates/arrowDown.png
Executable file
After Width: | Height: | Size: 174 B |
BIN
gen/plone25/templates/arrowUp.png
Executable file
After Width: | Height: | Size: 174 B |
7
gen/plone25/templates/colophon.pt
Executable file
|
@ -0,0 +1,7 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
|
||||
i18n:domain="<!applicationName!>">
|
||||
<body>
|
||||
<div id="portal-colophon" metal:define-macro="colophon">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
43
gen/plone25/templates/config.py
Executable file
|
@ -0,0 +1,43 @@
|
|||
<!codeHeader!>
|
||||
import sys
|
||||
try: # New CMF
|
||||
from Products.CMFCore.permissions import setDefaultRoles
|
||||
except ImportError: # Old CMF
|
||||
from Products.CMFCore.CMFCorePermissions import setDefaultRoles
|
||||
|
||||
import Extensions.appyWrappers
|
||||
<!imports!>
|
||||
|
||||
# The following imports are here for allowing mixin classes to access those
|
||||
# elements without being statically dependent on Plone/Zope packages. Indeed,
|
||||
# every Archetype instance has a method "getProductConfig" that returns this
|
||||
# module.
|
||||
from persistent.list import PersistentList
|
||||
from Products.Archetypes.utils import DisplayList
|
||||
from OFS.Image import File
|
||||
from DateTime import DateTime
|
||||
from Products.CMFCore.utils import getToolByName
|
||||
from Products.CMFPlone.PloneBatch import Batch
|
||||
import logging
|
||||
logger = logging.getLogger('<!applicationName!>')
|
||||
|
||||
# Some global variables --------------------------------------------------------
|
||||
defaultAddRoles = [<!defaultAddRoles!>]
|
||||
DEFAULT_ADD_CONTENT_PERMISSION = "Add portal content"
|
||||
ADD_CONTENT_PERMISSIONS = {
|
||||
<!addPermissions!>}
|
||||
setDefaultRoles(DEFAULT_ADD_CONTENT_PERMISSION, tuple(defaultAddRoles))
|
||||
product_globals = globals()
|
||||
PROJECTNAME = '<!applicationName!>'
|
||||
applicationRoles = [<!roles!>]
|
||||
referers = {
|
||||
<!referers!>
|
||||
}
|
||||
# In the following dict, we keep one instance for every Appy workflow defined
|
||||
# in the application. Those prototypical instances will be used for executing
|
||||
# user-defined actions and transitions. For each instance, we add a special
|
||||
# attribute "_transitionsMapping" that allows to get Appy transitions from the
|
||||
# names of DC transitions.
|
||||
workflowInstances = {}
|
||||
<!workflowInstancesInit!>
|
||||
# ------------------------------------------------------------------------------
|
14
gen/plone25/templates/configure.zcml
Executable file
|
@ -0,0 +1,14 @@
|
|||
<configure xmlns="http://namespaces.zope.org/zope"
|
||||
xmlns:browser="http://namespaces.zope.org/browser"
|
||||
xmlns:five="http://namespaces.zope.org/five"
|
||||
xmlns:genericsetup="http://namespaces.zope.org/genericsetup"
|
||||
i18n_domain="<!applicationName!>">
|
||||
|
||||
<!--five:deprecatedManageAddDelete class=".Meeting.Meeting"/-->
|
||||
|
||||
<genericsetup:registerProfile name="default"
|
||||
title="<!applicationName!>" description=""
|
||||
provides="Products.GenericSetup.interfaces.EXTENSION"
|
||||
for="Products.CMFPlone.interfaces.IPloneSiteRoot"/>
|
||||
|
||||
</configure>
|
27
gen/plone25/templates/createAppyObject.cpy
Executable file
|
@ -0,0 +1,27 @@
|
|||
## Controller Python Script "createAppyObject"
|
||||
##bind container=container
|
||||
##bind context=context
|
||||
##bind namespace=
|
||||
##bind script=script
|
||||
##bind state=state
|
||||
##bind subpath=traverse_subpath
|
||||
##parameters=initiator, field, type_name
|
||||
##title=createAppyObject
|
||||
##
|
||||
if not initiator or not field:
|
||||
raise Exception, 'You must specify the uid of the object that initiates ' \
|
||||
'this creation in the "initiator" parameter and the ' \
|
||||
'related field in the "field" param.'
|
||||
|
||||
if not type_name:
|
||||
raise Exception, 'You must specify the target type name in the "type_name" ' \
|
||||
'parameter.'
|
||||
|
||||
initiatorRes = context.uid_catalog.searchResults(UID=initiator)
|
||||
if not initiatorRes:
|
||||
raise Exception, 'Given initiator UID does not correspond to a valid object.'
|
||||
|
||||
context.REQUEST.SESSION['initiator'] = initiator
|
||||
context.REQUEST.SESSION['initiatorField'] = field
|
||||
context.REQUEST.SESSION['initiatorTarget'] = type_name
|
||||
return state.set(status='success')
|
2
gen/plone25/templates/createAppyObject.cpy.metadata
Executable file
|
@ -0,0 +1,2 @@
|
|||
[actions]
|
||||
action.success=redirect_to:python:'createObject?type_name=%s' % request.SESSION.get('initiatorTarget')
|
BIN
gen/plone25/templates/current.png
Executable file
After Width: | Height: | Size: 244 B |
51
gen/plone25/templates/do.py
Executable file
|
@ -0,0 +1,51 @@
|
|||
## Python Script "<!applicationName!>_do.py"
|
||||
##bind container=container
|
||||
##bind context=context
|
||||
##bind namespace=
|
||||
##bind script=script
|
||||
##bind subpath=traverse_subpath
|
||||
##parameters=actionType
|
||||
##title=Executes an action
|
||||
rq = context.REQUEST
|
||||
urlBack = rq['HTTP_REFERER']
|
||||
|
||||
if actionType == 'appyAction':
|
||||
obj = context.uid_catalog(UID=rq['objectUid'])[0].getObject()
|
||||
res, msg = obj.executeAppyAction(rq['fieldName'])
|
||||
if not msg:
|
||||
# Use the default i18n messages
|
||||
suffix = 'ko'
|
||||
if res:
|
||||
suffix = 'ok'
|
||||
label = '%s_action_%s' % (obj.getLabelPrefix(rq['fieldName']), suffix)
|
||||
msg = context.utranslate(label, domain='<!applicationName!>')
|
||||
context.plone_utils.addPortalMessage(msg)
|
||||
|
||||
elif actionType == 'changeRefOrder':
|
||||
# Move the item up (-1), down (+1) or at a given position ?
|
||||
move = -1 # Move up
|
||||
isDelta = True
|
||||
if rq.get('moveDown.x', None) != None:
|
||||
move = 1 # Move down
|
||||
elif rq.get('moveSeveral.x', None) != None:
|
||||
try:
|
||||
move = int(rq.get('moveValue'))
|
||||
# In this case, it is not a delta value; it is the new position where
|
||||
# the item must be moved.
|
||||
isDelta = False
|
||||
except ValueError:
|
||||
context.plone_utils.addPortalMessage(
|
||||
context.utranslate('ref_invalid_index', domain='<!applicationName!>'))
|
||||
context.changeAppyRefOrder(rq['fieldName'], rq['objectUid'], move, isDelta)
|
||||
|
||||
elif actionType == 'triggerTransition':
|
||||
from Products.CMFPlone import PloneMessageFactory as _
|
||||
context.portal_workflow.doActionFor(context, rq['workflow_action'],
|
||||
comment=rq.get('comment', ''))
|
||||
if urlBack.find('?') != -1:
|
||||
# Remove params; this way, the user may be redirected to correct phase
|
||||
# when relevant.
|
||||
urlBack = urlBack[:urlBack.find('?')]
|
||||
context.plone_utils.addPortalMessage(_(u'Your content\'s status has been modified.'))
|
||||
|
||||
return rq.RESPONSE.redirect(urlBack)
|
BIN
gen/plone25/templates/doc.png
Executable file
After Width: | Height: | Size: 818 B |
BIN
gen/plone25/templates/done.png
Executable file
After Width: | Height: | Size: 248 B |
7
gen/plone25/templates/footer.pt
Executable file
|
@ -0,0 +1,7 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
|
||||
i18n:domain="<!applicationName!>">
|
||||
<body>
|
||||
<div id="portal-footer" metal:define-macro="portal_footer">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
15
gen/plone25/templates/frontPage.pt
Executable file
|
@ -0,0 +1,15 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
|
||||
metal:use-macro="here/main_template/macros/master" i18n:domain="<!applicationName!>">
|
||||
|
||||
<!-- Disable standard Plone green tabs -->
|
||||
<div metal:fill-slot="top_slot">
|
||||
<metal:block metal:use-macro="here/global_defines/macros/defines" />
|
||||
<div tal:define="dummy python:request.set('disable_border', 1)" />
|
||||
</div>
|
||||
|
||||
<body>
|
||||
<div metal:fill-slot="main">
|
||||
<span tal:replace="structure python: context.<!toolInstanceName!>.translateWithMapping('front_page_text')"/>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
8
gen/plone25/templates/import_steps.xml
Executable file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0"?>
|
||||
<import-steps>
|
||||
<import-step id="install-product-<!applicationName!>" version="1.0"
|
||||
handler="Products.<!applicationName!>.profiles.install_default"
|
||||
title="Product <!applicationName!>: installation.">
|
||||
Product <!applicationName!>: installation.
|
||||
</import-step>
|
||||
</import-steps>
|
BIN
gen/plone25/templates/nextPhase.png
Executable file
After Width: | Height: | Size: 201 B |
BIN
gen/plone25/templates/nextState.png
Executable file
After Width: | Height: | Size: 192 B |
BIN
gen/plone25/templates/odt.png
Executable file
After Width: | Height: | Size: 754 B |
BIN
gen/plone25/templates/pdf.png
Executable file
After Width: | Height: | Size: 228 B |
BIN
gen/plone25/templates/plus.png
Executable file
After Width: | Height: | Size: 225 B |
BIN
gen/plone25/templates/rtf.png
Executable file
After Width: | Height: | Size: 225 B |
BIN
gen/plone25/templates/tool.gif
Executable file
After Width: | Height: | Size: 339 B |
11
gen/plone25/templates/workflows.py
Normal file
|
@ -0,0 +1,11 @@
|
|||
<!codeHeader!>
|
||||
from Products.CMFCore.WorkflowTool import addWorkflowFactory
|
||||
from Products.DCWorkflow.DCWorkflow import DCWorkflowDefinition
|
||||
from appy.gen.plone25.workflow import WorkflowCreator
|
||||
from Products.<!applicationName!>.config import PROJECTNAME
|
||||
from Products.ExternalMethod.ExternalMethod import ExternalMethod
|
||||
import logging
|
||||
logger = logging.getLogger('<!applicationName!>')
|
||||
from appy.gen.plone25.workflow import do
|
||||
|
||||
<!workflows!>
|