Added a CSS parser; corrected bug that prevents Appy to create a root folder in a Plone site; allowed methods from an appy tool or flavour to be available in ZPTs.
This commit is contained in:
parent
741f760bb5
commit
f7143a2afd
|
@ -149,7 +149,8 @@ class Generator(AbstractGenerator):
|
||||||
destName = '%s.css.dtml' % self.applicationName)
|
destName = '%s.css.dtml' % self.applicationName)
|
||||||
self.copyFile('do.py', self.repls, destFolder=self.skinsFolder,
|
self.copyFile('do.py', self.repls, destFolder=self.skinsFolder,
|
||||||
destName='%s_do.py' % self.applicationName)
|
destName='%s_do.py' % self.applicationName)
|
||||||
self.copyFile('colophon.pt', self.repls, destFolder=self.skinsFolder)
|
if self.config.minimalistPlone:
|
||||||
|
self.copyFile('colophon.pt', self.repls,destFolder=self.skinsFolder)
|
||||||
self.copyFile('footer.pt', self.repls, destFolder=self.skinsFolder)
|
self.copyFile('footer.pt', self.repls, destFolder=self.skinsFolder)
|
||||||
# Create version.txt
|
# Create version.txt
|
||||||
f = open(os.path.join(self.outputFolder, 'version.txt'), 'w')
|
f = open(os.path.join(self.outputFolder, 'version.txt'), 'w')
|
||||||
|
@ -502,6 +503,7 @@ class Generator(AbstractGenerator):
|
||||||
parentWrapper = '%s_Wrapper' % k.name
|
parentWrapper = '%s_Wrapper' % k.name
|
||||||
wrapperDef = 'class %s_Wrapper(%s, %s):\n' % \
|
wrapperDef = 'class %s_Wrapper(%s, %s):\n' % \
|
||||||
(c.name, parentWrapper, parentClass)
|
(c.name, parentWrapper, parentClass)
|
||||||
|
wrapperDef += ' security = ClassSecurityInfo()\n'
|
||||||
titleFound = False
|
titleFound = False
|
||||||
for attrName in c.orderedAttributes:
|
for attrName in c.orderedAttributes:
|
||||||
if attrName == 'title':
|
if attrName == 'title':
|
||||||
|
@ -519,12 +521,20 @@ class Generator(AbstractGenerator):
|
||||||
# Implicitly, the title will be added by Archetypes. So I need
|
# Implicitly, the title will be added by Archetypes. So I need
|
||||||
# to define a property for it.
|
# to define a property for it.
|
||||||
wrapperDef += self.generateWrapperProperty('title', String())
|
wrapperDef += self.generateWrapperProperty('title', String())
|
||||||
# For custom tool, flavour and pod template, add a call to a method
|
|
||||||
# that allows to custom element to update the basic element.
|
|
||||||
if isinstance(c, CustomToolClassDescriptor) or \
|
if isinstance(c, CustomToolClassDescriptor) or \
|
||||||
isinstance(c, CustomFlavourClassDescriptor):
|
isinstance(c, CustomFlavourClassDescriptor):
|
||||||
wrapperDef += " if hasattr(%s, 'update'): %s.update(%s.__bases__[1])" % \
|
# For custom tool and flavour, add a call to a method that
|
||||||
(parentClass, parentClass, parentWrapper)
|
# allows to customize elements from the base class.
|
||||||
|
wrapperDef += " if hasattr(%s, 'update'):\n " \
|
||||||
|
"%s.update(%s.__bases__[1])\n" % (
|
||||||
|
parentClass, parentClass, parentWrapper)
|
||||||
|
# For custom tool and flavour, add security declaration that
|
||||||
|
# will allow to call their methods from ZPTs.
|
||||||
|
wrapperDef += " for elem in dir(%s):\n " \
|
||||||
|
"if not elem.startswith('_'): security.declarePublic" \
|
||||||
|
"(elem)\n" % (parentClass)
|
||||||
|
# Register the class in Zope.
|
||||||
|
wrapperDef += 'InitializeClass(%s_Wrapper)\n' % c.name
|
||||||
wrappers.append(wrapperDef)
|
wrappers.append(wrapperDef)
|
||||||
repls = self.repls.copy()
|
repls = self.repls.copy()
|
||||||
repls['imports'] = '\n'.join(imports)
|
repls['imports'] = '\n'.join(imports)
|
||||||
|
|
|
@ -105,6 +105,9 @@ class PloneInstaller:
|
||||||
if not hasattr(site.aq_base, self.productName):
|
if not hasattr(site.aq_base, self.productName):
|
||||||
# Temporarily allow me to create Appy large plone folders
|
# Temporarily allow me to create Appy large plone folders
|
||||||
getattr(site.portal_types, self.appyFolderType).global_allow = 1
|
getattr(site.portal_types, self.appyFolderType).global_allow = 1
|
||||||
|
# Allow to create Appy large folders in the plone site
|
||||||
|
getattr(site.portal_types,
|
||||||
|
'Plone Site').allowed_content_types += (self.appyFolderType,)
|
||||||
site.invokeFactory(self.appyFolderType, self.productName,
|
site.invokeFactory(self.appyFolderType, self.productName,
|
||||||
title=self.productName)
|
title=self.productName)
|
||||||
getattr(site.portal_types, self.appyFolderType).global_allow = 0
|
getattr(site.portal_types, self.appyFolderType).global_allow = 0
|
||||||
|
|
|
@ -4,6 +4,8 @@ from appy.gen.plone25.wrappers import AbstractWrapper, FileWrapper
|
||||||
from appy.gen.plone25.wrappers.ToolWrapper import ToolWrapper
|
from appy.gen.plone25.wrappers.ToolWrapper import ToolWrapper
|
||||||
from appy.gen.plone25.wrappers.FlavourWrapper import FlavourWrapper
|
from appy.gen.plone25.wrappers.FlavourWrapper import FlavourWrapper
|
||||||
from appy.gen.plone25.wrappers.PodTemplateWrapper import PodTemplateWrapper
|
from appy.gen.plone25.wrappers.PodTemplateWrapper import PodTemplateWrapper
|
||||||
|
from Globals import InitializeClass
|
||||||
|
from AccessControl import ClassSecurityInfo
|
||||||
<!imports!>
|
<!imports!>
|
||||||
|
|
||||||
class PodTemplate(PodTemplateWrapper):
|
class PodTemplate(PodTemplateWrapper):
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
'''This package contains base classes for wrappers that hide to the Appy
|
'''This package contains base classes for wrappers that hide to the Appy
|
||||||
developer the real classes used by the undelrying web framework.'''
|
developer the real classes used by the underlying web framework.'''
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
import time, os.path, mimetypes
|
import time, os.path, mimetypes
|
||||||
|
|
|
@ -150,7 +150,7 @@ class XmlUnmarshaller(XmlParser):
|
||||||
If "object" is specified, it means that the tag contains sub-tags, each
|
If "object" is specified, it means that the tag contains sub-tags, each
|
||||||
one corresponding to the value of an attribute for this object.
|
one corresponding to the value of an attribute for this object.
|
||||||
if "tuple" is specified, it will be converted to a list.'''
|
if "tuple" is specified, it will be converted to a list.'''
|
||||||
def __init__(self, klass=None):
|
def __init__(self, klass=None, tagTypes={}):
|
||||||
XmlParser.__init__(self)
|
XmlParser.__init__(self)
|
||||||
self.klass = klass # If a klass is given here, instead of creating
|
self.klass = klass # If a klass is given here, instead of creating
|
||||||
# a root UnmarshalledObject instance, we will create an instance of this
|
# a root UnmarshalledObject instance, we will create an instance of this
|
||||||
|
@ -160,6 +160,13 @@ class XmlUnmarshaller(XmlParser):
|
||||||
# careful: we will not call the constructor of this class. We will
|
# careful: we will not call the constructor of this class. We will
|
||||||
# simply create an instance of UnmarshalledObject and dynamically change
|
# simply create an instance of UnmarshalledObject and dynamically change
|
||||||
# the class of the created instance to this class.
|
# the class of the created instance to this class.
|
||||||
|
self.tagTypes = tagTypes
|
||||||
|
# We expect that the parsed XML file will follow some conventions
|
||||||
|
# (ie, a tag that corresponds to a list has attribute type="list" or a
|
||||||
|
# tag that corresponds to an object has attribute type="object".). If
|
||||||
|
# it is not the case of p_xmlContent, you can provide the missing type
|
||||||
|
# information in p_tagTypes. Here is an example of p_tagTypes:
|
||||||
|
# {"information": "list", "days": "list", "person": "object"}.
|
||||||
|
|
||||||
def startDocument(self):
|
def startDocument(self):
|
||||||
self.res = None # The resulting web of Python objects
|
self.res = None # The resulting web of Python objects
|
||||||
|
@ -179,6 +186,8 @@ class XmlUnmarshaller(XmlParser):
|
||||||
elemType = 'unicode' # Default value
|
elemType = 'unicode' # Default value
|
||||||
if attrs.has_key('type'):
|
if attrs.has_key('type'):
|
||||||
elemType = attrs['type']
|
elemType = attrs['type']
|
||||||
|
elif self.tagTypes.has_key(elem):
|
||||||
|
elemType = self.tagTypes[elem]
|
||||||
if elemType in self.containerTags:
|
if elemType in self.containerTags:
|
||||||
# I must create a new container object.
|
# I must create a new container object.
|
||||||
if elemType == 'object': newObject = UnmarshalledObject()
|
if elemType == 'object': newObject = UnmarshalledObject()
|
||||||
|
@ -216,7 +225,18 @@ class XmlUnmarshaller(XmlParser):
|
||||||
currentContainer.content += value
|
currentContainer.content += value
|
||||||
else:
|
else:
|
||||||
# Current container is an object
|
# Current container is an object
|
||||||
setattr(currentContainer, name, value)
|
if hasattr(currentContainer, name):
|
||||||
|
# We have already encountered a sub-object with this name.
|
||||||
|
# Having several sub-objects with the same name, we will
|
||||||
|
# create a list.
|
||||||
|
attrValue = getattr(currentContainer, name)
|
||||||
|
if not isinstance(attrValue, list):
|
||||||
|
attrValue = [attrValue, value]
|
||||||
|
else:
|
||||||
|
attrValue.append(value)
|
||||||
|
else:
|
||||||
|
attrValue = value
|
||||||
|
setattr(currentContainer, name, attrValue)
|
||||||
|
|
||||||
def characters(self, content):
|
def characters(self, content):
|
||||||
e = XmlParser.characters(self, content)
|
e = XmlParser.characters(self, content)
|
||||||
|
@ -246,9 +266,15 @@ class XmlUnmarshaller(XmlParser):
|
||||||
else:
|
else:
|
||||||
e.containerStack.pop()
|
e.containerStack.pop()
|
||||||
|
|
||||||
# Alias 'unmarshall' -> 'parse'
|
# Alias: "unmarshall" -> "parse"
|
||||||
unmarshall = XmlParser.parse
|
unmarshall = XmlParser.parse
|
||||||
|
|
||||||
|
class CssParser(XmlUnmarshaller):
|
||||||
|
cssTags = {'rss': 'object', 'channel': 'object', 'item': 'object'}
|
||||||
|
def startDocument(self):
|
||||||
|
XmlUnmarshaller.startDocument(self)
|
||||||
|
self.tagTypes.update(self.cssTags)
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
class XmlMarshaller:
|
class XmlMarshaller:
|
||||||
'''This class allows to produce a XML version of a Python object, which
|
'''This class allows to produce a XML version of a Python object, which
|
||||||
|
|
Loading…
Reference in a new issue