diff --git a/gen/mixins/ToolMixin.py b/gen/mixins/ToolMixin.py
index 27a41be..78d1acc 100644
--- a/gen/mixins/ToolMixin.py
+++ b/gen/mixins/ToolMixin.py
@@ -9,7 +9,8 @@ from appy.gen.wrappers import AbstractWrapper
from appy.gen.descriptors import ClassDescriptor
from appy.gen.mail import sendMail
from appy.shared import mimeTypes
-from appy.shared.utils import getOsTempFolder, sequenceTypes, normalizeString
+from appy.shared.utils import getOsTempFolder, sequenceTypes, normalizeString, \
+ splitList
from appy.shared.data import languages
try:
from AccessControl.ZopeSecurityPolicy import _noroles
@@ -224,6 +225,13 @@ class ToolMixin(BaseMixin):
for key in self.queryParamNames])
return res
+ def getResultMode(self, className):
+ '''Must we show, on result.pt, instances of p_className as a list or
+ as a grid?'''
+ klass = self.getAppyClass(className)
+ if hasattr(klass, 'resultMode'): return klass.resultMode
+ return 'list' # The default mode
+
def getImportElements(self, contentType):
'''Returns the list of elements that can be imported from p_path for
p_contentType.'''
@@ -416,6 +424,11 @@ class ToolMixin(BaseMixin):
return '%s' % \
(text, uText[:width].encode('utf-8') + '...')
+ def splitList(self, l, sub):
+ '''Returns a list made of the same elements as p_l, but grouped into
+ sub-lists of p_sub elements.'''
+ return splitList(l, sub)
+
def getLayoutType(self):
'''Guess the current layout type, according to actual URL.'''
actualUrl = self.REQUEST['ACTUAL_URL']
diff --git a/gen/mixins/__init__.py b/gen/mixins/__init__.py
index f45e274..53ee9c3 100644
--- a/gen/mixins/__init__.py
+++ b/gen/mixins/__init__.py
@@ -1606,7 +1606,12 @@ class BaseMixin:
if parent.meta_type not in ('Folder', 'Temporary Folder'): return parent
def getBreadCrumb(self):
- '''Gets breadcrumb info about this object and its parents.'''
+ '''Gets breadcrumb info about this object and its parents (if it must
+ be shown).'''
+ # Return an empty breadcrumb if it must not be shown.
+ klass = self.getClass()
+ if hasattr(klass, 'breadcrumb') and not klass.breadcrumb: return ()
+ # Compute the breadcrumb
res = [{'url': self.absolute_url(),
'title': self.getFieldValue('title', layoutType='view')}]
parent = self.getParent()
@@ -1746,7 +1751,8 @@ class BaseMixin:
appyType = self.getAppyType(name)
else:
appyType = self.getAppyType(name.split('_img_')[0])
- if not appyType.isShowable(self, 'view'):
+ if (not appyType.isShowable(self, 'view')) and \
+ (not appyType.isShowable(self, 'result')):
from zExceptions import NotFound
raise NotFound()
theFile = getattr(self.aq_base, name, None)
diff --git a/gen/ui/appy.css b/gen/ui/appy.css
index 7f3c2a8..fb05f4b 100644
--- a/gen/ui/appy.css
+++ b/gen/ui/appy.css
@@ -1,141 +1,141 @@
body { font: 75% Helvetica,Arial,sans-serif; background-color: #EAEAEA;
- margin-top: 18px}
-pre { font: 100% Helvetica,Arial,sans-serif; margin: 0}
-h1 { font-size: 14pt; margin:6px 0 6px 0}
+ margin-top: 18px }
+pre { font: 100% Helvetica,Arial,sans-serif; margin: 0 }
+h1 { font-size: 14pt; margin:6px 0 6px 0 }
h2 { font-size: 13pt; margin:6px 0 6px 0; font-style: italic;
- font-weight: normal}
-h3 { font-size: 12pt; margin:4px 0 4px 0; font-weight: bold;}
-h4 { font-size: 11pt; margin:4px 0 4px 0}
+ font-weight: normal }
+h3 { font-size: 12pt; margin:4px 0 4px 0; font-weight: bold }
+h4 { font-size: 11pt; margin:4px 0 4px 0 }
h5 { font-size: 10pt; margin:0; font-style: italic; font-weight: normal;
- background-color: #d7dee4}
-h6 { font-size: 9pt; margin:0; font-weight: bold;}
-a { text-decoration: none; color: #436976;}
-a:visited { color: #436976;}
+ background-color: #d7dee4 }
+h6 { font-size: 9pt; margin:0; font-weight: bold }
+a { text-decoration: none; color: #436976 }
+a:visited { color: #436976 }
table { font-size: 100%; border-spacing: 0px; border-collapse:collapse;}
-form { margin: 0; padding: 0;}
-p { margin: 0;}
-acronym {cursor: help;}
+form { margin: 0; padding: 0 }
+p { margin: 0 }
+acronym { cursor: help }
input { font: 92% Helvetica,Arial,sans-serif }
-input[type=image] { border: 0; background: none; cursor: pointer; }
-input[type=checkbox] { border: 0; background: none; cursor: pointer;}
-input[type=radio] { border: 0; background: none; cursor: pointer;}
+input[type=image] { border: 0; background: none; cursor: pointer }
+input[type=checkbox] { border: 0; background: none; cursor: pointer }
+input[type=radio] { border: 0; background: none; cursor: pointer }
input[type=file] { border: 0px solid #d0d0d0;
- background-color: #f8f8f8; cursor: pointer;}
+ background-color: #f8f8f8; cursor: pointer }
input[type=button] { border: 1px solid #d0d0d0;
- background-color: #f8f8f8; cursor: pointer;}
+ background-color: #f8f8f8; cursor: pointer }
input[type=submit] { border: 1px solid #d0d0d0; background-color: #f8f8f8;
- cursor: pointer; }
+ cursor: pointer }
input[type=password] { border: 1px solid #d0d0d0; background-color: #f8f8f8;
- font-family: Helvetica,Arial,sans-serif;}
+ font-family: Helvetica,Arial,sans-serif }
input[type=text] { border: 1px solid #d0d0d0; background-color: #f8f8f8;
font-family: Helvetica,Arial,sans-serif;
- margin-bottom: 1px}
-select { border: 1px solid #d0d0d0; background-color: #f8f8f8;}
+ margin-bottom: 1px }
+select { border: 1px solid #d0d0d0; background-color: #f8f8f8 }
textarea { width: 99%; font: 100% Helvetica,Arial,sans-serif;
- border: 1px solid #d0d0d0; background-color: #f8f8f8;}
-label { font-weight: 600; font-style: italic; line-height: 1.4em;}
-legend { padding-bottom: 2px; padding-right: 3px; color: black;}
+ border: 1px solid #d0d0d0; background-color: #f8f8f8 }
+label { font-weight: 600; font-style: italic; line-height: 1.4em }
+legend { padding-bottom: 2px; padding-right: 3px; color: black }
ul { line-height: 1.2em; margin: 0 0 0.2em 0.6em; padding: 0;
- list-style: none outside none;}
+ list-style: none outside none }
ul li { margin: 0; background-image: url("ui/li.gif"); padding-left: 10px;
- background-repeat: no-repeat; background-position: 0 4px;}
-img { border: 0; vertical-align: middle}
+ background-repeat: no-repeat; background-position: 0 4px }
+img { border: 0; vertical-align: middle }
/* Styles that apply when viewing content of XHTML fields, that mimic styles
that ckeditor uses for displaying XHTML content in the edit view. */
.xhtml { margin-top: 5px; background-color: white;
padding: 6px; border: 1px dashed grey; border-radius: 0.3em }
.xhtml img { margin-right: 5px }
-.xhtml p { margin: 3px 0 7px 0}
+.xhtml p { margin: 3px 0 7px 0 }
.main { width: 900px; background-color: white; box-shadow: 3px 3px 3px #A9A9A9;
- border-style: solid; border-width: 1px; border-color: grey}
-.top { height: 89px; margin-left: 3em; vertical-align: top;}
-.lang { margin-right: 6px; }
+ border-style: solid; border-width: 1px; border-color: grey }
+.top { height: 89px; margin-left: 3em; vertical-align: top }
+.lang { margin-right: 6px }
.userStrip { background-color: #6282B3; height: 35px;
- border-top: 3px solid #034984; border-bottom: 2px solid #034984; }
+ border-top: 3px solid #034984; border-bottom: 2px solid #034984 }
.userStripText { padding: 0 0.3em 0 0.3em; color: white }
.userStrip a { color: #e7e7e7 }
.userStrip a:visited { color: #e7e7e7 }
.navigate { border-bottom: 1px solid #5F7983;
background-color: #dbdde1; font-weight: bold }
.navigate td { padding: 4px 9px }
-.login { margin-top: 2px; margin-bottom: 2px; color: black;}
-.buttons { margin-left: 4px;}
+.login { margin-top: 2px; margin-bottom: 2px; color: black }
+.buttons { margin-left: 4px }
.fakeButton { border: 1px solid #D7DEE4; background-color: #fde8e0;
padding: 0px 8px 2px; font: italic 92% Helvetica,Arial,sans-serif}
.message { position: absolute; top: -40px; left: 150px; font-size: 90%;
width: 600px; border: 1px #F0C36D solid; padding: 6px;
background-color: #F9EDBE; text-align: center;
- border-radius: 2px 2px 2px 2px; box-shadow: 0 2px 4px #A9A9A9;}
+ border-radius: 2px 2px 2px 2px; box-shadow: 0 2px 4px #A9A9A9 }
.focus { font-size: 90%; margin: 7px 0 7px 0; padding: 7px;
background-color: #d7dee4; border-radius: 2px 2px 2px 2px;
box-shadow: 0 2px 4px #A9A9A9 }
.focus td { padding: 4px 0px 4px 4px }
.discreet { font-size: 90%; color: grey }
-.lostPassword a { font-size: 90%; color: white; padding-left: 1em;}
+.lostPassword a { font-size: 90%; color: white; padding-left: 1em }
.portlet { width: 150px; border-right: 1px solid #5F7983;
- background-color: #ededed}
+ background-color: #ededed }
.portletContent { margin: 4px 9px }
-.portletTitle { font-weight: bold; font-size: 110%; margin-bottom: 4px;}
-.portletCurrent { font-weight: bold; }
-.portletSep { border-top: 1px solid #5F7983; margin-top: 2px;}
+.portletTitle { font-weight: bold; font-size: 110%; margin-bottom: 4px }
+.portletCurrent { font-weight: bold }
+.portletSep { border-top: 1px solid #5F7983; margin-top: 2px }
.portletPage { font-style: italic }
.portletGroup { font-variant: small-caps; font-weight: bold; font-size: 105%;
- 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 }
.content { padding: 14px 14px 9px 15px; background-color: #f1f1f1 }
.grey { display: none; position: absolute; left: 0px; top: 0px;
background:grey; opacity:0.5; -moz-opacity:0.5; -khtml-opacity:0.5;
- filter:alpha(Opacity=50);}
+ filter:alpha(Opacity=50) }
.popup { display: none; position: absolute; top: 30%; left: 35%;
width: 350px; z-index : 100; background: white; padding: 8px;
- border: 1px solid grey; }
-.list { border: 1px solid grey; margin-bottom: 3px;}
+ border: 1px solid grey }
+.list { border: 1px solid grey; margin-bottom: 3px }
.list td, .list th { border: 1px solid grey;
- padding-left: 5px; padding-right: 5px; padding-top: 3px;}
+ padding-left: 5px; padding-right: 5px; padding-top: 3px }
.list th { background-color: #d7dee4; font-style: italic; font-weight: normal }
.grid th { font-style: italic; font-weight: normal;
border-bottom: 2px solid grey; padding: 2px 2px }
.grid td { padding-right: 5px }
.cellGap { padding-right: 0.4em }
.cellDashed { border: 1px dashed grey !important }
-.noStyle { border: 0 !important; padding: 0 !important; margin: 0 !important; }
-.noStyle td { border:0 !important; padding:0 !important; margin:0 !important; }
+.noStyle { border: 0 !important; padding: 0 !important; margin: 0 !important }
+.noStyle td { border:0 !important; padding:0 !important; margin:0 !important }
.translationLabel { background-color: #EAEAEA; border-bottom: 1px dashed grey;
- margin-top: 0.5em; margin-bottom: 0.5em; }
+ margin-top: 0.5em; margin-bottom: 0.5em }
.section1 { font-size: 120%; margin: 0.45em 0em 0.1em 0;
padding: 0.3em 0em 0.2em 0.1em; background-color: #eef3f5;
- border-top: 1px solid #8CACBB;border-bottom: 1px solid #8CACBB; }
+ border-top: 1px solid #8CACBB;border-bottom: 1px solid #8CACBB }
.section2 { font-size: 110%; font-style: italic; margin: 0.45em 0em 0.2em 0;
- border-bottom: 2px solid grey; }
+ border-bottom: 2px solid grey }
.section3 { font-size: 100%; font-style: italic; font-weight: bold;
margin: 0.45em 0em 0.1em 0; background-color: #95a1b3;
- text-align: center; color: white; }
-.odd { background-color: #f9f9f9; }
-.even { background-color: #f4f4f4; }
+ text-align: center; color: white }
+.odd { background-color: #f9f9f9 }
+.even { background-color: #f4f4f4 }
.summary { margin-bottom: 5px; background-color: #e9e9e9;
border: 1px dashed grey }
.objectTitle { font-size: 11pt; border-bottom: 3px solid grey;
- font-weight: bold;}
+ font-weight: bold }
.by { padding: 5px; color: grey; font-size: 97% }
-.underline { border-bottom: 1px dotted grey;}
-.state { font-weight: bold; border-bottom: 1px dashed grey;}
-.historyLabel { font-variant: small-caps; font-weight: bold;}
+.underline { border-bottom: 1px dotted grey }
+.state { font-weight: bold; border-bottom: 1px dashed grey }
+.historyLabel { font-variant: small-caps; font-weight: bold }
.history td { border-top: 1px solid grey; padding: 0 5px 0 5px }
.history th { font-style: italic; text-align: left; padding: 0 5px 0 5px }
-.topSpace { margin-top: 15px;}
-.bottomSpace { margin-bottom: 15px;}
+.topSpace { margin-top: 15px }
+.bottomSpace { margin-bottom: 15px }
.pageLink { padding-left: 8px }
.footer { font-size: 95% }
.footer td { background-color: #CBCBC9; border-top: 1px solid grey;
padding: 0.4em 1em 0.5em }
-.code { font-family: "Lucida Console","Courier New";}
+.code { font-family: "Lucida Console","Courier New" }
.codePara { background-color: #EEFFCC; border-color: grey;
border-style: solid none; border-width: 1px medium;
color: #333333; line-height: 120%;
- padding: 10px; margin: 10px 0 10px 0}
-.homeTable { background-color: #E3E3E3; border-top: 1px solid grey}
-.homeTable td { padding: 10px 5px 10px 10px}
+ padding: 10px; margin: 10px 0 10px 0 }
+.homeTable { background-color: #E3E3E3; border-top: 1px solid grey }
+.homeTable td { padding: 10px 5px 10px 10px }
.homeTable th { padding-top: 5px; font-size: 105% }
diff --git a/gen/ui/result.pt b/gen/ui/result.pt
index 278db68..f1ae78f 100644
--- a/gen/ui/result.pt
+++ b/gen/ui/result.pt
@@ -1,3 +1,87 @@
+Show field content of a given object.
+
+ Title
+
+
+
+
+
+ Actions: edit, delete
+
+
+
+
+
+ Any other field
+
+
+
+
+
+
+
+Show query results as a list.
+
+ Headers, with filters and sort arrows
+
+
+
+
+
+
+ |
+
+
+
+ Results
+
+
+
+
+
+
+ |
+
+
+
+
+
+Show query results as a grid.
+
+
+Show paginated query results as a list or grid.
+ showSubTitles python: request.get('showSubTitles', 'true') == 'true';
+ resultMode python: tool.getResultMode(className)">
Display here POD templates if required.
@@ -56,68 +141,17 @@
-
- Headers, with filters and sort arrows
-
-
-
-
-
-
- |
-
-
- Results
-
-
-
-
-
- Title
-
-
-
-
-
- Actions: edit, delete
-
-
-
-
-
-
- Any other field
-
-
-
-
-
- |
-
-
-
-
+ Results, as a list or grid
+
+
+
+
+
+
+
+
Appy (bottom) navigation