appy.gen: added the possibility to create and manage web pages into an app; every class can now define a method showPortlet. If the class does not define it or if it returns False, the portlet won't be shown when showing/editing instances of this class.
This commit is contained in:
parent
8aa03a091a
commit
1e9e4df5a6
|
@ -637,7 +637,7 @@ class TranslationClassDescriptor(ClassDescriptor):
|
||||||
self.customized = False
|
self.customized = False
|
||||||
|
|
||||||
def getParents(self, allClasses=()): return ('Translation',)
|
def getParents(self, allClasses=()): return ('Translation',)
|
||||||
|
def isFolder(self, klass=None): return False
|
||||||
def generateSchema(self):
|
def generateSchema(self):
|
||||||
ClassDescriptor.generateSchema(self, configClass=True)
|
ClassDescriptor.generateSchema(self, configClass=True)
|
||||||
|
|
||||||
|
@ -681,4 +681,29 @@ class TranslationClassDescriptor(ClassDescriptor):
|
||||||
params['format'] = gen.String.TEXT
|
params['format'] = gen.String.TEXT
|
||||||
params['height'] = height
|
params['height'] = height
|
||||||
self.addField(messageId, gen.String(**params))
|
self.addField(messageId, gen.String(**params))
|
||||||
|
|
||||||
|
class PageClassDescriptor(ClassDescriptor):
|
||||||
|
'''Represents the class that corresponds to a Page.'''
|
||||||
|
def __init__(self, klass, generator):
|
||||||
|
ClassDescriptor.__init__(self,klass,klass._appy_attributes[:],generator)
|
||||||
|
self.modelClass = self.klass
|
||||||
|
self.predefined = True
|
||||||
|
self.customized = False
|
||||||
|
def getParents(self, allClasses=()):
|
||||||
|
res = ['Page']
|
||||||
|
if self.customized:
|
||||||
|
res.append('%s.%s' % (self.klass.__module__, self.klass.__name__))
|
||||||
|
return res
|
||||||
|
def update(self, klass, attributes):
|
||||||
|
'''This method is called by the generator when he finds a custom page
|
||||||
|
definition. We must then add the custom page elements in this
|
||||||
|
default Page descriptor.
|
||||||
|
|
||||||
|
NOTE: currently, it is not possible to define a custom Page class.'''
|
||||||
|
self.orderedAttributes += attributes
|
||||||
|
self.klass = klass
|
||||||
|
self.customized = True
|
||||||
|
def isFolder(self, klass=None): return True
|
||||||
|
def generateSchema(self):
|
||||||
|
ClassDescriptor.generateSchema(self, configClass=True)
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -6,7 +6,7 @@ import appy.gen as gen
|
||||||
from po import PoMessage, PoFile, PoParser
|
from po import PoMessage, PoFile, PoParser
|
||||||
from descriptors import *
|
from descriptors import *
|
||||||
from utils import produceNiceMessage, getClassName
|
from utils import produceNiceMessage, getClassName
|
||||||
from model import ModelClass, User, Group, Tool, Translation
|
from model import ModelClass, User, Group, Tool, Translation, Page
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
class GeneratorError(Exception): pass
|
class GeneratorError(Exception): pass
|
||||||
|
@ -353,11 +353,12 @@ class ZopeGenerator(Generator):
|
||||||
Generator.__init__(self, *args, **kwargs)
|
Generator.__init__(self, *args, **kwargs)
|
||||||
# Set our own Descriptor classes
|
# Set our own Descriptor classes
|
||||||
self.descriptorClasses['class'] = ClassDescriptor
|
self.descriptorClasses['class'] = ClassDescriptor
|
||||||
# Create our own Tool, User, Group and Translation instances
|
# Create Tool, User, Group, Translation and Page instances.
|
||||||
self.tool = ToolClassDescriptor(Tool, self)
|
self.tool = ToolClassDescriptor(Tool, self)
|
||||||
self.user = UserClassDescriptor(User, self)
|
self.user = UserClassDescriptor(User, self)
|
||||||
self.group = GroupClassDescriptor(Group, self)
|
self.group = GroupClassDescriptor(Group, self)
|
||||||
self.translation = TranslationClassDescriptor(Translation, self)
|
self.translation = TranslationClassDescriptor(Translation, self)
|
||||||
|
self.page = PageClassDescriptor(Page, self)
|
||||||
# i18n labels to generate
|
# i18n labels to generate
|
||||||
self.labels = [] # i18n labels
|
self.labels = [] # i18n labels
|
||||||
self.referers = {}
|
self.referers = {}
|
||||||
|
@ -603,13 +604,14 @@ class ZopeGenerator(Generator):
|
||||||
'''Returns the descriptors for all the classes in the generated
|
'''Returns the descriptors for all the classes in the generated
|
||||||
gen-application. If p_include is:
|
gen-application. If p_include is:
|
||||||
* "all" it includes the descriptors for the config-related
|
* "all" it includes the descriptors for the config-related
|
||||||
classes (tool, user, group, translation)
|
classes (tool, user, group, translation, page)
|
||||||
* "allButTool" it includes the same descriptors, the tool excepted
|
* "allButTool" it includes the same descriptors, the tool excepted
|
||||||
* "custom" it includes descriptors for the config-related classes
|
* "custom" it includes descriptors for the config-related classes
|
||||||
for which the user has created a sub-class.'''
|
for which the user has created a sub-class.'''
|
||||||
if not include: return self.classes
|
if not include: return self.classes
|
||||||
res = self.classes[:]
|
res = self.classes[:]
|
||||||
configClasses = [self.tool, self.user, self.group, self.translation]
|
configClasses = [self.tool, self.user, self.group, self.translation,
|
||||||
|
self.page]
|
||||||
if include == 'all':
|
if include == 'all':
|
||||||
res += configClasses
|
res += configClasses
|
||||||
elif include == 'allButTool':
|
elif include == 'allButTool':
|
||||||
|
@ -789,16 +791,22 @@ class ZopeGenerator(Generator):
|
||||||
Tool.users.klass = self.user.klass
|
Tool.users.klass = self.user.klass
|
||||||
Group.users.klass = self.user.klass
|
Group.users.klass = self.user.klass
|
||||||
|
|
||||||
# Generate the Tool-related classes (User, Group, Translation)
|
# Generate the Tool-related classes (User, Group, Translation, Page)
|
||||||
for klass in (self.user, self.group, self.translation):
|
for klass in (self.user, self.group, self.translation, self.page):
|
||||||
klassType = klass.name[len(self.applicationName):]
|
klassType = klass.name[len(self.applicationName):]
|
||||||
klass.generateSchema()
|
klass.generateSchema()
|
||||||
self.labels += [ Msg(klass.name, '', klassType),
|
self.labels += [ Msg(klass.name, '', klassType),
|
||||||
Msg('%s_plural' % klass.name,'', klass.name+'s')]
|
Msg('%s_plural' % klass.name,'', klass.name+'s')]
|
||||||
repls = self.repls.copy()
|
repls = self.repls.copy()
|
||||||
|
if klass.isFolder():
|
||||||
|
parents = 'BaseMixin, Folder'
|
||||||
|
icon = 'folder.gif'
|
||||||
|
else:
|
||||||
|
parents = 'BaseMixin, SimpleItem'
|
||||||
|
icon = 'object.gif'
|
||||||
repls.update({'methods': klass.methods, 'genClassName': klass.name,
|
repls.update({'methods': klass.methods, 'genClassName': klass.name,
|
||||||
'baseMixin':'BaseMixin', 'parents': 'BaseMixin, SimpleItem',
|
'baseMixin':'BaseMixin', 'parents': parents,
|
||||||
'classDoc': 'Standard Appy class', 'icon':'object.gif'})
|
'classDoc': 'Standard Appy class', 'icon': icon})
|
||||||
self.copyFile('Class.pyt', repls, destName='%s.py' % klass.name)
|
self.copyFile('Class.pyt', repls, destName='%s.py' % klass.name)
|
||||||
|
|
||||||
# Before generating the Tool class, finalize it with query result
|
# Before generating the Tool class, finalize it with query result
|
||||||
|
|
|
@ -223,14 +223,14 @@ class ToolMixin(BaseMixin):
|
||||||
return [importParams['headers'], elems]
|
return [importParams['headers'], elems]
|
||||||
|
|
||||||
def showPortlet(self, context):
|
def showPortlet(self, context):
|
||||||
if self.userIsAnon(): return False
|
|
||||||
if context.id == 'ui': context = context.getParentNode()
|
if context.id == 'ui': context = context.getParentNode()
|
||||||
res = True
|
res = True
|
||||||
if not self.getRootClasses():
|
if hasattr(context.aq_base, 'appy'):
|
||||||
res = False
|
appyObj = context.appy()
|
||||||
# If there is no root class, show the portlet only if we are within
|
try:
|
||||||
# the configuration.
|
res = appyObj.showPortlet()
|
||||||
if (self.id in context.absolute_url()): res = True
|
except AttributeError:
|
||||||
|
res = True
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def getObject(self, uid, appy=False, brain=False):
|
def getObject(self, uid, appy=False, brain=False):
|
||||||
|
@ -1000,4 +1000,10 @@ class ToolMixin(BaseMixin):
|
||||||
return '<table class="main" align="center" cellpadding="0"><tr>' \
|
return '<table class="main" align="center" cellpadding="0"><tr>' \
|
||||||
'<td style="padding: 1em 1em 1em 1em">An error occurred. %s' \
|
'<td style="padding: 1em 1em 1em 1em">An error occurred. %s' \
|
||||||
'</td></tr></table>' % '\n'.join(htmlMessage)
|
'</td></tr></table>' % '\n'.join(htmlMessage)
|
||||||
|
|
||||||
|
def getMainPages(self):
|
||||||
|
'''Returns the main pages.'''
|
||||||
|
if hasattr(self.o.aq_base, 'pages') and self.o.pages:
|
||||||
|
return [self.getObject(uid) for uid in self.o.pages ]
|
||||||
|
return ()
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -1312,6 +1312,9 @@ class BaseMixin:
|
||||||
Else (if the object is stored directly within the tool or the root
|
Else (if the object is stored directly within the tool or the root
|
||||||
data folder) it returns None.'''
|
data folder) it returns None.'''
|
||||||
parent = self.getParentNode()
|
parent = self.getParentNode()
|
||||||
|
# Not-Managers can't navigate back to the tool
|
||||||
|
if (parent.id == 'config') and not self.getUser().has_role('Manager'):
|
||||||
|
return False
|
||||||
if parent.meta_type != 'Folder': return parent
|
if parent.meta_type != 'Folder': return parent
|
||||||
|
|
||||||
def index_html(self):
|
def index_html(self):
|
||||||
|
|
37
gen/model.py
37
gen/model.py
|
@ -42,7 +42,7 @@ class ModelClass:
|
||||||
in order to avoid name conflicts with user-defined parts of the
|
in order to avoid name conflicts with user-defined parts of the
|
||||||
application model.'''
|
application model.'''
|
||||||
_appy_attributes = [] # We need to keep track of attributes order.
|
_appy_attributes = [] # We need to keep track of attributes order.
|
||||||
|
folder = False
|
||||||
@classmethod
|
@classmethod
|
||||||
def _appy_getTypeBody(klass, appyType, wrapperName):
|
def _appy_getTypeBody(klass, appyType, wrapperName):
|
||||||
'''This method returns the code declaration for p_appyType.'''
|
'''This method returns the code declaration for p_appyType.'''
|
||||||
|
@ -67,6 +67,12 @@ class ModelClass:
|
||||||
value = 'tfw'
|
value = 'tfw'
|
||||||
else:
|
else:
|
||||||
value = appyType.getInputLayouts()
|
value = appyType.getInputLayouts()
|
||||||
|
elif (name == 'klass') and value and (value == klass):
|
||||||
|
# This is a auto-Ref (a Ref that references the klass itself).
|
||||||
|
# At this time, we can't reference the class that is still being
|
||||||
|
# defined. So we initialize it to None. The post-init of the
|
||||||
|
# field must be done manually in wrappers.py.
|
||||||
|
value = 'None'
|
||||||
elif isinstance(value, basestring):
|
elif isinstance(value, basestring):
|
||||||
value = '"%s"' % value
|
value = '"%s"' % value
|
||||||
elif isinstance(value, gen.Ref):
|
elif isinstance(value, gen.Ref):
|
||||||
|
@ -83,7 +89,7 @@ class ModelClass:
|
||||||
elif isinstance(value, gen.Group):
|
elif isinstance(value, gen.Group):
|
||||||
value = 'Grp("%s")' % value.name
|
value = 'Grp("%s")' % value.name
|
||||||
elif isinstance(value, gen.Page):
|
elif isinstance(value, gen.Page):
|
||||||
value = 'pages["%s"]' % value.name
|
value = 'pges["%s"]' % value.name
|
||||||
elif callable(value):
|
elif callable(value):
|
||||||
className = wrapperName
|
className = wrapperName
|
||||||
if (appyType.type == 'Ref') and appyType.isBack:
|
if (appyType.type == 'Ref') and appyType.isBack:
|
||||||
|
@ -104,7 +110,7 @@ class ModelClass:
|
||||||
else: wrapperName = 'W%s' % className
|
else: wrapperName = 'W%s' % className
|
||||||
res = 'class %s(%s):\n' % (className, wrapperName)
|
res = 'class %s(%s):\n' % (className, wrapperName)
|
||||||
# Tool must be folderish
|
# Tool must be folderish
|
||||||
if className == 'Tool': res += ' folder=True\n'
|
if klass.folder: res += ' folder=True\n'
|
||||||
# First, scan all attributes, determine all used pages and create a
|
# First, scan all attributes, determine all used pages and create a
|
||||||
# dict with it. It will prevent us from creating a new Page instance
|
# dict with it. It will prevent us from creating a new Page instance
|
||||||
# for every field.
|
# for every field.
|
||||||
|
@ -114,12 +120,12 @@ class ModelClass:
|
||||||
exec 'appyType = klass.%s' % name
|
exec 'appyType = klass.%s' % name
|
||||||
if appyType.page.name not in pages:
|
if appyType.page.name not in pages:
|
||||||
pages[appyType.page.name] = appyType.page
|
pages[appyType.page.name] = appyType.page
|
||||||
res += ' pages = {'
|
res += ' pges = {'
|
||||||
for page in pages.itervalues():
|
for page in pages.itervalues():
|
||||||
# Determine page show
|
# Determine page show
|
||||||
pageShow = page.show
|
pageShow = page.show
|
||||||
if isinstance(pageShow, basestring): pageShow='"%s"' % pageShow
|
if isinstance(pageShow, basestring): pageShow='"%s"' % pageShow
|
||||||
res += '"%s":Page("%s", show=%s),'% (page.name, page.name, pageShow)
|
res += '"%s":Pge("%s", show=%s),'% (page.name, page.name, pageShow)
|
||||||
res += '}\n'
|
res += '}\n'
|
||||||
# Secondly, dump every attribute
|
# Secondly, dump every attribute
|
||||||
for name in klass._appy_attributes:
|
for name in klass._appy_attributes:
|
||||||
|
@ -183,13 +189,27 @@ class Translation(ModelClass):
|
||||||
def label(self): pass
|
def label(self): pass
|
||||||
def show(self, name): pass
|
def show(self, name): pass
|
||||||
|
|
||||||
|
# The Page class ---------------------------------------------------------------
|
||||||
|
class Page(ModelClass):
|
||||||
|
_appy_attributes = ['title', 'content', 'pages']
|
||||||
|
folder = True
|
||||||
|
title = gen.String(show='edit', indexed=True)
|
||||||
|
content = gen.String(format=gen.String.XHTML, layouts='f')
|
||||||
|
# Pages can contain other pages.
|
||||||
|
def showSubPages(self): pass
|
||||||
|
pages = gen.Ref(None, multiplicity=(0,None), add=True, link=False,
|
||||||
|
back=gen.Ref(attribute='parent', show=False),
|
||||||
|
show=showSubPages)
|
||||||
|
Page.pages.klass = Page
|
||||||
|
setattr(Page, Page.pages.back.attribute, Page.pages.back)
|
||||||
|
|
||||||
# The Tool class ---------------------------------------------------------------
|
# The Tool class ---------------------------------------------------------------
|
||||||
# Prefixes of the fields generated on the Tool.
|
# Prefixes of the fields generated on the Tool.
|
||||||
toolFieldPrefixes = ('defaultValue', 'podTemplate', 'formats', 'resultColumns',
|
toolFieldPrefixes = ('defaultValue', 'podTemplate', 'formats', 'resultColumns',
|
||||||
'enableAdvancedSearch', 'numberOfSearchColumns',
|
'enableAdvancedSearch', 'numberOfSearchColumns',
|
||||||
'searchFields', 'optionalFields', 'showWorkflow',
|
'searchFields', 'optionalFields', 'showWorkflow',
|
||||||
'showAllStatesInPhase')
|
'showAllStatesInPhase')
|
||||||
defaultToolFields = ('title', 'users', 'groups', 'translations',
|
defaultToolFields = ('title', 'users', 'groups', 'translations', 'pages',
|
||||||
'enableNotifications', 'unoEnabledPython','openOfficePort',
|
'enableNotifications', 'unoEnabledPython','openOfficePort',
|
||||||
'numberOfResultsPerPage', 'listBoxesMaximumWidth',
|
'numberOfResultsPerPage', 'listBoxesMaximumWidth',
|
||||||
'appyVersion')
|
'appyVersion')
|
||||||
|
@ -197,6 +217,7 @@ defaultToolFields = ('title', 'users', 'groups', 'translations',
|
||||||
class Tool(ModelClass):
|
class Tool(ModelClass):
|
||||||
# In a ModelClass we need to declare attributes in the following list.
|
# In a ModelClass we need to declare attributes in the following list.
|
||||||
_appy_attributes = list(defaultToolFields)
|
_appy_attributes = list(defaultToolFields)
|
||||||
|
folder = True
|
||||||
|
|
||||||
# Tool attributes
|
# Tool attributes
|
||||||
title = gen.String(show=False, page=gen.Page('main', show=False))
|
title = gen.String(show=False, page=gen.Page('main', show=False))
|
||||||
|
@ -222,6 +243,9 @@ class Tool(ModelClass):
|
||||||
link=False, show='view',
|
link=False, show='view',
|
||||||
back=gen.Ref(attribute='trToTool', show=False),
|
back=gen.Ref(attribute='trToTool', show=False),
|
||||||
page=gen.Page('translations', show='view'))
|
page=gen.Page('translations', show='view'))
|
||||||
|
pages = gen.Ref(Page, multiplicity=(0,None), add=True, link=False,
|
||||||
|
show='view', back=gen.Ref(attribute='toTool3', show=False),
|
||||||
|
page=gen.Page('pages', show='view'))
|
||||||
enableNotifications = gen.Boolean(default=True,
|
enableNotifications = gen.Boolean(default=True,
|
||||||
page=gen.Page('notifications', show=False))
|
page=gen.Page('notifications', show=False))
|
||||||
|
|
||||||
|
@ -235,4 +259,5 @@ class Tool(ModelClass):
|
||||||
for k in toClean:
|
for k in toClean:
|
||||||
exec 'del klass.%s' % k
|
exec 'del klass.%s' % k
|
||||||
klass._appy_attributes = list(defaultToolFields)
|
klass._appy_attributes = list(defaultToolFields)
|
||||||
|
klass.folder = True
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
from appy.gen import *
|
from appy.gen import *
|
||||||
Grp = Group # Avoid name clashes with the Group class below and appy.gen.Group
|
Grp = Group # Avoid name clashes with the Group class below and appy.gen.Group
|
||||||
|
Pge = Page # Avoid name clashes with the Page class below and appy.gen.Page
|
||||||
from appy.gen.wrappers import AbstractWrapper
|
from appy.gen.wrappers import AbstractWrapper
|
||||||
from appy.gen.wrappers.ToolWrapper import ToolWrapper as WTool
|
from appy.gen.wrappers.ToolWrapper import ToolWrapper as WTool
|
||||||
from appy.gen.wrappers.UserWrapper import UserWrapper as WUser
|
from appy.gen.wrappers.UserWrapper import UserWrapper as WUser
|
||||||
from appy.gen.wrappers.GroupWrapper import GroupWrapper as WGroup
|
from appy.gen.wrappers.GroupWrapper import GroupWrapper as WGroup
|
||||||
from appy.gen.wrappers.TranslationWrapper import TranslationWrapper as WT
|
from appy.gen.wrappers.TranslationWrapper import TranslationWrapper as WT
|
||||||
|
from appy.gen.wrappers.PageWrapper import PageWrapper as WPage
|
||||||
from Globals import InitializeClass
|
from Globals import InitializeClass
|
||||||
from AccessControl import ClassSecurityInfo
|
from AccessControl import ClassSecurityInfo
|
||||||
tfw = {"edit":"f","cell":"f","view":"f"} # Layout for Translation fields
|
tfw = {"edit":"f","cell":"f","view":"f"} # Layout for Translation fields
|
||||||
|
@ -14,6 +16,10 @@ tfw = {"edit":"f","cell":"f","view":"f"} # Layout for Translation fields
|
||||||
<!User!>
|
<!User!>
|
||||||
<!Group!>
|
<!Group!>
|
||||||
<!Translation!>
|
<!Translation!>
|
||||||
|
<!Page!>
|
||||||
|
Page.pages.klass = Page
|
||||||
|
setattr(Page, Page.pages.back.attribute, Page.pages.back)
|
||||||
|
|
||||||
<!Tool!>
|
<!Tool!>
|
||||||
<!wrappers!>
|
<!wrappers!>
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
body { font: 75% Helvetica,Arial,sans-serif; background-color: #EAEAEA; }
|
body { font: 75% Helvetica,Arial,sans-serif; background-color: #EAEAEA;
|
||||||
|
margin-top: 18px}
|
||||||
pre { font: 100% Helvetica,Arial,sans-serif; margin: 0}
|
pre { font: 100% Helvetica,Arial,sans-serif; margin: 0}
|
||||||
h1 { font-size: 11pt; margin:0;}
|
h1 { font-size: 11pt; margin:0;}
|
||||||
h2 { font-size: 10pt; margin:0; font-style: italic; font-weight: normal;}
|
h2 { font-size: 10pt; margin:0; font-style: italic; font-weight: normal;}
|
||||||
|
@ -38,12 +39,12 @@ img {border: 0}
|
||||||
.xhtml img { margin-right: 5px }
|
.xhtml img { margin-right: 5px }
|
||||||
|
|
||||||
.main { width: 900px; background-color: white; box-shadow: 3px 3px 3px #A9A9A9;
|
.main { width: 900px; background-color: white; 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: 75px; margin-left: 3em; vertical-align: top;}
|
.top { height: 75px; margin-left: 3em; vertical-align: top;}
|
||||||
.lang { margin-right: 3px; }
|
.lang { margin-right: 3px; }
|
||||||
.userStrip { background-color: #d7dee4; height: 40px;
|
.userStrip { background-color: #d7dee4; height: 35px;
|
||||||
border-top: 1px solid #5F7983; border-bottom: 1px solid #5F7983; }
|
border-top: 1px solid #5F7983; border-bottom: 1px solid #5F7983; }
|
||||||
.login { margin-top: 2px; margin-bottom: 2px; color: white;}
|
.login { margin-top: 2px; margin-bottom: 2px; color: black;}
|
||||||
.buttons { margin-left: 4px;}
|
.buttons { margin-left: 4px;}
|
||||||
.fakeButton { border: 1px solid #D7DEE4; background-color: #fde8e0;
|
.fakeButton { border: 1px solid #D7DEE4; background-color: #fde8e0;
|
||||||
padding: 0px 8px 2px; font: italic 92% Helvetica,Arial,sans-serif}
|
padding: 0px 8px 2px; font: italic 92% Helvetica,Arial,sans-serif}
|
||||||
|
@ -104,3 +105,4 @@ img {border: 0}
|
||||||
.history th { font-style: italic; text-align; left;}
|
.history th { font-style: italic; text-align; left;}
|
||||||
.topSpace { margin-top: 15px;}
|
.topSpace { margin-top: 15px;}
|
||||||
.discreet { color: grey}
|
.discreet { color: grey}
|
||||||
|
.pageLink { padding-left: 6px; font-style: italic}
|
||||||
|
|
|
@ -29,7 +29,11 @@
|
||||||
<td tal:attributes="style python: 'background-image: url(%s/ui/banner.jpg)' % appUrl">
|
<td tal:attributes="style python: 'background-image: url(%s/ui/banner.jpg)' % appUrl">
|
||||||
<table width="100%">
|
<table width="100%">
|
||||||
<tr valign="top">
|
<tr valign="top">
|
||||||
<td></td>
|
<tal:comment replace="nothing">Links to main pages</tal:comment>
|
||||||
|
<td>
|
||||||
|
<a tal:repeat="page tool/getMainPages" class="pageLink"
|
||||||
|
tal:content="page/title" tal:attributes="href page/absolute_url"></a>
|
||||||
|
</td>
|
||||||
<tal:comment replace="nothing">Language selector (links or listbox)</tal:comment>
|
<tal:comment replace="nothing">Language selector (links or listbox)</tal:comment>
|
||||||
<td align="right" tal:condition="tool/showLanguageSelector">
|
<td align="right" tal:condition="tool/showLanguageSelector">
|
||||||
<tal:lgs define="languages tool/getLanguages;
|
<tal:lgs define="languages tool/getLanguages;
|
||||||
|
|
10
gen/utils.py
10
gen/utils.py
|
@ -18,8 +18,14 @@ def createObject(folder, id, className, appName, wf=True):
|
||||||
obj.portal_type = className
|
obj.portal_type = className
|
||||||
obj.id = id
|
obj.id = id
|
||||||
obj._at_uid = id
|
obj._at_uid = id
|
||||||
userId = obj.getUser().getId()
|
user = obj.getUser()
|
||||||
# If user is anonymous, userIs is None
|
if not user.getId():
|
||||||
|
if user.name == 'System Processes':
|
||||||
|
userId = 'admin' # This is what happens when Zope is starting.
|
||||||
|
else:
|
||||||
|
userId = None # Anonymous.
|
||||||
|
else:
|
||||||
|
userId = user.getId()
|
||||||
obj.creator = userId or 'Anonymous User'
|
obj.creator = userId or 'Anonymous User'
|
||||||
from DateTime import DateTime
|
from DateTime import DateTime
|
||||||
obj.created = DateTime()
|
obj.created = DateTime()
|
||||||
|
|
Loading…
Reference in a new issue