[gen] On Page instances, one may now define a method for conditionnally showing the 'edit' button on 'view' layout. [gen] An app may now, on its Config class, define a method getHomeObject that must return an object that will be the home object for a given (class of) user(s). This object's menu will appear when the user is consulting a page with no tied menu (like a search for example). [gen] More ZPT->PX work.
This commit is contained in:
parent
7fcd2f44d3
commit
2b5d286668
|
@ -37,9 +37,10 @@ def initMasterValue(v):
|
||||||
# (pages, groups,...) ----------------------------------------------------------
|
# (pages, groups,...) ----------------------------------------------------------
|
||||||
class Page:
|
class Page:
|
||||||
'''Used for describing a page, its related phase, show condition, etc.'''
|
'''Used for describing a page, its related phase, show condition, etc.'''
|
||||||
subElements = ('save', 'cancel', 'previous', 'next')
|
subElements = ('save', 'cancel', 'previous', 'next', 'edit')
|
||||||
def __init__(self, name, phase='main', show=True, showSave=True,
|
def __init__(self, name, phase='main', show=True, showSave=True,
|
||||||
showCancel=True, showPrevious=True, showNext=True):
|
showCancel=True, showPrevious=True, showNext=True,
|
||||||
|
showEdit=True):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.phase = phase
|
self.phase = phase
|
||||||
self.show = show
|
self.show = show
|
||||||
|
@ -53,6 +54,8 @@ class Page:
|
||||||
# When editing the page, and when a next page exists, must I show the
|
# When editing the page, and when a next page exists, must I show the
|
||||||
# "next" button?
|
# "next" button?
|
||||||
self.showNext = showNext
|
self.showNext = showNext
|
||||||
|
# When viewing the page, must I show the "edit" button?
|
||||||
|
self.showEdit = showEdit
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get(pageData):
|
def get(pageData):
|
||||||
|
@ -77,7 +80,7 @@ class Page:
|
||||||
or 'view' (page is available only in "view" mode).
|
or 'view' (page is available only in "view" mode).
|
||||||
|
|
||||||
If p_elem is not "page", this method returns the fact that a
|
If p_elem is not "page", this method returns the fact that a
|
||||||
sub-element is viewable or not (button "save", "cancel", etc).'''
|
sub-element is viewable or not (buttons "save", "cancel", etc).'''
|
||||||
# Define what attribute to test for "showability".
|
# Define what attribute to test for "showability".
|
||||||
showAttr = 'show'
|
showAttr = 'show'
|
||||||
if elem != 'page':
|
if elem != 'page':
|
||||||
|
|
|
@ -49,6 +49,11 @@ class ToolMixin(BaseMixin):
|
||||||
tool = self.appy()
|
tool = self.appy()
|
||||||
return tool.pxQuery({'self': tool})
|
return tool.pxQuery({'self': tool})
|
||||||
|
|
||||||
|
def search(self):
|
||||||
|
'''Returns the content of px ToolWrapper.pxSearch.'''
|
||||||
|
tool = self.appy()
|
||||||
|
return tool.pxSearch({'self': tool})
|
||||||
|
|
||||||
def getHomePage(self):
|
def getHomePage(self):
|
||||||
'''Return the home page when a user hits the app.'''
|
'''Return the home page when a user hits the app.'''
|
||||||
# If the app defines a method "getHomePage", call it.
|
# If the app defines a method "getHomePage", call it.
|
||||||
|
@ -64,6 +69,24 @@ class ToolMixin(BaseMixin):
|
||||||
url = self.goto(self.getApp().ui.home.absolute_url())
|
url = self.goto(self.getApp().ui.home.absolute_url())
|
||||||
return url
|
return url
|
||||||
|
|
||||||
|
def getHomeObject(self):
|
||||||
|
'''The concept of "home object" is the object where the user must "be",
|
||||||
|
even if he is "nowhere". For example, if the user is on a search
|
||||||
|
screen, there is no contextual object. In this case, if we have a
|
||||||
|
home object for him, we will use it as contextual object, and its
|
||||||
|
portlet menu will nevertheless appear: the user will not have the
|
||||||
|
feeling of being lost.'''
|
||||||
|
# If the app defines a method "getHomeObject", call it.
|
||||||
|
appyTool = self.appy()
|
||||||
|
try:
|
||||||
|
obj = appyTool.getHomeObject()
|
||||||
|
if obj: return obj.o
|
||||||
|
except AttributeError:
|
||||||
|
# For managers, the home object is the config. For others, there is
|
||||||
|
# no default home object.
|
||||||
|
user = self.getUser()
|
||||||
|
if user.has_role('Manager'): return self
|
||||||
|
|
||||||
def getCatalog(self):
|
def getCatalog(self):
|
||||||
'''Returns the catalog object.'''
|
'''Returns the catalog object.'''
|
||||||
return self.getParentNode().catalog
|
return self.getParentNode().catalog
|
||||||
|
@ -455,13 +478,9 @@ class ToolMixin(BaseMixin):
|
||||||
|
|
||||||
def getLayoutType(self):
|
def getLayoutType(self):
|
||||||
'''Guess the current layout type, according to actual URL.'''
|
'''Guess the current layout type, according to actual URL.'''
|
||||||
actualUrl = self.REQUEST['ACTUAL_URL']
|
url = self.REQUEST['ACTUAL_URL']
|
||||||
res = ''
|
if url.endswith('/view'): return 'view'
|
||||||
if actualUrl.endswith('/view'):
|
if url.endswith('/edit') or url.endswith('/do'): return 'edit'
|
||||||
res = 'view'
|
|
||||||
elif actualUrl.endswith('/edit') or actualUrl.endswith('/do'):
|
|
||||||
res = 'edit'
|
|
||||||
return res
|
|
||||||
|
|
||||||
def getPublishedObject(self, layoutType):
|
def getPublishedObject(self, layoutType):
|
||||||
'''Gets the currently published object, if its meta_class is among
|
'''Gets the currently published object, if its meta_class is among
|
||||||
|
|
|
@ -300,13 +300,13 @@
|
||||||
editable python: pageInfo['showOnEdit'] and contextObj.mayEdit()">
|
editable python: pageInfo['showOnEdit'] and contextObj.mayEdit()">
|
||||||
|
|
||||||
<tal:comment replace="nothing">Edit</tal:comment>
|
<tal:comment replace="nothing">Edit</tal:comment>
|
||||||
<input type="button" class="button" tal:condition="python: editable and not locked"
|
<input type="button" class="button" tal:condition="python: editable and not locked and pageInfo['showEdit']"
|
||||||
tal:attributes="style string: background-image: url($appUrl/ui/buttonEdit.png);
|
tal:attributes="style string: background-image: url($appUrl/ui/buttonEdit.png);
|
||||||
value python: _('object_edit');
|
value python: _('object_edit');
|
||||||
onclick python: 'window.location=\'%s\'' % contextObj.getUrl(mode='edit', page=page)">
|
onclick python: 'window.location=\'%s\'' % contextObj.getUrl(mode='edit', page=page)">
|
||||||
|
|
||||||
<tal:comment replace="nothing">Locked</tal:comment>
|
<tal:comment replace="nothing">Locked</tal:comment>
|
||||||
<a tal:condition="python: editable and locked">
|
<a tal:condition="python: editable and locked and pageInfo['showEdit']">
|
||||||
<img style="cursor: help"
|
<img style="cursor: help"
|
||||||
tal:define="lockDate python: tool.formatDate(locked[1]);
|
tal:define="lockDate python: tool.formatDate(locked[1]);
|
||||||
lockMsg python: _('page_locked', mapping={'user':tool.getUserName(locked[0]), 'date': lockDate})"
|
lockMsg python: _('page_locked', mapping={'user':tool.getUserName(locked[0]), 'date': lockDate})"
|
||||||
|
|
|
@ -134,7 +134,7 @@
|
||||||
</tal:comment>
|
</tal:comment>
|
||||||
<table metal:define-macro="phases" class="portletContent"
|
<table metal:define-macro="phases" class="portletContent"
|
||||||
tal:define="singlePhase python: phases and (len(phases) == 1);
|
tal:define="singlePhase python: phases and (len(phases) == 1);
|
||||||
page python: req.get('page', 'main');
|
page python: req.get('page', '');
|
||||||
mayEdit contextObj/mayEdit">
|
mayEdit contextObj/mayEdit">
|
||||||
<tal:phase repeat="phase phases">
|
<tal:phase repeat="phase phases">
|
||||||
<tal:comment replace="nothing">The box containing phase-related information</tal:comment>
|
<tal:comment replace="nothing">The box containing phase-related information</tal:comment>
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
resp req/RESPONSE;
|
resp req/RESPONSE;
|
||||||
lang tool/getUserLanguage;
|
lang tool/getUserLanguage;
|
||||||
layoutType tool/getLayoutType;
|
layoutType tool/getLayoutType;
|
||||||
contextObj python: tool.getPublishedObject(layoutType);
|
contextObj python: tool.getPublishedObject(layoutType) or tool.getHomeObject();
|
||||||
|
showPortlet python: tool.showPortlet(context, layoutType);
|
||||||
dir python: tool.getLanguageDirection(lang);
|
dir python: tool.getLanguageDirection(lang);
|
||||||
discreetLogin python: tool.getAttr('discreetLogin', source='config');
|
discreetLogin python: tool.getAttr('discreetLogin', source='config');
|
||||||
dleft python: (dir == 'ltr') and 'left' or 'right';
|
dleft python: (dir == 'ltr') and 'left' or 'right';
|
||||||
|
@ -185,7 +186,7 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tal:comment replace="nothing">The navigation strip</tal:comment>
|
<tal:comment replace="nothing">The navigation strip</tal:comment>
|
||||||
<tr tal:condition="python: contextObj and (layoutType == 'view')">
|
<tr tal:condition="python: contextObj and showPortlet and (layoutType != 'edit')">
|
||||||
<td><metal:navigate use-macro="app/ui/navigate/macros/navigationStrip"/></td>
|
<td><metal:navigate use-macro="app/ui/navigate/macros/navigationStrip"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -193,7 +194,7 @@
|
||||||
<table width="100%" cellpadding="0" cellspacing="0">
|
<table width="100%" cellpadding="0" cellspacing="0">
|
||||||
<tr valign="top">
|
<tr valign="top">
|
||||||
<tal:comment replace="nothing">Portlet</tal:comment>
|
<tal:comment replace="nothing">Portlet</tal:comment>
|
||||||
<td tal:condition="python: tool.showPortlet(context, layoutType)" class="portlet">
|
<td tal:condition="showPortlet" class="portlet">
|
||||||
<metal:portlet use-macro="app/ui/portlet/macros/portlet"/>
|
<metal:portlet use-macro="app/ui/portlet/macros/portlet"/>
|
||||||
</td>
|
</td>
|
||||||
<tal:comment replace="nothing">Page content</tal:comment>
|
<tal:comment replace="nothing">Page content</tal:comment>
|
||||||
|
|
|
@ -212,6 +212,162 @@ class ToolWrapper(AbstractWrapper):
|
||||||
<x>:self.pxPagePrologue</x><x>:self.pxQueryResult</x>
|
<x>:self.pxPagePrologue</x><x>:self.pxQueryResult</x>
|
||||||
</x>''', template=AbstractWrapper.pxTemplate, hook='content')
|
</x>''', template=AbstractWrapper.pxTemplate, hook='content')
|
||||||
|
|
||||||
|
pxSearch = Px('''
|
||||||
|
<x var="className=req['className'];
|
||||||
|
refInfo=req.get('ref', None);
|
||||||
|
searchInfo=ztool.getSearchInfo(className, refInfo);
|
||||||
|
cssJs={};
|
||||||
|
x=ztool.getCssJs(searchInfo['fields'], 'edit', cssJs)">
|
||||||
|
|
||||||
|
<!-- Include type-specific CSS and JS. -->
|
||||||
|
<link for="cssFile in cssJs['css']" rel="stylesheet" type="text/css"
|
||||||
|
href=":'%s/ui/%s' % (appUrl, cssFile)"/>
|
||||||
|
<script for="jsFile in cssJs['js']" type="text/javascript"
|
||||||
|
src=":'%s/ui/%s' % (appUrl, jsFile)"></script>
|
||||||
|
|
||||||
|
<!-- Search title -->
|
||||||
|
<h1><x>:_('%s_plural'%className)</x> –
|
||||||
|
<x>:_('search_title')</x></h1>
|
||||||
|
<br/>
|
||||||
|
<!-- Form for searching objects of request/className. -->
|
||||||
|
<form name="search" action=":ztool.absolute_url()+'/do'" method="post">
|
||||||
|
<input type="hidden" name="action" value="SearchObjects"/>
|
||||||
|
<input type="hidden" name="className" value=":className"/>
|
||||||
|
<input if="refInfo" type="hidden" name="ref" value=":refInfo"/>
|
||||||
|
|
||||||
|
<table width="100%">
|
||||||
|
<tr for="searchRow in ztool.getGroupedSearchFields(searchInfo)"
|
||||||
|
valign="top">
|
||||||
|
<x for="widget in searchRow">
|
||||||
|
<td var="scolspan=widget and widget['scolspan'] or 1"
|
||||||
|
colspan=":scolspan"
|
||||||
|
width=":'%d%%' % ((100/searchInfo['nbOfColumns'])*scolspan)">
|
||||||
|
<x if="widget">
|
||||||
|
<x var="name=widget['name'];
|
||||||
|
widgetName='w_%s' % name;
|
||||||
|
macroPage=widget['type'].lower()">
|
||||||
|
<!--metal:call use-macro="python: getattr(appFolder.ui.widgets, macroPage).macros['search']"/-->
|
||||||
|
</x>
|
||||||
|
</x><br class="discreet"/>
|
||||||
|
</td>
|
||||||
|
</x>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- Submit button -->
|
||||||
|
<p align=":dright"><br/>
|
||||||
|
<input type="submit" class="button" value=":_('search_button')"
|
||||||
|
style=":'background-image: url(%s/ui/buttonSearch.png)'%appUrl"/>
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
|
</x>
|
||||||
|
''', template=AbstractWrapper.pxTemplate, hook='content')
|
||||||
|
|
||||||
|
pxImport = Px('''
|
||||||
|
<x var="className=req['className'];
|
||||||
|
importElems=ztool.getImportElements(className);
|
||||||
|
allAreImported=True">
|
||||||
|
<x>:self.pxPagePrologue</x>
|
||||||
|
<script type="text/javascript"><![CDATA[
|
||||||
|
var importedElemsShown = false;
|
||||||
|
function toggleViewableElements() {
|
||||||
|
var rows = document.getElementsByName('importedElem');
|
||||||
|
var newDisplay = 'table-row';
|
||||||
|
if (isIe) newDisplay = 'block';
|
||||||
|
if (importedElemsShown) newDisplay = 'none';
|
||||||
|
for (var i=0; i<rows.length; i++) {
|
||||||
|
rows[i].style.display = newDisplay;
|
||||||
|
}
|
||||||
|
importedElemsShown = !importedElemsShown;
|
||||||
|
}
|
||||||
|
var checkBoxesChecked = true;
|
||||||
|
function toggleCheckboxes() {
|
||||||
|
var checkBoxes = document.getElementsByName('cbElem');
|
||||||
|
var newCheckValue = true;
|
||||||
|
if (checkBoxesChecked) newCheckValue = false;
|
||||||
|
for (var i=0; i<checkBoxes.length; i++) {
|
||||||
|
checkBoxes[i].checked = newCheckValue;
|
||||||
|
}
|
||||||
|
checkBoxesChecked = newCheckValue;
|
||||||
|
}
|
||||||
|
function importSingleElement(importPath) {
|
||||||
|
var f = document.forms['importElements'];
|
||||||
|
f.importPath.value = importPath;
|
||||||
|
f.submit();
|
||||||
|
}
|
||||||
|
function importManyElements() {
|
||||||
|
var f = document.forms['importElements'];
|
||||||
|
var importPaths = '';
|
||||||
|
// Get the values of the checkboxes
|
||||||
|
var checkBoxes = document.getElementsByName('cbElem');
|
||||||
|
for (var i=0; i<checkBoxes.length; i++) {
|
||||||
|
if (checkBoxes[i].checked) {
|
||||||
|
importPaths += checkBoxes[i].value + '|';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (! importPaths) alert(no_elem_selected);
|
||||||
|
else {
|
||||||
|
f.importPath.value = importPaths;
|
||||||
|
f.submit();
|
||||||
|
}
|
||||||
|
}]]>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- Form for importing several elements at once. -->
|
||||||
|
<form name="importElements"
|
||||||
|
action=":ztool.absolute_url()+'/do'" method="post">
|
||||||
|
<input type="hidden" name="action" value="ImportObjects"/>
|
||||||
|
<input type="hidden" name="className" value=":className"/>
|
||||||
|
<input type="hidden" name="importPath" value=""/>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<h1>:_('import_title')"></h1><br/>
|
||||||
|
<table class="list" width="100%">
|
||||||
|
<tr>
|
||||||
|
<th for="columnHeader in importElems[0]">
|
||||||
|
<img if="loop.columnHeader.nb == 0" src=":'%s/ui/eye.png' % appUrl"
|
||||||
|
title="_('import_show_hide')" style="cursor:pointer"
|
||||||
|
onClick="toggleViewableElements()" align=":dleft" />
|
||||||
|
<x>:columnHeader</x>
|
||||||
|
</th>
|
||||||
|
<th></th>
|
||||||
|
<th width="20px"><img src=":'%s/ui/select_elems.png' % $appUrl"
|
||||||
|
title=":_('select_delesect')" onClick="toggleCheckboxes()"
|
||||||
|
style="cursor:pointer"/></th>
|
||||||
|
</tr>
|
||||||
|
<x for="row in importElems[1]">
|
||||||
|
<tr var="alreadyImported=ztool.isAlreadyImported(className, row[0]);
|
||||||
|
allAreImported=allAreImported and alreadyImported;
|
||||||
|
odd=loop.row.odd"
|
||||||
|
id=":alreadyImported and 'importedElem' or 'notImportedElem'"
|
||||||
|
name=":alreadyImported and 'importedElem' or 'notImportedElem'"
|
||||||
|
style=":alreadyImported and 'display:none' or 'display:table-row'"
|
||||||
|
class=":odd and 'even' or 'odd'">
|
||||||
|
<td for="elem in row[1:]">:elem</td>
|
||||||
|
<td>
|
||||||
|
<input type="button" if="not alreadyImported"
|
||||||
|
onClick=":'importSingleElement("%s")' % row[0]"
|
||||||
|
value=":_('query_import')"/>
|
||||||
|
<x if="alreadyImported">:_('import_already')</x>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<input if="not alreadyImported" type="checkbox" checked="checked"
|
||||||
|
id="cbElem" name="cbElem" value="row[0]" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</x>
|
||||||
|
<tr if="not importElems[1] or allAreImported">
|
||||||
|
<td colspan="15">:_('query_no_result')</td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- Button for importing several elements at once. -->
|
||||||
|
<p align=":dright"><br/>
|
||||||
|
<input if="importElems[1] and not allAreImported"
|
||||||
|
type="button" onClick="importManyElements()"
|
||||||
|
value=":_('import_many')"/>
|
||||||
|
</p>
|
||||||
|
</x>''', template=AbstractWrapper.pxTemplate, hook='content')
|
||||||
|
|
||||||
def validPythonWithUno(self, value):
|
def validPythonWithUno(self, value):
|
||||||
'''This method represents the validator for field unoEnabledPython.'''
|
'''This method represents the validator for field unoEnabledPython.'''
|
||||||
if value:
|
if value:
|
||||||
|
|
|
@ -244,7 +244,7 @@ class AbstractWrapper(object):
|
||||||
<x if="contextObj and phases and contextObj.mayNavigate()">
|
<x if="contextObj and phases and contextObj.mayNavigate()">
|
||||||
<table class="portletContent"
|
<table class="portletContent"
|
||||||
var="singlePhase=phases and (len(phases) == 1);
|
var="singlePhase=phases and (len(phases) == 1);
|
||||||
page=req.get('page', 'main');
|
page=req.get('page', '');
|
||||||
mayEdit=contextObj.mayEdit()">
|
mayEdit=contextObj.mayEdit()">
|
||||||
<x for="phase in phases">:phase['px']</x>
|
<x for="phase in phases">:phase['px']</x>
|
||||||
</table>
|
</table>
|
||||||
|
@ -334,6 +334,7 @@ class AbstractWrapper(object):
|
||||||
</x>
|
</x>
|
||||||
</x>''')
|
</x>''')
|
||||||
|
|
||||||
|
# The message that is shown when a user triggers an action.
|
||||||
pxMessage = Px('''
|
pxMessage = Px('''
|
||||||
<x var="messages=ztool.consumeMessages()" if="messages">
|
<x var="messages=ztool.consumeMessages()" if="messages">
|
||||||
<div class="message">
|
<div class="message">
|
||||||
|
@ -346,6 +347,7 @@ class AbstractWrapper(object):
|
||||||
</div>
|
</div>
|
||||||
</x>''')
|
</x>''')
|
||||||
|
|
||||||
|
# The page footer.
|
||||||
pxFooter = Px('''
|
pxFooter = Px('''
|
||||||
<table cellpadding="0" cellspacing="0" width="100%" class="footer">
|
<table cellpadding="0" cellspacing="0" width="100%" class="footer">
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -353,6 +355,15 @@ class AbstractWrapper(object):
|
||||||
<a href="http://appyframework.org" target="_blank">Appy</a></td></tr>
|
<a href="http://appyframework.org" target="_blank">Appy</a></td></tr>
|
||||||
</table>''')
|
</table>''')
|
||||||
|
|
||||||
|
# Hook for defining a PX that proposes additional links, after the links
|
||||||
|
# corresponding to top-level pages.
|
||||||
|
pxLinks = ''
|
||||||
|
|
||||||
|
# Hook for defining a PX that proposes additional icons after standard
|
||||||
|
# icons in the user strip.
|
||||||
|
pxIcons = ''
|
||||||
|
|
||||||
|
# The template PX for all pages.
|
||||||
pxTemplate = Px('''
|
pxTemplate = Px('''
|
||||||
<html var="tool=self.tool; ztool=tool.o; user=tool.user;
|
<html var="tool=self.tool; ztool=tool.o; user=tool.user;
|
||||||
isAnon=ztool.userIsAnon(); app=ztool.getApp();
|
isAnon=ztool.userIsAnon(); app=ztool.getApp();
|
||||||
|
@ -361,7 +372,9 @@ class AbstractWrapper(object):
|
||||||
req=ztool.REQUEST; resp=req.RESPONSE;
|
req=ztool.REQUEST; resp=req.RESPONSE;
|
||||||
lang=ztool.getUserLanguage();
|
lang=ztool.getUserLanguage();
|
||||||
layoutType=ztool.getLayoutType();
|
layoutType=ztool.getLayoutType();
|
||||||
contextObj=ztool.getPublishedObject(layoutType);
|
contextObj=ztool.getPublishedObject(layoutType) or \
|
||||||
|
ztool.getHomeObject();
|
||||||
|
showPortlet=ztool.showPortlet(contextObj, layoutType);
|
||||||
dir=ztool.getLanguageDirection(lang);
|
dir=ztool.getLanguageDirection(lang);
|
||||||
discreetLogin=ztool.getAttr('discreetLogin', source='config');
|
discreetLogin=ztool.getAttr('discreetLogin', source='config');
|
||||||
dleft=(dir == 'ltr') and 'left' or 'right';
|
dleft=(dir == 'ltr') and 'left' or 'right';
|
||||||
|
@ -439,8 +452,9 @@ class AbstractWrapper(object):
|
||||||
<a class="pageLink" href=":appUrl" title=": _('app_home')">
|
<a class="pageLink" href=":appUrl" title=": _('app_home')">
|
||||||
<img src=":'%s/ui/home.gif' % appUrl" style="margin-right: 3px"/>
|
<img src=":'%s/ui/home.gif' % appUrl" style="margin-right: 3px"/>
|
||||||
</a>
|
</a>
|
||||||
<!-- Additional links (or icons) from icons.pt -->
|
|
||||||
<!--metal:call use-macro="app/ui/icons/macros/links"/-->
|
<!-- Additional links -->
|
||||||
|
<x>:self.pxLinks</x>
|
||||||
|
|
||||||
<!-- Top-level pages -->
|
<!-- Top-level pages -->
|
||||||
<a for="page in tool.pages" class="pageLink"
|
<a for="page in tool.pages" class="pageLink"
|
||||||
|
@ -513,8 +527,8 @@ class AbstractWrapper(object):
|
||||||
<a if="user.has_role('Manager')" href=":tool.url"
|
<a if="user.has_role('Manager')" href=":tool.url"
|
||||||
title=":_('%sTool' % appName)">
|
title=":_('%sTool' % appName)">
|
||||||
<img src=":'%s/ui/appyConfig.gif' % appUrl"/></a>
|
<img src=":'%s/ui/appyConfig.gif' % appUrl"/></a>
|
||||||
<!-- Additional icons from icons.pt -->
|
<!-- Additional icons -->
|
||||||
<!--metal:call use-macro="app/ui/icons/macros/icons"/-->
|
<x>:self.pxIcons</x>
|
||||||
<!-- Log out -->
|
<!-- Log out -->
|
||||||
<a href=":tool.url + '/performLogout'" title=":_('app_logout')">
|
<a href=":tool.url + '/performLogout'" title=":_('app_logout')">
|
||||||
<img src=":'%s/ui/logout.gif' % appUrl"/></a>
|
<img src=":'%s/ui/logout.gif' % appUrl"/></a>
|
||||||
|
@ -534,7 +548,7 @@ class AbstractWrapper(object):
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<!-- The navigation strip -->
|
<!-- The navigation strip -->
|
||||||
<tr if="contextObj and (layoutType == 'view')">
|
<tr if="contextObj and showPortlet and (layoutType != 'edit')">
|
||||||
<td>:self.pxNavigationStrip</td>
|
<td>:self.pxNavigationStrip</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -542,8 +556,7 @@ class AbstractWrapper(object):
|
||||||
<table width="100%" cellpadding="0" cellspacing="0">
|
<table width="100%" cellpadding="0" cellspacing="0">
|
||||||
<tr valign="top">
|
<tr valign="top">
|
||||||
<!-- The portlet -->
|
<!-- The portlet -->
|
||||||
<td if="ztool.showPortlet(contextObj, layoutType)"
|
<td if="showPortlet" class="portlet">:self.pxPortlet</td>
|
||||||
class="portlet">:self.pxPortlet</td>
|
|
||||||
<!-- Page content -->
|
<!-- Page content -->
|
||||||
<td class="content">:content</td>
|
<td class="content">:content</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
Loading…
Reference in a new issue