20 register_persistent_options( ( |
20 register_persistent_options( ( |
21 # site-wide only web ui configuration |
21 # site-wide only web ui configuration |
22 ('site-title', |
22 ('site-title', |
23 {'type' : 'string', 'default': 'unset title', |
23 {'type' : 'string', 'default': 'unset title', |
24 'help': _('site title'), |
24 'help': _('site title'), |
25 'sitewide': True, 'group': 'ui', |
25 'sitewide': True, 'group': 'ui', |
26 }), |
26 }), |
27 ('main-template', |
27 ('main-template', |
28 {'type' : 'string', 'default': 'main-template', |
28 {'type' : 'string', 'default': 'main-template', |
29 'help': _('id of main template used to render pages'), |
29 'help': _('id of main template used to render pages'), |
30 'sitewide': True, 'group': 'ui', |
30 'sitewide': True, 'group': 'ui', |
52 ('combobox-limit', |
52 ('combobox-limit', |
53 {'type' : 'int', 'default': 20, |
53 {'type' : 'int', 'default': 20, |
54 'help': _('maximum number of entities to display in related combo box'), |
54 'help': _('maximum number of entities to display in related combo box'), |
55 'group': 'navigation', |
55 'group': 'navigation', |
56 }), |
56 }), |
57 |
57 |
58 )) |
58 )) |
59 |
59 |
60 |
60 |
61 class WebConfiguration(CubicWebConfiguration): |
61 class WebConfiguration(CubicWebConfiguration): |
62 """the WebConfiguration is a singleton object handling application's |
62 """the WebConfiguration is a singleton object handling application's |
63 configuration and preferences |
63 configuration and preferences |
64 """ |
64 """ |
65 cubicweb_vobject_path = CubicWebConfiguration.cubicweb_vobject_path | set(['web/views']) |
65 cubicweb_vobject_path = CubicWebConfiguration.cubicweb_vobject_path | set(['web/views']) |
66 cube_vobject_path = CubicWebConfiguration.cube_vobject_path | set(['views']) |
66 cube_vobject_path = CubicWebConfiguration.cube_vobject_path | set(['views']) |
67 |
67 |
68 options = merge_options(CubicWebConfiguration.options + ( |
68 options = merge_options(CubicWebConfiguration.options + ( |
69 ('anonymous-user', |
69 ('anonymous-user', |
70 {'type' : 'string', |
70 {'type' : 'string', |
71 'default': None, |
71 'default': None, |
72 'help': 'login of the CubicWeb user account to use for anonymous user (if you want to allow anonymous)', |
72 'help': 'login of the CubicWeb user account to use for anonymous user (if you want to allow anonymous)', |
183 'default': True, |
183 'default': True, |
184 'help': 'use Accept-Language http header to try to set user '\ |
184 'help': 'use Accept-Language http header to try to set user '\ |
185 'interface\'s language according to browser defined preferences', |
185 'interface\'s language according to browser defined preferences', |
186 'group': 'web', 'inputlevel': 2, |
186 'group': 'web', 'inputlevel': 2, |
187 }), |
187 }), |
188 |
188 |
189 ('print-traceback', |
189 ('print-traceback', |
190 {'type' : 'yn', |
190 {'type' : 'yn', |
191 'default': not CubicWebConfiguration.mode == 'installed', |
191 'default': not CubicWebConfiguration.mode == 'installed', |
192 'help': 'print the traceback on the error page when an error occured', |
192 'help': 'print the traceback on the error page when an error occured', |
193 'group': 'web', 'inputlevel': 2, |
193 'group': 'web', 'inputlevel': 2, |
204 return 'http://intranet.logilab.fr/jpl/view?__linkto=concerns:%s:subject&etype=Ticket&type=bug&vid=creation' % cubeeid |
204 return 'http://intranet.logilab.fr/jpl/view?__linkto=concerns:%s:subject&etype=Ticket&type=bug&vid=creation' % cubeeid |
205 return None |
205 return None |
206 |
206 |
207 def fckeditor_installed(self): |
207 def fckeditor_installed(self): |
208 return exists(self.ext_resources['FCKEDITOR_PATH']) |
208 return exists(self.ext_resources['FCKEDITOR_PATH']) |
209 |
209 |
210 def eproperty_definitions(self): |
210 def eproperty_definitions(self): |
211 for key, pdef in super(WebConfiguration, self).eproperty_definitions(): |
211 for key, pdef in super(WebConfiguration, self).eproperty_definitions(): |
212 if key == 'ui.fckeditor' and not self.fckeditor_installed(): |
212 if key == 'ui.fckeditor' and not self.fckeditor_installed(): |
213 continue |
213 continue |
214 yield key, pdef |
214 yield key, pdef |
215 |
215 |
216 # method used to connect to the repository: 'inmemory' / 'pyro' |
216 # method used to connect to the repository: 'inmemory' / 'pyro' |
217 # Pyro repository by default |
217 # Pyro repository by default |
218 repo_method = 'pyro' |
218 repo_method = 'pyro' |
219 |
219 |
220 # don't use @cached: we want to be able to disable it while this must still |
220 # don't use @cached: we want to be able to disable it while this must still |
221 # be cached |
221 # be cached |
222 def repository(self, vreg=None): |
222 def repository(self, vreg=None): |
223 """return the application's repository object""" |
223 """return the application's repository object""" |
224 try: |
224 try: |
233 self.__repo = repo |
233 self.__repo = repo |
234 return repo |
234 return repo |
235 |
235 |
236 def vc_config(self): |
236 def vc_config(self): |
237 return self.repository().get_versions() |
237 return self.repository().get_versions() |
238 |
238 |
239 # mapping to external resources (id -> path) (`external_resources` file) ## |
239 # mapping to external resources (id -> path) (`external_resources` file) ## |
240 ext_resources = { |
240 ext_resources = { |
241 'FAVICON': 'DATADIR/favicon.ico', |
241 'FAVICON': 'DATADIR/favicon.ico', |
242 'LOGO': 'DATADIR/logo.png', |
242 'LOGO': 'DATADIR/logo.png', |
243 'RSS_LOGO': 'DATADIR/rss.png', |
243 'RSS_LOGO': 'DATADIR/rss.png', |
244 'HELP': 'DATADIR/help.png', |
244 'HELP': 'DATADIR/help.png', |
245 'CALENDAR_ICON': 'DATADIR/calendar.gif', |
245 'CALENDAR_ICON': 'DATADIR/calendar.gif', |
246 'SEARCH_GO':'DATADIR/go.png', |
246 'SEARCH_GO':'DATADIR/go.png', |
247 |
247 |
248 'FCKEDITOR_PATH': '/usr/share/fckeditor/', |
248 'FCKEDITOR_PATH': '/usr/share/fckeditor/', |
249 |
249 |
250 'IE_STYLESHEETS': ['DATADIR/cubicweb.ie.css'], |
250 'IE_STYLESHEETS': ['DATADIR/cubicweb.ie.css'], |
251 'STYLESHEETS': ['DATADIR/cubicweb.css'], |
251 'STYLESHEETS': ['DATADIR/cubicweb.css'], |
252 'STYLESHEETS_PRINT': ['DATADIR/cubicweb.print.css'], |
252 'STYLESHEETS_PRINT': ['DATADIR/cubicweb.print.css'], |
253 |
253 |
254 'JAVASCRIPTS': ['DATADIR/jquery.js', |
254 'JAVASCRIPTS': ['DATADIR/jquery.js', |
255 'DATADIR/jquery.corner.js', |
255 'DATADIR/jquery.corner.js', |
256 'DATADIR/jquery.json.js', |
256 'DATADIR/jquery.json.js', |
257 'DATADIR/cubicweb.compat.js', |
257 'DATADIR/cubicweb.compat.js', |
258 'DATADIR/cubicweb.python.js', |
258 'DATADIR/cubicweb.python.js', |
259 'DATADIR/cubicweb.htmlhelpers.js'], |
259 'DATADIR/cubicweb.htmlhelpers.js'], |
260 } |
260 } |
261 |
261 |
262 |
262 |
263 def anonymous_user(self): |
263 def anonymous_user(self): |
264 """return a login and password to use for anonymous users. None |
264 """return a login and password to use for anonymous users. None |
265 may be returned for both if anonymous connections are not allowed |
265 may be returned for both if anonymous connections are not allowed |
266 """ |
266 """ |
267 try: |
267 try: |
270 except KeyError: |
270 except KeyError: |
271 user, passwd = None, None |
271 user, passwd = None, None |
272 if user is not None: |
272 if user is not None: |
273 user = unicode(user) |
273 user = unicode(user) |
274 return user, passwd |
274 return user, passwd |
275 |
275 |
276 def has_resource(self, rid): |
276 def has_resource(self, rid): |
277 """return true if an external resource is defined""" |
277 """return true if an external resource is defined""" |
278 return bool(self.ext_resources.get(rid)) |
278 return bool(self.ext_resources.get(rid)) |
279 |
279 |
280 @cached |
280 @cached |
281 def locate_resource(self, rid): |
281 def locate_resource(self, rid): |
282 """return the directory where the given resource may be found""" |
282 """return the directory where the given resource may be found""" |
283 return self._fs_locate(rid, 'data') |
283 return self._fs_locate(rid, 'data') |
284 |
284 |
285 @cached |
285 @cached |
286 def locate_doc_file(self, fname): |
286 def locate_doc_file(self, fname): |
287 """return the directory where the given resource may be found""" |
287 """return the directory where the given resource may be found""" |
288 return self._fs_locate(fname, 'wdoc') |
288 return self._fs_locate(fname, 'wdoc') |
289 |
289 |
290 def _fs_locate(self, rid, rdirectory): |
290 def _fs_locate(self, rid, rdirectory): |
291 """return the directory where the given resource may be found""" |
291 """return the directory where the given resource may be found""" |
292 path = [self.apphome] + self.cubes_path() + [join(self.shared_dir())] |
292 path = [self.apphome] + self.cubes_path() + [join(self.shared_dir())] |
293 for directory in path: |
293 for directory in path: |
294 if exists(join(directory, rdirectory, rid)): |
294 if exists(join(directory, rdirectory, rid)): |
295 return join(directory, rdirectory) |
295 return join(directory, rdirectory) |
296 |
296 |
297 def locate_all_files(self, rid, rdirectory='wdoc'): |
297 def locate_all_files(self, rid, rdirectory='wdoc'): |
298 """return all files corresponding to the given resource""" |
298 """return all files corresponding to the given resource""" |
299 path = [self.apphome] + self.cubes_path() + [join(self.shared_dir())] |
299 path = [self.apphome] + self.cubes_path() + [join(self.shared_dir())] |
300 for directory in path: |
300 for directory in path: |
301 fpath = join(directory, rdirectory, rid) |
301 fpath = join(directory, rdirectory, rid) |
306 """load application's configuration files""" |
306 """load application's configuration files""" |
307 super(WebConfiguration, self).load_configuration() |
307 super(WebConfiguration, self).load_configuration() |
308 # load external resources definition |
308 # load external resources definition |
309 self._build_ext_resources() |
309 self._build_ext_resources() |
310 self._init_base_url() |
310 self._init_base_url() |
311 |
311 |
312 def _init_base_url(self): |
312 def _init_base_url(self): |
313 # normalize base url(s) |
313 # normalize base url(s) |
314 baseurl = self['base-url'] |
314 baseurl = self['base-url'] |
315 if baseurl and baseurl[-1] != '/': |
315 if baseurl and baseurl[-1] != '/': |
316 baseurl += '/' |
316 baseurl += '/' |
339 files = [w.strip() for w in val.split(',') if w.strip()] |
339 files = [w.strip() for w in val.split(',') if w.strip()] |
340 self.ext_resources[resource] = files |
340 self.ext_resources[resource] = files |
341 |
341 |
342 |
342 |
343 # static files handling ################################################### |
343 # static files handling ################################################### |
344 |
344 |
345 @property |
345 @property |
346 def static_directory(self): |
346 def static_directory(self): |
347 return join(self.appdatahome, 'static') |
347 return join(self.appdatahome, 'static') |
348 |
348 |
349 def static_file_exists(self, rpath): |
349 def static_file_exists(self, rpath): |
350 return exists(join(self.static_directory, rpath)) |
350 return exists(join(self.static_directory, rpath)) |
351 |
351 |
352 def static_file_open(self, rpath, mode='wb'): |
352 def static_file_open(self, rpath, mode='wb'): |
353 staticdir = self.static_directory |
353 staticdir = self.static_directory |