From 3fd2d62b30b3eeb90ffa3c8e902eaafe0e51b421 Mon Sep 17 00:00:00 2001 From: Gaetan Delannay Date: Sat, 13 Nov 2010 17:54:08 +0100 Subject: [PATCH] Added the possibility to take into account layout modifications in Python files without needing to restart Zope while in debug mode. --- gen/__init__.py | 10 ++++++++++ gen/plone25/mixins/__init__.py | 26 +++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/gen/__init__.py b/gen/__init__.py index acffd86..57ee232 100644 --- a/gen/__init__.py +++ b/gen/__init__.py @@ -477,6 +477,16 @@ class Type: if isinstance(self, Ref) and not self.isBack: self.back.relationship = '%s_%s_rel' % (prefix, name) + def reload(self, klass, obj): + '''In debug mode, we want to reload layouts without restarting Zope. + So this method will prepare a "new", reloaded version of p_self, + that corresponds to p_self after a "reload" of its containing Python + module has been performed.''' + res = getattr(klass, self.name, None) + if not res: return self + res.init(self.name, klass, obj.getProductConfig().PROJECTNAME) + return res + def isMultiValued(self): '''Does this type definition allow to define multiple values?''' res = False diff --git a/gen/plone25/mixins/__init__.py b/gen/plone25/mixins/__init__.py index 4fc5a93..1cd7c7d 100644 --- a/gen/plone25/mixins/__init__.py +++ b/gen/plone25/mixins/__init__.py @@ -3,7 +3,7 @@ - mixins/ToolMixin is mixed in with the generated application Tool class.''' # ------------------------------------------------------------------------------ -import os, os.path, types, mimetypes +import os, os.path, sys, types, mimetypes import appy.gen from appy.gen import Type, String, Selection, Role from appy.gen.utils import * @@ -379,6 +379,24 @@ class BaseMixin: res = sortedObjectsUids.index(obj.UID()) return res + def isDebug(self): + '''Are we in debug mode ?''' + for arg in sys.argv: + if arg == 'debug-mode=on': return True + return False + + def getClass(self, reloaded=False): + '''Returns the Appy class that dictates self's behaviour.''' + if not reloaded: + return self.getTool().getAppyClass(self.__class__.__name__) + else: + klass = self.appy().klass + moduleName = klass.__module__ + exec 'import %s' % moduleName + exec 'reload(%s)' % moduleName + exec 'res = %s.%s' % (moduleName, klass.__name__) + return res + def getAppyType(self, name, asDict=False, className=None): '''Returns the Appy type named p_name. If no p_className is defined, the field is supposed to belong to self's class.''' @@ -399,7 +417,13 @@ class BaseMixin: (dict version) is given.''' res = [] groups = {} # The already encountered groups + # In debug mode, reload the module containing self's class. + debug = self.isDebug() + if debug: + klass = self.getClass(reloaded=True) for appyType in self.getAllAppyTypes(): + if debug: + appyType = appyType.reload(klass, self) if appyType.page.name != pageName: continue if not appyType.isShowable(self, layoutType): continue if not appyType.group: