activitypods icon indicating copy to clipboard operation
activitypods copied to clipboard

Read OWL files to display names of classes in Pod frontend

Open srosset81 opened this issue 2 years ago • 4 comments

When we have the prefix, we can see if it is listed in LOV:

https://lov.linkeddata.es/dataset/lov/api/v2/vocabulary/info?vocab=foaf

Then we can look at the versions property, take the first one (the most recent one), and the OWL file will be in the fileURL property:

https://lov.linkeddata.es/dataset/lov/vocabs/foaf/versions/2014-01-14.n3

Pending issues

  • The LOV database doesn't include all vocabularies. ActivityStreams is missing (!)
  • Submitting a vocabulary takes times and is subject to approval
  • Almost all classes descriptions in OWL files are in English...
  • Parsing the LOV results and the OWL files will take time, and must most likely be done on the frontend

Alternatives

  • Create our own database, listing OWL files and JSON-LD context

srosset81 avatar Nov 22 '23 08:11 srosset81

Finally we will do it a bit differently, inspiring ourselves from the Access Descriptions of Solid Application Interoperability.

{
  "@type": "apods:ClassDescription",
  "apods:describedClass": "https://www.w3.org/ns/activitystreams#Event",
  "apods:describedBy": "https://welcometomyplace.org",
  "skos:prefLabel": "Events"@en,
  "apods:labelPredicate": "https://www.w3.org/ns/activitystreams#name",
  "apods:openEndpoint": "https://welcometomyplace.org/r",
}

Notes:

  • apods:labelPredicate will allow the frontend to display the title of resources in the "My Data" tab.
  • If apods:openEndpoint is defined, it means resources of this type can be opened up with the app. The endpoint will receive the type URI as well as the resource URI in query string, and the application will be in charge of redirecting to the correct page (like we do now with the /r endpoint)
  • apods:describedBy enable to keep a link to the application, so that it's easier to handle the cache.

The ClassDescription will be contained in an AccessDescriptionSet:

{
  "@type": "interop:AccessDescriptionSet",
  "interop:usesLanguage": "en", // xsd:language
  "apods:hasClassDescription": URIs
}

Descriptions will be optional. They won't be necessary if the application wants to use a resource type which is already defined elsewhere, for example vcard:Address. If missing, the Pod frontend will display the prefixed class (as:Event) for the label.

On the AppService, we will define the ClassDescriptions with a setting like this:

classDescriptions: {
  'as:Event': {
    label: {
      en: 'Events',
      fr: 'Evénements'
    },
    labelPredicate: 'as:name',
    openEndpoint: urlJoin(CONFIG.FRONT_URL, '/r')
  }
}

On application start, this will automatically create the apods:ClassDescription for every resource and defined language, as well as the corresponding interop:AccessDescriptionSet. If the resources are already created, we will need to ensure they have not been modified.

When a application register, the Pod will put in cache the apods:ClassDescription resources. When browsing the "My data" tab, these resources will be loaded to know how to display them. We will need to take into account the "preferred app" (https://github.com/assemblee-virtuelle/activitypods/issues/189)

We need to have ClassDescriptions for resources which are automatically defined in the Pod: for this, we will create a new ClassDescriptionMixin, to be used with the ControlledContainerMixin, which will automatically create ClassDescription resources based on a classDescription setting which will look like this:

classDescription: {
  label: {
    en: 'Profile',
    fr: 'Profil'
  },
  labelPredicate: 'foaf:name',
  openEndpoint: 'https://app.mypod.store/r'
}

Important things to note:

  • ClassDescriptions resources must be created every time a Pod is created (auth.registered)
  • We must plan a migration tool
  • We will also need to ensure the ClassDescriptions are updated.

To avoid duplicate code, we will create a ClassDescriptionService with a register action which will receive the above informations (label, labelPredicate, openEndpoint). This service will be used by the applications (AppService) and the Pod provider (ClassDescriptionMixin).

srosset81 avatar Mar 04 '24 14:03 srosset81

Most of the work has been done here: #190

We still need a migration tool from v1

srosset81 avatar Apr 10 '24 16:04 srosset81

When we have the prefix, we can see if it is listed in LOV:

https://lov.linkeddata.es/dataset/lov/api/v2/vocabulary/info?vocab=foaf

This is different from my understanding of how Web ontology works. From my understanding, you should go back to the actual resource this prefix points to, from the heading section (of turtle, e.g.).

For example, you can have

@prefix foaf <http://xmlns.com/foaf/0.1/>.
@prefix : <http://example.org>.

:me a foaf:Person.

Then you need to download http://xmlns.com/foaf/0.1/ as specified in the heading, which in turn is a valid owl file (maybe you need to explicitly specify the Accept: application/rdf+xml header or alike). Then you should parse this owl file to obtain the definitions.

IIRC, some / many rdf.js libraries do not expose the prefixes. This is always a question from me. On the other hand, Python's rdflib seems to do a good job, IIRC.

This is decentralized. While relying on lov.linkeddata.es is centralized, and problematic, because the prefix name itself may be different -- I do not have to use foaf as the prefix name for foaf vocabulary. In fact, my experience with rdf.js libraries shows that many of them manipulate the prefixes arbitrarily.

Of course, we always need to deal with the issue of prefix being arbitrary, and sometime non-existent.

renyuneyun avatar Jun 06 '24 16:06 renyuneyun

@renyuneyun Unfortunately some ontologies don't have an OWL file, or the OWL file doesn't have a definition for all classes. And even when they have, there is never a translation in other language, which was a requirement for us (ActivityPods is being used by many french users).

srosset81 avatar Jun 07 '24 15:06 srosset81