[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"), 'view': Table('w|-b|', align="center"),
'edit': Table('w|-b|') '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 # The default layout for fields. Alternative layouts may exist and are declared
# as static attributes of the concerned Type subclass. # as static attributes of the concerned Type subclass.
defaultFieldLayouts = {'edit': 'lrv-f'} defaultFieldLayouts = {'edit': 'lrv-f'}

View file

@ -810,6 +810,15 @@ class BaseMixin:
res['css'] = css res['css'] = css
res['js'] = js 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): def getColumnsSpecifiers(self, columnLayouts, dir):
'''Extracts and returns, from a list of p_columnLayouts, the information '''Extracts and returns, from a list of p_columnLayouts, the information
that is necessary for displaying a column in a result screen or for 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; textarea { width: 99%; font: 100% "Lucida Grande","Lucida Sans Unicode",Helvetica,Arial,Verdana,sans-serif;
border: 1px solid #d0d0d0; background-color: #f8f8f8 } 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 } legend { padding-bottom: 2px; padding-right: 3px; color: black }
ul { line-height: 1.2em; margin: 0 0 0.2em 0.6em; padding: 0; ul { line-height: 1.2em; margin: 0 0 0.2em 0.6em; padding: 0;
list-style: none outside none } list-style: none outside none }
@ -76,7 +77,8 @@ img { border: 0; vertical-align: middle }
box-shadow: 0 2px 4px #A9A9A9 } box-shadow: 0 2px 4px #A9A9A9 }
.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 }
.objectLink {} .title { color: #BA9440 }
.breadcrumb { color: #BA9440; font-size: 13px }
.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; .portlet { width: 150px; border-right: 1px solid #5F7983;
background-color: #ededed } background-color: #ededed }
@ -98,7 +100,7 @@ img { border: 0; vertical-align: middle }
.list { margin-bottom: 3px } .list { margin-bottom: 3px }
.list td, .list th { border: 1px solid grey; .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 } .list th { background-color: #e5e5e5; font-style: italic; font-weight: normal }
.grid th { font-style: italic; font-weight: normal; .grid th { font-style: italic; font-weight: normal;
border-bottom: 2px solid grey; padding: 2px 2px } border-bottom: 2px solid grey; padding: 2px 2px }
.grid td { padding-right: 5px } .grid td { padding-right: 5px }
@ -110,16 +112,17 @@ img { border: 0; vertical-align: middle }
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; .section1 { font-size: 120%; margin: 0.45em 0em 0.1em 0;
padding: 0.3em 0em 0.2em 0.1em; background-color: #eef3f5; 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; .section2 { font-size: 14px; padding: 6px; text-transform: uppercase;
border-bottom: 1px solid #DADADA } border-bottom: 1px dashed #cccccc; border-top: 1px dashed #cccccc;
.section3 { font-size: 100%; font-style: italic; font-weight: bold; background-color: #f9f9f9 }
margin: 0.45em 0em 0.1em 0; background-color: #a1aeb5; .section3 { font-size: 11px; font-weight: bold; text-transform: uppercase;
text-align: center; color: white } padding: 2px 0px; background-color: #a1aeb5; text-align: center;
color: white }
.even { background-color: #f9f9f9 } .even { background-color: #f9f9f9 }
.odd { background-color: #f4f4f4 } .odd { background-color: #f4f4f4 }
.summary { margin-bottom: 5px; background-color: #e9e9e9; .summary { margin-bottom: 5px; background-color: #f9f9f9;
border: 1px dashed grey } border-bottom: 1px dashed #cccccc; border-top: 1px dashed #cccccc; }
.objectTitle { font-size: 11pt; border-bottom: 3px solid grey; .objectTitle { font-size: 11pt; border-bottom: 3px solid grey;
font-weight: bold } font-weight: bold }
.by { padding: 5px; color: grey; font-size: 97% } .by { padding: 5px; color: grey; font-size: 97% }

View file

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

View file

@ -2,15 +2,16 @@
<metal:field define-macro="field"> <metal:field define-macro="field">
<tal:comment replace="nothing">Title</tal:comment> <tal:comment replace="nothing">Title</tal:comment>
<tal:title condition="python: widget['name'] == 'title'"> <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)"/> <tal:sup replace="structure python: obj.getSupTitle(navInfo)"/>
<a class="objectLink" tal:content="obj/Title" tal:condition="enableLinks" <a tal:content="obj/Title" tal:condition="enableLinks"
tal:attributes="href python: obj.getUrl(nav=navInfo, page=obj.getDefaultViewPage())"></a><span tal:attributes="href python: obj.getUrl(nav=navInfo, page=obj.getDefaultViewPage()); class cssClass"></a><span
tal:condition="not: enableLinks" class="objectLink" tal:content="obj/Title"></span><span tal:condition="not: enableLinks" tal:attributes="class cssClass" tal:content="obj/Title"></span><span
name="subTitle" tal:content="structure obj/getSubTitle" name="subTitle" tal:content="structure obj/getSubTitle"
tal:attributes="style python: showSubTitles and 'display:inline' or 'display:none'"></span> tal:attributes="style python: showSubTitles and 'display:inline' or 'display:none'"></span>
<tal:comment replace="nothing">Actions: edit, delete</tal:comment> <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);" <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:attributes="href python: obj.getUrl(mode='edit', page=obj.getDefaultEditPage(), nav=navInfo)"
tal:condition="obj/mayEdit"> tal:condition="obj/mayEdit">

View file

@ -4,18 +4,18 @@
<metal:objectTitle define-macro="objectTitle" <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); 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 <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 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 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 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> from one object to the next/previous on ui/view.</tal:comment>
<tal:sup replace="structure python: obj.getSupTitle(navInfo)"/> <tal:sup replace="structure python: obj.getSupTitle(navInfo)"/>
<a class="objectLink" <a tal:define="includeShownInfo includeShownInfo | python:False;
tal:define="includeShownInfo includeShownInfo | python:False;
pageName python: appyType['isBack'] and appyType['backd']['pageName'] or 'main'; pageName python: appyType['isBack'] and appyType['backd']['pageName'] or 'main';
fullUrl python: obj.getUrl(page=pageName, nav=navInfo)" 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 tal:content="python: (not includeShownInfo) and obj.Title() or contextObj.getReferenceLabel(fieldName, obj.appy())"></a><span
name="subTitle" tal:content="structure obj/getSubTitle" name="subTitle" tal:content="structure obj/getSubTitle"
tal:attributes="style python: showSubTitles and 'display:inline' or 'display:none'"></span> tal:attributes="style python: showSubTitles and 'display:inline' or 'display:none'"></span>
@ -24,9 +24,22 @@
<metal:objectActions define-macro="objectActions"> <metal:objectActions define-macro="objectActions">
<tal:comment replace="nothing">Displays icons for triggering actions on a given <tal:comment replace="nothing">Displays icons for triggering actions on a given
referenced object (edit, delete, etc).</tal:comment> referenced object (edit, delete, etc).</tal:comment>
<table class="noStyle" <table class="noStyle" tal:define="isBack appyType/isBack">
tal:define="isBack appyType/isBack">
<tr> <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> <tal:comment replace="nothing">Workflow transitions</tal:comment>
<td tal:condition="python: obj.showTransitions('result')"> <td tal:condition="python: obj.showTransitions('result')">
<tal:def define="targetObj python: obj"> <tal:def define="targetObj python: obj">
@ -55,20 +68,6 @@
onClick python:'onUnlinkObject(\'%s\',\'%s\',\'%s\')' % (contextObj.UID(), appyType['name'], obj.UID()); onClick python:'onUnlinkObject(\'%s\',\'%s\',\'%s\')' % (contextObj.UID(), appyType['name'], obj.UID());
title python: _('object_unlink')"/> title python: _('object_unlink')"/>
</td> </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> </tr>
</table> </table>
</metal:objectActions> </metal:objectActions>
@ -205,9 +204,9 @@
tal:attributes="width column/width; align column/align"> tal:attributes="width column/width; align column/align">
<tal:def define="widget column/field"> <tal:def define="widget column/field">
<tal:title condition="python: widget['name'] == 'title'"> <tal:title condition="python: widget['name'] == 'title'">
<metal:showObjectTitle use-macro="app/ui/widgets/ref/macros/objectTitle"/> <metal:title use-macro="app/ui/widgets/ref/macros/objectTitle"/>
<div tal:attributes="align dright" tal:condition="obj/mayAct"> <div tal:condition="obj/mayAct">
<metal:showObjectActions use-macro="app/ui/widgets/ref/macros/objectActions" /> <metal:actions use-macro="app/ui/widgets/ref/macros/objectActions" />
</div> </div>
</tal:title> </tal:title>
<tal:other condition="python: widget['name'] != 'title'"> <tal:other condition="python: widget['name'] != 'title'">

View file

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

View file

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