Custom RendererΒΆ
In this example, we are creating a custom Renderer
class by inheritance to cater for a media type instance. More information about this code can be found at this repository.
- The interest for
View
declarations are on lines 10-19. - On line 20-25, we pass we call the
__init__()
of the super class, passing in the list ofView
objects and some other arguments. - Lines 27-57 demonstrate how to implement the abstract
pyldapi.Renderer.render()
and how it works in tandem with the list ofView
objects.
Note
The focus here is to demonstrate how to create a custom Renderer
class, defining a custom render()
method and defining a list of View
objects.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | from flask import Response, render_template
from SPARQLWrapper import SPARQLWrapper, JSON
from rdflib import Graph, URIRef, Namespace, RDF, RDFS, XSD, OWL, Literal
from pyldapi import Renderer, Profile
import _conf as conf
class MediaTypeRenderer(Renderer):
def __init__(self, request, instance_uri):
profiles = {
'mt': Profile(
'Mediatype View',
'Basic properties of a Media Type, as recorded by IANA',
['text/html'] + Renderer.RDF_MEDIA_TYPES,
'text/turtle',
languages=['en', 'pl'],
uri='http://test.linked.data.gov.au/def/mt#'
)
}
super(MediaTypeRenderer, self).__init__(
request,
instance_uri,
profiles,
'mt'
)
def render(self):
if hasattr(self, 'vf_error'):
return Response(self.vf_error, status=406, mimetype='text/plain')
else:
if self.profile == 'alternates':
return self._render_alternates_profile()
elif self.profile == 'mt':
if self.format in Renderer.RDF_MEDIA_TYPES:
rdf = self._get_instance_rdf()
if rdf is None:
return Response('No triples contain that URI as subject', status=404, mimetype='text/plain')
else:
return Response(rdf, mimetype=self.format)
else: # only the HTML format left
deets = self._get_instance_details()
if deets is None:
return Response('That URI yielded no data', status=404, mimetype='text/plain')
else:
mediatype = self.instance_uri.replace('%2B', '+').replace('%2F', '/').split('/mediatype/')[1]
if self.language == 'pl':
return render_template(
'mediatype-pl.html',
deets=deets,
mediatype=mediatype
)
else:
return render_template(
'mediatype-en.html',
deets=deets,
mediatype=mediatype
)
def _get_instance_details(self):
sparql = SPARQLWrapper(conf.SPARQL_QUERY_URI, returnFormat=JSON)
q = '''
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX dct: <http://purl.org/dc/terms/>
SELECT *
WHERE {{
<{0[uri]}> rdfs:label ?label .
OPTIONAL {{ <{0[uri]}> dct:contributor ?contributor . }}
}}
'''.format({'uri': self.instance_uri})
sparql.setQuery(q)
d = sparql.query().convert()
d = d.get('results').get('bindings')
if d is None or len(d) < 1: # handle no result
return None
label = ''
contributors = []
for r in d:
label = str(r.get('label').get('value'))
contributors.append(str(r.get('contributor').get('value')))
return {
'label': label,
'contributors': contributors
}
def _get_instance_rdf(self):
deets = self._get_instance_details()
g = Graph()
DCT = Namespace('http://purl.org/dc/terms/')
g.bind('dct', DCT)
me = URIRef(self.instance_uri)
g.add((me, RDF.type, DCT.FileFormat))
g.add((
me,
OWL.sameAs,
URIRef(self.instance_uri.replace('https://w3id.org/mediatype/', 'https://www.iana.org/assignments/media-types/'))
))
g.add((me, RDFS.label, Literal(deets.get('label'), datatype=XSD.string)))
source = 'https://www.iana.org/assignments/media-types/' + self.instance_uri.replace('%2B', '+').replace('%2F', '/').split('/mediatype/')[1]
g.add((me, DCT.source, URIRef(source)))
if deets.get('contributors') is not None:
for contributor in deets.get('contributors'):
g.add((me, DCT.contributor, URIRef(contributor)))
if self.format in ['application/rdf+json', 'application/json']:
return g.serialize(format='json-ld')
else:
return g.serialize(format=self.format)
|