From d976ac9ea34bdde1b916f51457480ae8ce0874f5 Mon Sep 17 00:00:00 2001 From: Mirek Simek Date: Fri, 15 Dec 2023 19:22:36 +0100 Subject: [PATCH] Template optimizations (layout + blocks removed as they can be done in client code if needed) --- oarepo_ui/ext.py | 5 +- oarepo_ui/resources/catalog.py | 24 --------- oarepo_ui/resources/config.py | 3 ++ oarepo_ui/resources/resource.py | 90 +++++++++++--------------------- tests/model.py | 4 +- tests/templates/TestDetail.jinja | 3 +- 6 files changed, 41 insertions(+), 88 deletions(-) diff --git a/oarepo_ui/ext.py b/oarepo_ui/ext.py index 8e8d895b..5387b899 100644 --- a/oarepo_ui/ext.py +++ b/oarepo_ui/ext.py @@ -101,7 +101,10 @@ def _catalog_config(self, catalog, env): env.policies.setdefault("json.dumps_kwargs", {}).setdefault("default", str) self.app.update_template_context(context) catalog.jinja_env.loader = env.loader - catalog.jinja_env.autoescape = env.autoescape + + # autoescape everything (this catalogue is used just for html jinjax components, so can do that) ... + catalog.jinja_env.autoescape = True + context.update(catalog.jinja_env.globals) context.update(env.globals) catalog.jinja_env.globals = context diff --git a/oarepo_ui/resources/catalog.py b/oarepo_ui/resources/catalog.py index 4560e7a3..d58bb4d4 100644 --- a/oarepo_ui/resources/catalog.py +++ b/oarepo_ui/resources/catalog.py @@ -91,30 +91,6 @@ def _get_from_file( return component -def get_jinja_template(_catalog, template_def, fields=None): - if fields is None: - fields = [] - jinja_content = None - for component in _catalog.jinja_env.loader.searchpath: - if component["component_file"].endswith(template_def["layout"]): - with open(component["component_file"], "r") as file: - jinja_content = file.read() - if not jinja_content: - raise Exception("%s was not found" % (template_def["layout"])) - assembled_template = [jinja_content] - if "blocks" in template_def: - for blk_name, blk in template_def["blocks"].items(): - component_content = "" - for field in fields: - component_content = component_content + "%s={%s} " % (field, field) - component_str = "<%s %s> " % (blk, component_content, blk) - assembled_template.append( - "{%% block %s %%}%s{%% endblock %%}" % (blk_name, component_str) - ) - assembled_template = "\n".join(assembled_template) - return assembled_template - - def lazy_string_encoder(obj): if isinstance(obj, list): return [lazy_string_encoder(item) for item in obj] diff --git a/oarepo_ui/resources/config.py b/oarepo_ui/resources/config.py index d20eec71..78223248 100644 --- a/oarepo_ui/resources/config.py +++ b/oarepo_ui/resources/config.py @@ -60,6 +60,9 @@ class RecordsUIResourceConfig(UIResourceConfig): api_service = None """Name of the API service as registered inside the service registry""" + search_app_id = None + """ID of the app used for rendering the search config""" + templates = { "detail": None, "search": None, diff --git a/oarepo_ui/resources/resource.py b/oarepo_ui/resources/resource.py index e274f0f5..0fe808c8 100644 --- a/oarepo_ui/resources/resource.py +++ b/oarepo_ui/resources/resource.py @@ -32,7 +32,6 @@ # Resource # from ..proxies import current_oarepo_ui -from .catalog import get_jinja_template from .config import RecordsUIResourceConfig, UIResourceConfig request_export_args = request_parser( @@ -127,38 +126,30 @@ def fill_jinja_context(self): @request_view_args def detail(self): """Returns item detail page.""" - """Returns item detail page.""" + record = self._get_record(resource_requestctx, allow_draft=False) + # TODO: handle permissions UI way - better response than generic error ui_data = self.config.ui_serializer.dump_obj(record.to_dict()) - # make links absolute - if "links" in ui_data: - for k, v in list(ui_data["links"].items()): - if not isinstance(v, str): - continue - if not v.startswith("/") and not v.startswith("https://"): - v = f"/api{self.api_service.config.url_prefix}{v}" - ui_data["links"][k] = v + ui_data.setdefault("links", {}) + ui_links = self.expand_detail_links(identity=g.identity, record=record) export_path = request.path.split("?")[0] if not export_path.endswith("/"): export_path += "/" export_path += "export" - _catalog = current_oarepo_ui.catalog + ui_data["links"].update( + { + "ui_links": ui_links, + "export_path": export_path, + "search_link": self.config.url_prefix, + } + ) - template_def = self.get_template_def("detail") - fields = ["metadata", "ui", "layout", "record", "extra_context"] - source = get_jinja_template(_catalog, template_def, fields) + self.make_links_absolute(ui_data["links"], self.api_service.config.url_prefix) extra_context = dict() - ui_links = self.expand_detail_links(identity=g.identity, record=record) - - ui_data["extra_links"] = { - "ui_links": ui_links, - "export_path": export_path, - "search_link": self.config.url_prefix, - } self.run_components( "before_ui_detail", @@ -171,10 +162,8 @@ def detail(self): ui_links=ui_links, ) metadata = dict(ui_data.get("metadata", ui_data)) - return _catalog.render( - "detail", - # TODO: Alzbeta: why is this here? It does not seem to be used anywhere inside the library - __source=source, + return current_oarepo_ui.catalog.render( + self.get_template_def("detail"), metadata=metadata, ui=dict(ui_data.get("ui", ui_data)), record=ui_data, @@ -182,6 +171,15 @@ def detail(self): ui_links=ui_links, ) + def make_links_absolute(self, links, api_prefix): + # make links absolute + for k, v in list(links.items()): + if not isinstance(v, str): + continue + if not v.startswith("/") and not v.startswith("https://"): + v = f"/api{api_prefix}{v}" + links[k] = v + def _get_record(self, resource_requestctx, allow_draft=False): if allow_draft: read_method = ( @@ -202,19 +200,6 @@ def search_without_slash(self): @request_search_args def search(self): - _catalog = current_oarepo_ui.catalog - - template_def = self.get_template_def("search") - app_id = template_def["app_id"] - fields = [ - "search_app_config", - "ui_layout", - "layout", - "ui_links", - "extra_content", - ] - source = get_jinja_template(_catalog, template_def, fields) - page = resource_requestctx.args.get("page", 1) size = resource_requestctx.args.get("size", 10) pagination = Pagination( @@ -249,11 +234,10 @@ def search(self): search_config = partial(self.config.search_app_config, **search_options) - search_app_config = search_config(app_id=app_id) + search_app_config = search_config(app_id=self.config.search_app_id) - return _catalog.render( - "search", - __source=source, + return current_oarepo_ui.catalog.render( + self.get_template_def("search"), search_app_config=search_app_config, ui_config=self.config, ui_resource=self, @@ -331,20 +315,13 @@ def edit(self): extra_context=extra_context, ) - template_def = self.get_template_def("edit") - - _catalog = current_oarepo_ui.catalog - source = get_jinja_template( - _catalog, template_def, ["record", "extra_context", "form_config", "data"] - ) ui_record["extra_links"] = { "ui_links": ui_links, "search_link": self.config.url_prefix, } - return _catalog.render( - "edit", - __source=source, + return current_oarepo_ui.catalog.render( + self.get_template_def("edit"), record=ui_record, form_config=form_config, extra_context=extra_context, @@ -383,16 +360,9 @@ def create(self): identity=g.identity, extra_context=extra_context, ) - template_def = self.get_template_def("create") - _catalog = current_oarepo_ui.catalog - - source = get_jinja_template( - _catalog, template_def, ["record", "extra_context", "form_config", "data"] - ) - return _catalog.render( - "create", - __source=source, + return current_oarepo_ui.catalog.render( + self.get_template_def("create"), record=empty_record, form_config=form_config, extra_context=extra_context, diff --git a/tests/model.py b/tests/model.py index dd6dcd9d..5de3f400 100644 --- a/tests/model.py +++ b/tests/model.py @@ -87,8 +87,8 @@ class ModelUIResourceConfig(RecordsUIResourceConfig): ui_serializer_class = ModelUISerializer templates = { **RecordsUIResourceConfig.templates, - "detail": {"layout": "TestDetail.jinja", "blocks": {}}, - "search": {"layout": "TestSearch.jinja", "app_id": "SimpleModel.Search"}, + "detail": "TestDetail", + "search": "TestSearch", } components = [BabelComponent, PermissionsComponent] diff --git a/tests/templates/TestDetail.jinja b/tests/templates/TestDetail.jinja index 92f76875..e5dc3c36 100644 --- a/tests/templates/TestDetail.jinja +++ b/tests/templates/TestDetail.jinja @@ -1,5 +1,6 @@ {#def record, extra_context #} -{%- for link_name, link in record.extra_links.ui_links.items() -%} + +{%- for link_name, link in record.links.ui_links.items() -%} {{link_name}}:{{link}} {% endfor-%} permissions={{ extra_context.permissions }}