diff --git a/gen/installer.py b/gen/installer.py index d32db31..d4e3445 100644 --- a/gen/installer.py +++ b/gen/installer.py @@ -398,4 +398,6 @@ class ZopeInstaller: self.installCatalog() self.installTool() self.installUi() + # Empty the fake REQUEST object, only used at Zope startup. + del self.app.config.getProductConfig().fakeRequest.wrappers # ------------------------------------------------------------------------------ diff --git a/gen/mixins/ToolMixin.py b/gen/mixins/ToolMixin.py index 86cef2a..335e8b7 100644 --- a/gen/mixins/ToolMixin.py +++ b/gen/mixins/ToolMixin.py @@ -1,5 +1,5 @@ # ------------------------------------------------------------------------------ -import re, os, os.path, time, random, types, base64, urllib +import os, os.path, sys, re, time, random, types, base64, urllib from appy.shared import mimeTypes from appy.shared.utils import getOsTempFolder from appy.shared.data import languages @@ -96,17 +96,14 @@ class ToolMixin(BaseMixin): p_code.''' return languages.get(code)[2] - def getMessages(self): - '''Returns the list of messages to return to the user.''' - if hasattr(self.REQUEST, 'messages'): - # Empty the messages and return it - res = self.REQUEST.messages - del self.REQUEST.messages - else: - res = [] - # Add portal_status_message key if present - if 'portal_status_message' in self.REQUEST: - res.append( ('info', self.REQUEST['portal_status_message']) ) + def consumeMessages(self): + '''Returns the list of messages to show to a web page and clean it in + the session.''' + rq = self.REQUEST + res = rq.SESSION.get('messages', '') + if res: + del rq.SESSION['messages'] + res = ' '.join([m[1] for m in res]) return res def getRootClasses(self): @@ -960,4 +957,15 @@ class ToolMixin(BaseMixin): randomNumber = str(random.random()).split('.')[1] timestamp = ('%f' % time.time()).replace('.', '') return '%s%s%s' % (name, timestamp, randomNumber) + + def manageError(self, error): + '''Manages an error.''' + tb = sys.exc_info() + from zExceptions.ExceptionFormatter import format_exception + htmlMessage = format_exception(tb[0], tb[1], tb[2], as_html=1) + textMessage = format_exception(tb[0], tb[1], tb[2], as_html=0) + self.log(''.join(textMessage).strip(), type='error') + return '' \ + '
An error occurred. %s' \ + '
' % '\n'.join(htmlMessage) # ------------------------------------------------------------------------------ diff --git a/gen/mixins/__init__.py b/gen/mixins/__init__.py index 9dbee23..8dac749 100644 --- a/gen/mixins/__init__.py +++ b/gen/mixins/__init__.py @@ -314,15 +314,13 @@ class BaseMixin: def say(self, msg, type='info'): '''Prints a p_msg in the user interface. p_logLevel may be "info", "warning" or "error".''' - mType = type rq = self.REQUEST - if not hasattr(rq, 'messages'): - messages = rq.messages = [] + if 'messages' not in rq.SESSION.keys(): + plist = self.getProductConfig().PersistentList + messages = rq.SESSION['messages'] = plist() else: - messages = rq.messages - if mType == 'warning': mType = 'warn' - elif mType == 'error': mType = 'stop' - messages.append( (mType, msg) ) + messages = rq.SESSION['messages'] + messages.append( (type, msg) ) def log(self, msg, type='info'): '''Logs a p_msg in the log file. p_logLevel may be "info", "warning" @@ -409,13 +407,7 @@ class BaseMixin: def goto(self, url, msg=None): '''Brings the user to some p_url after an action has been executed.''' - if msg: - # Remove previous message if any - if 'portal_status_message=' in url: - url = url[:url.find('portal_status_message=')-1] - if '?' in url: op = '&' - else: op = '?' - url += op + urllib.urlencode([('portal_status_message',msg)]) + if msg: self.say(msg) return self.REQUEST.RESPONSE.redirect(url) def gotoEdit(self): @@ -1085,9 +1077,12 @@ class BaseMixin: way.''' # Create the dict for storing Appy wrapper on the REQUEST if needed. rq = getattr(self, 'REQUEST', None) - if not rq: rq = Object() + if not rq: + # We are in test mode or Zope is starting. Use static variable + # config.fakeRequest instead. + rq = self.getProductConfig().fakeRequest if not hasattr(rq, 'wrappers'): rq.wrappers = {} - # Return the Appy wrapper from rq.wrappers if already there + # Return the Appy wrapper if already present in the cache uid = self.UID() if uid in rq.wrappers: return rq.wrappers[uid] # Create the Appy wrapper, cache it in rq.wrappers and return it @@ -1293,14 +1288,8 @@ class BaseMixin: return self.__class__.config def index_html(self): - """Redirects to /ui. Transfers the status message if any.""" - rq = self.REQUEST - msg = rq.get('portal_status_message', '') - if msg: - url = self.getUrl(portal_status_message=msg) - else: - url = self.getUrl() - return rq.RESPONSE.redirect(url) + '''Redirects to /ui.''' + return self.REQUEST.RESPONSE.redirect(self.getUrl()) def userIsAnon(self): '''Is the currently logged user anonymous ?''' diff --git a/gen/templates/config.py b/gen/templates/config.py index b640024..c8052ab 100644 --- a/gen/templates/config.py +++ b/gen/templates/config.py @@ -1,5 +1,6 @@ import os, os.path, sys, copy +import appy import appy.gen import wrappers @@ -46,4 +47,8 @@ grantableRoles = [] languages = [] languageSelector = sourceLanguage = '' + +# When Zope is starting or runs in test mode, there is no request object. We +# create here a fake one for storing Appy wrappers. +fakeRequest = appy.Object() # ------------------------------------------------------------------------------ diff --git a/gen/ui/appy.css b/gen/ui/appy.css index ce27f63..9d81cb2 100644 --- a/gen/ui/appy.css +++ b/gen/ui/appy.css @@ -1,4 +1,5 @@ body { font: 70% Lucida,Helvetica,Arial,sans-serif; background-color: #EAEAEA; } +pre { font: 100% Lucida,Helvetica,Arial,sans-serif; margin: 0} h1 { font-size: 11pt; margin:0;} h2 { font-size: 10pt; margin:0; font-style: italic; font-weight: normal;} h3 { font-size: 9pt; margin:0; font-weight: bold;} diff --git a/gen/ui/page.pt b/gen/ui/page.pt index fa1afd9..84d95ef 100644 --- a/gen/ui/page.pt +++ b/gen/ui/page.pt @@ -313,6 +313,6 @@ This macro displays the global message on the page. - -
+ +
diff --git a/gen/ui/template.pt b/gen/ui/template.pt index 3b05c65..d2158f0 100644 --- a/gen/ui/template.pt +++ b/gen/ui/template.pt @@ -18,7 +18,7 @@ - + Top banner