nulib/web: ajout de redirect() et set_profile(). améliorer la lisibilité des arguments
This commit is contained in:
parent
c58a6ccaf7
commit
1a3550ed9a
|
@ -46,14 +46,20 @@ def load(prefix=None, icons=True, charset="utf-8"):
|
|||
################################################################################
|
||||
# Menu
|
||||
|
||||
NAVBAR_TYPE_MAP = {
|
||||
'fixed': 'fixed-top',
|
||||
'static': 'static-top',
|
||||
}
|
||||
|
||||
class Menu(ui.Menu):
|
||||
"""Un menu"""
|
||||
|
||||
def __init__(self, title, mitems=None, profiles=None,
|
||||
id=None, p=None, c=None, t=None, **kw):
|
||||
super(Menu, self).__init__(title, mitems, profiles, id, p, c, **kw)
|
||||
if t is None: t = 'static'
|
||||
self.navbar_type = t
|
||||
id=None, in_profiles=None, css=None, navbar_type=None, **kw):
|
||||
if navbar_type is None: navbar_type = kw.pop('t', None)
|
||||
super(Menu, self).__init__(title, mitems, profiles, id, in_profiles, css, **kw)
|
||||
if navbar_type is None: navbar_type = 'static'
|
||||
self.navbar_type = navbar_type
|
||||
|
||||
def __mitem(self, mitem, sel_profile):
|
||||
# ne pas afficher un menu qui n'est pas dans le bon profil
|
||||
|
@ -87,16 +93,20 @@ class Menu(ui.Menu):
|
|||
lines.append(u"""</ul>""")
|
||||
return lines
|
||||
|
||||
def __call__(self, s=None, p=None, t=None):
|
||||
if t is None: t = self.navbar_type
|
||||
if s is not None: self.select(s, p)
|
||||
def render(self, select=None, profile=None, navbar_type=None, **kw):
|
||||
if select is None: select = kw.pop('s', None)
|
||||
if profile is None: profile = kw.pop('p', None)
|
||||
if navbar_type is None: navbar_type = kw.pop('t', None)
|
||||
|
||||
if navbar_type is None: navbar_type = self.navbar_type
|
||||
if select is not None: self.select(select, profile)
|
||||
selection = self.get_mitem()
|
||||
lines = []
|
||||
if t == 'fixed' or t == 'fixed-top':
|
||||
if navbar_type == 'fixed' or navbar_type == 'fixed-top':
|
||||
lines.append(u"""<style type="text/css">body { margin-top: 50px; }</style>""")
|
||||
css = u''
|
||||
css = ui.addclassif('navbar-fixed-top', t == 'fixed' or t == 'fixed-top', css)
|
||||
css = ui.addclassif('navbar-static-top', t == 'static' or t == 'static-top', css)
|
||||
css = ui.addclassif('navbar-fixed-top', navbar_type == 'fixed' or navbar_type == 'fixed-top', css)
|
||||
css = ui.addclassif('navbar-static-top', navbar_type == 'static' or navbar_type == 'static-top', css)
|
||||
if self.profiles is not None and self.sel_profile is not None:
|
||||
css = ui.addclassif('%s-profile' % self.sel_profile, None, css)
|
||||
css = ui.addclassif(self.css, None, css)
|
||||
|
@ -145,10 +155,9 @@ class Menu(ui.Menu):
|
|||
</div>
|
||||
</div>""")
|
||||
return u"\n".join(lines)
|
||||
def __unicode__(self): return self.render()
|
||||
|
||||
def __unicode__(self): return self()
|
||||
|
||||
def set_menu(menu):
|
||||
def set_menu(menu, **params):
|
||||
"""Décorateur qui permet d'initialiser une instance de menu dans la session
|
||||
"""
|
||||
def decorator(method):
|
||||
|
@ -159,16 +168,24 @@ def set_menu(menu):
|
|||
return wrapper
|
||||
return decorator
|
||||
|
||||
def menu(id=None, p=None):
|
||||
"""Décorateur qui permet de mettre à jour la sélection et le profil dans le menu
|
||||
def menu(id=None, profile=None, **params):
|
||||
"""Décorateur qui permet de mettre à jour la sélection et le profil dans
|
||||
le menu
|
||||
|
||||
par défaut, prendre le profil courant dans la session. le profil courant
|
||||
est initialisé par le décorateur @set_profile
|
||||
"""
|
||||
if profile is None: profile = params.pop('p', None)
|
||||
def decorator(method):
|
||||
def wrapper(self, *args, **kw):
|
||||
session = _ensure_session(self)
|
||||
if 'menu' not in session:
|
||||
raise ValueError("menu is required")
|
||||
raise ValueError("menu est requis")
|
||||
sel_profile = profile
|
||||
if sel_profile is None and 'profile' in session:
|
||||
sel_profile = session.profile
|
||||
if id is not None:
|
||||
session.menu.select(id, p)
|
||||
session.menu.select(id, sel_profile)
|
||||
return method(self, *args, **kw)
|
||||
return wrapper
|
||||
return decorator
|
||||
|
@ -229,64 +246,74 @@ class Alert(object):
|
|||
action = None
|
||||
showtb = None
|
||||
|
||||
def __init__(self, msg=None, e=Undef, t="error", c=False, x=None, action=None, showtb=True):
|
||||
self(msg, e, t, c, x, action, showtb)
|
||||
def __init__(self, msg=None, exc_info=Undef, type="error", closeable=False, escape=None, action=None, showtb=True, **kw):
|
||||
self(msg, exc_info, type, closeable, escape, action, showtb, **kw)
|
||||
|
||||
def __call__(self, msg=Undef, exc_info=Undef, type=Undef, closeable=Undef, escape=Undef, action=Undef, showtb=Undef, **kw):
|
||||
if exc_info is Undef: exc_info = kw.pop('e', Undef)
|
||||
if type is Undef: type = kw.pop('t', Undef)
|
||||
if closeable is Undef: closeable = kw.pop('c', Undef)
|
||||
if escape is Undef: escape = kw.pop('x', Undef)
|
||||
|
||||
def __call__(self, msg=Undef, e=Undef, t=Undef, c=Undef, x=Undef, action=Undef, showtb=Undef):
|
||||
if msg is Undef:
|
||||
# si on ne spécifie pas de message, alors prendre la valeur actuelle
|
||||
msg = self.msg
|
||||
if e is Undef: e = self.exc_info
|
||||
if exc_info is Undef: exc_info = self.exc_info
|
||||
else:
|
||||
# si on spécifie un message, alors prendre aussi l'exception courante
|
||||
if e is Undef: e = sys.exc_info()
|
||||
if e == (None, None, None): e = None
|
||||
if t is Undef: t = self.type
|
||||
if c is Undef: c = self.closeable
|
||||
if x is Undef: x = self.escape
|
||||
if exc_info is Undef: exc_info = sys.exc_info()
|
||||
if exc_info == (None, None, None): exc_info = None
|
||||
if type is Undef: type = self.type
|
||||
if closeable is Undef: closeable = self.closeable
|
||||
if escape is Undef: escape = self.escape
|
||||
if action is Undef: action = self.action
|
||||
if showtb is Undef: showtb = self.showtb
|
||||
|
||||
self.msg = msg
|
||||
self.exc_info = e
|
||||
self.type = ALERT_TYPE_MAP.get(t, t)
|
||||
self.closeable = c
|
||||
self.escape = x
|
||||
self.exc_info = exc_info
|
||||
self.type = ALERT_TYPE_MAP.get(type, type)
|
||||
self.closeable = closeable
|
||||
self.escape = escape
|
||||
self.action = action
|
||||
self.showtb = showtb
|
||||
return self
|
||||
|
||||
def render(self, msg=Undef, e=Undef, t=Undef, c=Undef, x=Undef, action=Undef, showtb=Undef):
|
||||
def render(self, msg=Undef, exc_info=Undef, type=Undef, closeable=Undef, escape=Undef, action=Undef, showtb=Undef, **kw):
|
||||
if exc_info is Undef: exc_info = kw.pop('e', Undef)
|
||||
if type is Undef: type = kw.pop('t', Undef)
|
||||
if closeable is Undef: closeable = kw.pop('c', Undef)
|
||||
if escape is Undef: escape = kw.pop('x', Undef)
|
||||
|
||||
if msg is Undef:
|
||||
# si on ne spécifie pas de message, alors prendre la valeur initiale
|
||||
msg = self.msg
|
||||
if e is Undef: e = self.exc_info
|
||||
if exc_info is Undef: exc_info = self.exc_info
|
||||
else:
|
||||
# si on spécifie un message, alors prendre aussi l'exception courante
|
||||
if e is Undef: e = sys.exc_info()
|
||||
if t is Undef: t = self.type
|
||||
if c is Undef: c = self.closeable
|
||||
if x is Undef: x = self.escape
|
||||
if exc_info is Undef: exc_info = sys.exc_info()
|
||||
if type is Undef: type = self.type
|
||||
if closeable is Undef: closeable = self.closeable
|
||||
if escape is Undef: escape = self.escape
|
||||
if action is Undef: action = self.action
|
||||
if showtb is Undef: showtb = self.showtb
|
||||
|
||||
if callable(msg):
|
||||
# si msg est callable, par défaut ne pas mettre le résultat en
|
||||
# échappement
|
||||
if x is None: x = False
|
||||
if escape is None: escape = False
|
||||
msg = msg()
|
||||
if x is None: x = True
|
||||
if escape is None: escape = True
|
||||
|
||||
if msg is None and e is not None:
|
||||
if msg is None and exc_info is not None:
|
||||
msg = u"Une erreur inattendue s'est produite"
|
||||
if msg is None: return u""
|
||||
if x: msg = web.websafe(msg)
|
||||
if escape: msg = web.websafe(msg)
|
||||
|
||||
lines = []
|
||||
css = u"alert alert-%s" % t
|
||||
css = ui.addclassif("alert-dismissible", c, css)
|
||||
css = u"alert alert-%s" % ALERT_TYPE_MAP.get(type, type)
|
||||
css = ui.addclassif("alert-dismissible", closeable, css)
|
||||
lines.append(u"""<div class="%s" role="alert">""" % css)
|
||||
if c:
|
||||
if closeable:
|
||||
lines.append(u"""<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>""")
|
||||
lines.append(p(msg))
|
||||
if action is not None:
|
||||
|
@ -296,19 +323,19 @@ class Alert(object):
|
|||
title = web.websafe(action.title or u"Cliquez ici pour continuer")
|
||||
action = u"""<p><a href="%s" accesskey="r">%s</a></p>""" % (url, title)
|
||||
lines.append(p(action))
|
||||
if e is not None:
|
||||
if exc_info is not None:
|
||||
lines.append(u"""<div class="small" style="margin-top: 3em; color: gray;">Pour information, le message d'erreur technique est """)
|
||||
lines.extend(traceback.format_exception_only(*e[:2]))
|
||||
lines.extend(traceback.format_exception_only(*exc_info[:2]))
|
||||
if showtb:
|
||||
lines.append(u"<!--")
|
||||
lines.append("".join(traceback.format_exception(*e)))
|
||||
lines.append("".join(traceback.format_exception(*exc_info)))
|
||||
lines.append(u"-->")
|
||||
lines.append(u"""</div>""")
|
||||
lines.append(u"""</div>""")
|
||||
return u"\n".join([u(line) for line in lines])
|
||||
def __unicode__(self): return self.render()
|
||||
|
||||
def set_alert(template=None, action=Undef, delay=None):
|
||||
def set_alert(template=None, action=Undef, delay=None, **params):
|
||||
"""Décorateur qui permet de gérer automatiquement une instance de Alert dans la
|
||||
page.
|
||||
|
||||
|
@ -357,10 +384,14 @@ def set_alert(template=None, action=Undef, delay=None):
|
|||
lines.append(u"""\
|
||||
<title>%(title)s</title>
|
||||
</head>
|
||||
<body>
|
||||
<body>""" % locals())
|
||||
if web.config.have_session:
|
||||
session = web.config._session
|
||||
if 'menu' in session: lines.append(session.menu.render())
|
||||
lines.append(u"""\
|
||||
<div class="container">
|
||||
<h1>%(title)s</h1>""" % locals())
|
||||
lines.append(alert())
|
||||
lines.append(alert.render())
|
||||
lines.append(u"""\
|
||||
</div>
|
||||
</body>
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
# -*- coding: utf-8 mode: python -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||||
|
||||
__all__ = (
|
||||
'nocache', 'auth', 'defaults',
|
||||
'nocache', 'auth', 'defaults', 'redirect',
|
||||
'reset_session', 'set_session', 'session', 'check_session',
|
||||
'set_profile',
|
||||
'Page', 'Application',
|
||||
)
|
||||
|
||||
|
@ -45,7 +46,7 @@ class MetaPage(type):
|
|||
_fix_PATH(cls, name)
|
||||
HANDLER_CLASSES.append(cls)
|
||||
|
||||
def nocache(method):
|
||||
def nocache(method, **params):
|
||||
"""Décorateur pour s'assurer que le résultat de la méthode web n'est pas mis en cache
|
||||
"""
|
||||
def wrapper(self, *args, **kw):
|
||||
|
@ -55,7 +56,7 @@ def nocache(method):
|
|||
return method(self, *args, **kw)
|
||||
return wrapper
|
||||
|
||||
def auth(authenticator=None, realm='nulib'):
|
||||
def auth(authenticator=None, realm='nulib', **params):
|
||||
"""Décorateur pour s'assurer que la méthode web est authentifiée.
|
||||
|
||||
La fonction authenticator avec la signature (username, password) permet
|
||||
|
@ -75,6 +76,22 @@ def auth(authenticator=None, realm='nulib'):
|
|||
return wrapper
|
||||
return decorator
|
||||
|
||||
def redirect(desturl, **params):
|
||||
"""rediriger vers l'url spécifiée si la méthode retourne None.
|
||||
|
||||
L'url est enregistrée dans l'objet avec le nom desturl au cas où on
|
||||
voudrait s'en servir dans la page retournée.
|
||||
"""
|
||||
def decorator(method):
|
||||
def wrapper(self, *args, **kw):
|
||||
self.desturl = desturl
|
||||
self.desturl_params = params
|
||||
result = method(self, *args, **kw)
|
||||
if result is not None: return result
|
||||
else: return web.redirect(web.url(desturl, **params))
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
def defaults(*required, **defaults):
|
||||
"""Initialiser dans l'objet courant des variables à des valeurs par
|
||||
défaut, ou en les prenant parmi les paramètres de la requête.
|
||||
|
@ -207,6 +224,22 @@ def check_session(_onerror=None, **validators):
|
|||
return wrapper
|
||||
return decorator
|
||||
|
||||
def set_profile(profile=None, **params):
|
||||
"""mettre à jour la valeur du profil courant
|
||||
|
||||
s'assurer que l'objet courant contient la variable session. si les sessions
|
||||
n'ont pas été configurées au niveau de l'application, une exception est
|
||||
levée
|
||||
"""
|
||||
if profile is None: profile = params.pop('p', None)
|
||||
def decorator(method):
|
||||
def wrapper(self, *args, **kw):
|
||||
session = _ensure_session(self)
|
||||
session.profile = profile
|
||||
return method(self, *args, **kw)
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
def _fix_PATH(cls, name):
|
||||
if cls.PATH is None:
|
||||
if cls.PREFIX is None:
|
||||
|
@ -491,6 +524,8 @@ class Application(object):
|
|||
session = web.session.Session(self.webapp, store, initializer=initializer)
|
||||
self.session = web.config._session = session
|
||||
|
||||
web.config.have_session = session is not None
|
||||
|
||||
tg = self.template_globals
|
||||
# session et application comme variables globales du template
|
||||
tg.setdefault("S", session)
|
||||
|
@ -529,7 +564,7 @@ class Application(object):
|
|||
if args is None: args = []
|
||||
options, args = get_args(map(_u, args),
|
||||
'S:s:H:P:Dp:' + (self.OPTIONS or ''),
|
||||
['server-type=', 'server-socket=', 'host=', 'port=', 'debug', 'profile='] + list(self.LONG_OPTIONS or ()))
|
||||
['server-type=', 'server-socket=', 'host=', 'port=', 'debug', 'no-debug', 'profile='] + list(self.LONG_OPTIONS or ()))
|
||||
server_type = None
|
||||
server_socket = None
|
||||
for option, value in options:
|
||||
|
@ -542,6 +577,8 @@ class Application(object):
|
|||
elif option in ('-D', '--debug'):
|
||||
self.DEBUG = True
|
||||
set_verbosity('--debug')
|
||||
elif option in ('--no-debug',):
|
||||
self.DEBUG = False
|
||||
elif option in ('-p', '--profile'): self.PROFILE = value
|
||||
self.args = args
|
||||
self.process_args(args)
|
||||
|
|
|
@ -82,11 +82,11 @@ class Action(odict):
|
|||
url: cible de l'action ou du lien (avec querystring)
|
||||
title: titre du lien ou de l'élément de menu
|
||||
id: identifiant dans un menu
|
||||
p (in_profiles): profils dans lequel l'action est valide. le premier profil
|
||||
in_profiles (p): profils dans lequel l'action est valide. le premier profil
|
||||
est le profil par défaut
|
||||
c (css): classe css à appliquer au lien
|
||||
ak (accesskey): accesskey à installer sur le lien
|
||||
q (query): paramètres de la requête, sous forme de dictionnaire ou de chaine
|
||||
css (c): classe css à appliquer au lien
|
||||
accesskey (ak): accesskey à installer sur le lien
|
||||
query (q): paramètres de la requête, sous forme de dictionnaire ou de chaine
|
||||
method: type de requête, get ou post
|
||||
PROFILE_url, PROFILE_query: valeurs spécifiques à certains profils, PROFILE
|
||||
étant une valeur de in_profiles
|
||||
|
@ -121,74 +121,79 @@ class Action(odict):
|
|||
self[querykey] = query
|
||||
self[urlkey] = url
|
||||
|
||||
def __init__(self, url, title=None, id=None, p=None, c=None, ak=None, q=None, method=None, **kw):
|
||||
def __init__(self, url, title=None, id=None, in_profiles=None, css=None, accesskey=None, query=None, method=None, **kw):
|
||||
super(Action, self).__init__(**kw)
|
||||
if isseq(url):
|
||||
if url[1:2]: title = url[1]
|
||||
if url[2:3]: id = url[2]
|
||||
if url[3:4]: p = url[3]
|
||||
if url[4:5]: c = url[4]
|
||||
if url[5:6]: ak = url[5]
|
||||
if url[3:4]: in_profiles = url[3]
|
||||
if url[4:5]: css = url[4]
|
||||
if url[5:6]: accesskey = url[5]
|
||||
if url[6:7]: method = url[6]
|
||||
url = url[0] if url[0:1] else None
|
||||
if url is None: raise ValueError("url is required")
|
||||
if title is None: title = url
|
||||
if p is None: p = kw.get('in_profiles', None)
|
||||
if c is None: c = kw.get('css', None)
|
||||
if ak is None: ak = kw.get('accesskey', None)
|
||||
if q is None: q = kw.get('query', None)
|
||||
if in_profiles is None: in_profiles = kw.pop('p', None)
|
||||
if css is None: css = kw.pop('c', None)
|
||||
if accesskey is None: accesskey = kw.pop('ak', None)
|
||||
if query is None: query = kw.pop('q', None)
|
||||
if method is None: method = 'get'
|
||||
|
||||
self.title = title
|
||||
self.id = id
|
||||
self.css = c
|
||||
self.accesskey = ak
|
||||
self.css = css
|
||||
self.accesskey = accesskey
|
||||
self.method = method
|
||||
|
||||
self.url = url
|
||||
self.query = q
|
||||
self.query = query
|
||||
self.__update_url('url', 'query', 'baseurl')
|
||||
|
||||
self.in_profiles = seqof(p, None)
|
||||
self.in_profiles = seqof(in_profiles, None)
|
||||
if self.in_profiles is None: return
|
||||
for p in self.in_profiles:
|
||||
self.__update_url(*['%s_%s' % (p, key) for key in ('url', 'query', 'baseurl')])
|
||||
self.__update_url(*['to_%s_%s' % (p, key) for key in ('url', 'query', 'baseurl')])
|
||||
for profile in self.in_profiles:
|
||||
self.__update_url(*['%s_%s' % (profile, key) for key in ('url', 'query', 'baseurl')])
|
||||
self.__update_url(*['to_%s_%s' % (profile, key) for key in ('url', 'query', 'baseurl')])
|
||||
|
||||
def __get_key(self, key, p=None, to=False):
|
||||
if p is not None:
|
||||
pkey = '%s%s_%s' % ('to_' if to else '', p, key)
|
||||
def __get_key(self, key, profile=None, to=False):
|
||||
if profile is not None:
|
||||
pkey = '%s%s_%s' % ('to_' if to else '', profile, key)
|
||||
value = self.get(pkey, None)
|
||||
if value is not None: return value
|
||||
return self[key]
|
||||
def get_baseurl(self, p=None, to=False):
|
||||
def get_baseurl(self, profile=None, to=False, **kw):
|
||||
"""obtenir l'url de base
|
||||
"""
|
||||
return self.__get_key('baseurl', p, to)
|
||||
def get_query(self, p=None, to=False):
|
||||
if profile is None: profile = kw.pop('p', None)
|
||||
return self.__get_key('baseurl', profile, to)
|
||||
def get_query(self, profile=None, to=False, **kw):
|
||||
"""obtenir les paramètres de la requête sous forme de dictionnaire
|
||||
"""
|
||||
return self.__get_key('query', p, to)
|
||||
def get_url(self, p=None, to=False):
|
||||
if profile is None: profile = kw.pop('p', None)
|
||||
return self.__get_key('query', profile, to)
|
||||
def get_url(self, profile=None, to=False, **kw):
|
||||
"""obtenir l'url
|
||||
"""
|
||||
return self.__get_key('url', p, to)
|
||||
if profile is None: profile = kw.pop('p', None)
|
||||
return self.__get_key('url', profile, to)
|
||||
|
||||
def get_qs(self, p=None, to=False, sep=None):
|
||||
def get_qs(self, profile=None, to=False, sep=None, **kw):
|
||||
"""obtenir les paramètres de la requête sous forme de query-string
|
||||
sep vaut par défaut '?' mais peut valoir '&'
|
||||
"""
|
||||
query = self.get_query(p, to)
|
||||
if profile is None: profile = kw.pop('p', None)
|
||||
query = self.get_query(profile, to)
|
||||
if sep is None: sep = '?'
|
||||
return '%s%s' % (sep, urllib.urlencode(query, True))
|
||||
qs = property(get_qs)
|
||||
get_querystring = get_qs; querystring = property(get_qs)
|
||||
|
||||
def get_inputs(self, p=None, to=False):
|
||||
def get_inputs(self, profile=None, to=False, **kw):
|
||||
"""obtenir les paramètres de la requête sous forme d'une liste de définitions
|
||||
d'éléments de formulaire de type hidden
|
||||
"""
|
||||
query = self.get_query(p, to)
|
||||
if profile is None: profile = kw.pop('p', None)
|
||||
query = self.get_query(profile, to)
|
||||
Hidden = web.form.Hidden
|
||||
inputs = []
|
||||
for name, value in query.items():
|
||||
|
@ -212,7 +217,9 @@ class Menu(odict):
|
|||
return nextid
|
||||
|
||||
def __init__(self, title, mitems=None, profiles=None,
|
||||
id=None, p=None, c=None, **kw):
|
||||
id=None, in_profiles=None, css=None, **kw):
|
||||
if in_profiles is None: in_profiles = kw.pop('p', None)
|
||||
if css is None: css = kw.pop('c', None)
|
||||
super(Menu, self).__init__(**kw)
|
||||
self.__dict__['nextid'] = 0
|
||||
self.__dict__['idmap'] = {}
|
||||
|
@ -225,7 +232,7 @@ class Menu(odict):
|
|||
self.default_profile = profiles[0] if profiles is not None else None
|
||||
self.id = str(id)
|
||||
self.in_profiles = seqof(p, None)
|
||||
self.css = c
|
||||
self.css = css
|
||||
self.sel_id = None
|
||||
self.sel_profile = None
|
||||
self.active = False
|
||||
|
@ -244,7 +251,7 @@ class Menu(odict):
|
|||
self.mitems.append(mitem)
|
||||
self.idmap[mitem.id] = mitem
|
||||
|
||||
def reset_selection(self):
|
||||
def reset_selection(self, **kw):
|
||||
self.sel_id = None
|
||||
self.sel_profile = self.default_profile
|
||||
self.active = False
|
||||
|
@ -254,7 +261,8 @@ class Menu(odict):
|
|||
else:
|
||||
mitem.active = False
|
||||
|
||||
def select(self, id, p=None):
|
||||
def select(self, id, profile=None, **kw):
|
||||
if profile is None: profile = kw.pop('p', None)
|
||||
# d'abord déselectionner tout le monde
|
||||
self.reset_selection()
|
||||
# ensuite chercher le mitem à sélectionner
|
||||
|
@ -262,10 +270,10 @@ class Menu(odict):
|
|||
mitem = self.idmap.get(id, None)
|
||||
if mitem is not None:
|
||||
self.sel_id = id
|
||||
if p is None and mitem.in_profiles:
|
||||
p = mitem.in_profiles[0]
|
||||
if p is None: p = self.default_profile
|
||||
self.sel_profile = p
|
||||
if profile is None and mitem.in_profiles:
|
||||
profile = mitem.in_profiles[0]
|
||||
if profile is None: profile = self.default_profile
|
||||
self.sel_profile = profile
|
||||
mitem.active = self.active = True
|
||||
return True
|
||||
else:
|
||||
|
@ -278,7 +286,7 @@ class Menu(odict):
|
|||
return True
|
||||
return False
|
||||
|
||||
def get_mitem(self, id=None):
|
||||
def get_mitem(self, id=None, **kw):
|
||||
"""retourner l'élément de menu correspondant à la sélection courante
|
||||
"""
|
||||
if id is None: id = self.sel_id
|
||||
|
|
|
@ -2,11 +2,13 @@
|
|||
|
||||
__all__ = (
|
||||
'web', 'Page', 'bs',
|
||||
'nocache', 'auth', 'defaults',
|
||||
'nocache', 'auth', 'defaults', 'redirect',
|
||||
'reset_session', 'set_session', 'session', 'check_session',
|
||||
'set_profile',
|
||||
'config',
|
||||
)
|
||||
|
||||
from nulib.web import web, Page, bs, nocache, auth, defaults
|
||||
from nulib.web import web, Page, bs, nocache, auth, defaults, redirect
|
||||
from nulib.web import reset_session, set_session, session, check_session
|
||||
from nulib.web import set_profile
|
||||
from nulib.web.config_loader import config
|
||||
|
|
Loading…
Reference in New Issue