From 7ff56a6520eef9e8108fef76af8e665dc9bc4c13 Mon Sep 17 00:00:00 2001 From: Gaetan Delannay Date: Sun, 18 Sep 2011 15:00:05 +0200 Subject: [PATCH] Continued work on new Appy GUI. --- gen/__init__.py | 20 +- gen/layout.py | 6 +- gen/plone25/generator.py | 13 +- gen/plone25/installer.py | 93 ------ gen/plone25/mixins/ToolMixin.py | 15 +- gen/plone25/skin/ajax.pt | 29 +- gen/plone25/skin/appy.css | 89 +++-- gen/plone25/skin/appy.js | 374 +++++++++++++++++++++ gen/plone25/skin/calendar.css | 252 ++++++++++++++ gen/plone25/skin/calendar.gif | Bin 0 -> 953 bytes gen/plone25/skin/calendar.js | 140 ++++++++ gen/plone25/skin/callMacro.pt | 5 +- gen/plone25/skin/edit.gif | Bin 476 -> 475 bytes gen/plone25/skin/edit.pt | 94 ++---- gen/plone25/skin/import.pt | 4 +- gen/plone25/skin/navigate.pt | 84 ++--- gen/plone25/skin/page.pt | 438 ++----------------------- gen/plone25/skin/plus.png | Bin 225 -> 246 bytes gen/plone25/skin/portlet.pt | 160 ++++----- gen/plone25/skin/query.pt | 28 +- gen/plone25/skin/result.pt | 25 +- gen/plone25/skin/search.gif | Bin 433 -> 189 bytes gen/plone25/skin/search.pt | 56 +--- gen/plone25/skin/template.pt | 62 +++- gen/plone25/skin/view.pt | 49 +-- gen/plone25/skin/widgets/computed.pt | 6 +- gen/plone25/skin/widgets/date.pt | 6 +- gen/plone25/skin/widgets/file.pt | 2 +- gen/plone25/skin/widgets/pod.pt | 2 +- gen/plone25/skin/widgets/ref.pt | 57 ++-- gen/plone25/skin/widgets/show.pt | 36 +- gen/plone25/skin/widgets/string.pt | 2 +- gen/plone25/templates/IEFixes.css.dtml | 82 ----- gen/plone25/templates/Portlet.pt | 17 - gen/plone25/templates/Styles.css.dtml | 206 +----------- gen/plone25/templates/colophon.pt | 7 - gen/plone25/templates/config.py | 2 - gen/plone25/templates/footer.pt | 7 - 38 files changed, 1179 insertions(+), 1289 deletions(-) create mode 100755 gen/plone25/skin/calendar.css create mode 100755 gen/plone25/skin/calendar.gif create mode 100755 gen/plone25/skin/calendar.js delete mode 100644 gen/plone25/templates/IEFixes.css.dtml delete mode 100644 gen/plone25/templates/Portlet.pt delete mode 100644 gen/plone25/templates/colophon.pt delete mode 100644 gen/plone25/templates/footer.pt diff --git a/gen/__init__.py b/gen/__init__.py index 815587c..b8d5513 100644 --- a/gen/__init__.py +++ b/gen/__init__.py @@ -674,7 +674,7 @@ class Type: if 'cell' not in layouts: layouts['cell'] = Table(other=layouts['view'], derivedType='cell') # Put the required CSS classes in the layouts - layouts['cell'].addCssClasses('no-style-table') + layouts['cell'].addCssClasses('noStyle') if self.master: # This type has a master (so is a slave): we add css classes # allowing to show/hide, in Javascript, its widget according to @@ -1462,13 +1462,10 @@ class Date(Type): label) def getCss(self, layoutType): - if (layoutType == 'edit') and self.calendar: - return ('jscalendar/calendar-system.css',) + if (layoutType == 'edit') and self.calendar: return ('calendar.css',) def getJs(self, layoutType): - if (layoutType == 'edit') and self.calendar: - return ('jscalendar/calendar_stripped.js', - 'jscalendar/calendar-en.js') + if (layoutType == 'edit') and self.calendar: return ('calendar.js',) def getSelectableYears(self): '''Gets the list of years one may select for this field.''' @@ -1727,7 +1724,8 @@ class Ref(Type): historized, sync, mapping, label) self.validable = self.link - def getDefaultLayouts(self): return {'view': Table('l-f'), 'edit': 'lrv-f'} + def getDefaultLayouts(self): + return {'view': Table('l-f', width='100%'), 'edit': 'lrv-f'} def isShowable(self, obj, layoutType): res = Type.isShowable(self, obj, layoutType) @@ -2639,11 +2637,6 @@ class Config: # People having one of these roles will be able to create instances # of classes defined in your application. self.defaultCreators = ['Manager', 'Owner'] - # If True, the following flag will produce a minimalist Plone, where - # some actions, portlets or other stuff less relevant for building - # web applications, are removed or hidden. Using this produces - # effects on your whole Plone site! - self.minimalistPlone = False # If you want to replace the Plone front page with a page coming from # your application, use the following parameter. Setting # frontPage = True will replace the Plone front page with a page @@ -2651,9 +2644,6 @@ class Config: self.frontPage = False # You can choose the Plone or Appy main template self.frontPageTemplate = 'plone' # or "appy" - # If you don't need the portlet that appy.gen has generated for your - # application, set the following parameter to False. - self.showPortlet = True # Number of translations for every page on a Translation object self.translationsPerPage = 30 # Language that will be used as a basis for translating to other diff --git a/gen/layout.py b/gen/layout.py index 8ec6ef2..66777e5 100644 --- a/gen/layout.py +++ b/gen/layout.py @@ -14,9 +14,6 @@ # w - The widgets of the current page/class # n - The navigation panel (inter-objects navigation) # b - The range of buttons (intra-object navigation, save, edit, delete...) -# m - The global status message sometimes shown. If you specify this in a -# layout, ensure that you have hidden the global_statusmessage zone as -# proposed by Plone. Else, the message will appear twice. # Layout elements for a field -------------------------------------------------- # l - "label" The field label @@ -48,7 +45,6 @@ macroDict = { # Page-related elements 's': ('page', 'header'), 'w': ('page', 'widgets'), 'n': ('navigate', 'objectNavigate'), 'b': ('page', 'buttons'), - 'm': ('page', 'message'), # Field-related elements 'l': ('show', 'label'), 'd': ('show', 'description'), 'h': ('show', 'help'), 'v': ('show', 'validation'), @@ -220,6 +216,6 @@ class Table(LayoutElement): # ------------------------------------------------------------------------------ defaultPageLayouts = { - 'view': Table('m;-s|-n!-w|-b|'), 'edit': Table('m;-w|-b|')} + 'view': Table('s|-n!-w|-b|'), 'edit': Table('w|-b|')} defaultFieldLayouts = {'edit': 'lrv;f!'} # ------------------------------------------------------------------------------ diff --git a/gen/plone25/generator.py b/gen/plone25/generator.py index cb497d4..1a82737 100644 --- a/gen/plone25/generator.py +++ b/gen/plone25/generator.py @@ -45,7 +45,6 @@ class Generator(AbstractGenerator): # i18n labels to generate self.labels = [] # i18n labels self.toolInstanceName = 'portal_%s' % self.applicationName.lower() - self.portletName = '%s_portlet' % self.applicationName.lower() self.skinsFolder = 'skins/%s' % self.applicationName # The following dict, pre-filled in the abstract generator, contains a # series of replacements that need to be applied to file templates to @@ -168,15 +167,9 @@ class Generator(AbstractGenerator): destFolder='profiles/default') self.copyFile('ProfileInit.py', self.repls, destFolder='profiles', destName='__init__.py') - self.copyFile('Portlet.pt', self.repls, - destName='%s.pt' % self.portletName, destFolder=self.skinsFolder) self.copyFile('tool.gif', {}) self.copyFile('Styles.css.dtml',self.repls, destFolder=self.skinsFolder, destName = '%s.css.dtml' % self.applicationName) - self.copyFile('IEFixes.css.dtml',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) # Create version.txt f = open(os.path.join(self.outputFolder, 'version.txt'), 'w') f.write(self.version) @@ -393,10 +386,8 @@ class Generator(AbstractGenerator): grantableRoles = self.getAllUsedRoles(local=False, grantable=True) repls['grRoles'] = ','.join(['"%s"' % r.name for r in grantableRoles]) # Generate configuration options - repls['showPortlet'] = self.config.showPortlet repls['languages'] = ','.join('"%s"' % l for l in self.config.languages) repls['languageSelector'] = self.config.languageSelector - repls['minimalistPlone'] = self.config.minimalistPlone repls['appFrontPage'] = bool(self.config.frontPage) repls['sourceLanguage'] = self.config.sourceLanguage self.copyFile('config.py', repls) @@ -595,9 +586,7 @@ class Generator(AbstractGenerator): "(getattr(OrderedBaseFolder,'__implements__',()),)", 'register': "registerType(%s, '%s')" % (self.tool.name, self.applicationName), - 'static': "left_slots = ['here/portlet_prefs/macros/portlet']\n " \ - "right_slots = []\n " \ - "def __init__(self, id=None):\n " \ + 'static': "def __init__(self, id=None):\n " \ " OrderedBaseFolder.__init__(self, '%s')\n " \ " self.setTitle('%s')\n" % (self.toolInstanceName, self.applicationName)}) diff --git a/gen/plone25/installer.py b/gen/plone25/installer.py index 19053b5..1bdd544 100644 --- a/gen/plone25/installer.py +++ b/gen/plone25/installer.py @@ -27,7 +27,6 @@ class PloneInstaller: self.config = cfg = config # Unwrap some useful variables from config self.productName = cfg.PROJECTNAME - self.minimalistPlone = cfg.minimalistPlone self.appClasses = cfg.appClasses self.appClassNames = cfg.appClassNames self.allClassNames = cfg.allClassNames @@ -35,7 +34,6 @@ class PloneInstaller: self.applicationRoles = cfg.applicationRoles # Roles defined in the app self.defaultAddRoles = cfg.defaultAddRoles self.appFrontPage = cfg.appFrontPage - self.showPortlet = cfg.showPortlet self.languages = cfg.languages self.languageSelector = cfg.languageSelector self.attributes = cfg.attributes @@ -78,19 +76,6 @@ class PloneInstaller: logger.info('Created index "%s" of type "%s"...' % \ (indexName, indexType)) - actionsToHide = { - 'portal_actions': ('sitemap', 'accessibility', 'change_state','sendto'), - 'portal_membership': ('mystuff', 'preferences'), - 'portal_undo': ('undo',) - } - def customizePlone(self): - '''Hides some UI elements that appear by default in Plone.''' - for portalName, toHide in self.actionsToHide.iteritems(): - portal = getattr(self.ploneSite, portalName) - portalActions = portal.listActions() - for action in portalActions: - if action.id in toHide: action.visible = False - appyFolderType = 'AppyFolder' def registerAppyFolderType(self): '''We need a specific content type for the folder that will hold all @@ -265,30 +250,6 @@ class PloneInstaller: # If an instance with the same name already exists, this error will # be unelegantly raised by Zope. pass - except: - e = sys.exc_info() - if e[0] != 'Bad Request': raise - - # Hide the tool from the search form - portalProperties = self.ploneSite.portal_properties - if portalProperties is not None: - siteProperties = getattr(portalProperties, 'site_properties', None) - if siteProperties is not None and \ - siteProperties.hasProperty('types_not_searched'): - current = list(siteProperties.getProperty('types_not_searched')) - if self.toolName not in current: - current.append(self.toolName) - siteProperties.manage_changeProperties( - **{'types_not_searched' : current}) - - # Hide the tool in the navigation - if portalProperties is not None: - nvProps = getattr(portalProperties, 'navtree_properties', None) - if nvProps is not None and nvProps.hasProperty('idsNotToList'): - current = list(nvProps.getProperty('idsNotToList')) - if self.toolInstanceName not in current: - current.append(self.toolInstanceName) - nvProps.manage_changeProperties(**{'idsNotToList': current}) self.tool = getattr(self.ploneSite, self.toolInstanceName) self.tool.refreshSecurity() @@ -297,25 +258,9 @@ class PloneInstaller: self.tool.createOrUpdate(False, None) else: self.tool.createOrUpdate(True, None) - self.updatePodTemplates() - - # Uncatalog tool self.tool.unindexObject() - # Register tool as configlet - portalControlPanel = self.ploneSite.portal_controlpanel - portalControlPanel.unregisterConfiglet(self.toolName) - portalControlPanel.registerConfiglet( - self.toolName, self.productName, - 'string:${portal_url}/%s' % self.toolInstanceName, 'python:True', - 'Manage portal', # Access permission - 'Products', # Section to which the configlet should be added: - # (Plone, Products (default) or Member) - 1, # Visibility - '%sID' % self.toolName, 'site_icon.gif', # Icon in control_panel - self.productName, None) - def installTranslations(self): '''Creates or updates the translation objects within the tool.''' translations = [t.o.id for t in self.appyTool.translations] @@ -386,32 +331,6 @@ class PloneInstaller: defaults.update(cssInfo) portalCss.registerStylesheet(**defaults) - def managePortlets(self): - '''Shows or hides the application-specific portlet and configures other - Plone portlets if relevant.''' - portletName= 'here/%s_portlet/macros/portlet' % self.productName.lower() - site = self.ploneSite - leftPortlets = site.getProperty('left_slots') - if not leftPortlets: leftPortlets = [] - else: leftPortlets = list(leftPortlets) - - if self.showPortlet and (portletName not in leftPortlets): - leftPortlets.insert(0, portletName) - if not self.showPortlet and (portletName in leftPortlets): - leftPortlets.remove(portletName) - # Remove some basic Plone portlets that make less sense when building - # web applications. - portletsToRemove = ["here/portlet_navigation/macros/portlet", - "here/portlet_recent/macros/portlet", - "here/portlet_related/macros/portlet"] - if not self.minimalistPlone: portletsToRemove = [] - for p in portletsToRemove: - if p in leftPortlets: - leftPortlets.remove(p) - site.manage_changeProperties(left_slots=tuple(leftPortlets)) - if self.minimalistPlone: - site.manage_changeProperties(right_slots=()) - def manageIndexes(self): '''For every indexed field, this method installs and updates the corresponding index if it does not exist yet.''' @@ -442,21 +361,11 @@ class PloneInstaller: def finalizeInstallation(self): '''Performs some final installation steps.''' site = self.ploneSite - # Do not generate an action (tab) for each root folder - if self.minimalistPlone: - site.portal_properties.site_properties.manage_changeProperties( - disable_folder_sections=True) # Do not allow an anonymous user to register himself as new user site.manage_permission('Add portal member', ('Manager',), acquire=0) # Call custom installer if any if hasattr(self.appyTool, 'install'): self.tool.executeAppyAction('install', reindex=False) - # Patch the "logout" action with a custom Appy one that updates the - # list of currently logged users. - for action in site.portal_membership._actions: - if action.id == 'logout': - action.setActionExpression( - 'string:${portal_url}/%s/logout' % self.toolInstanceName) # Replace Plone front-page with an application-specific page if needed if self.appFrontPage: frontPageName = self.productName + 'FrontPage' @@ -465,14 +374,12 @@ class PloneInstaller: def info(self, msg): return self.appyTool.log(msg) def install(self): - if self.minimalistPlone: self.customizePlone() self.installRootFolder() self.installTypes() self.installTool() self.installTranslations() self.installRolesAndGroups() self.installStyleSheet() - self.managePortlets() self.manageIndexes() self.manageLanguages() self.finalizeInstallation() diff --git a/gen/plone25/mixins/ToolMixin.py b/gen/plone25/mixins/ToolMixin.py index eee7bea..cf2eefe 100644 --- a/gen/plone25/mixins/ToolMixin.py +++ b/gen/plone25/mixins/ToolMixin.py @@ -27,6 +27,10 @@ class ToolMixin(BaseMixin): res = '%s%s' % (elems[1], elems[4]) return res + def getApp(self): + '''Returns the root application object.''' + return self.portal_url.getPortalObject() + def getSiteUrl(self): '''Returns the absolute URL of this site.''' return self.portal_url.getPortalObject().absolute_url() @@ -342,6 +346,11 @@ class ToolMixin(BaseMixin): def getPublishedObject(self): '''Gets the currently published object, if its meta_class is among application classes.''' + req = self.REQUEST + # If we are querying object, there is no published object (the truth is: + # the tool is the currently published object but we don't want to + # consider it this way). + if not req['ACTUAL_URL'].endswith('/skyn/view'): return obj = self.REQUEST['PUBLISHED'] parent = obj.getParentNode() if parent.id == 'skyn': obj = parent.getParentNode() @@ -538,8 +547,8 @@ class ToolMixin(BaseMixin): if refInfo: criteria['_ref'] = refInfo rq.SESSION['searchCriteria'] = criteria # Go to the screen that displays search results - backUrl = '%s/query?type_name=%s&&search=_advanced' % \ - (os.path.dirname(rq['URL']),rq['type_name']) + backUrl = '%s/skyn/query?type_name=%s&&search=_advanced' % \ + (self.absolute_url(), rq['type_name']) return self.goto(backUrl) def getJavascriptMessages(self): @@ -605,7 +614,7 @@ class ToolMixin(BaseMixin): '''This method creates the URL that allows to perform a (non-Ajax) request for getting queried objects from a search named p_searchName on p_contentType.''' - baseUrl = self.getAppFolder().absolute_url() + '/skyn' + baseUrl = self.absolute_url() + '/skyn' baseParams = 'type_name=%s' % contentType rq = self.REQUEST if rq.get('ref'): baseParams += '&ref=%s' % rq.get('ref') diff --git a/gen/plone25/skin/ajax.pt b/gen/plone25/skin/ajax.pt index 861d2dc..ae26c0e 100644 --- a/gen/plone25/skin/ajax.pt +++ b/gen/plone25/skin/ajax.pt @@ -4,23 +4,26 @@ It can also have a parameter "action", that refers to a method that will be triggered on contextObj before returning the result of the macro to the browser. - + Keys "Expires" and "CacheControl" are used for preventing IE to cache this page. Indeed, this page is retrieved through an asynchronous XMLHttpRequest by the browser, and IE caches this by default. - + diff --git a/gen/plone25/skin/appy.css b/gen/plone25/skin/appy.css index bd5edc9..82755d4 100644 --- a/gen/plone25/skin/appy.css +++ b/gen/plone25/skin/appy.css @@ -1,37 +1,64 @@ -body { - font: 75% Lucida,Helvetica,Arial,sans-serif; - background-color: #EAEAEA; -} - -a {text-decoration: none; color: #747171;} -a:visited {color: #840107;} +body { font: 70% Lucida,Helvetica,Arial,sans-serif; background-color: #EAEAEA; } +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;} +a { text-decoration: none; color: #503737;} +a:visited { color: #503737;} table { font-size: 100%; border-spacing: 0px; border-collapse:collapse;} -input {border: 1px solid #a79e9e;} -form {margin: 0; padding: 0;} -p {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;} - -.main { - width: 900px; - background-color: white; - border-style: solid; - border-width: 1px; - border-color: grey; - box-shadow: 3px 3px 3px #A9A9A9; -} +form { margin: 0; padding: 0;} +p { margin: 0;} +acronym {cursor: help;} +input { border: 1px solid #a79e9e; + font-family: Lucida,Helvetica,Arial,sans-serif; } +input[type=image] { border-width: 0px; background: none; } +textarea { width: 99%; font: 100% Lucida,Helvetica,Arial,sans-serif; + border: 1px solid #a79e9e;} +label { font-weight: 600; font-style: italic; line-height: 1.4em;} +.main { width: 900px; background-color: white; box-shadow: 3px 3px 3px #A9A9A9; + border-style: solid; border-width: 1px; border-color: grey; } .top { height: 75px; margin-left: 3em; vertical-align: top;} .lang { margin-right: 3px; } -.userStrip { - background-color: #a2a2a2; - border-top: 3px solid #525252; - border-bottom: 2px solid #9b0000; - height: 30px; -} +.userStrip { background-color: #a2a2a2; height: 30px; + border-top: 3px solid #525252; border-bottom: 2px solid #9b0000; } .login { margin-top: 2px; margin-bottom: 2px; color: white;} .buttons { margin-left: 4px; } -.content {margin: 7px 0 9px 4px;} -.message {color: #9b0000; font-style: italic; position: absolute; top: -50px; right: 5px} +.message { color: #9b0000; font-style: italic; + position: absolute; top: -15px; right: 5px} +.discreet { font-size: 90%; } +.portlet { width: 150px; padding: 3px 7px 0px 7px; + border-right: 1px solid #9b0000;} +.portletCurrent { font-weight: bold; } +.portletSep { border-top: 1px solid grey; margin-top: 5px; padding-top: 5px} +.portletPage { font-style: italic; } +.phase { border-style: dashed; border-width: thin; padding: 0 0.6em 0 1em; } +.content { padding: 3px 3px 7px 15px;} +.grey { display: none; position: absolute; left: 0px; top: 0px; + width:100%; height:100%; background:grey; opacity:0.5; + -moz-opacity:0.5; -khtml-opacity:0.5; filter:alpha(Opacity=50);} +.popup { display: none; position: absolute; top: 30%; left: 35%; + width: 350px; z-index : 100; background: white; padding: 8px; + border: 1px solid grey; } +.list { border: 1px solid grey; margin-bottom: 3px;} +.list td, .list th { border: 1px solid grey; + padding-left: 3px; padding-right: 3px;} +.list th { background-color: #cbcbcb; font-style: italic; font-weight: normal;} +.noStyle { border: 0 !important; padding: 0 !important; margin: 0 !important; } +.noStyle td { border:0 !important; padding:0 !important; margin:0 !important; } +.translationLabel { background-color: #EAEAEA; border-bottom: 1px dashed grey; + margin-top: 0.5em; margin-bottom: 0.5em; } +.section1 { font-size: 120%; margin: 0.45em 0em 0.1em 0; + padding: 0.3em 0em 0.2em 0.1em; background-color: #eef3f5; + border-top: 1px solid #8CACBB;border-bottom: 1px solid #8CACBB; } +.section2 { font-size: 110%; font-style: italic; margin: 0.45em 0em 0.1em 0; + border-bottom: 2px solid grey; } +.section3 { font-size: 100%; font-style: italic; margin: 0.45em 0em 0.1em 0; + background-color: #efeae8; text-align: center; color: grey; } +.odd { background-color: white; } +.even { background-color: #ededed; } +.summary {margin-bottom: 5px;} +.objectTitle { font-size: 11pt; border-bottom: 3px solid grey; + font-weight: bold;} +.by { background-color: #ededed; font-style: italic; padding-top: 3px;} +.workflow { background-color: #ededed; text-align: center;} +.objectNavigate { margin-top: 3px;} diff --git a/gen/plone25/skin/appy.js b/gen/plone25/skin/appy.js index 15b6391..e9862ec 100644 --- a/gen/plone25/skin/appy.js +++ b/gen/plone25/skin/appy.js @@ -1,3 +1,4 @@ +// Functions related to user authentication function cookiesAreEnabled() { // Test whether cookies are enabled by attempting to set a cookie and then // change its value @@ -30,3 +31,376 @@ function setLoginVars() { if (password.value.length==0) emptyPassword.value = '1'; else emptyPassword.value = '0'; } + +// AJAX machinery +var isIe = (navigator.appName == "Microsoft Internet Explorer"); +// AJAX machinery +var xhrObjects = new Array(); // An array of XMLHttpRequest objects +function XhrObject() { // Wraps a XmlHttpRequest object + this.freed = 1; // Is this xhr object already dealing with a request or not? + this.xhr = false; + if (window.XMLHttpRequest) this.xhr = new XMLHttpRequest(); + else this.xhr = new ActiveXObject("Microsoft.XMLHTTP"); + this.hook = ''; /* The ID of the HTML element in the page that will be + replaced by result of executing the Ajax request. */ + this.onGet = ''; /* The name of a Javascript function to call once we + receive the result. */ + this.info = {}; /* An associative array for putting anything else. */ +} + +function getAjaxChunk(pos) { + // This function is the callback called by the AJAX machinery (see function + // askAjaxChunk below) when an Ajax response is available. + // First, find back the correct XMLHttpRequest object + if ( (typeof(xhrObjects[pos]) != 'undefined') && + (xhrObjects[pos].freed == 0)) { + var hook = xhrObjects[pos].hook; + if (xhrObjects[pos].xhr.readyState == 1) { + // The request has been initialized: display the waiting radar + var hookElem = document.getElementById(hook); + if (hookElem) hookElem.innerHTML = "
<\/div>"; + } + if (xhrObjects[pos].xhr.readyState == 4) { + // We have received the HTML chunk + var hookElem = document.getElementById(hook); + if (hookElem && (xhrObjects[pos].xhr.status == 200)) { + hookElem.innerHTML = xhrObjects[pos].xhr.responseText; + // Call a custom Javascript function if required + if (xhrObjects[pos].onGet) { + xhrObjects[pos].onGet(xhrObjects[pos], hookElem); + } + // Eval inner scripts if any. + var innerScripts = document.getElementsByName("appyHook"); + for (var i=0; i
@@ -97,11 +97,11 @@ - - @@ -110,7 +110,7 @@ - diff --git a/gen/plone25/skin/page.pt b/gen/plone25/skin/page.pt index a40441c..dbd9ef8 100644 --- a/gen/plone25/skin/page.pt +++ b/gen/plone25/skin/page.pt @@ -2,374 +2,9 @@ This macro contains global page-related Javascripts.
- Global elements used in every page. - Javascript messages - "Static" javascripts - Global form for deleting an object
@@ -405,14 +40,14 @@ layoutType We must know if we must render the widgets in a "view", "edit" or "cell" layout -
- + - +
@@ -501,7 +136,7 @@ tal:content="python: tool.translate(contextObj.getWorkflowLabel(stateInfo['name']))"> - + @@ -558,15 +193,13 @@ tal:condition="not: contextObj/isTemporary"> Information that is common to all tabs (object title, state, etc) - - - Title and state - +
- -
+ + Title + - - + Object history - + Workflow-related information and actions - - +
+
Creator and last modification date Plus/minus icon for accessing history @@ -579,34 +212,32 @@ Show document creator - - by + + by Show last modification date -
-
+
@@ -622,7 +253,7 @@ The page footer. - + - - + + diff --git a/gen/plone25/skin/result.pt b/gen/plone25/skin/result.pt index c01d0d6..1919f2d 100644 --- a/gen/plone25/skin/result.pt +++ b/gen/plone25/skin/result.pt @@ -1,6 +1,5 @@ + newSearchUrl python: '%s/skyn/search?type_name=%s&ref=%s' % (tool.absolute_url(), contentType, refInfo);"> @@ -36,7 +35,7 @@ Display here POD templates if required. -
@@ -46,7 +45,7 @@
- +
@@ -118,21 +117,21 @@ Column "Actions"
+ class="list" width="100%"> Headers, with filters and sort arrows
- +
Edit the element - Delete the element - diff --git a/gen/plone25/skin/search.gif b/gen/plone25/skin/search.gif index ccdee1d37f9bea828abe28a4c740de241a4a4552..9640de52a2c4f3a654e3dcede232640c4d607635 100644 GIT binary patch delta 101 zcmdnUyqA&3-P6s&GLfHwm!XAsB2Qv~;!hSv1_pTs9R?r(2{W)-Jy7pU$()zAV9{d- zkz)t>Iw$G$)bM#Nw&0)Jxvb$q%i)fcq6Hi5+BKdARQBmiU-h;5YShLVy5`DUj11NQ D&j%u4 literal 433 zcmZ?wbhEHb6kyI>if{QNFnym;sJuNR;G z9K8K={>iWZ|NlSv;OEja-|oEred58-19yI`KL35so;~09m(EI2c~&d?>-wsL+m-;8 zVFCtP0>%H_ey$ - - - - Disable standard Plone green tabs -
- -
-
+ + + Include type-specific CSS and JS. - - - - - - - - - - - - - + + Search title

— @@ -49,7 +22,7 @@ -

+ + tal:condition="python: obj.allows('Modify portal content')"> + tal:attributes="src string: $appUrl/skyn/edit.gif"/> - +
+
@@ -69,7 +42,6 @@

- - + - + diff --git a/gen/plone25/skin/template.pt b/gen/plone25/skin/template.pt index 35117f6..68d90ba 100644 --- a/gen/plone25/skin/template.pt +++ b/gen/plone25/skin/template.pt @@ -1,14 +1,16 @@ + x python: resp.setHeader('Content-Language', req.get('language', 'en'))"> @@ -17,14 +19,14 @@ - +
Top banner - The message strip - - -
Logo - + Language selector (links or listbox) + + The user data strip @@ -103,20 +135,16 @@
The message strip +
+
+ +
+ Grey background shown when popups are shown +
+ + Popup for confirming an action + +
@@ -88,12 +115,17 @@ - + + + - +
-
-
-
-
- - - diff --git a/gen/plone25/skin/view.pt b/gen/plone25/skin/view.pt index 95f411d..440c5c1 100644 --- a/gen/plone25/skin/view.pt +++ b/gen/plone25/skin/view.pt @@ -1,34 +1,17 @@ - - - - - Disable standard Plone green tabs -
- -
-
- - Fill main slot of Plone main_template - - - - - - - + + + + + + + + diff --git a/gen/plone25/skin/widgets/computed.pt b/gen/plone25/skin/widgets/computed.pt index e0acae4..3bc6295 100644 --- a/gen/plone25/skin/widgets/computed.pt +++ b/gen/plone25/skin/widgets/computed.pt @@ -20,17 +20,17 @@ widget python: contextObj.getAppyType(name, asDict=True); value python: contextObj.getFieldValue(name); sync python:True"> - + Edit macro for a Computed. - + Cell macro for a Computed. - + Search macro for a Computed. diff --git a/gen/plone25/skin/widgets/date.pt b/gen/plone25/skin/widgets/date.pt index b7eab48..b6a2499 100644 --- a/gen/plone25/skin/widgets/date.pt +++ b/gen/plone25/skin/widgets/date.pt @@ -44,7 +44,7 @@ The icon for displaying the calendar (=date chooser) + tal:attributes="onclick python: 'return showJsCalendar(\'%s_month\', \'%s\', \'%s_year\', \'%s_month\', \'%s_day\', null, null, %d, %d)' % (name, dummyName, name, name, name, years[0], years[-1])">
To @@ -142,7 +142,7 @@ - +
+ + + Portlet + + Page content +
+
diff --git a/gen/plone25/skin/widgets/file.pt b/gen/plone25/skin/widgets/file.pt index 332593e..19ef3bd 100644 --- a/gen/plone25/skin/widgets/file.pt +++ b/gen/plone25/skin/widgets/file.pt @@ -4,7 +4,7 @@ imageSrc string:${contextObj/absolute_url}/download?name=$name"> + tal:condition="icon" tal:attributes="src string: $appUrl/$icon"/>   - diff --git a/gen/plone25/skin/widgets/pod.pt b/gen/plone25/skin/widgets/pod.pt index f09db67..10211c9 100644 --- a/gen/plone25/skin/widgets/pod.pt +++ b/gen/plone25/skin/widgets/pod.pt @@ -8,7 +8,7 @@ tal:content="python: tool.translate(doLabel)"> diff --git a/gen/plone25/skin/widgets/ref.pt b/gen/plone25/skin/widgets/ref.pt index 777d82b..08dc54c 100644 --- a/gen/plone25/skin/widgets/ref.pt +++ b/gen/plone25/skin/widgets/ref.pt @@ -19,39 +19,39 @@ Displays icons for triggering actions on a given referenced object (edit, delete, etc). - +
Arrows for moving objects up or down - Edit the element - Delete the element - @@ -68,7 +68,7 @@ formCall python: test(appyType['addConfirm'], 'askConfirm(\'script\', "%s", "%s")' % (formCall, addConfirmMsg), formCall); noFormCall python: navBaseCall.replace('**v**', '%d, \'CreateWithoutForm\'' % startNumber); noFormCall python: test(appyType['addConfirm'], 'askConfirm(\'script\', "%s", "%s")' % (noFormCall, addConfirmMsg), noFormCall)" - tal:attributes="src string:$portal_url/skyn/plus.png; + tal:attributes="src string:$appUrl/skyn/plus.png; title python: tool.translate('add_ref'); onClick python: test(appyType['noForm'], noFormCall, formCall)"/> @@ -81,10 +81,10 @@ tal:define="ajaxBaseCall python: navBaseCall.replace('**v**', '\'%s\',\'SortReference\', {\'sortKey\':\'%s\', \'reverse\':\'**v**\'}' % (startNumber, widget['name']))" tal:condition="python: canWrite and tool.isSortable(widget['name'], objs[0].meta_type, 'ref')"> @@ -115,16 +115,16 @@ folder python: contextObj.isPrincipiaFolderish and contextObj or contextObj.getParentNode(); linkedPortalType python: tool.getPortalType(appyType['klass']); addPermission python: '%s: Add %s' % (tool.getAppName(), linkedPortalType); - canWrite python: not appyType['isBack'] and member.has_permission(appyType['writePermission'], contextObj); + canWrite python: not appyType['isBack'] and contextObj.allows(appyType['writePermission']); multiplicity appyType/multiplicity; maxReached python:(multiplicity[1] != None) and (len(objs) >= multiplicity[1]); - showPlusIcon python:not appyType['isBack'] and appyType['add'] and not maxReached and member.has_permission(addPermission, folder) and canWrite; + showPlusIcon python:not appyType['isBack'] and appyType['add'] and not maxReached and user.has_permission(addPermission, folder) and canWrite; atMostOneRef python: (multiplicity[1] == 1) and (len(objs)<=1); label python: contextObj.translate('label', field=appyType); addConfirmMsg python: appyType['addConfirm'] and tool.translate('%s_addConfirm' % appyType['labelId']) or ''; navBaseCall python: 'askRefField(\'%s\',\'%s\',\'%s\',\'%s\',**v**)' % (ajaxHookId, contextObj.absolute_url(), fieldName, innerRef)"> - This macro displays the Reference widget on a "consult" page. + This macro displays the Reference widget on a "view" page. The definition of "atMostOneRef" above may sound strange: we shouldn't check the actual number of referenced objects. But for back references people often forget to specify multiplicities. @@ -133,20 +133,20 @@ Display a simplified widget if maximum number of referenced objects is 1. -
+ Move up Move down + + tal:attributes="src string: $appUrl/skyn/edit.gif"/> - +
+
If there is no object... - + If there is an object... - +
@@ -158,7 +158,7 @@ () - + The search icon if field is queryable @@ -175,28 +175,27 @@ No object is present

-
Show forward or backward reference(s) - +
- Actions @@ -254,7 +253,7 @@ Cell macro for a Ref. - + Search macro for a Ref. diff --git a/gen/plone25/skin/widgets/show.pt b/gen/plone25/skin/widgets/show.pt index ac5b443..dd44798 100644 --- a/gen/plone25/skin/widgets/show.pt +++ b/gen/plone25/skin/widgets/show.pt @@ -8,10 +8,10 @@ Options: contextMacro The base folder containing the macros to call for rendering the elements within the layout. - Defaults to portal.skyn + Defaults to app.skyn + tal:define="contextMacro contextMacro| python: app.skyn">
- +
- + @@ -205,13 +204,13 @@ - + - +
+ style python: test(repeat['cell'].end, '', 'padding-right: 0.4em')">
@@ -42,7 +42,7 @@ widget The widget to render - +
- + - + - - @@ -141,7 +141,7 @@ class widget/style" align="left"> - + @@ -164,10 +164,10 @@ style python: test(repeat['widget'].number() != len(widgetRow), 'padding-right: %s'%cellgap, '')"> - + - + @@ -182,10 +182,10 @@ Displays a field help. - + Displays validation-error-related info about a field. - + Displays the fact that a field is required. - + diff --git a/gen/plone25/skin/widgets/string.pt b/gen/plone25/skin/widgets/string.pt index be4ba95..e0949e1 100644 --- a/gen/plone25/skin/widgets/string.pt +++ b/gen/plone25/skin/widgets/string.pt @@ -74,7 +74,7 @@ content="python: ', '.join(value)"> - + diff --git a/gen/plone25/templates/IEFixes.css.dtml b/gen/plone25/templates/IEFixes.css.dtml deleted file mode 100644 index 9970dd5..0000000 --- a/gen/plone25/templates/IEFixes.css.dtml +++ /dev/null @@ -1,82 +0,0 @@ -/* Appy-specific IE-fixes */ -.portletSearch { font-size: 85%; border-left: 1px solid #8cacbb; border-right: 1px solid #8cacbb; } - -/* Stylesheet with Internet Explorer-specific workarounds. */ -* html #portal-columns { width: 100%; } -* html*#portal-columns { width: auto; } - -/* */ -#topIcons { right: 238px; } -#portal-globalnav { margin-top: -1px; } -#portal-globalnav th { height: 32px; } -.navTreeItem a, dd.portletItem .navTreeItem a { font-size: 105%; } -#portlet-navigation-tree { margin-top: 8px; } -.navigation-section-header { height: 28px; } -#portal-globalnav a { font-size: 110%; } -#portal-column-two .portletHeader { font-size:110%; padding-bottom:11px; } -#portlet-hp-news .portletHeader { margin-top: 1px; } -.section-ncp-home .portletHeader { font-size:110%; } -input { margin-bottom: 1px; } -table.listing td.top { position: relative; left: -1px; top: -1px; } -div#portal-columns div.portlet { text-align: left; } -div#portal-columns div#portal-column-one, -div#portal-columns div#portal-column-two { overflow: hidden; } -textarea { width: 97%; } -.visualOverflow { width: 88%; } -.visualGhosted { filter:alpha(opacity=20); } -#portal-logo { - height /**/: px; - overflow: hidden; -} - -#clear-space-before-wrapper-table { display: none }; -/* Fix bottom margin on tabs in IE */ -#portal-globalnav li.selected a { position: relative; } -#portal-colophon .colophonIcon { height: 0px !important; height /**/: 15px; } -.actionMenu .actionMenuHeader a { display: inline; } -.actionMenu .actionMenuContent { top: 1.4em; } - -/* Calendar fixes */ -.ploneCalendar { border-collapse:collapse; width:auto; height:1%; } -.ploneCalendar td { width:1%; } -.ploneCalendar .todaynoevent, -.ploneCalendar .todayevent { position: relative; } -.hiddenStructure { position: absolute; } - -body { /* These work in IE only, changes the look of the scrollbar + textareas */ - scrollbar-base-color: &dtml-globalBackgroundColor;; - scrollbar-highlight-color: &dtml-globalBackgroundColor;; - scrollbar-track-color: &dtml-evenRowBackgroundColor;; - scrollbar-darkshadow-color: &dtml-evenRowBackgroundColor;; - scrollbar-3dlight-color: &dtml-globalBorderColor;; - scrollbar-shadow-color: &dtml-globalBorderColor;; - scrollbar-arrow-color: &dtml-globalFontColor;; -} - -#floatholder, #float { height: 1%; } -* html .link-external, -* html .link-external a, -* html .link-mailto a, -* html .link-mailto { height: 1%; } -* html .visualIEFloatFix, -* html h1, -* html h2, -* html h3, -* html h4, -* html h5, -* html h6, -* html dd, -* html .documentDescription, -* html .visualClear, -* html .portalMessage, -* html .portalWarningMessage, -* html .portalStopMessage, -* html .system-message, -* html #error-handling, -* html .documentContent { height: 0.1%; } -* html p { position: relative; } -* html h1.documentFirstHeading { height: auto; } -* html #objectMenu.actionMenu .actionMenuContent li { height: auto; } -#portal-searchbox { overflow: hidden; } - -/* */ diff --git a/gen/plone25/templates/Portlet.pt b/gen/plone25/templates/Portlet.pt deleted file mode 100644 index e69e71f..0000000 --- a/gen/plone25/templates/Portlet.pt +++ /dev/null @@ -1,17 +0,0 @@ - - -
- - -
- -
-
- - diff --git a/gen/plone25/templates/Styles.css.dtml b/gen/plone25/templates/Styles.css.dtml index 0491dab..64507fc 100644 --- a/gen/plone25/templates/Styles.css.dtml +++ b/gen/plone25/templates/Styles.css.dtml @@ -1,20 +1,11 @@ -/* (this is for http compression) */ -/* (do not remove this :) */ -/* (not this either :) */ - textarea { width: 99%; } -#portal-breadcrumbs { display: none; } #importedElem { color: grey; font-style: italic; } label { font-weight: bold; font-style: italic; line-height: 1.4em; font-size: 92%;} -.discreet { font-size: 94%; } .appyList { line-height: 1.1em; margin: 0 0 0.5em 1.2em; padding: 0; } .appyBullet { margin: 0; } .appyPod { float:right; } -.appyNav { padding: 0.4em 0 0.4em 0; } .appyFocus { color: #900101; } -.appyTitle { padding-top: 0.5em; font-size: 110%; } -.appyWorkflow { text-align: center; background-color: &dtml-globalBackgroundColor;;} .appyPlusImg { vertical-align: top; @@ -23,12 +14,6 @@ label { font-weight: bold; font-style: italic; line-height: 1.4em; font- top: -0.55em; } -.appyPhase { - border-style: dashed; - border-width: thin; - padding: 0 0.6em 0 1em; -} - .appyState { font-size: 85%; font-style: normal; @@ -61,54 +46,6 @@ label { font-weight: bold; font-style: italic; line-height: 1.4em; font- font-size: 105%; } -/* Following classes are used for displaying status of a phase or state. */ -.stepDone { - background-color: #cde2a7; - background-image: url(&dtml-portal_url;/skyn/done.png); - background-repeat: no-repeat; - background-position: -1px 7px; -} -.stepDoneState { - background-color: #cde2a7; - background-image: url(&dtml-portal_url;/skyn/done.png); - background-repeat: no-repeat; - background-position: -1px 4px; -} - -.stepCurrent { - background-color: #eef3f5; - background-image: url(&dtml-portal_url;/skyn/current.png); - background-repeat: no-repeat; - background-position: -1px 7px; -} -.stepCurrentState { - background-color: #eef3f5; - background-image: url(&dtml-portal_url;/skyn/current.png); - background-repeat: no-repeat; - background-position: -1px 4px; -} - -.stepFuture { - background-color: #ffffff; - color: #C8C8C8; - border-style: dashed; -} - -.stepUnselected { - background-color: #ffffff; -} - -.appyCommonInfo { - border-color: #ffa500; - background-color: &dtml-evenRowBackgroundColor;; - border-style: solid; - border-width: 2px; - margin-bottom: 0.5em; -} - -/* With fields layout in columns, standard error frame is too large */ -.odd { background-color: white; } - /* Tooltip */ a.tooltip span { display:none; @@ -126,18 +63,6 @@ a.tooltip:hover span { } /* Table styles */ -.no-style-table { - border: 0 !important; - padding: 0 !important; - margin: 0 !important; -} - -.no-style-table td { - border: 0 !important; - padding-left: 0 !important; - margin: 0 !important; -} - fieldset { line-height: 1em; border: 2px solid #8CACBB; @@ -145,41 +70,6 @@ fieldset { padding: 0 0.7em 0.5em; } -th { - font-style: italic; - font-weight: normal; -} - -.section1 { - font-size: 120%; - margin: 0.45em 0em 0.1em 0; - padding: 0.3em 0em 0.2em 0.1em; - background-color: #eef3f5; - border-top: 1px solid #8CACBB; - border-bottom: 1px solid #8CACBB; -} - -.section2 { - font-size: 110%; - font-style: italic; - margin: 0.45em 0em 0.1em 0; - border-bottom: 2px solid #8CACBB; -} - -.section3 { - font-size: 100%; - font-style: italic; - margin: 0.45em 0em 0.1em 0; - background-color: #efeae8; - text-align: center; - color: grey; -} - -.imageInput { - border-width: 0px; - background: none; -} - .noPadding { padding-right: 0em !important; padding-left: 0em !important; @@ -238,14 +128,6 @@ th { text-transform: none; padding: 1px 0.5em; } -.portletAppyItem { - margin: 0; - padding: 1px 0.5em; - border-left: 1px solid #8cacbb; - border-right: 1px solid #8cacbb; - font-weight: normal; - text-transform: none; -} .portletSearch { padding: 0 0 0 0.6em; font-style: normal; @@ -256,53 +138,10 @@ th { font-weight: bold; font-style: normal; } -.portletSep { border-top: 1px dashed #8cacbb; } + .portletGroupItem { padding-left: 0.8em; font-style: italic; } -.portletPageItem { font-style: italic; } -.portletCurrent { font-weight: bold; } .portletMenu { margin-bottom: 0.4em; } -div.appyGrey { - display: none; - position: absolute; - left: 0px; - top: 0px; - width:100%; - height:100%; - background:gray; - filter:alpha(Opacity=50); - opacity:0.5; - -moz-opacity:0.5; - -khtml-opacity:0.5 -} -div.appyPopup { - display: none; - position: absolute; - top: 30%; - left: 35%; - width: 350px; - z-index : 100; - background: white; - padding: 8px; - border: 1px solid gray; -} - -.translationLabel { - background-color: #EAEAEA; - border-bottom: 1px dashed grey; - margin-top: 1em; - margin-bottom: 0.5em; -} - -/* Uncomment this if you want to hide breadcrumbs */ -/* -#portal-breadcrumbs { - display: none; -} -*/ - -/* */ - /* image-right, but without border */ .image-right { border:0px solid Black; @@ -311,47 +150,4 @@ div.appyPopup { margin:0.5em; } -/* DOCUMENTATION ON PRE-DEFINED PROPERTIES FROM PLONE */ - - /* You can insert colors and other variables from Plone's - base_properties by doing: - & dtml-variableName ; (without the spaces, excluded here to not make it render) - - Example: - myLink { - color: & dtml-fontColor ; (again, without the spaces) - } - This means you can generate your own elements that use Plone's defaults, - and respect any customizations people have done. See base_properties for - the default values. - - These are the available properties: - logoName - the file name of the portal logo. - fontFamily - the font family used for all text that is not headers - fontBaseSize - the base font size that everything is calculated from - fontColor - the main font color - backgroundColor - the background color - linkColor - the color used on normal links - linkActiveColor - color used on active links - linkVisitedColor - color used on visited links - borderWidth - the width of most borders in Plone - borderStyle - the style of the border lines, normally solid - borderStyleAnnotations - style of border lines on comments etc - globalBorderColor - the border color used on the main tabs, the portlets etc - globalBackgroundColor - background color for the selected tabs, portlet headings etc - globalFontColor - the color of the font in the tabs and in portlet headings - headingFontFamily - font family for h1/h2/h3/h4/h5/h6 headlines. - headingFontBaseSize - the base size used when calculating the different headline sizes - contentViewBorderColor - the content view tabs border color - contentViewBackgroundColor - the content view tabs background color - contentViewFontColor - the font color used in the content view tabs - textTransform - whether to lowercase text in portlets, tabs etc. - evenRowBackgroundColor - the background color of even rows in listings - oddRowBackgroundColor - the background color of even rows in listings - notifyBorderColor - border color of notification elements like the status message, the calendar focus - notifyBackgroundColor - background color of notification elements like the status message, the calendar focus - discreetColor:string=#999999 - helpBackgroundColor:string=#ffffe1 - */ - diff --git a/gen/plone25/templates/colophon.pt b/gen/plone25/templates/colophon.pt deleted file mode 100644 index 54d062b..0000000 --- a/gen/plone25/templates/colophon.pt +++ /dev/null @@ -1,7 +0,0 @@ - - -
-
- - diff --git a/gen/plone25/templates/config.py b/gen/plone25/templates/config.py index d0e6feb..93ce0b9 100644 --- a/gen/plone25/templates/config.py +++ b/gen/plone25/templates/config.py @@ -66,10 +66,8 @@ applicationGlobalRoles = [] grantableRoles = [] # Configuration options -showPortlet = languages = [] languageSelector = -minimalistPlone = appFrontPage = sourceLanguage = '' # ------------------------------------------------------------------------------ diff --git a/gen/plone25/templates/footer.pt b/gen/plone25/templates/footer.pt deleted file mode 100644 index 8b4f327..0000000 --- a/gen/plone25/templates/footer.pt +++ /dev/null @@ -1,7 +0,0 @@ - - - - -
- @@ -111,10 +111,10 @@ style python: test(repeat['widgetRow'].number()==1, 'display:table-row', 'display:none')"> - + - +