[webconfig] introduce property sheets. Use them to replace external_resources
--- a/cwconfig.py Thu Apr 29 14:21:59 2010 +0200
+++ b/cwconfig.py Fri Apr 30 12:14:15 2010 +0200
@@ -664,7 +664,8 @@
self.debugmode = debugmode
self.adjust_sys_path()
self.load_defaults()
- self.translations = {}
+ # will be properly initialized later by _gettext_init
+ self.translations = {'en': (unicode, lambda ctx, msgid: unicode(msgid) )}
# don't register ReStructured Text directives by simple import, avoid pb
# with eg sphinx.
# XXX should be done properly with a function from cw.uicfg
@@ -985,7 +986,7 @@
super(CubicWebConfiguration, self).load_configuration()
if self.apphome and self.set_language:
# init gettext
- self._set_language()
+ self._gettext_init()
def init_log(self, logthreshold=None, force=False):
"""init the log service"""
@@ -1013,7 +1014,7 @@
if lang != 'en':
yield lang
- def _set_language(self):
+ def _gettext_init(self):
"""set language for gettext"""
from gettext import translation
path = join(self.apphome, 'i18n')
--- a/cwvreg.py Thu Apr 29 14:21:59 2010 +0200
+++ b/cwvreg.py Fri Apr 30 12:14:15 2010 +0200
@@ -449,7 +449,6 @@
super(CubicWebVRegistry, self).__init__(config)
self.schema = None
self.initialized = False
- self.reset()
# XXX give force_reload (or refactor [re]loading...)
if self.config.mode != 'test':
# don't clear rtags during test, this may cause breakage with
--- a/devtools/fake.py Thu Apr 29 14:21:59 2010 +0200
+++ b/devtools/fake.py Fri Apr 30 12:14:15 2010 +0200
@@ -39,6 +39,7 @@
self['uid'] = None
self['base-url'] = BASE_URL
self['rql-cache-size'] = 100
+ self.datadir_url = BASE_URL + 'data/'
def cubes(self, expand=False):
return self._cubes
--- a/server/session.py Thu Apr 29 14:21:59 2010 +0200
+++ b/server/session.py Fri Apr 30 12:14:15 2010 +0200
@@ -302,16 +302,15 @@
def set_language(self, language):
"""i18n configuration for translation"""
- vreg = self.vreg
language = language or self.user.property_value('ui.language')
try:
- gettext, pgettext = vreg.config.translations[language]
+ gettext, pgettext = self.vreg.config.translations[language]
self._ = self.__ = gettext
self.pgettext = pgettext
except KeyError:
- language = vreg.property_value('ui.language')
+ language = self.vreg.property_value('ui.language')
try:
- gettext, pgettext = vreg.config.translations[language]
+ gettext, pgettext = self.vreg.config.translations[language]
self._ = self.__ = gettext
self.pgettext = pgettext
except KeyError:
--- a/web/data/external_resources Thu Apr 29 14:21:59 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-# -*- shell-script -*-
-###############################################################################
-#
-# external resources file for core library resources
-#
-# Commented values are default values used by the application.
-#
-###############################################################################
-
-
-# CSS stylesheets to include in HTML headers
-STYLESHEETS = DATADIR/cubicweb.reset.css, DATADIR/cubicweb.css
-
-# CSS stylesheets for print
-#STYLESHEETS_PRINT = DATADIR/cubicweb.print.css
-
-#CSS stylesheets for IE
-#IE_STYLESHEETS = DATADIR/cubicweb.ie.css
-
-# Javascripts files to include in HTML headers
-#JAVASCRIPTS = DATADIR/jquery.js, DATADIR/cubicweb.python.js, DATADIR/jquery.json.js, DATADIR/cubicweb.compat.js, DATADIR/cubicweb.htmlhelpers.js
-
-# path to favicon (relative to the application main script, seen as a
-# directory, hence .. when you are not using an absolute path)
-#FAVICON = DATADIR/favicon.ico
-
-# path to the logo (relative to the application main script, seen as a
-# directory, hence .. when you are not using an absolute path)
-LOGO = DATADIR/logo.png
-
-# rss logo (link to get the rss view of a selection)
-RSS_LOGO = DATADIR/rss.png
-RSS_LOGO_16 = DATADIR/feed-icon16x16.png
-RSS_LOGO_32 = DATADIR/feed-icon32x32.png
-
-# path to search image
-SEARCH_GO = DATADIR/go.png
-
-#FCKEDITOR_PATH = /usr/share/fckeditor/
-
-PUCE_UP = DATADIR/puce_up.png
-PUCE_DOWN = DATADIR/puce_down.png
-
-# icons for entity types
-BOOKMARK_ICON = DATADIR/icon_bookmark.gif
-EMAILADDRESS_ICON = DATADIR/icon_emailaddress.gif
-EUSER_ICON = DATADIR/icon_euser.gif
-STATE_ICON = DATADIR/icon_state.gif
-
-# other icons
-CALENDAR_ICON = DATADIR/calendar.gif
-CANCEL_EMAIL_ICON = DATADIR/sendcancel.png
-SEND_EMAIL_ICON = DATADIR/sendok.png
-DOWNLOAD_ICON = DATADIR/download.gif
-UPLOAD_ICON = DATADIR/upload.gif
-GMARKER_ICON = DATADIR/gmap_blue_marker.png
-UP_ICON = DATADIR/up.gif
-
-OK_ICON = DATADIR/ok.png
-CANCEL_ICON = DATADIR/cancel.png
-APPLY_ICON = DATADIR/plus.png
-TRASH_ICON = DATADIR/trash_can_small.png
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/web/data/uiprops.py Fri Apr 30 12:14:15 2010 +0200
@@ -0,0 +1,57 @@
+"""define default ui properties"""
+
+# CSS stylesheets to include systematically in HTML headers
+STYLESHEETS = ['%s/cubicweb.reset.css' % datadir_url,
+ '%s/cubicweb.css' % datadir_url]
+STYLESHEETS_IE = ['%s/cubicweb.ie.css' % datadir_url]
+STYLESHEETS_PRINT = ['%s/cubicweb.print.css' % datadir_url]
+
+# Javascripts files to include systematically in HTML headers
+JAVASCRIPTS = ['%s/jquery.js' % datadir_url,
+ '%s/jquery.corner.js' % datadir_url,
+ '%s/jquery.json.js' % datadir_url,
+ '%s/cubicweb.compat.js' % datadir_url,
+ '%s/cubicweb.python.js' % datadir_url,
+ '%s/cubicweb.htmlhelpers.js' % datadir_url]
+
+# where is installed fckeditor
+FCKEDITOR_PATH = '/usr/share/fckeditor/'
+
+# favicon and logo for the instance
+FAVICON = '%s/favicon.ico' % datadir_url
+LOGO = '%s/logo.png' % datadir_url
+
+# rss logo (link to get the rss view of a selection)
+RSS_LOGO = '%s/rss.png' % datadir_url
+RSS_LOGO_16 = '%s/feed-icon16x16.png' % datadir_url
+RSS_LOGO_32 = '%s/feed-icon32x32.png' % datadir_url
+
+# XXX cleanup resources below, some of them are probably not used
+# (at least entity types icons...)
+
+# images
+HELP = '%s/help.png' % datadir_url
+SEARCH_GO = '%s/go.png' % datadir_url
+PUCE_UP = '%s/puce_up.png' % datadir_url
+PUCE_DOWN = '%s/puce_down.png' % datadir_url
+
+# button icons
+OK_ICON = '%s/ok.png' % datadir_url
+CANCEL_ICON = '%s/cancel.png' % datadir_url
+APPLY_ICON = '%s/plus.png' % datadir_url
+TRASH_ICON = '%s/trash_can_small.png' % datadir_url
+
+# icons for entity types
+BOOKMARK_ICON = '%s/icon_bookmark.gif' % datadir_url
+EMAILADDRESS_ICON = '%s/icon_emailaddress.gif' % datadir_url
+EUSER_ICON = '%s/icon_euser.gif' % datadir_url
+STATE_ICON = '%s/icon_state.gif' % datadir_url
+
+# other icons
+CALENDAR_ICON = '%s/calendar.gif' % datadir_url
+CANCEL_EMAIL_ICON = '%s/sendcancel.png' % datadir_url
+SEND_EMAIL_ICON = '%s/sendok.png' % datadir_url
+DOWNLOAD_ICON = '%s/download.gif' % datadir_url
+UPLOAD_ICON = '%s/upload.gif' % datadir_url
+GMARKER_ICON = '%s/gmap_blue_marker.png' % datadir_url
+UP_ICON = '%s/up.gif' % datadir_url
--- a/web/formwidgets.py Thu Apr 29 14:21:59 2010 +0200
+++ b/web/formwidgets.py Fri Apr 30 12:14:15 2010 +0200
@@ -550,7 +550,7 @@
return (u"""<a onclick="toggleCalendar('%s', '%s', %s, %s);" class="calhelper">
<img src="%s" title="%s" alt="" /></a><div class="calpopup hidden" id="%s"></div>"""
% (helperid, inputid, year, month,
- form._cw.external_resource('CALENDAR_ICON'),
+ form._cw.vreg.config.uiprops['CALENDAR_ICON'],
form._cw._('calendar'), helperid) )
@@ -574,7 +574,7 @@
req.add_onload(u'jqNode("%s").datepicker('
'{buttonImage: "%s", dateFormat: "%s", firstDay: 1,'
' showOn: "button", buttonImageOnly: true})' % (
- domid, req.external_resource('CALENDAR_ICON'), fmt))
+ domid, req.vreg.config.uiprops['CALENDAR_ICON'], fmt))
if self.datestr is None:
value = self.values(form, field)[0]
else:
@@ -954,7 +954,7 @@
if self.settabindex and not 'tabindex' in attrs:
attrs['tabindex'] = form._cw.next_tabindex()
if self.icon:
- img = tags.img(src=form._cw.external_resource(self.icon), alt=self.icon)
+ img = tags.img(src=form._cw.vreg.config.uiprops[self.icon], alt=self.icon)
else:
img = u''
return tags.button(img + xml_escape(label), escapecontent=False,
@@ -985,7 +985,7 @@
def render(self, form, field=None, renderer=None):
label = form._cw._(self.label)
- imgsrc = form._cw.external_resource(self.imgressource)
+ imgsrc = form._cw.vreg.config.uiprops[self.imgressource]
return '<a id="%(domid)s" href="%(href)s">'\
'<img src="%(imgsrc)s" alt="%(label)s"/>%(label)s</a>' % {
'label': label, 'imgsrc': imgsrc,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/web/propertysheet.py Fri Apr 30 12:14:15 2010 +0200
@@ -0,0 +1,31 @@
+# copyright 2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
+#
+# This file is part of CubicWeb.
+#
+# CubicWeb is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 2.1 of the License, or (at your option)
+# any later version.
+#
+# CubicWeb 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 Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License along
+# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
+"""property sheets allowing configuration of the web ui"""
+
+__docformat__ = "restructuredtext en"
+
+class PropertySheet(dict):
+ def __init__(self, **context):
+ self._context = context
+ context['sheet'] = self
+
+ def load(self, fpath):
+ scriptglobals = self._context.copy()
+ scriptglobals['__file__'] = fpath
+ execfile(fpath, scriptglobals, self)
+
--- a/web/request.py Thu Apr 29 14:21:59 2010 +0200
+++ b/web/request.py Fri Apr 30 12:14:15 2010 +0200
@@ -99,7 +99,7 @@
self.next_tabindex = self.tabindexgen.next
# page id, set by htmlheader template
self.pageid = None
- self.datadir_url = self._datadir_url()
+ self.datadir_url = vreg.config.datadir_url
self._set_pageid()
# prepare output header
self.headers_out = Headers()
@@ -589,10 +589,6 @@
"""return currently accessed url"""
return self.base_url() + self.relative_path(includeparams)
- def _datadir_url(self):
- """return url of the instance's data directory"""
- return self.base_url() + 'data%s/' % self.vreg.config.instance_md5_version()
-
def selected(self, url):
"""return True if the url is equivalent to currently accessed url"""
reqpath = self.relative_path().lower()
@@ -618,25 +614,6 @@
return controller
return 'view'
- def external_resource(self, rid, default=_MARKER):
- """return a path to an external resource, using its identifier
-
- raise KeyError if the resource is not defined
- """
- try:
- value = self.vreg.config.ext_resources[rid]
- except KeyError:
- if default is _MARKER:
- raise
- return default
- if value is None:
- return None
- baseurl = self.datadir_url[:-1] # remove trailing /
- if isinstance(value, list):
- return [v.replace('DATADIR', baseurl) for v in value]
- return value.replace('DATADIR', baseurl)
- external_resource = cached(external_resource, keyarg=1)
-
def validate_cache(self):
"""raise a `DirectResponse` exception if a cached page along the way
exists and is still usable.
@@ -712,12 +689,6 @@
auth, ex.__class__.__name__, ex)
return None, None
- @deprecated("[3.4] use parse_accept_header('Accept-Language')")
- def header_accept_language(self):
- """returns an ordered list of preferred languages"""
- return [value.split('-')[0] for value in
- self.parse_accept_header('Accept-Language')]
-
def parse_accept_header(self, header):
"""returns an ordered list of preferred languages"""
accepteds = self.get_header(header, '')
@@ -823,5 +794,25 @@
u'<div xmlns="http://www.w3.org/1999/xhtml" xmlns:cubicweb="http://www.logilab.org/2008/cubicweb">')
return u'<div>'
+ @deprecated('[3.9] use req.vreg.config.uiprops[rid]')
+ def external_resource(self, rid, default=_MARKER):
+ """return a path to an external resource, using its identifier
+
+ raise `KeyError` if the resource is not defined
+ """
+ try:
+ return self.vreg.config.uiprops[rid]
+ except KeyError:
+ if default is _MARKER:
+ raise
+ return default
+
+ @deprecated("[3.4] use parse_accept_header('Accept-Language')")
+ def header_accept_language(self):
+ """returns an ordered list of preferred languages"""
+ return [value.split('-')[0] for value in
+ self.parse_accept_header('Accept-Language')]
+
+
from cubicweb import set_log_methods
set_log_methods(CubicWebRequestBase, LOGGER)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/web/test/data/sheet1.py Fri Apr 30 12:14:15 2010 +0200
@@ -0,0 +1,3 @@
+bgcolor = '#000000'
+stylesheets = ['%s/cubicweb.css' % datadir_url]
+logo = '%s/logo.png' % datadir_url
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/web/test/data/sheet2.py Fri Apr 30 12:14:15 2010 +0200
@@ -0,0 +1,3 @@
+fontcolor = 'black'
+bgcolor = '#FFFFFF'
+stylesheets = sheet['stylesheets'] + ['%s/mycube.css' % datadir_url]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/web/test/unittest_propertysheet.py Fri Apr 30 12:14:15 2010 +0200
@@ -0,0 +1,24 @@
+from os.path import join, dirname
+from logilab.common.testlib import TestCase, unittest_main
+from cubicweb.web.propertysheet import *
+
+DATADIR = join(dirname(__file__), 'data')
+class PropertySheetTC(TestCase):
+
+ def test(self):
+ ps = PropertySheet(datadir_url='http://cwtest.com')
+ ps.load(join(DATADIR, 'sheet1.py'))
+ ps.load(join(DATADIR, 'sheet2.py'))
+ # defined by sheet1
+ self.assertEquals(ps['logo'], 'http://cwtest.com/logo.png')
+ # defined by sheet1, overriden by sheet2
+ self.assertEquals(ps['bgcolor'], '#FFFFFF')
+ # defined by sheet2
+ self.assertEquals(ps['fontcolor'], 'black')
+ # defined by sheet1, extended by sheet2
+ self.assertEquals(ps['stylesheets'], ['http://cwtest.com/cubicweb.css',
+ 'http://cwtest.com/mycube.css'])
+
+
+if __name__ == '__main__':
+ unittest_main()
--- a/web/test/unittest_views_basecontrollers.py Thu Apr 29 14:21:59 2010 +0200
+++ b/web/test/unittest_views_basecontrollers.py Fri Apr 30 12:14:15 2010 +0200
@@ -643,7 +643,7 @@
# silly tests
def test_external_resource(self):
self.assertEquals(self.remote_call('external_resource', 'RSS_LOGO')[0],
- json.dumps(self.request().external_resource('RSS_LOGO')))
+ json.dumps(self.config.uiprops['RSS_LOGO']))
def test_i18n(self):
self.assertEquals(self.remote_call('i18n', ['bimboom'])[0],
json.dumps(['bimboom']))
--- a/web/test/unittest_webconfig.py Thu Apr 29 14:21:59 2010 +0200
+++ b/web/test/unittest_webconfig.py Fri Apr 30 12:14:15 2010 +0200
@@ -33,15 +33,14 @@
def test_nonregr_print_css_as_list(self):
"""make sure PRINT_CSS *must* is a list"""
config = self.config
- req = fake.FakeRequest()
- print_css = req.external_resource('STYLESHEETS_PRINT')
+ print_css = config.uiprops['STYLESHEETS_PRINT']
self.failUnless(isinstance(print_css, list))
- ie_css = req.external_resource('IE_STYLESHEETS')
+ ie_css = config.uiprops['STYLESHEETS_IE']
self.failUnless(isinstance(ie_css, list))
def test_locate_resource(self):
- self.failUnless('FILE_ICON' in self.config.ext_resources)
- rname = self.config.ext_resources['FILE_ICON'].replace('DATADIR/', '')
+ self.failUnless('FILE_ICON' in self.config.uiprops)
+ rname = self.config.uiprops['FILE_ICON'].replace(self.config.datadir_url, '')
self.failUnless('file' in self.config.locate_resource(rname).split(os.sep))
cubicwebcsspath = self.config.locate_resource('cubicweb.css').split(os.sep)
self.failUnless('web' in cubicwebcsspath or 'shared' in cubicwebcsspath) # 'shared' if tests under apycot
--- a/web/views/basecomponents.py Thu Apr 29 14:21:59 2010 +0200
+++ b/web/views/basecomponents.py Fri Apr 30 12:14:15 2010 +0200
@@ -79,7 +79,7 @@
def call(self):
self.w(u'<a href="%s"><img class="logo" src="%s" alt="logo"/></a>'
- % (self._cw.base_url(), self._cw.external_resource('LOGO')))
+ % (self._cw.base_url(), self._cw.vreg.config.uiprops['LOGO']))
class ApplHelp(component.Component):
--- a/web/views/basecontrollers.py Thu Apr 29 14:21:59 2010 +0200
+++ b/web/views/basecontrollers.py Fri Apr 30 12:14:15 2010 +0200
@@ -481,7 +481,7 @@
@jsonize
def js_external_resource(self, resource):
"""returns the URL of the external resource named `resource`"""
- return self._cw.external_resource(resource)
+ return self._cw.vreg.config.uiprops[resource]
@check_pageid
@jsonize
--- a/web/views/basetemplates.py Thu Apr 29 14:21:59 2010 +0200
+++ b/web/views/basetemplates.py Fri Apr 30 12:14:15 2010 +0200
@@ -294,22 +294,22 @@
self.alternates()
def favicon(self):
- favicon = self._cw.external_resource('FAVICON', None)
+ favicon = self._cw.vreg.config.uiprops.get('FAVICON', None)
if favicon:
self.whead(u'<link rel="shortcut icon" href="%s"/>\n' % favicon)
def stylesheets(self):
req = self._cw
add_css = req.add_css
- for css in req.external_resource('STYLESHEETS'):
+ for css in req.vreg.config.uiprops['STYLESHEETS']:
add_css(css, localfile=False)
- for css in req.external_resource('STYLESHEETS_PRINT'):
+ for css in req.vreg.config.uiprops['STYLESHEETS_PRINT']:
add_css(css, u'print', localfile=False)
- for css in req.external_resource('IE_STYLESHEETS'):
+ for css in req.vreg.config.uiprops['STYLESHEETS_IE']:
add_css(css, localfile=False, ieonly=True)
def javascripts(self):
- for jscript in self._cw.external_resource('JAVASCRIPTS'):
+ for jscript in self._cw.vreg.config.uiprops['JAVASCRIPTS']:
self._cw.add_js(jscript, localfile=False)
def alternates(self):
--- a/web/views/idownloadable.py Thu Apr 29 14:21:59 2010 +0200
+++ b/web/views/idownloadable.py Fri Apr 30 12:14:15 2010 +0200
@@ -48,7 +48,7 @@
w(u'<div class="sideBox downloadBox"><div class="sideBoxBody">')
w(u'<a href="%s"><img src="%s" alt="%s"/> %s</a>'
% (xml_escape(entity.download_url()),
- req.external_resource('DOWNLOAD_ICON'),
+ req.vreg.config.uiprops['DOWNLOAD_ICON'],
_('download icon'), xml_escape(label or entity.dc_title())))
w(u'%s</div>' % footer)
w(u'</div></div>\n')
--- a/web/views/igeocodable.py Thu Apr 29 14:21:59 2010 +0200
+++ b/web/views/igeocodable.py Fri Apr 30 12:14:15 2010 +0200
@@ -59,7 +59,7 @@
if hasattr(entity, 'marker_icon'):
icon = entity.marker_icon()
else:
- icon = (self._cw.external_resource('GMARKER_ICON'), (20, 34), (4, 34), None)
+ icon = (self._cw.vreg.config.uiprops['GMARKER_ICON'], (20, 34), (4, 34), None)
return {'latitude': entity.latitude, 'longitude': entity.longitude,
'title': entity.dc_long_title(),
#icon defines : (icon._url, icon.size, icon.iconAncho', icon.shadow)
--- a/web/views/schema.py Thu Apr 29 14:21:59 2010 +0200
+++ b/web/views/schema.py Fri Apr 30 12:14:15 2010 +0200
@@ -248,7 +248,7 @@
eschema.type, self._cw.build_url('cwetype/%s' % eschema.type),
eschema.type, _(eschema.type)))
self.w(u'<a href="%s#schema_security"><img src="%s" alt="%s"/></a>' % (
- url, self._cw.external_resource('UP_ICON'), _('up')))
+ url, self._cw.vreg.config.uiprops['UP_ICON'], _('up')))
self.w(u'</h3>')
self.w(u'<div style="margin: 0px 1.5em">')
self.permissions_table(eschema)
@@ -277,7 +277,7 @@
rschema.type, self._cw.build_url('cwrtype/%s' % rschema.type),
rschema.type, _(rschema.type)))
self.w(u'<a href="%s#schema_security"><img src="%s" alt="%s"/></a>' % (
- url, self._cw.external_resource('UP_ICON'), _('up')))
+ url, self._cw.vreg.config.uiprops['UP_ICON'], _('up')))
self.w(u'</h3>')
self.grouped_permissions_table(rschema)
--- a/web/views/tableview.py Thu Apr 29 14:21:59 2010 +0200
+++ b/web/views/tableview.py Fri Apr 30 12:14:15 2010 +0200
@@ -204,7 +204,7 @@
def render_actions(self, divid, actions):
box = MenuWidget('', 'tableActionsBox', _class='', islist=False)
- label = tags.img(src=self._cw.external_resource('PUCE_DOWN'),
+ label = tags.img(src=self._cw.vreg.config.uiprops['PUCE_DOWN'],
alt=xml_escape(self._cw._('action(s) on this selection')))
menu = PopupBoxMenu(label, isitem=False, link_class='actionsBox',
ident='%sActions' % divid)
--- a/web/views/xmlrss.py Thu Apr 29 14:21:59 2010 +0200
+++ b/web/views/xmlrss.py Fri Apr 30 12:14:15 2010 +0200
@@ -147,7 +147,7 @@
def call(self, **kwargs):
try:
- rss = self._cw.external_resource('RSS_LOGO')
+ rss = self._cw.vreg.config.uiprops['RSS_LOGO']
except KeyError:
self.error('missing RSS_LOGO external resource')
return
--- a/web/webconfig.py Thu Apr 29 14:21:59 2010 +0200
+++ b/web/webconfig.py Fri Apr 30 12:14:15 2010 +0200
@@ -23,6 +23,7 @@
import os
from os.path import join, exists, split
+from warnings import warn
from logilab.common.decorators import cached
@@ -208,7 +209,7 @@
))
def fckeditor_installed(self):
- return exists(self.ext_resources['FCKEDITOR_PATH'])
+ return exists(self.uiprops['FCKEDITOR_PATH'])
def eproperty_definitions(self):
for key, pdef in super(WebConfiguration, self).eproperty_definitions():
@@ -239,30 +240,6 @@
def vc_config(self):
return self.repository().get_versions()
- # mapping to external resources (id -> path) (`external_resources` file) ##
- ext_resources = {
- 'FAVICON': 'DATADIR/favicon.ico',
- 'LOGO': 'DATADIR/logo.png',
- 'RSS_LOGO': 'DATADIR/rss.png',
- 'HELP': 'DATADIR/help.png',
- 'CALENDAR_ICON': 'DATADIR/calendar.gif',
- 'SEARCH_GO':'DATADIR/go.png',
-
- 'FCKEDITOR_PATH': '/usr/share/fckeditor/',
-
- 'IE_STYLESHEETS': ['DATADIR/cubicweb.ie.css'],
- 'STYLESHEETS': ['DATADIR/cubicweb.css'],
- 'STYLESHEETS_PRINT': ['DATADIR/cubicweb.print.css'],
-
- 'JAVASCRIPTS': ['DATADIR/jquery.js',
- 'DATADIR/jquery.corner.js',
- 'DATADIR/jquery.json.js',
- 'DATADIR/cubicweb.compat.js',
- 'DATADIR/cubicweb.python.js',
- 'DATADIR/cubicweb.htmlhelpers.js'],
- }
-
-
def anonymous_user(self):
"""return a login and password to use for anonymous users. None
may be returned for both if anonymous connections are not allowed
@@ -278,7 +255,7 @@
def has_resource(self, rid):
"""return true if an external resource is defined"""
- return bool(self.ext_resources.get(rid))
+ return bool(self.uiprops.get(rid))
@cached
def locate_resource(self, rid):
@@ -310,7 +287,7 @@
super(WebConfiguration, self).load_configuration()
# load external resources definition
self._init_base_url()
- self._build_ext_resources()
+ self._build_ui_properties()
def _init_base_url(self):
# normalize base url(s)
@@ -324,25 +301,40 @@
httpsurl += '/'
if not self.repairing:
self.global_set_option('https-url', httpsurl)
+ if self.debugmode:
+ self.datadir_url = baseurl + 'data/'
+ else:
+ self.datadir_url = baseurl + 'data%s/' % self.instance_md5_version()
- def _build_ext_resources(self):
- libresourcesfile = join(self.shared_dir(), 'data', 'external_resources')
- self.ext_resources.update(read_config(libresourcesfile))
+ def _build_ui_properties(self):
+ # self.datadir_url[:-1] to remove trailing /
+ from cubicweb.web.propertysheet import PropertySheet
+ self.uiprops = PropertySheet(datadir_url=self.datadir_url[:-1])
+ libuiprops = join(self.shared_dir(), 'data', 'uiprops.py')
+ self.uiprops.load(libuiprops)
for path in reversed([self.apphome] + self.cubes_path()):
- resourcesfile = join(path, 'data', 'external_resources')
- if exists(resourcesfile):
- self.debug('loading %s', resourcesfile)
- self.ext_resources.update(read_config(resourcesfile))
- resourcesfile = join(self.apphome, 'external_resources')
+ self._load_ui_properties(join(path, 'data'))
+ self._load_ui_properties(self.apphome)
+
+ def _load_ui_properties(self, path):
+ resourcesfile = join(path, 'external_resources')
if exists(resourcesfile):
- self.debug('loading %s', resourcesfile)
- self.ext_resources.update(read_config(resourcesfile))
- for resource in ('STYLESHEETS', 'STYLESHEETS_PRINT',
- 'IE_STYLESHEETS', 'JAVASCRIPTS'):
- val = self.ext_resources[resource]
- if isinstance(val, str):
- files = [w.strip() for w in val.split(',') if w.strip()]
- self.ext_resources[resource] = files
+ warn('[3.9] %s file is deprecated, use an uiprops.py file'
+ % resourcesfile, DeprecationWarning)
+ for rid, val in read_config(resourcesfile).iteritems():
+ if rid in ('STYLESHEETS', 'STYLESHEETS_PRINT',
+ 'IE_STYLESHEETS', 'JAVASCRIPTS'):
+ val = [w.strip().replace('DATADIR/', self.datadir_url)
+ for w in val.split(',') if w.strip()]
+ if rid == 'IE_STYLESHEETS':
+ rid = 'STYLESHEETS_IE'
+ else:
+ val = val.strip().replace('DATADIR/', self.datadir_url)
+ self.uiprops[rid] = val
+ uipropsfile = join(path, 'uiprops.py')
+ if exists(uipropsfile):
+ self.debug('loading %s', uipropsfile)
+ self.uiprops.load(uipropsfile)
# static files handling ###################################################