## $Id: layout.py 7456 2012-01-12 12:13:36Z henrik $ ## ## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## """Basic layout components. """ import os import grok from datetime import date, datetime import grokcore.view from cgi import escape from zope.i18nmessageid import Message from hurry.resource import mode from megrok.layout import Page, Layout, Form, EditForm, DisplayForm, AddForm from z3c.flashmessage.interfaces import IMessageSource, IMessageReceiver from zope.component import getUtility, queryUtility, ComponentLookupError from zope.formlib.utility import setUpWidgets from grokcore.formlib.formlib import Action from zope.interface import Interface from zope.site.hooks import getSite from waeup.sirp.interfaces import ISIRPObject, IUserAccount from waeup.sirp.browser.interfaces import ITheme from waeup.sirp.browser.theming import get_all_themes, SIRPThemeBase from waeup.sirp.students.interfaces import IStudentNavigation from waeup.sirp.applicants.interfaces import IApplicant from waeup.sirp.authentication import get_principal_role_manager grok.templatedir('templates') default_waeup_display_template = grokcore.view.PageTemplateFile( os.path.join('templates', 'default_waeup_display_form.pt')) default_waeup_display_template.__grok_name__ = 'default_waeup_display_form' default_waeup_edit_template = grokcore.view.PageTemplateFile( os.path.join('templates', 'default_waeup_edit_form.pt')) default_waeup_edit_template.__grok_name__ = 'default_waeup_edit_form' default_primary_nav_template = grokcore.view.PageTemplateFile( os.path.join('templates', 'primarynavtab.pt')) default_primary_nav_template.__grok_name__ = 'default_primary_nav' class action(grok.action): def __call__(self, success): action = SIRPAction(self.label, success=success, **self.options) self.actions.append(action) return action class SIRPAction(Action): def __init__(self, label, style='', **options): super(SIRPAction, self).__init__(label, **options) self.style = style def render(self): if not self.available(): return '' label = self.label if isinstance(label, Message): label = zope.i18n.translate(self.label, context=self.form.request) return ('' % (self.__name__, self.__name__, escape(label, quote=True), self.style)) class jsaction(grok.action): def __call__(self, success): action = JSAction(self.label, success=success, **self.options) self.actions.append(action) return action class JSAction(Action): msg = '\'Are you sure?\'' def render(self): if not self.available(): return '' label = self.label if isinstance(label, Message): label = zope.i18n.translate(self.label, context=self.form.request) return ('' % (self.__name__, self.__name__, escape(label, quote=True), self.msg) ) def NullValidator(*args, **kw): """A validator that does not validate. This is needed especially for cancel buttons. We don't want data to be validated that will be thrown away in the next step. You can use it with ``grok.action`` decorator like this:: @grok.action('Cancel', validator=NullValidator) def cancel(self, **data): self.redirect() """ return dict() class Messages(grok.View): """Display messages of message receivers. """ grok.context(Interface) @property def messages(self): receiver = getUtility(IMessageReceiver) return receiver.receive() class UtilityView(object): """A view mixin with useful methods. The ``pnav`` attribute (a number) tells, to which primary navigation tab a page declares to belong. """ title = u'' # What appears in the content title... pnav = 0 # Primary navigation index... def application_url(self, name=None): """Return the URL of the nearest site. """ site = getSite() #if not site: # raise ComponentLookupError("No site found.") return self.url(site, name) def flash(self, message, type='alert-message warning'): """Send a short message to the user. """ source = queryUtility(IMessageSource, name='session') if source is None: return None source.send(message, type) return True class SIRPLayout(UtilityView,Layout): """A megrok.layout.Layout with additional methods. """ grok.baseclass() class SIRPForm(UtilityView,Form): """A megrok.layout.Form with additional methods. """ grok.baseclass() def setUpWidgets(self,ignore_request=False): super(SIRPForm,self).setUpWidgets(ignore_request) # Width parameters will be overridden by Bootstrap # so we have to set the css class if self.widgets.get('subject'): self.widgets['subject'].cssClass = 'span9' if self.widgets.get('body'): self.widgets['body'].height = 10 if self.widgets.get('body'): self.widgets['body'].cssClass = 'span9' class SIRPPage(UtilityView,Page): """A megrok.layout page with additional methods. """ grok.baseclass() class SIRPDisplayFormPage(UtilityView,DisplayForm): """A megrok.layout.DisplayForm with additional methods. """ grok.baseclass() template = default_waeup_display_template class SIRPEditFormPage(UtilityView,EditForm): """A megrok.layout.EditForm with additional methods. """ grok.baseclass() template = default_waeup_edit_template def setUpWidgets(self,ignore_request=False): super(SIRPEditFormPage,self).setUpWidgets(ignore_request) for widget in self.widgets: if widget.__class__.__name__ == 'TextWidget': widget.cssClass = 'span8' elif widget.__class__.__name__ == 'IntWidget': widget.cssClass = 'span2' #import pdb; pdb.set_trace() if self.widgets.get('title'): self.widgets['title'].cssClass = 'span12' if self.widgets.get('frontpage'): self.widgets['frontpage'].cssClass = 'span12' if self.widgets.get('phone'): self.widgets['phone'].cssClass = 'span4' if self.widgets.get('notice'): self.widgets['notice'].height = 3 if self.widgets.get('perm_address'): self.widgets['perm_address'].cssClass = 'span8' self.widgets['perm_address'].height = 10 class SIRPAddFormPage(UtilityView,AddForm): """A megrok.layout.AddForm with additional methods. """ grok.baseclass() template = default_waeup_edit_template class SiteLayout(SIRPLayout): """ The general site layout. """ grok.context(ISIRPObject) #: An instance of the default theme to use for the site layout default_theme = SIRPThemeBase() stafftemp = grok.PageTemplateFile('templates/staffsitelayout.pt') studenttemp = grok.PageTemplateFile('templates/studentsitelayout.pt') @property def site(self): return grok.getSite() def getAppTitle(self): return getattr(grok.getSite()['configuration'], 'name', u'Sample University') def getAppAcronym(self): return getattr(grok.getSite()['configuration'], 'acronym', u'Acronym') def isAuthenticated(self): """Return True if the calling user is authenticated. """ usertitle = self.request.principal.title return usertitle != 'Unauthenticated User' def getUserTitle(self): """Return principal title of current user. """ usertitle = self.request.principal.title if usertitle == 'Unauthenticated User': return u'Anonymous User' return usertitle def getUserId(self): """Return id of current user. """ userid = self.request.principal.id return userid def isStudent(self): usertype = getattr(self.request.principal, 'user_type', None) if not usertype: return False return self.request.principal.user_type == 'student' def isApplicant(self): usertype = getattr(self.request.principal, 'user_type', None) if not usertype: return False return self.request.principal.user_type == 'applicant' def getStudentName(self): """Return the student name. """ if IStudentNavigation.providedBy(self.context): return self.context.getStudent().display_fullname return def getApplicantName(self): """Return the applicant name. """ if IApplicant.providedBy(self.context): return self.context.fullname return def formatDatetime(self,datetimeobj): if isinstance(datetimeobj, datetime): return datetimeobj.strftime("%Y-%m-%d %H:%M:%S") else: return None def update(self): """Include the resources required by the chosen skin/theme. University instances provide a 'skin' attribute, that should hold the internal name of a theme. A theme in the waeup.sirp sense consists of a list of CSS/JavaScript resources defined in the :mod:`waeup.sirp.browser.resources` module. If the context University object has no such attribute or the set value is not a valid theme name, we pick 'gray waeup theme' as default. """ mode('minified') theme_name = getattr(grok.getSite()['configuration'], 'skin', '') theme = queryUtility(ITheme, name=theme_name, default=self.default_theme) for resource in theme.getResources(): resource.need() return def render(self): if self.isStudent() or self.isApplicant() or not self.isAuthenticated(): return self.studenttemp.render(self) return self.stafftemp.render(self)