Added the possibility to define POD templates for any search result (Pod field with param view='search'), bugfix while getting default value for a Ref field, added Computed fields that computes a ZPT macro given as a string to param 'method', added the possibility to define a global style mapping for every Pod field, stopped to generate a field-specific set of i18n labels for pod output formats, carry portal_status_message even through page redirections, added 'deprecatedAddRemove' tags in generated configure.zcml, onEdit can now return a customized message, added possibility to normalize strings for other usages than 'fileName', in appy.shared.utils.normalizeString (for alpha and alphanum usages)

This commit is contained in:
Gaetan Delannay 2011-01-28 14:36:30 +01:00
parent 38f71be89a
commit 90553381a3
18 changed files with 250 additions and 59 deletions

View file

@ -84,8 +84,10 @@ class BufferIterator:
self.remainingElemIndexes = self.buffer.elements.keys()
self.remainingSubBufferIndexes.sort()
self.remainingElemIndexes.sort()
def hasNext(self):
return self.remainingSubBufferIndexes or self.remainingElemIndexes
def next(self):
nextSubBufferIndex = None
if self.remainingSubBufferIndexes:
@ -113,36 +115,45 @@ class BufferIterator:
class Buffer:
'''Abstract class representing any buffer used during rendering.'''
elementRex = re.compile('([\w-]+:[\w-]+)\s*(.*?)>', re.S)
def __init__(self, env, parent):
self.parent = parent
self.subBuffers = {} # ~{i_bufferIndex: Buffer}~
self.env = env
def addSubBuffer(self, subBuffer=None):
if not subBuffer:
subBuffer = MemoryBuffer(self.env, self)
self.subBuffers[self.getLength()] = subBuffer
subBuffer.parent = self
return subBuffer
def removeLastSubBuffer(self):
subBufferIndexes = self.subBuffers.keys()
subBufferIndexes.sort()
lastIndex = subBufferIndexes.pop()
del self.subBuffers[lastIndex]
def write(self, something): pass # To be overridden
def getLength(self): pass # To be overridden
def dumpStartElement(self, elem, attrs={}):
self.write('<%s' % elem)
for name, value in attrs.items():
self.write(' %s="%s"' % (name, value))
self.write('>')
def dumpEndElement(self, elem):
self.write('</%s>' % elem)
def dumpElement(self, elem, content=None, attrs={}):
'''For dumping a whole element at once.'''
self.dumpStartElement(elem, attrs)
if content:
self.dumpContent(content)
self.dumpEndElement(elem)
def dumpContent(self, content):
'''Dumps string p_content into the buffer.'''
for c in content:
@ -150,6 +161,7 @@ class Buffer:
self.write(XML_SPECIAL_CHARS[c])
else:
self.write(c)
def dumpAttribute(self, name, value):
self.write(''' %s="%s" ''' % (name, value))
@ -160,17 +172,21 @@ class FileBuffer(Buffer):
self.result = result
self.content = file(result, 'w')
self.content.write(xmlPrologue)
def getLength(self): return 0
# getLength is used to manage insertions into sub-buffers. But in the case
# of a FileBuffer, we will only have 1 sub-buffer at a time, and we don't
# care about where it will be inserted into the FileBuffer.
def getLength(self): return 0
def write(self, something):
self.content.write(something.encode('utf-8'))
def addExpression(self, expression):
try:
self.dumpContent(Expression(expression).evaluate(self.env.context))
except Exception, e:
PodError.dump(self, EVAL_EXPR_ERROR % (expression, e), dumpTb=False)
def pushSubBuffer(self, subBuffer): pass
# ------------------------------------------------------------------------------
@ -179,24 +195,30 @@ class MemoryBuffer(Buffer):
'(?:\s+(for|if|else|with)\s*(.*))?')
forRex = re.compile('\s*([\w\-_]+)\s+in\s+(.*)')
varRex = re.compile('\s*([\w\-_]+)\s*=\s*(.*)')
def __init__(self, env, parent):
Buffer.__init__(self, env, parent)
self.content = u''
self.elements = {}
self.action = None
def addSubBuffer(self, subBuffer=None):
sb = Buffer.addSubBuffer(self, subBuffer)
self.content += ' ' # To avoid having several subbuffers referenced at
# the same place within this buffer.
return sb
def getFileBuffer(self):
if isinstance(self.parent, FileBuffer):
res = self.parent
else:
res = self.parent.getFileBuffer()
return res
def getLength(self): return len(self.content)
def write(self, thing): self.content += thing
def getIndex(self, podElemName):
res = -1
for index, podElem in self.elements.iteritems():
@ -204,11 +226,13 @@ class MemoryBuffer(Buffer):
if index > res:
res = index
return res
def getMainElement(self):
res = None
if self.elements.has_key(0):
res = self.elements[0]
return res
def isMainElement(self, elem):
res = False
mainElem = self.getMainElement()
@ -221,6 +245,7 @@ class MemoryBuffer(Buffer):
res = False
break
return res
def unreferenceElement(self, elem):
# Find last occurrence of this element
elemIndex = -1
@ -229,6 +254,7 @@ class MemoryBuffer(Buffer):
if (podElem.OD.elem == elem) and (index > elemIndex):
elemIndex = index
del self.elements[elemIndex]
def pushSubBuffer(self, subBuffer):
'''Sets p_subBuffer at the very end of the buffer.'''
subIndex = None
@ -242,6 +268,7 @@ class MemoryBuffer(Buffer):
del self.subBuffers[subIndex]
self.subBuffers[self.getLength()] = subBuffer
self.content += u' '
def transferAllContent(self):
'''Transfer all content to parent.'''
if isinstance(self.parent, FileBuffer):
@ -263,18 +290,21 @@ class MemoryBuffer(Buffer):
MemoryBuffer.__init__(self, self.env, self.parent)
# Change buffer position wrt parent
self.parent.pushSubBuffer(self)
def addElement(self, elem):
newElem = PodElement.create(elem)
self.elements[self.getLength()] = newElem
if isinstance(newElem, Cell) or isinstance(newElem, Table):
newElem.tableInfo = self.env.getTable()
def addExpression(self, expression):
# Create the POD expression
expr = Expression(expression)
expr.expr = expression
self.elements[self.getLength()] = expr
self.content += u' ' # To be sure that an expr and an elem can't be found
self.content += u' '# To be sure that an expr and an elem can't be found
# at the same index in the buffer.
def createAction(self, statementGroup):
'''Tries to create an action based on p_statementGroup. If the statement
is not correct, r_ is -1. Else, r_ is the index of the element within
@ -363,6 +393,7 @@ class MemoryBuffer(Buffer):
except ParsingError, ppe:
PodError.dump(self, ppe, removeFirstLine=True)
return res
def cut(self, index, keepFirstPart):
'''Cuts this buffer into 2 parts. Depending on p_keepFirstPart, the 1st
(from 0 to index-1) or the second (from index to the end) part of the
@ -418,6 +449,7 @@ class MemoryBuffer(Buffer):
res.write(self.content[:index])
self.content = self.content[index:]
return res
def getElementIndexes(self, expressions=True):
res = []
for index, elem in self.elements.iteritems():
@ -427,6 +459,7 @@ class MemoryBuffer(Buffer):
if condition:
res.append(index)
return res
def transferActionIndependentContent(self, actionElemIndex):
# Manage content to transfer to parent buffer
if actionElemIndex != 0:
@ -451,6 +484,7 @@ class MemoryBuffer(Buffer):
else:
res = self
return res
def getStartIndex(self, removeMainElems):
'''When I must dump the buffer, sometimes (if p_removeMainElems is
True), I must dump only a subset of it. This method returns the start
@ -476,6 +510,7 @@ class MemoryBuffer(Buffer):
else:
res = 0
return res
def getStopIndex(self, removeMainElems):
'''This method returns the stop index of the buffer part I must dump.'''
if removeMainElems: