diff --git a/gen/__init__.py b/gen/__init__.py
index 97dc997..a37c3db 100644
--- a/gen/__init__.py
+++ b/gen/__init__.py
@@ -37,9 +37,10 @@ def initMasterValue(v):
# (pages, groups,...) ----------------------------------------------------------
class Page:
'''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,
- showCancel=True, showPrevious=True, showNext=True):
+ showCancel=True, showPrevious=True, showNext=True,
+ showEdit=True):
self.name = name
self.phase = phase
self.show = show
@@ -53,6 +54,8 @@ class Page:
# When editing the page, and when a next page exists, must I show the
# "next" button?
self.showNext = showNext
+ # When viewing the page, must I show the "edit" button?
+ self.showEdit = showEdit
@staticmethod
def get(pageData):
@@ -77,7 +80,7 @@ class Page:
or 'view' (page is available only in "view" mode).
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".
showAttr = 'show'
if elem != 'page':
diff --git a/gen/mixins/ToolMixin.py b/gen/mixins/ToolMixin.py
index 8cca03c..57fc42f 100644
--- a/gen/mixins/ToolMixin.py
+++ b/gen/mixins/ToolMixin.py
@@ -49,6 +49,11 @@ class ToolMixin(BaseMixin):
tool = self.appy()
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):
'''Return the home page when a user hits the app.'''
# 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())
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):
'''Returns the catalog object.'''
return self.getParentNode().catalog
@@ -455,13 +478,9 @@ class ToolMixin(BaseMixin):
def getLayoutType(self):
'''Guess the current layout type, according to actual URL.'''
- actualUrl = self.REQUEST['ACTUAL_URL']
- res = ''
- if actualUrl.endswith('/view'):
- res = 'view'
- elif actualUrl.endswith('/edit') or actualUrl.endswith('/do'):
- res = 'edit'
- return res
+ url = self.REQUEST['ACTUAL_URL']
+ if url.endswith('/view'): return 'view'
+ if url.endswith('/edit') or url.endswith('/do'): return 'edit'
def getPublishedObject(self, layoutType):
'''Gets the currently published object, if its meta_class is among
diff --git a/gen/ui/page.pt b/gen/ui/page.pt
index 7ee2a2d..ff547d1 100644
--- a/gen/ui/page.pt
+++ b/gen/ui/page.pt
@@ -300,13 +300,13 @@
editable python: pageInfo['showOnEdit'] and contextObj.mayEdit()">
Edit
-
Locked
-
+
The box containing phase-related information
diff --git a/gen/ui/template.pt b/gen/ui/template.pt
index 4ba932a..23cb86e 100644
--- a/gen/ui/template.pt
+++ b/gen/ui/template.pt
@@ -13,7 +13,8 @@
resp req/RESPONSE;
lang tool/getUserLanguage;
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);
discreetLogin python: tool.getAttr('discreetLogin', source='config');
dleft python: (dir == 'ltr') and 'left' or 'right';
@@ -185,7 +186,7 @@
The navigation strip
-
+ ''', template=AbstractWrapper.pxTemplate, hook='content')
+
def validPythonWithUno(self, value):
'''This method represents the validator for field unoEnabledPython.'''
if value:
diff --git a/gen/wrappers/__init__.py b/gen/wrappers/__init__.py
index d280556..b051755 100644
--- a/gen/wrappers/__init__.py
+++ b/gen/wrappers/__init__.py
@@ -244,7 +244,7 @@ class AbstractWrapper(object):
:phase['px']
@@ -334,6 +334,7 @@ class AbstractWrapper(object):
''')
+ # The message that is shown when a user triggers an action.
pxMessage = Px('''
@@ -346,6 +347,7 @@ class AbstractWrapper(object):
''')
+ # The page footer.
pxFooter = Px('''
@@ -353,6 +355,15 @@ class AbstractWrapper(object):
Appy
''')
+ # 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('''
-
-
+
+
+ :self.pxLinks
-
-
+
+ :self.pxIcons
@@ -534,7 +548,7 @@ class AbstractWrapper(object):
-
+
:self.pxNavigationStrip
@@ -542,8 +556,7 @@ class AbstractWrapper(object):