[gen] Added the possibility to define dict someClass.styles (with, currently, a single entry 'title'), allowing to specify alternative CSS classes for class-related elements (here, 'title' allows to define an alternative CSS class for the link allowing to click on some instance of the class on a query or ref).

This commit is contained in:
Gaetan Delannay 2013-04-27 02:15:44 +02:00
parent ca16f8989c
commit 1c3555fd28
8 changed files with 61 additions and 42 deletions

View file

@ -227,6 +227,11 @@ widePageLayouts = {
'view': Table('w|-b|', align="center"),
'edit': Table('w|-b|')
}
centeredPageLayouts = {
'view': Table('w|-b|', align="center"),
'edit': Table('w|-b|', width=None, align='center')
}
# The default layout for fields. Alternative layouts may exist and are declared
# as static attributes of the concerned Type subclass.
defaultFieldLayouts = {'edit': 'lrv-f'}

View file

@ -810,6 +810,15 @@ class BaseMixin:
res['css'] = css
res['js'] = js
def getCssFor(self, elem):
'''Gets the name of the CSS class to use for styling some p_elem. If
self's class does not define a dict "styles", the defaut CSS class
to use will be named p_elem.'''
klass = self.getClass()
if hasattr(klass, 'styles') and (elem in klass.styles):
return klass.styles[elem]
return elem
def getColumnsSpecifiers(self, columnLayouts, dir):
'''Extracts and returns, from a list of p_columnLayouts, the information
that is necessary for displaying a column in a result screen or for

View file

@ -35,7 +35,8 @@ select { border: 1px solid #d0d0d0; background-color: #f8f8f8 }
textarea { width: 99%; font: 100% "Lucida Grande","Lucida Sans Unicode",Helvetica,Arial,Verdana,sans-serif;
border: 1px solid #d0d0d0; background-color: #f8f8f8 }
label { font-weight: 600; font-style: italic; line-height: 1.4em }
label { color: #888888; font-size: 11px; margin: 3px 0;
text-transform: uppercase }
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 }
@ -76,7 +77,8 @@ img { border: 0; vertical-align: middle }
box-shadow: 0 2px 4px #A9A9A9 }
.focus td { padding: 4px 0px 4px 4px }
.discreet { font-size: 90%; color: grey }
.objectLink {}
.title { color: #BA9440 }
.breadcrumb { color: #BA9440; font-size: 13px }
.lostPassword a { font-size: 90%; color: white; padding-left: 1em }
.portlet { width: 150px; border-right: 1px solid #5F7983;
background-color: #ededed }
@ -98,7 +100,7 @@ img { border: 0; vertical-align: middle }
.list { margin-bottom: 3px }
.list td, .list th { border: 1px solid grey;
padding-left: 5px; padding-right: 5px; padding-top: 3px }
.list th { background-color: #d7dee4; font-style: italic; font-weight: normal }
.list th { background-color: #e5e5e5; 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 }
@ -110,16 +112,17 @@ img { border: 0; vertical-align: middle }
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 }
.section2 { font-size: 110%; font-style: italic; margin: 0.45em 0em 0.2em 0;
border-bottom: 1px solid #DADADA }
.section3 { font-size: 100%; font-style: italic; font-weight: bold;
margin: 0.45em 0em 0.1em 0; background-color: #a1aeb5;
text-align: center; color: white }
border-top: 1px solid #8CACBB;border-bottom: 1px solid #8cacbb }
.section2 { font-size: 14px; padding: 6px; text-transform: uppercase;
border-bottom: 1px dashed #cccccc; border-top: 1px dashed #cccccc;
background-color: #f9f9f9 }
.section3 { font-size: 11px; font-weight: bold; text-transform: uppercase;
padding: 2px 0px; background-color: #a1aeb5; text-align: center;
color: white }
.even { background-color: #f9f9f9 }
.odd { background-color: #f4f4f4 }
.summary { margin-bottom: 5px; background-color: #e9e9e9;
border: 1px dashed grey }
.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% }

View file

@ -92,7 +92,7 @@
<table metal:define-macro="navigationStrip" tal:condition="python: contextObj"
width="100%" class="navigate">
<tr>
<td tal:define="breadcrumb contextObj/getBreadCrumb">
<td tal:define="breadcrumb contextObj/getBreadCrumb" class="breadcrumb">
<tal:bc repeat="bc breadcrumb">
<tal:elem define="nb repeat/bc/number">
<tal:sep condition="python: nb != 1">

View file

@ -2,15 +2,16 @@
<metal:field define-macro="field">
<tal:comment replace="nothing">Title</tal:comment>
<tal:title condition="python: widget['name'] == 'title'">
<tal:nav define="navInfo python:'search.%s.%s.%d.%d' % (className, searchName, startNumber+currentNumber, totalNumber)">
<tal:nav define="navInfo python:'search.%s.%s.%d.%d' % (className, searchName, startNumber+currentNumber, totalNumber);
cssClass python: obj.getCssFor('title')">
<tal:sup replace="structure python: obj.getSupTitle(navInfo)"/>
<a class="objectLink" tal:content="obj/Title" tal:condition="enableLinks"
tal:attributes="href python: obj.getUrl(nav=navInfo, page=obj.getDefaultViewPage())"></a><span
tal:condition="not: enableLinks" class="objectLink" tal:content="obj/Title"></span><span
<a tal:content="obj/Title" tal:condition="enableLinks"
tal:attributes="href python: obj.getUrl(nav=navInfo, page=obj.getDefaultViewPage()); class cssClass"></a><span
tal:condition="not: enableLinks" tal:attributes="class cssClass" tal:content="obj/Title"></span><span
name="subTitle" tal:content="structure obj/getSubTitle"
tal:attributes="style python: showSubTitles and 'display:inline' or 'display:none'"></span>
<tal:comment replace="nothing">Actions: edit, delete</tal:comment>
<div tal:attributes="align dright" tal:condition="obj/mayAct">
<div tal:condition="obj/mayAct">
<a tal:define="navInfo python:'search.%s.%s.%d.%d' % (className, searchName, repeat['obj'].number()+startNumber, totalNumber);"
tal:attributes="href python: obj.getUrl(mode='edit', page=obj.getDefaultEditPage(), nav=navInfo)"
tal:condition="obj/mayEdit">

View file

@ -4,18 +4,18 @@
<metal:objectTitle define-macro="objectTitle"
tal:define="navInfo python:'ref.%s.%s:%s.%d.%d' % (contextObj.UID(), fieldName, appyType['pageName'], repeat['obj'].number()+startNumber, totalNumber);
navInfo python: test(appyType['isBack'], '', navInfo)">
navInfo python: test(appyType['isBack'], '', navInfo);
cssClass python: obj.getCssFor('title')">
<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. If we are
on a forward reference, the "nav" parameter is added to the URL for allowing to navigate
from one object to the next/previous on ui/view.</tal:comment>
<tal:sup replace="structure python: obj.getSupTitle(navInfo)"/>
<a class="objectLink"
tal:define="includeShownInfo includeShownInfo | python:False;
<a tal:define="includeShownInfo includeShownInfo | python:False;
pageName python: appyType['isBack'] and appyType['backd']['pageName'] or 'main';
fullUrl python: obj.getUrl(page=pageName, nav=navInfo)"
tal:attributes="href fullUrl"
tal:attributes="href fullUrl; class cssClass"
tal:content="python: (not includeShownInfo) and obj.Title() or contextObj.getReferenceLabel(fieldName, obj.appy())"></a><span
name="subTitle" tal:content="structure obj/getSubTitle"
tal:attributes="style python: showSubTitles and 'display:inline' or 'display:none'"></span>
@ -24,9 +24,22 @@
<metal:objectActions define-macro="objectActions">
<tal:comment replace="nothing">Displays icons for triggering actions on a given
referenced object (edit, delete, etc).</tal:comment>
<table class="noStyle"
tal:define="isBack appyType/isBack">
<table class="noStyle" tal:define="isBack appyType/isBack">
<tr>
<tal:comment replace="nothing">Arrows for moving objects up or down</tal:comment>
<td tal:condition="python: not isBack and (len(objs)&gt;1) and changeOrder and canWrite">
<tal:moveRef define="objectIndex python: contextObj.getAppyRefIndex(fieldName, obj);
ajaxBaseCall python: navBaseCall.replace('**v**', '\'%s\',\'ChangeRefOrder\', {\'refObjectUid\':\'%s\', \'move\':\'**v**\'}' % (startNumber, obj.UID()))">
<img tal:condition="python: objectIndex &gt; 0" style="cursor:pointer"
tal:attributes="src string: $appUrl/ui/arrowUp.png;
title python: _('move_up');
onClick python: ajaxBaseCall.replace('**v**', 'up')"/><img style="cursor:pointer"
tal:condition="python: objectIndex &lt; (totalNumber-1)"
tal:attributes="src string: $appUrl/ui/arrowDown.png;
title python: _('move_down');
onClick python: ajaxBaseCall.replace('**v**', 'down')"/>
</tal:moveRef>
</td>
<tal:comment replace="nothing">Workflow transitions</tal:comment>
<td tal:condition="python: obj.showTransitions('result')">
<tal:def define="targetObj python: obj">
@ -55,20 +68,6 @@
onClick python:'onUnlinkObject(\'%s\',\'%s\',\'%s\')' % (contextObj.UID(), appyType['name'], obj.UID());
title python: _('object_unlink')"/>
</td>
<tal:comment replace="nothing">Arrows for moving objects up or down</tal:comment>
<td tal:condition="python: not isBack and (len(objs)&gt;1) and changeOrder and canWrite">
<tal:moveRef define="objectIndex python: contextObj.getAppyRefIndex(fieldName, obj);
ajaxBaseCall python: navBaseCall.replace('**v**', '\'%s\',\'ChangeRefOrder\', {\'refObjectUid\':\'%s\', \'move\':\'**v**\'}' % (startNumber, obj.UID()))">
<img tal:condition="python: objectIndex &gt; 0" style="cursor:pointer"
tal:attributes="src string: $appUrl/ui/arrowUp.png;
title python: _('move_up');
onClick python: ajaxBaseCall.replace('**v**', 'up')"/><img style="cursor:pointer"
tal:condition="python: objectIndex &lt; (totalNumber-1)"
tal:attributes="src string: $appUrl/ui/arrowDown.png;
title python: _('move_down');
onClick python: ajaxBaseCall.replace('**v**', 'down')"/>
</tal:moveRef>
</td>
</tr>
</table>
</metal:objectActions>
@ -205,9 +204,9 @@
tal:attributes="width column/width; align column/align">
<tal:def define="widget column/field">
<tal:title condition="python: widget['name'] == 'title'">
<metal:showObjectTitle use-macro="app/ui/widgets/ref/macros/objectTitle"/>
<div tal:attributes="align dright" tal:condition="obj/mayAct">
<metal:showObjectActions use-macro="app/ui/widgets/ref/macros/objectActions" />
<metal:title use-macro="app/ui/widgets/ref/macros/objectTitle"/>
<div tal:condition="obj/mayAct">
<metal:actions use-macro="app/ui/widgets/ref/macros/objectActions" />
</div>
</tal:title>
<tal:other condition="python: widget['name'] != 'title'">

View file

@ -43,8 +43,9 @@ class ToolWrapper(AbstractWrapper):
def computeConnectedUsers(self):
'''Computes a table showing users that are currently connected.'''
res = '<table cellpadding="0" cellspacing="0" class="list"><tr>' \
'<th></th><th>%s</th></tr>' % self.translate('last_user_access')
res = '<table cellpadding="0" cellspacing="0" class="list">' \
'<tr><th></th><th>%s</th></tr>' % \
self.translate('last_user_access')
rows = []
for userId, lastAccess in loggedUsers.items():
user = self.search1('User', noSecurity=True, login=userId)

View file

@ -118,6 +118,7 @@ class AbstractWrapper(object):
return self.search1('User', noSecurity=True,
login=self.o.getUser().getId())
elif name == 'fields': return self.o.getAllAppyTypes()
elif name == 'siteUrl': return self.o.getTool().getSiteUrl()
# Now, let's try to return a real attribute.
res = object.__getattribute__(self, name)
# If we got an Appy type, return the value of this type for this object