# HG changeset patch # User Goffi # Date 1619722115 -7200 # Node ID 314bba1ae433256982c038ba079592138c9b5dd3 # Parent 0554103ec7000eb6e71fd51b44f6dbaaa5fc303e pages: breadcrumbs handling: a new `breadcrumbs` list of dict is created in `template_data`. By default it is automatically filled by pages run to reach the requested URI, but a page can customize it. A breadcrumb data dict must have a `label`, should have an `url` and may have an `icon` (which is the name of a SàT Media well-known icon). Pages may now have a `label` attribute, which is used to automatically fill the crumb (otherwise page name then URI is used). A new `add_breadcrumb` method can be used to manually breadcrumb data, in which case auto-filling is disabled. diff -r 0554103ec700 -r 314bba1ae433 libervia/server/pages.py --- a/libervia/server/pages.py Thu Apr 29 16:55:07 2021 +0200 +++ b/libervia/server/pages.py Thu Apr 29 20:48:35 2021 +0200 @@ -119,10 +119,10 @@ cache_pubsub_sub = set() def __init__( - self, host, vhost_root, root_dir, url, name=None, redirect=None, access=None, - dynamic=False, parse_url=None, prepare_render=None, render=None, template=None, - on_data_post=None, on_data=None, on_signal=None, url_cache=False, - replace_on_conflict=False + self, host, vhost_root, root_dir, url, name=None, label=None, redirect=None, + access=None, dynamic=False, parse_url=None, add_breadcrumb=None, + prepare_render=None, render=None, template=None, on_data_post=None, on_data=None, + on_signal=None, url_cache=False, replace_on_conflict=False ): """Initiate LiberviaPage instance @@ -152,6 +152,8 @@ @param parse_url(callable, None): if set it will be called to handle the URL path after this method, the page will be rendered if noting is left in path (request.postpath) else a the request will be transmitted to a subpage + @param add_breadcrumb(callable, None): if set, manage the breadcrumb data for this + page, otherwise it will be set automatically from page name or label. @param prepare_render(callable, None): if set, will be used to prepare the rendering. That often means gathering data using the bridge @param render(callable, None): if template is not set, this method will be @@ -185,6 +187,7 @@ self.root_dir = root_dir self.url = url self.name = name + self.label = label self.dyn_data = {} if name is not None: if (name in self.named_pages @@ -222,6 +225,7 @@ else: self.redirect = None self.parse_url = parse_url + self.add_breadcrumb = add_breadcrumb self.prepare_render = prepare_render self.template = template self.render_method = render @@ -298,10 +302,12 @@ root_dir=dir_path, url="/" + "/".join(url_elts), name=page_data.get("name"), + label=page_data.get("label"), redirect=page_data.get("redirect"), access=page_data.get("access"), dynamic=page_data.get("dynamic", False), parse_url=page_data.get("parse_url"), + add_breadcrumb=page_data.get("add_breadcrumb"), prepare_render=page_data.get("prepare_render"), render=page_data.get("render"), template=page_data.get("template"), @@ -1455,6 +1461,14 @@ templates_root_url=str(self.vhost_root.getFrontURL(theme)), profile=session_data.profile) + uri = request.uri.decode() + try: + template_data["current_page"] = next( + m[0] for m in self.main_menu if uri.startswith(m[1]) + ) + except StopIteration: + pass + return self.host.renderer.render( self.template, theme=theme, @@ -1768,6 +1782,7 @@ "profile": session_data.profile, "csrf_token": session_data.csrf_token, "session_uuid": session_data.uuid, + "breadcrumbs": [] } # XXX: here is the code which need to be executed once @@ -1831,6 +1846,25 @@ else: await asDeferred(self.parse_url, self, request) + if self.add_breadcrumb is None: + label = ( + self.label + or self.name + or self.url[self.url.rfind('/')+1:] + ) + breadcrumb = { + "url": self.url, + "label": label.title(), + } + request.template_data["breadcrumbs"].append(breadcrumb) + else: + await asDeferred( + self.add_breadcrumb, + self, + request, + request.template_data["breadcrumbs"] + ) + self._subpagesHandler(request) if request.method not in (C.HTTP_METHOD_GET, C.HTTP_METHOD_POST):