Skip to content
Open
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
5 changes: 4 additions & 1 deletion lode/reader/config/owl.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,10 @@ mapper:

# ========== REWRITE BASE ==========

# empty for now
rdfs:isDefinedBy:
is: predicate
target_classes: [Resource]
setters: [set_is_defined_by: Individual] # involves in punning


# ======================
Expand Down
4 changes: 4 additions & 0 deletions lode/reader/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ def load(self, source: str) -> None:

if self._is_url(source):
self._load_from_url_with_content_negotiation(source)

# ADD BY VALE TO FIX WINDOWS LOCAL BUG - COMMENTED FOR PRODUCTION
# elif os.path.isfile(source):
# self._load_from_local_file(source)
else:
# A value carrying a URL scheme that is not http(s) (file:, ftp:, ...)
# must not be silently treated as a local path. Bare local paths
Expand Down
26 changes: 21 additions & 5 deletions lode/templates/_entity_card.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,14 @@
<a href="#{{ anchor_map[precise_key] }}" class="{{ dep_class }}" title="{{ precise_key }}{{dep_title}}">{{ v.text }}</a>
{% elif v.link in anchor_map %}
<a href="#{{ anchor_map[v.link] }}" class="{{ dep_class }}" title="{{ v.link }}{{dep_title}}">{{ v.text }}</a>
{% else %}
<div class="d-inline-block {{ dep_class }} {% if is_md %}render-markdown inline-markdown{% endif %}"
{% elif v.is_external %}
<div class="d-inline-block external-ref {{ dep_class }} {% if is_md %}render-markdown inline-markdown{% endif %}"
title="{{ v.link }}{{dep_title}}"
{% if is_md %}data-md="{{ v.text | e }}"{% endif %}>{{ v.text }}</div>
{% elif is_static %}
<a href="{{ resource_url(v.link, v_type ~ 's') }}" class="{{ dep_class }} {% if is_md %}render-markdown inline-markdown{% endif %}" title="{{ v.link }}{{dep_title}}">{{ v.text }}</a>
{% else %}
<a href="/extract?{{ nav_qs }}&resource={{ v.link | urlencode }}" class="{{ dep_class }} {% if is_md %}render-markdown inline-markdown{% endif %}" title="{{ v.link }}{{dep_title}}">{{ v.text }}</a>
{% endif %}

{% if v_type in type_map %}
Expand Down Expand Up @@ -61,6 +65,8 @@ <h4 class="fw-bold mb-0">
{% endif %}
</h4>


{% if not single_resource %}
<span class="backlink">
back to
<a href="#toc">ToC</a>
Expand All @@ -69,6 +75,7 @@ <h4 class="fw-bold mb-0">
<a href="#{{item.type.lower()}}s">{{type_map[item.type.lower()].singular}} ToC</a>
{% endif %}
</span>
{% endif %}
</div>

<div class="card-body px-1 pb-1">
Expand Down Expand Up @@ -188,8 +195,12 @@ <h6 class="fw-bold pb-1 mb-1 text-dark" style="font-size: 0.85rem;">
<a href="#{{ anchor_map[precise_key] }}" class="{% if is_md %}render-markdown{% endif %} {{dep_class}}" title="{{precise_key}}{{dep_title}}">{{ part.text }}</a>
{% elif part.link in anchor_map %}
<a href="#{{ anchor_map[part.link] }}" class="{% if is_md %}render-markdown{% endif %} {{dep_class}}" title="{{part.link}}{{dep_title}}">{{ part.text }}</a>
{% else %}
{% elif part.is_external %}
<span class="external-ref {% if is_md %}render-markdown{% endif %} {{dep_class}}" title="{{part.link}}{{dep_title}}">{{ part.text }}</span>
{% elif is_static %}
<a href="{{ resource_url(part.link, v_type ~ 's') }}" class="{% if is_md %}render-markdown{% endif %} {{dep_class}}" title="{{part.link}}{{dep_title}}">{{ part.text }}</a>
{% else %}
<a href="/extract?{{ nav_qs }}&resource={{ part.link | urlencode }}" class="{% if is_md %}render-markdown{% endif %} {{dep_class}}" title="{{part.link}}{{dep_title}}">{{ part.text }}</a>
{% endif %}

{% if v_type in type_map %}
Expand Down Expand Up @@ -227,11 +238,16 @@ <h6 class="fw-bold pb-1 mb-1 text-dark" style="font-size: 0.85rem;">
<a href="#{{ anchor_map[precise_key] }}" class="{{dep_class}}" title="{{rel_item.link}}{{dep_title}}">{{ rel_item.text }}</a>
{% elif rel_item.link in anchor_map %}
<a href="#{{ anchor_map[rel_item.link] }}" class="{{dep_class}}" title="{{rel_item.link}}{{dep_title}}">{{ rel_item.text }}</a>
{% else %}
{% elif rel_item.is_external %}
<span class="external-ref {% if is_md %}render-markdown inline-markdown{% endif %} {{dep_class}}"
title="{{rel_item.link}}{{dep_title}}"
{% if is_md %}data-md="{{ rel_item.text | e }}"{% endif %}>{{ rel_item.text }}</span>
{% if is_md %}data-md="{{ rel_item.text | e }}"{% endif %}>{{ rel_item.text }}</span>
{% elif is_static %}
<a href="{{ resource_url(rel_item.link, v_type ~ 's') }}" class="{% if is_md %}render-markdown inline-markdown{% endif %} {{dep_class}}" title="{{rel_item.link}}{{dep_title}}">{{ rel_item.text }}</a>
{% else %}
<a href="/extract?{{ nav_qs }}&resource={{ rel_item.link | urlencode }}" class="{% if is_md %}render-markdown inline-markdown{% endif %} {{dep_class}}" title="{{rel_item.link}}{{dep_title}}">{{ rel_item.text }}</a>
{% endif %}

{% if v_type in type_map %}
<sup class="badge text-secondary {{type_map[v_type].abb}}" title="{{ type_map[v_type].singular }}">{{ type_map[v_type].abb }}</sup>
{% endif %}
Expand Down
23 changes: 20 additions & 3 deletions lode/templates/viewer.html
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,22 @@
{% endif %}

{% if metadata %}
{% if single_resource %}
<details class="mb-4 border-bottom pb-4">
<summary style="cursor:pointer; list-style:none">
<h1 class="fw-bold mb-1 d-inline">
{% if metadata.title %}
{% for title in metadata.title %}{{ title.text }}{% endfor %}
{% elif metadata.label %}{{ metadata.label[0].text }}{% endif %}
</h1>
<span class="badge bg-light text-secondary border ms-2 align-middle">ontology context — click to expand</span>
<div class="d-flex align-items-center mt-2">
<p class="text-muted medium mb-0 font-monospace text-truncate">{{ metadata.uri[0].link }}</p>
<a href="{{ metadata.uri[0].link }}" target="_blank" class="btn btn-sm btn-outline-secondary ms-2" title="Go to Resource">↗</a>
</div>
</summary>
<div class="p-3">
{% else %}
<div class="mb-4 border-bottom pb-4">
<div class="p-3">
<h1 class="fw-bold mb-2">
Expand All @@ -79,6 +95,7 @@ <h1 class="fw-bold mb-2">
<a href="{{ metadata.uri[0].link }}" target="_blank"
class="btn btn-sm btn-outline-secondary ms-2" title="Go to Resource">↗</a>
</div>
{% endif %}

<dl class="row mb-0 lead fs-6">
{% for key, val_list in metadata.items() %}
Expand Down Expand Up @@ -137,7 +154,7 @@ <h1 class="fw-bold mb-2">
{% endif %}
</dl>
</div>
</div>
{% if single_resource %}</details>{% else %}</div>{% endif %}
{% endif %}

{% if grouped_view and sections %}
Expand Down Expand Up @@ -202,7 +219,7 @@ <h3 class="section-header d-flex align-items-center justify-content-between mb-4
</div>
{% endfor %}

{% if metadata and metadata._namespaces %}
{% if metadata and metadata._namespaces and not single_resource %}
<div id="namespaces" class="anchor-offset mb-5">
<h3 class="section-header d-flex align-items-center justify-content-between mb-4">
Namespace Declarations
Expand All @@ -220,7 +237,7 @@ <h3 class="section-header d-flex align-items-center justify-content-between mb-4

{% if single_resource %}
<div class="mt-3">
<a href="/extract?{{ nav_qs }}" class="btn btn-outline-secondary">← Back to Index</a>
<a href="/extract?{{ nav_qs }}" class="btn btn-outline-secondary">← Back to full documentation</a>
</div>
{% endif %}

Expand Down
35 changes: 31 additions & 4 deletions lode/viewer/base_viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@ class BaseViewer:
def __init__(self, reader):
self.reader = reader
self._cache = reader._instance_cache # it uses
self._internal_iris = None

def _is_internal(self, uri) -> bool:
if not uri:
return False
if self._internal_iris is None:
self._internal_iris = {
str(i.get_has_identifier())
for i in self.get_toc_instances() # <-- NON get_all_instances()
if hasattr(i, 'get_has_identifier') and i.get_has_identifier()
}
return str(uri) in self._internal_iris

def get_all_instances(self) -> List:
"""Ottiene tutte le istanze (esclusi literal)."""
Expand Down Expand Up @@ -106,6 +118,16 @@ def get_view_data(self, resource_uri: Optional[str] = None, language: Optional[s
'entities': self._format_entities(all_instances, language)
}

def _is_toc_entity(self, instance) -> bool:
"""Browsable (own card + clickable link) iff its type is in get_toc_config.
Resources not listed in get_o_config are shown when mentioned as plain text
in cards (external-ref), just never linked."""
toc_keys = {key for key, _id, _title in self.get_toc_config()}
return type(instance).__name__ in toc_keys

def get_toc_instances(self) -> List:
return [i for i in self.get_all_instances() if self._is_toc_entity(i)]

def _handle_single_resource(self, resource_uri: str, language: Optional[str] = None) -> Dict:
"""
Standard logic for displaying a single resource.
Expand All @@ -117,6 +139,9 @@ def _handle_single_resource(self, resource_uri: str, language: Optional[str] = N
return {'error': f'Resource {resource_uri} not found'}

instances = list(instance_set) if isinstance(instance_set, set) else [instance_set]
instances = [i for i in instances if self._is_toc_entity(i)]
if not instances:
return {'error': f'{resource_uri} is not a browsable entity'}

return {
'single_resource': True,
Expand Down Expand Up @@ -384,14 +409,15 @@ def _resolve_resource_value(self, obj, language=None) -> dict:
'lan': None,
'parts': None, # This key is for restrictions
'type': None,
'is_deprecated': False
'is_deprecated': False,
'is_external': False,
}

if not obj: return handler_dic

# --- 1. INTERCEPT RESTRICTIONS ---
restriction_types = ["Restriction", "PropertyConceptRestriction", "Quantifier", "Cardinality", "TruthFunction",
"OneOf", "Value"]
"OneOf", "Value", "DatatypeRestriction"]
obj_type = type(obj).__name__

if obj_type in restriction_types:
Expand All @@ -406,6 +432,7 @@ def _resolve_resource_value(self, obj, language=None) -> dict:
handler_dic['parts'] = parts
handler_dic['text'] = "".join([p['text'] for p in parts if p.get('text')])
handler_dic['link'] = None # Forces Jinja to ignore the blank node URI
handler_dic['is_external'] = not self._is_internal(handler_dic['link'])
handler_dic['type'] = obj_type
return handler_dic

Expand Down Expand Up @@ -483,7 +510,7 @@ def _resolve_resource_value(self, obj, language=None) -> dict:
# --- 5. Normal Resource Handling (Concepts, Properties, Individuals) ---
if hasattr(obj, 'get_has_identifier'):
handler_dic['link'] = obj.get_has_identifier()

handler_dic['is_external'] = not self._is_internal(handler_dic['link'])
is_dep = getattr(obj, 'get_is_deprecated')() if hasattr(obj,
'get_is_deprecated') else getattr(obj, 'is_deprecated',
False)
Expand Down Expand Up @@ -687,7 +714,7 @@ def _get(instance, prop_name, default=None):
resolved = self._resolve_resource_value(obj, language)

if resolved.get('text'):
return [{'text': resolved['text'], 'link': resolved.get('link'), 'type': resolved.get('type')}]
return [{'text': resolved['text'], 'link': resolved.get('link'), 'type': resolved.get('type'), 'is_external': resolved.get('is_external', False)}]

return []

Expand Down
1 change: 0 additions & 1 deletion lode/viewer/owl_viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ class OwlViewer(BaseViewer):
'attribute': {'singular': 'Data Property', 'plural': 'Data Properties', 'abb': 'dp'},
'annotation': {'singular': 'Annotation Property', 'plural': 'Annotation Properties', 'abb': 'ap'},
'individual': {'singular': 'Named Individual', 'plural': 'Named Individuals', 'abb': 'ni'},
'model': {'singular': 'Ontology', 'plural': 'Ontologies', 'abb': 'o'},
}

def get_toc_config(self):
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "lode"
version = "0.3.0"
version = "0.3.1"
description = "New reengineered version of LODE, maintained by OpenCitations"
authors = [{name = "Valentina Pasqual, Silvio Peroni", email = "valentina.pasqual2@unibo.it"}]
readme = "README.md"
Expand Down
Loading
Loading