From dad7da844e1f38fc6fa5b26d41674d1dcb5d00f7 Mon Sep 17 00:00:00 2001 From: tholzheim <> Date: Tue, 27 Apr 2021 22:39:21 +0200 Subject: [PATCH] Refactored and improved templates --- templates/category_page.jinja | 4 ++- templates/concept_page.jinja | 5 +-- templates/form_page.jinja | 5 +-- templates/list_of_page.jinja | 11 +++--- templates/template_page.jinja | 10 +++--- templates/uml.jinja | 6 ++-- tests/test_metamodel.py | 42 +++++++++++----------- tests/test_smw.py | 2 +- wikifile/metamodel.py | 67 ++++++++++++++++++++++++++--------- wikifile/smw.py | 32 ++++++++++------- 10 files changed, 109 insertions(+), 75 deletions(-) diff --git a/templates/category_page.jinja b/templates/category_page.jinja index aca689e..caaf857 100644 --- a/templates/category_page.jinja +++ b/templates/category_page.jinja @@ -23,4 +23,6 @@ __NOTOC__ == Properties == {{ SMW.render_as_list(map(Property.get_page_link, Property.get_entity_properties(topic.name, properties))) }} - \ No newline at end of file + + +{{ SMW.parser_function("set", oneliner=oneliner, **{"Has property description":topic.__dict__.get("documentation")+"@en"}) }} \ No newline at end of file diff --git a/templates/concept_page.jinja b/templates/concept_page.jinja index c1787c2..7fbe7cf 100644 --- a/templates/concept_page.jinja +++ b/templates/concept_page.jinja @@ -6,9 +6,6 @@ Input: properties: all properties of the wiki. Output: Generates the page Concept: #} -{#---------------------------------Import-------------------------------------#} -{% from 'macros/utils.jinja' import render_entity %} -{% from 'macros/form.jinja' import forminput %} {#-------------------------------Template-------------------------------------#} __NOCACHE__ {{ topic.render_entity(oneliner=False) }} @@ -29,4 +26,4 @@ __NOCACHE__ {# Add all topics that are related to this topic as list of page links -#} {{ SMW.render_as_list(map(Topic.get_page_link, topic.get_related_topics(properties))) }} {{ '}}' }} -{# [[:Category:{{ topic.name }}]] #} +[[:Category:{{ topic.name }}]] diff --git a/templates/form_page.jinja b/templates/form_page.jinja index 8946bd7..aed15c3 100644 --- a/templates/form_page.jinja +++ b/templates/form_page.jinja @@ -3,12 +3,9 @@ Generate the form of page for a entity. Input: topic: topic entity - properties: all properties of the wiki. - regexps: List of a regular expressions Output: Generates the page Category: #} {#----------------------------Global Variables--------------------------------#} -{% set topic_properties = Property.get_entity_properties(topic.name, properties) %} {#-------------------------------Template-------------------------------------#} {{ Form.forminput(form=topic.name, button_text='add ' + topic.name) }} @@ -19,7 +16,7 @@ Output: Generates the page Category: {# Form control buttons #} {{ Form.standard_input_tag(["save","preview","changes","cancel"]) }} {{ Form.page_form_function("for template", **{topic.name:True }) }} -{{ Form.form_table(topic.name, topic_properties) }} +{{ Form.form_table(topic.name, topic.properties) }} {{ Form.page_form_function("end template") }} {# Form control buttons -#} {{ Form.standard_input_tag(["save","preview","changes","cancel"]) }} diff --git a/templates/list_of_page.jinja b/templates/list_of_page.jinja index e2a13bf..624d747 100644 --- a/templates/list_of_page.jinja +++ b/templates/list_of_page.jinja @@ -7,23 +7,20 @@ Input: properties: all properties of the wiki. Output: Generates the page List of #} -{#---------------------------------Import-------------------------------------#} -{% from 'macros/utils.jinja' import render_entity %} -{% from 'macros/form.jinja' import forminput %} {#-------------------------------Template-------------------------------------#} __NOCACHE__ {{ topic.query_topic_overview() }} -== {{ topic.plural_name }} == +== {{ topic.pluralName }} == {{ Form.forminput(form=topic.name, button_text='add ' + topic.name) }} -{{ topic.query_number_entities() }} {{ topic.plural_name }}: +{{ topic.query_number_entities() }} {{ topic.pluralName }}: {{ topic.query_entities() }} == See also == {{ SMWPart.getAllAsPageLink(topic) }}
=== Example rendered with the corresponding Template ===
-{{ topic.query_entities(format="template", limit=1, template=topic.name) }} +{{ topic.query_entities(format="template", limit=0, template=topic.name, searchlabel="Show examples") }}
-{# [[:Category:{{ topic.name }}]] #} \ No newline at end of file +[[:Category:{{ topic.name }}]] \ No newline at end of file diff --git a/templates/template_page.jinja b/templates/template_page.jinja index 5ef897f..372462c 100644 --- a/templates/template_page.jinja +++ b/templates/template_page.jinja @@ -6,8 +6,6 @@ Input: properties: all properties of the wiki. Output: Generates the page Template: #} -{#----------------------------Global Variables--------------------------------#} -{% set topic_properties = Property.get_entity_properties(topic.name, properties) %} {#-------------------------------Template-------------------------------------#} This is the template {{ '{{' }}Link|target=Template:{{ topic.name }}|title={{ '}}' }}. @@ -17,16 +15,16 @@ This is the template {{ '{{' }}Link|target=Template:{{ topic.name }}|title={{ '} == Usage ==
-{{ SMW.render_sample_entity_with_properties(topic, topic_properties, oneliner=False) }}
+{{ SMW.render_sample_entity_with_properties(topic, topic.properties, oneliner=False) }}
 
-{{ SMW.render_sample_entity_with_properties(topic, topic_properties, oneliner=False) }} +{{ SMW.render_sample_entity_with_properties(topic, topic.properties, oneliner=False) }} [[Category:Template]]
-{{ SMW.set_entity_parameter(topic, topic_properties, oneliner=False) }} +{{ SMW.set_entity_parameter(topic, topic.properties, oneliner=False) }} -{{ Template.table_of_arguments(topic, topic_properties) }} +{{ Template.table_of_arguments(topic, topic.properties) }} [[Category:{{ topic.name }}]]{{ SMW.parser_function("default_form",presence_is_true=True, **{topic.name:True}) }} diff --git a/templates/uml.jinja b/templates/uml.jinja index 884e3ad..5fcf8ed 100644 --- a/templates/uml.jinja +++ b/templates/uml.jinja @@ -16,17 +16,17 @@ note as {{ topic.name }}Note {{ topic.documentation }} end note class {{ topic.name }} { -{% for property in Property.get_primitive_properties(topic.name,properties) -%} +{% for property in Property.get_primitive_properties(topic.name,topic.properties) -%} {{ property.type.replace("Special:Types/","") }}: {{ property.label }} {% endfor -%} } {{ topic.name }}Note .. {{ topic.name }} {# Set outgoing edges #} -{%- for edge in UML.get_outgoing_edges(topic.name,properties) %} +{%- for edge in UML.get_outgoing_edges(topic.name,topic.properties) %} "{{ edge.source }}" "{{ edge.source_cardinality }}" --> "{{ edge.target_cardinality }}" "{{ edge.target }}" : "{{ edge.property.name }}" {%- endfor -%} {# Set incoming edges #} -{% for edge in UML.get_incoming_edges(topic.name,properties) %} +{% for edge in UML.get_incoming_edges(topic.name,topic.properties) %} "{{ edge.target }}" "{{ edge.target_cardinality }}" <-- "{{ edge.source_cardinality }}" "{{ edge.source }}" : "{{ edge.property.name }}" {%- endfor %} diff --git a/tests/test_metamodel.py b/tests/test_metamodel.py index ee50d2a..c9324fa 100644 --- a/tests/test_metamodel.py +++ b/tests/test_metamodel.py @@ -159,9 +159,9 @@ def test_get_related_topics(self): def test_get_page_link(self): topic = Topic({"name": "Topic"}) - self.assertEqual("[[Concept:Topic]]", topic.get_page_link()) + self.assertEqual("[[Concept:Topic|Topic]]", topic.get_page_link()) topic.__dict__.update(pageTitle="Concept:Topic") - self.assertEqual("[[Concept:Topic]]", topic.get_page_link()) + self.assertEqual("[[Concept:Topic|Topic]]", topic.get_page_link()) def test_render_entity(self): data = {"name": "Topic", @@ -327,25 +327,25 @@ def test_query_examples(self): def test_query_entity_properties(self): topic = Topic({"name":"Test Title"}) - expected_query = """{{#ask:[[Concept:Property]][[Used for::Concept:Test Title]] -|?name=name -|?label=label -|?type=type -|?index=index -|?sortPos=sortPos -|?primaryKey=primary key -|?mandatory=mandatory -|?namespace=namespace -|?size=size -|?uploadable=uploadable -|?defaultValue=default -|?inputType=inputType -|?allowedValues=allowedValues -|?documentation=documentation -|?values_from=values from -|?showInGrid=showInGrid -|?isLink=isLink -|?nullable=allow nulls? + expected_query = """{{#ask:[[Concept:Property]][[Property topic::Concept:Test Title]] +|?Property name=name +|?Property label=label +|?Property type=type +|?Property index=index +|?Property sortPos=sortPos +|?Property primaryKey=primary key +|?Property mandatory=mandatory +|?Property namespace=namespace +|?Property size=size +|?Property uploadable=uploadable +|?Property defaultValue=default +|?Property inputType=inputType +|?Property allowedValues=allowedValues +|?Property documentation=documentation +|?Property values_from=values from +|?Property showInGrid=showInGrid +|?Property isLink=isLink +|?Property nullable=allow nulls? |format=wikitable }}""" actual_query = topic.query_entity_properties() diff --git a/tests/test_smw.py b/tests/test_smw.py index 1728427..e0d1c40 100644 --- a/tests/test_smw.py +++ b/tests/test_smw.py @@ -115,7 +115,7 @@ def test_field(self): self.assertEqual(test_field, Form.field(property)) def test_form_table(self): - exp_form_table = """{| class="formtable InfoBox mw-collapsible" style="width:100%" + exp_form_table = """{| class="wikitable mw-collapsible" style="width:100%" |- |colspan="2" |Basic Information |- diff --git a/wikifile/metamodel.py b/wikifile/metamodel.py index 0e8abec..84e263a 100644 --- a/wikifile/metamodel.py +++ b/wikifile/metamodel.py @@ -112,6 +112,28 @@ def get_prop_list_from_samples(samples: list): prop_list.append(key) return prop_list + def get_pageTitle(self, prefix:str, withNamespace=True): + """ + Returns page name of this metamodel element. If pageTitle is not defined, it is assumed that name corresponds to the pageTitle. + Args: + prefix: MetaModelElement prefix e.g. properties usually have the prefix Property + withNamespace: If true also the namespace of this property is returned. Otherwise, without namespace. + Returns: + Returns page name of this metamodel element. + """ + if self.pageTitle: + if withNamespace: + return self.pageTitle + else: + return self.pageTitle.replace(f"{prefix}:", "") + elif self.name: + if withNamespace: + return f"{prefix}:{self.name}" + else: + return self.name + else: + return None + class Context(MetaModelElement): """ @@ -159,6 +181,16 @@ def __init__(self, topic_properties: dict, properties: list=None): super(Topic, self).__init__(Topic.propList, properties=topic_properties) self.properties = properties + def get_pageTitle(self, withNamespace=True): + """ + Returns page name of this topic. If pageTitle is not defined, it is assumed that name corresponds to the pageTitle. + Args: + withNamespace: If true also the namespace of this property is returned. Otherwise, without namespace. + Returns: + Returns page name of this topic. + """ + return super(Topic, self).get_pageTitle("Concept", withNamespace) + def get_related_topics(self, properties): """ @@ -187,12 +219,15 @@ def render_entity(self, oneliner=True): res += SMW.render_parameters(oneliner, **MetaModelElement.get_parameters(self.__dict__, self.propList)) return res + "}}" - def get_page_link(self): + def get_page_link(self, withLabel=True, withDescription=False): """Returns a link to this page""" - if self.pageTitle: - return f"[[{self.pageTitle}]]" + pageTitle = self.get_pageTitle() + if withDescription: + pageTitle += "::@@@" + if withLabel: + return f"[[{pageTitle}|{self.name}]]" else: - return f"[[Concept:{self.name}]]" + return f"[[Concept:{pageTitle}]]" @classmethod def from_wiki_json(cls, topic_json, prop_json=None): @@ -242,7 +277,7 @@ def query_entity_properties(self, format="wikitable", oneliner=False): """Returns a SMW query querying all properties of this entity""" query = Query(format=format) query.select("Concept:Property") - query.select("Used for::Concept:" + self.name) + query.select("Property topic::Concept:" + self.name) query.printout_list_of_properties(Property.get_property_properties()) return query.render(oneliner=oneliner) @@ -315,7 +350,7 @@ def is_used_for(self): res.append(self.usedFor) return res - def get_pageName(self, withNamespace=True): + def get_pageTitle(self, withNamespace=True): """ Returns page name of this property. If pageTitle is not defined, it is assumed that name corresponds to the pageTitle. Args: @@ -323,19 +358,19 @@ def get_pageName(self, withNamespace=True): Returns: Returns page name of this property. """ - if self.pageTitle: - return self.pageTitle if withNamespace else self.pageTitle.replace("Property:", "") - elif self.name: - # ToDo if the properties from meta model are taken they do not have a page title name current assumption is that property.name is then the pageTitle (without namespace) - return f"Property:{self.name}" if withNamespace else self.name - else: - return None + return super(Property, self).get_pageTitle(self.__class__.__name__, withNamespace) + @staticmethod def get_property_properties(): """Returns the properties that describe properties""" properties_json = json.loads(pkgutil.get_data("wikifile", "/resources/metamodel/Property_properties.json")) - return [Property(x) for x in properties_json] + properties = [Property(x) for x in properties_json] + # Add pageTitle + for property in properties: + property.__dict__["pageTitle"] = f"Property:Property {property.name}" + print([p.pageTitle for p in properties]) + return properties @staticmethod def get_entity_properties(entity_name: str, properties: list): @@ -401,7 +436,7 @@ def get_page_link(self, name=None): SMW page link to this property """ if name is None: - name = self.get_pageName(withNamespace=True) + name = self.get_pageTitle(withNamespace=True) if self.label: return f"[[{name}|{self.label}]]" else: @@ -415,7 +450,7 @@ def get_description_page_link(self): Returns: SMW page link to this property """ - name = f"{self.get_pageName(withNamespace=False)}::@@@" + name = f"{self.get_pageTitle(withNamespace=False)}::@@@" return self.get_page_link(name) diff --git a/wikifile/smw.py b/wikifile/smw.py index 196883f..e6b9fc8 100644 --- a/wikifile/smw.py +++ b/wikifile/smw.py @@ -161,7 +161,7 @@ def render_parameters(oneliner=True, presence_is_true=False, **kwargs): return res @staticmethod - def set_entity_parameter(topic, properties, oneliner=True): + def set_entity_parameter(topic, properties, oneliner=True, withDescription=False): """ Args: @@ -173,7 +173,7 @@ def set_entity_parameter(topic, properties, oneliner=True): """ property_dict = {"isA": topic.name} for property in properties: - property_dict = {**property_dict, property.get_pageName(withNamespace=False): "{{{" + property.name + "|}}}"} + property_dict = {**property_dict, property.get_pageTitle(withNamespace=False): "{{{" + property.name + "|}}}"} return SMW.parser_function("set", oneliner=oneliner, **property_dict) @staticmethod @@ -227,11 +227,15 @@ def table_of_arguments(topic: Topic, properties: list, clickable_links=True): Returns: """ - label = lambda p: Property.get_description_page_link(property) if clickable_links else p.label formlink = Form.formlink(form=topic.name, link_text="✎", target="{{FULLPAGENAME}}", tooltip="Start editing this " + topic.name) - table_str = "{| class='wikitable'\n! colspan=2 | " + formlink + topic.name + "\n|-\n" - for property in properties: - table_str += "!style=\"text-align:left\" |" + label(property) + "\n" + table_str = "{| class='wikitable'\n! colspan=2 | " + formlink + topic.get_page_link()+ "\n|-\n" + sortBySortPos = lambda property: 99999 if "sortPos" not in property.__dict__ or property.__dict__.get( + "sortPos") is None else int(property.sortPos) + properties_sorted = sorted(properties, key=sortBySortPos) + for property in properties_sorted: + # ToDo: refactor Table definition + label = property.get_description_page_link() if clickable_links else property.label + table_str += "!style=\"text-align:left\" |" + label + "\n" table_str += "| {{#if:" + Template.template_arg(property.name) + "|" + Template.template_arg(property.name) + "|}}\n" table_str += "|-\n" return table_str + "|}" @@ -351,10 +355,12 @@ def field(property: Property): "allowedValues": "values"} parameters = {} for prop in prop_map.keys(): - if prop == "inputType"and property.__dict__[prop] is None: + if prop == "inputType": + if property.__dict__[prop] is None: property.__dict__[prop] = "text" + elif property.__dict__[prop].lower() == "textarea": + parameters["editor"] = "wikieditor" if prop in property.__dict__ and property.__dict__[prop] is not None: - if prop == "values_from": # values_from contains data like "concept=Country" so we add an auxiliary property "values from concept" with the value "Country" vals = property.__dict__[prop].split("=") @@ -378,7 +384,7 @@ def form_table(label: str, properties: list, is_collapsible=True, ): Returns a table containing form fields based on the given properties """ # Define styling - table_style = {"css_class": "formtable InfoBox", "style": "width:100%"} + table_style = {"css_class": "wikitable", "style": "width:100%"} if is_collapsible: table_style["css_class"] += " mw-collapsible" field_label_style = {"style": "text-align: left"} @@ -388,7 +394,9 @@ def form_table(label: str, properties: list, is_collapsible=True, ): if label: table.add_row().add_cell(content=label, colspan=2) # Add form field for each given property - for property in properties: + sortBySortPos = lambda property: 99999 if "sortPos" not in property.__dict__ or property.__dict__.get("sortPos") is None else int(property.sortPos) + properties_sorted = sorted(properties, key=sortBySortPos) + for property in properties_sorted: property_row = table.add_row() # Add field label field_label = property.get_description_page_link() @@ -489,7 +497,7 @@ def printout(self, property, label=None): if isinstance(property, str): self.printout_statements.append(self.PrintoutStatement(property, label)) else: - self.printout_statements.append(self.PrintoutStatement(property.get_pageName(withNamespace=False), label)) + self.printout_statements.append(self.PrintoutStatement(property.get_pageTitle(withNamespace=False), label)) return self def select(self, selector): @@ -513,7 +521,7 @@ def printout_list_of_properties(self, properties: list, withNamespace=False): The query object itself """ for property in properties: - self.printout(property.get_pageName(withNamespace), property.label) + self.printout(property.get_pageTitle(withNamespace), property.label) return self def sort_by(self, *properties):