[gen] Fixed groups with style 'tabs'; reused the same tabs for representing phases; pages and phases are now outside the portlet, rendered horizontally below the breadcrumb; methods getSupBreadCrumb and getSubBreadCrumb can now be defined on every gen-class to customize what is shown above and below the breadcrumb (=title with a prefix) on view layouts (those methods are similar to getSubTitle and getSupTitle when displaying lists of objects).

This commit is contained in:
Gaetan Delannay 2014-04-29 19:02:06 +02:00
parent cee7b49e3c
commit 7adbc7e4bc
15 changed files with 143 additions and 75 deletions

View file

@ -257,17 +257,16 @@ class UiGroup:
<table width=":field.wide" class=":groupCss" id=":tagId" name=":tagName"> <table width=":field.wide" class=":groupCss" id=":tagId" name=":tagName">
<!-- First row: the tabs. --> <!-- First row: the tabs. -->
<tr valign="middle"><td style="border-bottom: 1px solid #ff8040"> <tr valign="middle"><td style="border-bottom: 1px solid #ff8040">
<table style="position:relative; bottom:-2px" <table class="tabs" cellpadding="0" cellspacing="0">
cellpadding="0" cellspacing="0"> <tr valign="middle">
<tr valign="bottom">
<x for="row in field.elements" <x for="row in field.elements"
var2="rowNb=loop.row.nb; var2="nb = loop.row.nb + 1;
tabId='tab_%s_%d_%d' % (field.name, rowNb, lenFields)"> suffix='%s_%d_%d' % (field.name, nb, lenFields);
tabId='tab_%s' % suffix">
<td><img src=":url('tabLeft')" id=":'%s_left' % tabId"/></td> <td><img src=":url('tabLeft')" id=":'%s_left' % tabId"/></td>
<td style=":url('tabBg', bg=True)" id=":tabId"> <td style=":url('tabBg', bg=True)" class="tab" id=":tabId">
<a onclick=":'showTab(%s)' % q('%s_%d_%d' % (field.name, rowNb, \ <a onclick=":'showTab(%s)' % q(suffix)"
lenFields))" class="clickable">:_('%s_col%d' % (field.labelId, nb))</a>
class="clickable">:_('%s_col%d' % (field.labelId, rowNb))</a>
</td> </td>
<td><img id=":'%s_right' % tabId" src=":url('tabRight')"/></td> <td><img id=":'%s_right' % tabId" src=":url('tabRight')"/></td>
</x> </x>
@ -277,8 +276,9 @@ class UiGroup:
<!-- Other rows: the fields --> <!-- Other rows: the fields -->
<tr for="row in field.elements" <tr for="row in field.elements"
id=":'tabcontent_%s_%d_%d' % (field.name, loop.row.nb, lenFields)" var2="nb=loop.row.nb + 1"
style=":loop.row.nb==0 and 'display:table-row' or 'display:none')"> id=":'tabcontent_%s_%d_%d' % (field.name, nb, lenFields)"
style=":(nb == 1) and 'display:table-row' or 'display:none'">
<td var="field=row[0]"> <td var="field=row[0]">
<x if="field.type == 'group'">:field.pxView</x> <x if="field.type == 'group'">:field.pxView</x>
<x if="field.type != 'group'">:field.pxRender</x> <x if="field.type != 'group'">:field.pxRender</x>
@ -286,7 +286,7 @@ class UiGroup:
</tr> </tr>
</table> </table>
<script type="text/javascript">:'initTab(%s,%s)' % \ <script type="text/javascript">:'initTab(%s,%s)' % \
(q('tab_%s' % field.name), q('%s_1_%d' % (field.name, lenFields)))"> (q('tab_%s' % field.name), q('%s_1_%d' % (field.name, lenFields)))
</script> </script>
</x> </x>
</x>''') </x>''')

View file

@ -23,19 +23,16 @@ class Phase:
'''A group of pages.''' '''A group of pages.'''
pxView = Px(''' pxView = Px('''
<tr var="singlePage=len(phase.pages) == 1"> <table class="phase"
<td var="label='%s_phase_%s' % (zobj.meta_type, phase.name)"> var="singlePage=len(phase.pages) == 1;
label='%s_phase_%s' % (zobj.meta_type, phase.name)">
<!-- The title of the phase --> <tr valign="top">
<div class="portletGroup"
if="not singlePhase and not singlePage">::_(label)</div>
<!-- The page(s) within the phase --> <!-- The page(s) within the phase -->
<x for="aPage in phase.pages" var2="aPageInfo=phase.pagesInfo[aPage]"> <td for="aPage in phase.pages"
var2="aPageInfo=phase.pagesInfo[aPage]"
class=":(aPage == page) and 'currentPage' or ''">
<!-- First line: page name and icons --> <!-- First line: page name and icons -->
<div if="not (singlePhase and singlePage)" <span if="not (singlePhase and singlePage)">
class=":aPage==page and 'portletCurrent portletPage' or \
'portletPage'">
<a href=":zobj.getUrl(page=aPage)">::aPageInfo.page.getLabel(zobj)</a> <a href=":zobj.getUrl(page=aPage)">::aPageInfo.page.getLabel(zobj)</a>
<x var="locked=zobj.isLocked(user, aPage); <x var="locked=zobj.isLocked(user, aPage);
editable=mayEdit and aPageInfo.showOnEdit and \ editable=mayEdit and aPageInfo.showOnEdit and \
@ -52,17 +49,60 @@ class Phase:
src=":url('locked')" title=":lockMsg"/></a> src=":url('locked')" title=":lockMsg"/></a>
<a if="editable and locked and user.has_role('Manager')"> <a if="editable and locked and user.has_role('Manager')">
<img class="clickable" title=":_('page_unlock')" src=":url('unlock')" <img class="clickable" title=":_('page_unlock')" src=":url('unlock')"
onclick=":'onUnlockPage(%s,%s)' % \ onclick=":'onUnlockPage(%s,%s)' % (q(zobj.id), q(aPage))"/></a>
(q(zobj.UID()), q(aPage))"/></a>
</x> </x>
</div> </span>
<!-- Next lines: links --> <!-- Next lines: links -->
<x var="links=aPageInfo.links" if="links"> <x var="links=aPageInfo.links" if="links">
<div for="link in links"><a href=":link.url">:link.title</a></div> <div for="link in links" class="refLink">
</x> <a href=":link.url">:link.title</a></div>
</x> </x>
</td> </td>
</tr>''') </tr>
</table>''')
# "Static" PX that displays all phases of a given object.
pxAllPhases = Px('''
<x var="singlePhase=len(phases)==1;
page=req.get('page', '');
uid=zobj.id;
mayEdit=zobj.mayEdit()">
<x if="singlePhase" var2="phase=phases[0]">:phase.pxView</x>
<!-- Display several phases in tabs. -->
<x if="not singlePhase">
<table cellpadding="0" cellspacing="0">
<!-- First row: the tabs. -->
<tr><td style="border-bottom: 1px solid #ff8040; padding-bottom: 1px">
<table cellpadding="0" cellspacing="0" class="tabs">
<tr valign="middle">
<x for="phase in phases"
var2="nb=loop.phase.nb + 1;
suffix='%s_%d_%d' % (uid, nb, len(phases));
tabId='tab_%s' % suffix">
<td><img src=":url('tabLeft')" id=":'%s_left' % tabId"/></td>
<td style=":url('tabBg',bg=True)" id=":tabId" class="tab">
<a onclick=":'showTab(%s)' % q(suffix)"
class="clickable">:_('%s_phase_%s' % (zobj.meta_type, \
phase.name))</a>
</td>
<td><img id=":'%s_right' % tabId" src=":url('tabRight')"/></td>
</x>
</tr>
</table>
</td></tr>
<!-- Other rows: the fields -->
<tr for="phase in phases"
var2="nb=loop.phase.nb + 1"
id=":'tabcontent_%s_%d_%d' % (uid, nb, len(phases))"
style=":(nb == 1) and 'display:table-row' or 'display:none'">
<td>:phase.pxView</td>
</tr>
</table>
<script type="text/javascript">:'initTab(%s,%s)' % \
(q('tab_%s' % uid), q('%s_1_%d' % (uid, len(phases))))
</script>
</x>
</x>''')
def __init__(self, name, obj): def __init__(self, name, obj):
self.name = name self.name = name

View file

@ -148,7 +148,7 @@ class UiSearch:
<div class="portletSearch"> <div class="portletSearch">
<a href=":'%s?className=%s&amp;search=%s' % \ <a href=":'%s?className=%s&amp;search=%s' % \
(queryUrl, className, search.name)" (queryUrl, className, search.name)"
class=":search.name == currentSearch and 'portletCurrent' or ''" class=":(search.name == currentSearch) and 'current' or ''"
title=":search.translatedDescr">:search.translated</a> title=":search.translatedDescr">:search.translated</a>
</div>''') </div>''')

View file

@ -749,6 +749,14 @@ class ToolMixin(BaseMixin):
# advanced search. # advanced search.
return klass.searchAdvanced.isShowable(klass, self.appy()) return klass.searchAdvanced.isShowable(klass, self.appy())
def portletBottom(self, klass):
'''Is there a custom zone to display at the bottom of the portlet zone
for p_klass?'''
if not hasattr(klass, 'getPortletBottom'): return ''
res = klass.getPortletBottom(self.appy())
if not res: return ''
return res
def getQueryUrl(self, contentType, searchName, startNumber=None): def getQueryUrl(self, contentType, searchName, startNumber=None):
'''This method creates the URL that allows to perform a (non-Ajax) '''This method creates the URL that allows to perform a (non-Ajax)
request for getting queried objects from a search named p_searchName request for getting queried objects from a search named p_searchName

View file

@ -896,14 +896,28 @@ class BaseMixin:
def getSupTitle(self, navInfo=''): def getSupTitle(self, navInfo=''):
'''Gets the html code (icons,...) that can be shown besides the title '''Gets the html code (icons,...) that can be shown besides the title
of an object.''' of an object.'''
appyObj = self.appy() obj = self.appy()
if hasattr(appyObj, 'getSupTitle'): return appyObj.getSupTitle(navInfo) if hasattr(obj, 'getSupTitle'): return obj.getSupTitle(navInfo)
return '' return ''
def getSubTitle(self): def getSubTitle(self):
'''Gets the content that must appear below the title of an object.''' '''Gets the content that must appear below the title of an object.'''
appyObj = self.appy() obj = self.appy()
if hasattr(appyObj, 'getSubTitle'): return appyObj.getSubTitle() if hasattr(obj, 'getSubTitle'): return obj.getSubTitle()
return ''
def getSupBreadCrumb(self):
'''Gets the html code that can be shown besides the title of an object
in the breadcrumb.'''
obj = self.appy()
if hasattr(obj, 'getSupBreadCrumb'): return obj.getSupBreadCrumb()
return ''
def getSubBreadCrumb(self):
'''Gets the content that must appear below the title of an object in the
breadcrumb.'''
obj = self.appy()
if hasattr(obj, 'getSubBreadCrumb'): return obj.getSubBreadCrumb()
return '' return ''
# Workflow methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Workflow methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View file

@ -257,8 +257,8 @@ class Tool(ModelClass):
users = gen.Ref(User, multiplicity=(0,None), add=True, link=False, users = gen.Ref(User, multiplicity=(0,None), add=True, link=False,
back=gen.Ref(attribute='toTool', show=False), page=userPage, back=gen.Ref(attribute='toTool', show=False), page=userPage,
queryable=True, queryFields=('title', 'login'), queryable=True, queryFields=('title', 'login'),
show=isManager, show=isManager, showHeaders=True,
showHeaders=True, shownInfo=('title', 'login', 'roles')) shownInfo=('title', 'login*120px', 'roles*120px'))
def computeConnectedUsers(self): pass def computeConnectedUsers(self): pass
connectedUsers = gen.Computed(method=computeConnectedUsers, page=userPage, connectedUsers = gen.Computed(method=computeConnectedUsers, page=userPage,
plainText=False, show=isManager) plainText=False, show=isManager)
@ -266,7 +266,8 @@ class Tool(ModelClass):
back=gen.Ref(attribute='toTool2', show=False), back=gen.Ref(attribute='toTool2', show=False),
page=gen.Page('groups', show=isManager), show=isManager, page=gen.Page('groups', show=isManager), show=isManager,
queryable=True, queryFields=('title', 'login'), queryable=True, queryFields=('title', 'login'),
showHeaders=True, shownInfo=('title', 'login', 'roles')) showHeaders=True,
shownInfo=('title', 'login*120px', 'roles*120px'))
pt = gen.Page('translations', show=isManager) pt = gen.Page('translations', show=isManager)
translations = gen.Ref(Translation, multiplicity=(0,None), add=False, translations = gen.Ref(Translation, multiplicity=(0,None), add=False,
link=False, show='view', page=pt, link=False, show='view', page=pt,

View file

@ -52,6 +52,7 @@ img { border: 0; vertical-align: middle }
.xhtml img { margin-right: 5px } .xhtml img { margin-right: 5px }
.xhtml p { margin: 3px 0 7px 0 } .xhtml p { margin: 3px 0 7px 0 }
.clickable { cursor: pointer } .clickable { cursor: pointer }
.refLink { font-style: italic; padding-left: 5px; font-size: 90%; color: grey }
.main { width: 900px; height: 95%; box-shadow: 3px 3px 3px #A9A9A9; .main { width: 900px; height: 95%; box-shadow: 3px 3px 3px #A9A9A9;
border-style: solid; border-width: 1px; border-color: grey} border-style: solid; border-width: 1px; border-color: grey}
.top { height: 89px; margin-left: 3em; vertical-align: top; .top { height: 89px; margin-left: 3em; vertical-align: top;
@ -62,9 +63,7 @@ img { border: 0; vertical-align: middle }
.userStripText { padding: 0 0.3em 0 0.3em; color: white } .userStripText { padding: 0 0.3em 0 0.3em; color: white }
.userStrip a { color: #e7e7e7 } .userStrip a { color: #e7e7e7 }
.userStrip a:visited { color: #e7e7e7 } .userStrip a:visited { color: #e7e7e7 }
.navigate { border-bottom: 1px solid #5F7983; height: 100%; .breadcrumb { font-size: 11pt }
background-color: #dbdde1; font-weight: bold }
.navigate td { padding: 4px 9px }
.login { margin: 3px; color: black } .login { margin: 3px; color: black }
input.button { color: #666666; height: 20px; width: 130px; input.button { color: #666666; height: 20px; width: 130px;
cursor:pointer; font-size: 90%; padding: 1px 0 0 10px; cursor:pointer; font-size: 90%; padding: 1px 0 0 10px;
@ -84,26 +83,25 @@ input.buttonSmall { width: 100px !important; font-size: 85%; height: 18px;
.focus td { padding: 4px 0px 4px 4px } .focus td { padding: 4px 0px 4px 4px }
.discreet { font-size: 90%; color: grey } .discreet { font-size: 90%; color: grey }
.title { color: #BA9440 } .title { color: #BA9440 }
.breadcrumb { color: #BA9440; font-size: 13px }
.lostPassword { font-size: 90%; color: white; padding-left: 1em } .lostPassword { font-size: 90%; color: white; padding-left: 1em }
.current { font-weight: bold }
.portlet { width: 150px; border-right: 1px solid #5F7983; .portlet { width: 150px; border-right: 1px solid #5F7983;
background-color: #ededed } background-color: #ededed }
.portletContent { margin: 4px 9px } .portletContent { margin: 4px 9px }
.portletTitle { font-size: 110%; margin-bottom: 4px } .portletTitle { font-size: 110%; margin-bottom: 4px }
.portletCurrent { font-weight: bold; color: grey }
.portletSep { border-top: 1px solid #5F7983; margin-top: 2px } .portletSep { border-top: 1px solid #5F7983; margin-top: 2px }
.portletPage { font-style: italic }
.portletGroup { font-variant: small-caps; font-weight: bold; font-size: 110%; .portletGroup { font-variant: small-caps; font-weight: bold; font-size: 110%;
margin: 0.1em 0 0.3em ; border-bottom: 1px dashed grey } margin: 0.1em 0 0.3em ; border-bottom: 1px dashed grey }
.portletSearch { font-size: 90%; font-style: italic } .portletSearch { font-size: 90%; font-style: italic }
.inputSearch { height: 15px; width: 132px; margin: 3px 3px 2px 3px !important } .inputSearch { height: 15px; width: 132px; margin: 3px 3px 2px 3px !important }
td.search { padding-top: 8px } td.search { padding-top: 8px }
.content { padding: 14px 14px 9px 15px; background-color: #f1f1f1 } .content { padding: 9px; background-color: #f1f1f1 }
.popup { display: none; position: absolute; top: 30%; left: 35%; .popup { display: none; position: absolute; top: 30%; left: 35%;
width: 350px; z-index : 100; background: white; padding: 8px; width: 350px; z-index : 100; background: white; padding: 8px;
border: 1px solid grey; box-shadow: 2px 2px 2px #888888} border: 1px solid grey; box-shadow: 2px 2px 2px #888888}
.dropdown { display:none; position: absolute; border: 1px solid #cccccc; .dropdown { display:none; position: absolute; border: 1px solid #cccccc;
background-color: white; padding: 3px 4px 0 } background-color: white; padding: 3px 4px 0; font-size: 8pt;
font-weight: normal }
.dropdownMenu { cursor: pointer; padding-right: 4px; font-size: 93% } .dropdownMenu { cursor: pointer; padding-right: 4px; font-size: 93% }
.dropdown a:hover { text-decoration: underline } .dropdown a:hover { text-decoration: underline }
.list { margin-bottom: 3px } .list { margin-bottom: 3px }
@ -130,18 +128,20 @@ td.search { padding-top: 8px }
color: white } color: white }
.even { background-color: #f9f9f9 } .even { background-color: #f9f9f9 }
.odd { background-color: #f4f4f4 } .odd { background-color: #f4f4f4 }
.summary { margin-bottom: 5px; background-color: #f9f9f9; .summary { margin-bottom: 5px; background-color: #f9f9f9 }
border-bottom: 1px dashed #cccccc; border-top: 1px dashed #cccccc; }
.objectTitle { font-size: 11pt; border-bottom: 3px solid grey;
font-weight: bold }
.by { padding: 5px; color: grey; font-size: 97% } .by { padding: 5px; color: grey; font-size: 97% }
.underline { border-bottom: 1px dotted grey } .underline { border-bottom: 1px dotted grey }
.state { font-weight: bold; border-bottom: 1px dashed grey } .state { font-weight: bold; border-bottom: 1px dashed grey }
.historyLabel { font-variant: small-caps; font-weight: bold } .historyLabel { font-variant: small-caps; font-weight: bold }
.history td { border-top: 1px solid grey; padding: 0 5px 0 5px } .history td { border-top: 1px solid #e6e6e6; padding: 0 5px 0 5px }
.history th { font-style: italic; text-align: left; padding: 0 5px 0 5px } .history th { font-style: italic; text-align: left; padding: 0 5px 0 5px }
.topSpace { margin-top: 15px } .topSpace { margin-top: 15px }
.bottomSpace { margin-bottom: 15px } .bottomSpace { margin-bottom: 15px }
.phase { background-color: white; border: 1px solid #d0d0d0;
box-shadow: 2px 2px 2px #888888; margin-bottom: 7px }
.phase td { padding: 3px 7px 3px 7px; border-right: 1px solid #d0d0d0;
font-size: 96% }
.currentPage { background-color: #e6e6e6 }
.pageLink { margin-right: 8px } .pageLink { margin-right: 8px }
.footer { font-size: 95%; height: 100% } .footer { font-size: 95%; height: 100% }
.footer td { background-color: #CBCBC9; border-top: 1px solid grey; .footer td { background-color: #CBCBC9; border-top: 1px solid grey;
@ -159,3 +159,6 @@ td.search { padding-top: 8px }
.podName { font-size: 90% } .podName { font-size: 90% }
.podTable { margin-left: 15px } .podTable { margin-left: 15px }
.cbCell { width: 10px; text-align: center} .cbCell { width: 10px; text-align: center}
.tabs { position:relative; bottom:-2px }
.tab { padding: 0 10px 0 10px; text-align: center; font-size: 90%;
font-weight: bold}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 174 B

After

Width:  |  Height:  |  Size: 176 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 B

After

Width:  |  Height:  |  Size: 167 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 B

After

Width:  |  Height:  |  Size: 213 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 184 B

After

Width:  |  Height:  |  Size: 176 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 223 B

After

Width:  |  Height:  |  Size: 214 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 B

After

Width:  |  Height:  |  Size: 185 B

View file

@ -154,24 +154,14 @@ class ToolWrapper(AbstractWrapper):
currentSearch=req.get('search', None); currentSearch=req.get('search', None);
currentClass=req.get('className', None); currentClass=req.get('className', None);
currentPage=req['PATH_INFO'].rsplit('/',1)[-1]; currentPage=req['PATH_INFO'].rsplit('/',1)[-1];
rootClasses=ztool.getRootClasses(); rootClasses=ztool.getRootClasses()">
phases=zobj and zobj.getAppyPhases() or None">
<table class="portletContent"
if="zobj and phases and zobj.mayNavigate()"
var2="singlePhase=phases and (len(phases) == 1);
page=req.get('page', '');
mayEdit=zobj.mayEdit()">
<x for="phase in phases">:phase.pxView</x>
</table>
<!-- One section for every searchable root class --> <!-- One section for every searchable root class -->
<x for="rootClass in rootClasses" if="ztool.userMaySearch(rootClass)" <x for="rootClass in rootClasses" if="ztool.userMaySearch(rootClass)"
var2="className=ztool.getPortalType(rootClass)"> var2="className=ztool.getPortalType(rootClass)">
<!-- A separator if required --> <!-- A separator if required -->
<div class="portletSep" var="nb=loop.rootClass.nb" <div class="portletSep" if="loop.rootClass.nb != 0"></div>
if="(nb != 0) or ((nb == 0) and phases)"></div>
<!-- Section title (link triggers the default search) --> <!-- Section title (link triggers the default search) -->
<div class="portletContent" <div class="portletContent"
@ -183,7 +173,7 @@ class ToolWrapper(AbstractWrapper):
(queryUrl, className, queryParam)" (queryUrl, className, queryParam)"
class=":(not currentSearch and (currentClass==className) and \ class=":(not currentSearch and (currentClass==className) and \
(currentPage=='query')) and \ (currentPage=='query')) and \
'portletCurrent' or ''">::_(className + '_plural')</a> 'current' or ''">::_(className + '_plural')</a>
</div> </div>
<!-- Actions --> <!-- Actions -->
@ -220,7 +210,7 @@ class ToolWrapper(AbstractWrapper):
<!-- Advanced search --> <!-- Advanced search -->
<div var="highlighted=(currentClass == className) and \ <div var="highlighted=(currentClass == className) and \
(currentPage == 'search')" (currentPage == 'search')"
class=":highlighted and 'portletSearch portletCurrent' or \ class=":highlighted and 'portletSearch current' or \
'portletSearch'" 'portletSearch'"
align=":dright"> align=":dright">
<a var="text=_('search_title')" style="font-size: 88%" <a var="text=_('search_title')" style="font-size: 88%"
@ -234,6 +224,8 @@ class ToolWrapper(AbstractWrapper):
<x if="search.type == 'group'">:search.px</x> <x if="search.type == 'group'">:search.px</x>
<x if="search.type != 'group'">:search.pxView</x> <x if="search.type != 'group'">:search.pxView</x>
</x> </x>
<!-- Portlet bottom, potentially customized by the app -->
<x>::ztool.portletBottom(rootClass)</x>
</div> </div>
</x> </x>
</x>''') </x>''')

View file

@ -48,10 +48,13 @@ class AbstractWrapper(object):
</div>''') </div>''')
pxNavigationStrip = Px(''' pxNavigationStrip = Px('''
<table width="100%" class="navigate"> <table width="100%">
<tr> <tr>
<!-- Breadcrumb --> <!-- Breadcrumb -->
<td var="breadcrumb=zobj.getBreadCrumb()" class="breadcrumb"> <td var="sup=zobj.getSupBreadCrumb();
breadcrumb=zobj.getBreadCrumb();
sub=zobj.getSubBreadCrumb()" class="breadcrumb">
<x if="sup">::sup</x>
<x for="bc in breadcrumb" var2="nb=loop.bc.nb"> <x for="bc in breadcrumb" var2="nb=loop.bc.nb">
<img if="nb != 0" src=":url('to')"/> <img if="nb != 0" src=":url('to')"/>
<!-- Display only the title of the current object --> <!-- Display only the title of the current object -->
@ -59,11 +62,15 @@ class AbstractWrapper(object):
<!-- Display a link for parent objects --> <!-- Display a link for parent objects -->
<a if="nb != len(breadcrumb)-1" href=":bc.url">:bc.title</a> <a if="nb != len(breadcrumb)-1" href=":bc.url">:bc.title</a>
</x> </x>
<x if="sub">::sub</x>
</td> </td>
<!-- Object navigation --> <!-- Object navigation -->
<td align=":dright">:obj.pxNavigateSiblings</td> <td align=":dright">:obj.pxNavigateSiblings</td>
</tr> </tr>
</table>''') </table>
<!-- Object phases and pages -->
<x var="phases=zobj.getAppyPhases()"
if="phases and zobj.mayNavigate()">:phases[0].pxAllPhases</x>''')
# The template PX for all pages. # The template PX for all pages.
pxTemplate = Px(''' pxTemplate = Px('''
@ -267,19 +274,22 @@ class AbstractWrapper(object):
</table> </table>
</td> </td>
</tr> </tr>
<!-- The navigation strip -->
<tr height="26px" if="zobj and showPortlet and (layoutType != 'edit')">
<td>:obj.pxNavigationStrip</td>
</tr>
<tr valign="top"> <tr valign="top">
<td> <td>
<table width="100%" height="100%" cellpadding="0" cellspacing="0"> <table width="100%" height="100%" cellpadding="0" cellspacing="0">
<tr valign="top"> <tr valign="top">
<!-- The portlet --> <!-- The portlet -->
<td if="showPortlet" class="portlet">:tool.pxPortlet</td> <td if="showPortlet" class="portlet">:tool.pxPortlet</td>
<td class="content">
<table cellpadding="0" cellspacing="0" width="100%">
<!-- Navigation strip -->
<tr if="zobj and (layoutType != 'edit')"
height="26px"><td>:obj.pxNavigationStrip</td>
</tr>
<!-- Page content --> <!-- Page content -->
<td class="content">:content</td> <tr><td>:content</td></tr>
</table>
</td>
</tr> </tr>
</table> </table>
</td> </td>