{# Macros for SHACL constraints, see ontospy/core/shacl_helper.py. Used by html-multi (a page per entity) and html-single (one page, imported "with context" after setting shacl_anchor_links, so that links go to anchors in the page, backlog #37) #} {# the link to an entity: its page, or its anchor in the single page; a shape's anchor is prefixed, since a class can be a shape too (eg in QUDT) #} {% macro href(entity) -%} {%- if shacl_anchor_links is defined and shacl_anchor_links -%} #{% if entity.slug.startswith("shape-") %}shape-{% endif %}{{entity.qname}} {%- else -%} {{entity.slug}}.html {%- endif -%} {%- endmacro %} {# a Term: linked to its page if the graph defines it, else in italics #} {% macro term(t, css="rdfclass") -%} {%- if t.entity -%} {{t.qname}} {%- else -%} {{t.qname}} {%- endif -%} {%- endmacro %} {# a value of a constraint: a Term, or text #} {% macro value(v) -%} {%- if v.qname is defined -%}{{ term(v) }}{%- else -%}{{v}}{%- endif -%} {%- endmacro %} {# a list of (name, [values]), eg the constraints other than cardinality and type #} {% macro constraint_list(items) -%} {%- for name, values in items %}
{{name}} {% if name in ["sh:or", "sh:xone", "sh:and"] -%} {%- set sep = {"sh:or": " | ", "sh:xone": " xor ", "sh:and": " & "}[name] -%} ( {% for v in values %}{{v}}{% if not loop.last %}{{sep}}{% endif %}{% endfor %} ) {%- else -%} {% for v in values %}{{ value(v) }}{% if not loop.last %}, {% endif %}{% endfor %} {%- endif %}
{%- endfor %} {%- endmacro %} {# the PROPERTY cell: the property, linked if defined in the ontology, or the path #} {% macro path(constraint) -%} {%- set prop = constraint.property_obj.onto_property -%} {%- if prop -%} {{prop.qname}} {%- else -%} {{constraint.property_obj.qname}} {%- endif -%} {%- endmacro %} {# the DESCRIPTION cell: the shape's sh:name and sh:description, else the property's comment #} {% macro description(constraint) -%} {%- if constraint.sh_name %}{{constraint.sh_name|sort|join(", ")}}
{% endif -%} {%- if constraint.sh_description -%} {% for x in constraint.sh_description|sort %}{{x}}{% if not loop.last %}
{% endif %}{% endfor %} {%- elif constraint.rdfs_comment -%} {% for x in constraint.rdfs_comment|sort %}{{x}}{% if not loop.last %}
{% endif %}{% endfor %} {%- endif -%} {%- if constraint.sh_message %}
sh:message {{constraint.sh_message|sort|join("; ")}}
{% endif -%} {%- endmacro %} {# the VALUE TYPE cell: sh:datatype, sh:class, sh:node, sh:nodeKind #} {% macro value_types(constraint) -%} {%- for t in constraint.value_types %}{{ term(t) }}{% if not loop.last %}
{% endif %}{% endfor -%} {%- endmacro %} {# a table of constraints, with a header row for each class (in a class's list) #} {% macro constraints_table(constraints, with_property_info=False) -%}
{% if with_property_info %}{% endif %} {% if with_property_info %}{% endif %} {% for constraint in constraints %} {% if constraint.header %} {% else %} {% if with_property_info %} {% endif %} {% if with_property_info %} {% endif %} {% endif %} {% endfor %}
PROPERTYPROPERTY TYPEDESCRIPTION MIN MAX VALUE TYPE OTHER CONSTRAINTSGLOBAL RANGE
{{constraint.header}} {{ path(constraint) }}{% for x in constraint.rdftype_qname|sort %}{{x}}{% if not loop.last %}
{% endif %}{% else %}--{% endfor %}
{{ description(constraint) }} {{constraint.sh_minCount|sort|join(", ")|default("0", true)}} {{constraint.sh_maxCount|sort|join(", ")|default("*", true)}} {{ value_types(constraint) }} {{ constraint_list(constraint.other_constraints) }} {%- for t in constraint.rdfs_range|sort(attribute="qname") %}{{ term(t) }}{% if not loop.last %}
{% endif %}{% else %}--{% endfor -%}
{%- endmacro %}