Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config.public.mk
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ LINKML_SCHEMA_SOURCE_DIR="src/common_access_model/schema"
LINKML_GENERATORS_CONFIG_YAML=config.yaml

## pass args if gendoc ignores config.yaml (i.e. --no-mergeimports)
LINKML_GENERATORS_DOC_ARGS=
LINKML_GENERATORS_DOC_ARGS="--template-directory docs/templates-linkml"

## pass args to workaround genowl rdfs config bug (linkml#1453)
## (i.e. --no-type-objects --no-metaclasses --metadata-profile rdfs)
Expand Down
295 changes: 295 additions & 0 deletions docs/templates-linkml/class.md.jinja2
Original file line number Diff line number Diff line change
@@ -0,0 +1,295 @@
---
search:
boost: {% if element.deprecated %}0.5{% else %}10.0{% endif %}
---

{%- if element.title %}
{%- set title = element.title ~ ' (' ~ element.name ~ ')' -%}
{%- else %}
{%- if gen.use_class_uris -%}
{%- set title = element.name -%}
{%- else -%}
{%- set title = gen.name(element) -%}
{%- endif -%}
{%- endif -%}

{% macro compute_range(slot) -%}
{%- if slot.any_of or slot.exactly_one_of -%}
{%- set expr_ranges = (slot.exactly_one_of + slot.any_of) | selectattr('range') | map(attribute='range') | unique | list -%}
{%- if expr_ranges -%}
{%- for subslot_range in expr_ranges -%}
{{ gen.link(subslot_range) }}
{%- if not loop.last -%}
&nbsp;or&nbsp;<br />
{%- endif -%}
{%- endfor -%}
{%- else -%}
{{ gen.link(slot.range) }}
{%- endif -%}
{%- else -%}
{{ gen.link(slot.range) }}
{%- endif -%}
{% endmacro %}

# Class: {{ title }} {% if element.deprecated %} <span style="color: red;"><strong> (DEPRECATED) </strong></span> {% endif %}

{%- if header -%}
{{ header }}
{%- endif -%}

{% if element.description %}
{% set element_description_lines = element.description.split('\n') %}
{% for element_description_line in element_description_lines %}
_{{ element_description_line }}_
{% endfor %}
{% endif %}

<div data-search-exclude markdown="1">

{% if element.abstract %}
* __NOTE__: this is an abstract class and should not be instantiated directly
{% endif %}

URI: {{ gen.uri_link(element) }}

{% if diagram_type == "er_diagram" %}
```{{ gen.mermaid_directive() }}
{{ gen.mermaid_diagram([element.name]) }}
```
{% elif diagram_type == "plantuml_class_diagram" %}
```puml
{{ gen.mermaid_diagram([element.name]) }}
```
{% else %}
{% include "class_diagram.md.jinja2" %}
{% endif %}

{% if schemaview.class_parents(element.name) or schemaview.class_children(element.name, mixins=False) %}

## Inheritance
{{ gen.inheritance_tree(element, mixins=True) }}
{% else %}
<!-- no inheritance hierarchy -->
{% endif %}

{%- set has_class_props = element.class_uri or element.tree_root or element.mixin
or element.subclass_of or element.union_of or element.disjoint_with
or element.slot_names_unique or element.represents_relationship
or element.children_are_mutually_disjoint %}

{%- if has_class_props %}
## Class Properties

| Property | Value |
| --- | --- |
{%- if element.class_uri %}
| Class URI | {{ gen.uri_link(element.class_uri) }} |
{%- endif %}
{%- if element.mixin %}
| Mixin | Yes |
{%- endif %}
{%- if element.tree_root %}
| Tree Root | Yes |
{%- endif %}
{%- if element.slot_names_unique %}
| Slot Names Unique | Yes |
{%- endif %}
{%- if element.represents_relationship %}
| Represents Relationship | Yes |
{%- endif %}
{%- if element.subclass_of %}
| Subclass Of | {{ gen.links(element.subclass_of) | join(', ') }} |
{%- endif %}
{%- if element.union_of %}
| Union Of | {{ gen.links(element.union_of) | join(', ') }} |
{%- endif %}
{%- if element.disjoint_with %}
| Disjoint With | {{ gen.links(element.disjoint_with) | join(', ') }} |
{%- endif %}
{%- if element.children_are_mutually_disjoint %}
| Children Are Mutually Disjoint | Yes |
{%- endif %}

{% endif %}
## Slots

| Name | Cardinality and Range | Description | Inheritance |
| --- | --- | --- | --- |
{% if gen.get_direct_slots(element)|length > 0 %}
{%- for slot in gen.get_direct_slots(element) -%}
| {{ gen.link(slot) }} | {{ gen.cardinality(slot) }} <br/> {{ compute_range(slot) }} | {{ slot.description|enshorten }} | direct |
{% endfor -%}
{% endif -%}
{% if gen.get_indirect_slots(element)|length > 0 %}
{%- for slot in gen.get_indirect_slots(element) -%}
| {{ gen.link(slot) }} | {{ gen.cardinality(slot) }} <br/> {{ compute_range(slot) }} | {{ slot.description|enshorten }} | {{ gen.links(gen.get_slot_inherited_from(element.name, slot.name))|join(', ') }} |
{% endfor -%}
{% endif %}

{%- if element.unique_keys %}
## Unique Keys

{% for uk in element.unique_keys.values() %}
### {{ uk.unique_key_name }}

**Unique key slots:** {{ uk.unique_key_slots | join(', ') }}
{%- if uk.consider_nulls_inequal %}

Considers null values as inequal
{%- endif %}
{% endfor %}
{% endif %}

{%- if element.defining_slots %}
## Defining Slots

This class is defined by the following slots:

{% for slot_name in element.defining_slots %}
* {{ gen.link(slot_name) }}
{%- endfor %}
{% endif %}

{%- set has_expressions = element.any_of or element.all_of or element.exactly_one_of
or element.none_of or element.slot_conditions %}

{%- if has_expressions %}
<details>
<summary>Expressions & Logic</summary>

{%- if element.any_of %}
#### Any Of

The class must satisfy at least one of:

{%- for expr in element.any_of %}
- {{ expr }}
{%- endfor %}
{%- endif %}

{%- if element.all_of %}
#### All Of

The class must satisfy all of:

{%- for expr in element.all_of %}
- {{ expr }}
{%- endfor %}
{%- endif %}

{%- if element.exactly_one_of %}
#### Exactly One Of

The class must satisfy exactly one of:

{%- for expr in element.exactly_one_of %}
- {{ expr }}
{%- endfor %}
{%- endif %}

{%- if element.none_of %}
#### None Of

The class must not satisfy any of:

{%- for expr in element.none_of %}
- {{ expr }}
{%- endfor %}
{%- endif %}

{%- if element.slot_conditions %}
#### Slot Conditions

{%- for slot_name, conditions in element.slot_conditions.items() %}
- **{{ gen.link(slot_name) }}**: {{ conditions }}
{%- endfor %}
{%- endif %}

</details>
{% endif %}

{% if schemaview.is_mixin(element.name) %}
## Mixin Usage

| mixed into | description |
| --- | --- |
{% for c in schemaview.class_children(element.name, is_a=False) -%}
| {{ gen.link(c) }} | {{ schemaview.get_class(c).description|enshorten }} |
{% endfor %}
{% endif %}

{% if schemaview.usage_index().get(element.name) %}
## Usages

| used by | used in | type | used |
| --- | --- | --- | --- |
{% for usage in schemaview.usage_index().get(element.name) -%}
| {{ gen.link(usage.used_by) }} | {{ gen.link(usage.slot) }} | {{ usage.metaslot }} | {{ gen.link(usage.used) }} |
{% endfor %}
{% endif %}

{% if element.rules %}
## Rules

{% for rule in gen.classrule_to_dict_view(element) %}
### {{ rule.title }}

| Rule Applied | Preconditions | Postconditions | Elseconditions |
|--------------|---------------|----------------|----------------|
{% for key in rule.preconditions|default({}) -%}
| {{ key }} |
{%- if rule.preconditions[key] is defined -%}
```{{ rule.preconditions[key] }}```
{%- else -%}
{% endif %} |
{%- if rule.postconditions and rule.postconditions[key] is defined -%}
```{{ rule.postconditions[key] }}```
{%- else -%}
{% endif %} |
{%- if rule.elseconditions and rule.elseconditions[key] is defined -%}
```{{ rule.elseconditions[key] }}```
{%- else -%}
{% endif %} |
{% endfor %}

{% endfor %}
{% endif %}

{% include "common_metadata.md.jinja2" %}

{% if gen.example_object_blobs(element.name) -%}
## Examples
{% for name, blob in gen.example_object_blobs(element.name) -%}
### Example: {{ name }}

```yaml
{{ blob }}
```
{% endfor %}
{% endif %}

## LinkML Source

<!-- TODO: investigate https://stackoverflow.com/questions/37606292/how-to-create-tabbed-code-blocks-in-mkdocs-or-sphinx -->

### Direct

<details>
```yaml
{{ gen.yaml(element) }}
```
</details>

### Induced

<details>
```yaml
{{ gen.yaml(element, inferred=True) }}
```
</details>

{%- if footer -%}
{{ footer }}
{%- endif -%}

</div>
76 changes: 76 additions & 0 deletions docs/templates-linkml/class_diagram.md.jinja2
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
{% macro slot_relationship(element, slot) %}
{% if slot.range is not none %}
{% set range_element = gen.name(schemaview.get_element(slot.range)) %}
{% set relation_label = gen.name(slot) %}
{{ gen.name(element) }} --> "{{ gen.cardinality(slot) }}" {{ range_element }} : {{ relation_label }}
click {{ range_element }} href "{{ gen.link_mermaid(schemaview.get_element(slot.range)) }}"
{% endif %}
{% endmacro %}

{% if schemaview.class_parents(element.name) and schemaview.class_children(element.name) %}
```{{ gen.mermaid_directive() }}
classDiagram
class {{ gen.name(element) }}
click {{ gen.name(element) }} href "{{ gen.link_mermaid(element) }}"
{% for s in schemaview.class_parents(element.name)|sort(attribute='name') -%}
{{ gen.name(schemaview.get_element(s)) }} <|-- {{ gen.name(element) }}
click {{ gen.name(schemaview.get_element(s)) }} href "{{ gen.link_mermaid(schemaview.get_element(s)) }}"
{% endfor %}

{% for s in schemaview.class_children(element.name)|sort(attribute='name') -%}
{{ gen.name(element) }} <|-- {{ gen.name(schemaview.get_element(s)) }}
click {{ gen.name(schemaview.get_element(s)) }} href "{{ gen.link_mermaid(schemaview.get_element(s)) }}"
{% endfor %}

{% for s in schemaview.class_induced_slots(element.name)|sort(attribute='name') -%}
{{ gen.name(element) }} : {{ gen.name(s) }}
{% if s.range is not none and s.range not in gen.all_type_object_names() %}
{{ slot_relationship(element, s) }}
{% endif %}
{% endfor %}
```
{% elif schemaview.class_parents(element.name) %}
```{{ gen.mermaid_directive() }}
classDiagram
class {{ gen.name(element) }}
click {{ gen.name(element) }} href "{{ gen.link_mermaid(element) }}"
{% for s in schemaview.class_parents(element.name)|sort(attribute='name') -%}
{{ gen.name(schemaview.get_element(s)) }} <|-- {{ gen.name(element) }}
click {{ gen.name(schemaview.get_element(s)) }} href "{{ gen.link_mermaid(schemaview.get_element(s)) }}"
{% endfor %}
{% for s in schemaview.class_induced_slots(element.name)|sort(attribute='name') -%}
{{ gen.name(element) }} : {{ gen.name(s) }}
{% if s.range is not none and s.range not in gen.all_type_object_names() %}
{{ slot_relationship(element, s) }}
{% endif %}
{% endfor %}
```
{% elif schemaview.class_children(element.name) %}
```{{ gen.mermaid_directive() }}
classDiagram
class {{ gen.name(element) }}
click {{ gen.name(element) }} href "{{ gen.link_mermaid(element) }}"
{% for s in schemaview.class_children(element.name)|sort(attribute='name') -%}
{{ gen.name(element) }} <|-- {{ gen.name(schemaview.get_element(s)) }}
click {{ gen.name(schemaview.get_element(s)) }} href "{{ gen.link_mermaid(schemaview.get_element(s)) }}"
{% endfor %}
{% for s in schemaview.class_induced_slots(element.name)|sort(attribute='name') -%}
{{ gen.name(element) }} : {{ gen.name(s) }}
{% if s.range is not none and s.range not in gen.all_type_object_names() %}
{{ slot_relationship(element, s) }}
{% endif %}
{% endfor %}
```
{% else %}
```{{ gen.mermaid_directive() }}
classDiagram
class {{ gen.name(element) }}
click {{ gen.name(element) }} href "{{ gen.link_mermaid(element) }}"
{% for s in schemaview.class_induced_slots(element.name)|sort(attribute='name') -%}
{{ gen.name(element) }} : {{ gen.name(s) }}
{% if s.range is not none and s.range not in gen.all_type_object_names() %}
{{ slot_relationship(element, s) }}
{% endif %}
{% endfor %}
```
{% endif %}
Loading
Loading