Skip to content

Instantly share code, notes, and snippets.

@gkellogg
Last active August 29, 2015 13:57
Show Gist options
  • Save gkellogg/9711769 to your computer and use it in GitHub Desktop.
Save gkellogg/9711769 to your computer and use it in GitHub Desktop.
YourSports JSON-LD context and partial code for creating.
class Vocab
# Generate a JSON-LD context for the vocabulary + schema.org
module Context
# @return [Hash]
def generate_context
context = {
"@vocab" => "http://schema.org/",
"@language" => "en",
"foaf" => "http://xmlns.com/foaf/0.1/",
"hydra" => "http://www.w3.org/ns/hydra/core#",
"rdf" => "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
"rdfs" => "http://www.w3.org/2000/01/rdf-schema#",
"schema" => "http://schema.org/",
"xhv" => "http://www.w3.org/1999/xhtml/vocab#",
"xsd" => "http://www.w3.org/2001/XMLSchema",
"ys" => "#{NS}",
"ys-api" => "#{API}",
}
statements = {}
ranges = {}
# Add term definitions for each class and property not in schema:, and
# for those properties having an object range
graph.each do |statement|
(statements[statement.subject] ||= []) << statement
# Keep track of predicate ranges
if statement.predicate == RDF::SCHEMA.rangeIncludes
(ranges[statement.subject] ||= []) << statement.object
end
end
statements.each do |subject, values|
term = subject.to_s.split('/').last
if values.any? {|v| v.predicate == RDF.type && v.object == RDF::RDFS.Class}
next if subject.to_s.start_with?("http://schema.org/") # Already in vocab
defn = RDF::Linter::Parser::VOCAB_DEFS["Classes"][subject.to_s]
defn ||= VOCAB_DEF["Classes"].fetch(subject.to_s)
# Create term definition
context[term] = "#{defn['vocab']}:#{term}"
elsif values.any? {|v| v.predicate == RDF.type && v.object == RDF.Property}
defn = RDF::Linter::Parser::VOCAB_DEFS["Properties"][subject.to_s]
defn ||= VOCAB_DEF["Properties"].fetch(subject.to_s)
object_range = defn.fetch("rangeIncludes", []).first
case object_range
when RDF::RDFS.Literal, RDF::SCHEMA.Text, nil
context[term] = "#{defn['vocab']}:#{term}" unless defn['vocab'] == 'schema'
when RDF::XSD.string
context[term] = {"@id" => "#{defn['vocab']}:#{term}", "@language" => nil}
when RDF::XSD.boolean, RDF::SCHEMA.Boolean
context[term] = {"@id" => "#{defn['vocab']}:#{term}", "@type" => "xsd:boolean"}
when RDF::XSD.date, RDF::SCHEMA.Date
context[term] = {"@id" => "#{defn['vocab']}:#{term}", "@type" => "xsd:date"}
when RDF::XSD.dateTime, RDF::SCHEMA.DateTime
context[term] = {"@id" => "#{defn['vocab']}:#{term}", "@type" => "xsd:dateTime"}
when RDF::XSD.time, RDF::SCHEMA.DateTime
context[term] = {"@id" => "#{defn['vocab']}:#{term}", "@type" => "xsd:time"}
when RDF::XSD.duration, RDF::SCHEMA.Duration
context[term] = {"@id" => "#{defn['vocab']}:#{term}", "@type" => "xsd:duration"}
when RDF::XSD.decimal, RDF::SCHEMA.Number
context[term] = {"@id" => "#{defn['vocab']}:#{term}", "@type" => "xsd:decimal"}
when RDF::XSD.float, RDF::SCHEMA.Float
context[term] = {"@id" => "#{defn['vocab']}:#{term}", "@type" => "xsd:float"}
when RDF::XSD.integer, RDF::SCHEMA.Integer
context[term] = {"@id" => "#{defn['vocab']}:#{term}", "@type" => "xsd:integer"}
when RDF::XSD.anyURI, RDF::SCHEMA.URL
context[term] = {"@id" => "#{defn['vocab']}:#{term}", "@type" => "xsd:anyURI"}
else
# It's an object range
context[term] = {"@id" => "#{defn['vocab']}:#{term}", "@type" => "@id"}
end
# If the inverse propert is not defined in statements, create a reverse JSON-LD property
values.select {|v| v.predicate.to_s.end_with?("inverseOf")}.map(&:object).each do |o|
inverse_term = o.to_s.split('/').last
context[inverse_term] = {"@reverse" => "#{defn['vocab']}:#{term}"}
end
end
end
context
end
end
end
{
"@context": {
"@vocab": "http://schema.org/",
"@language": "en",
"foaf": "http://xmlns.com/foaf/0.1/",
"hydra": "http://www.w3.org/ns/hydra/core#",
"rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
"schema": "http://schema.org/",
"xhv": "http://www.w3.org/1999/xhtml/vocab#",
"xsd": "http://www.w3.org/2001/XMLSchema",
"ys": "http://yoursports.com/vocab/",
"ys-api": "http://yoursports.com/api-vocab/",
"Affiliate": "ys:Affiliate",
"Association": "ys:Association",
"Contribution": "ys:Contribution",
"Discipline": "ys:Discipline",
"Division": "ys:Division",
"Game": "ys:Game",
"League": "ys:League",
"Neighborhood": "ys:Neighborhood",
"Network": "ys:Network",
"Period": "ys:Period",
"Play": "ys:Play",
"Publisher": "ys:Publisher",
"Region": "ys:Region",
"RegionalNetwork": "ys:RegionalNetwork",
"RegisteredUser": "ys:RegisteredUser",
"Person": "foaf:Person",
"OnlineAccount": "foaf:OnlineAccount",
"Season": "ys:Season",
"Series": "ys:Series",
"SportsPerson": "ys:SportsPerson",
"Role": "ys:Role",
"TeamExecutive": "ys:TeamExecutive",
"Trophy": "ys:Trophy",
"World": "ys:World",
"checkin": {
"@id": "ys:checkin",
"@type": "@id"
},
"hasCheckedinTo": {
"@reverse": "ys:checkin"
},
"checkins": {
"@id": "ys:checkins",
"@type": "@id"
},
"comments": {
"@id": "ys:comments",
"@type": "@id"
},
"contribution": {
"@id": "ys:contribution",
"@type": "@id"
},
"contributedTo": {
"@reverse": "ys:contribution"
},
"contributions": {
"@id": "ys:contributions",
"@type": "@id"
},
"discipline": {
"@id": "ys:discipline",
"@type": "@id"
},
"account": "foaf:account",
"accountName": "foaf:accountName",
"accountServiceHomepage": "foaf:accountServiceHomepage",
"follow": {
"@id": "ys:follow",
"@type": "@id"
},
"followerOf": {
"@reverse": "ys:follow"
},
"follows": {
"@id": "schema:follows",
"@type": "@id"
},
"friend": {
"@id": "ys:friend",
"@type": "@id"
},
"friendOf": {
"@reverse": "ys:friend"
},
"friends": {
"@id": "ys:friends",
"@type": "@id"
},
"interaction": {
"@id": "ys:interaction",
"@type": "@id"
},
"interactedWith": {
"@reverse": "ys:interaction"
},
"interactions": {
"@id": "ys:interactions",
"@type": "@id"
},
"interest": {
"@id": "ys:interest",
"@type": "@id"
},
"interestedIn": {
"@reverse": "ys:interest"
},
"interests": {
"@id": "ys:interests",
"@type": "@id"
},
"likeKind": "ys:likeKind",
"question": {
"@id": "ys:question",
"@type": "@id"
},
"askedQuestionOf": {
"@reverse": "ys:question"
},
"questions": {
"@id": "ys:questions",
"@type": "@id"
},
"result": {
"@id": "schema:result",
"@type": "@id"
},
"role": {
"@id": "ys:role",
"@type": "@id"
},
"address": {
"@id": "schema:address",
"@type": "@id"
},
"affiliation": {
"@id": "schema:affiliation",
"@type": "@id"
},
"agent": {
"@id": "schema:agent",
"@type": "@id"
},
"agendOf": {
"@reverse": "schema:agent"
},
"aggregateRating": {
"@id": "schema:aggregateRating",
"@type": "@id"
},
"alumni": {
"@id": "schema:alumni",
"@type": "@id"
},
"alumniOf": {
"@id": "schema:alumniOf",
"@type": "@id"
},
"attendee": {
"@id": "schema:attendee",
"@type": "@id"
},
"attended": {
"@reverse": "schema:attendee"
},
"audience": {
"@id": "schema:audience",
"@type": "@id"
},
"birthDate": {
"@id": "schema:birthDate",
"@type": "xsd:date"
},
"brand": {
"@id": "schema:brand",
"@type": "@id"
},
"children": {
"@id": "schema:children",
"@type": "@id"
},
"parent": {
"@id": "schema:parent",
"@type": "@id"
},
"comment": {
"@id": "schema:comment",
"@type": "@id"
},
"commentOn": {
"@reverse": "schema:comment"
},
"commentTime": {
"@id": "schema:commentTime",
"@type": "xsd:date"
},
"containedIn": {
"@id": "schema:containedIn",
"@type": "@id"
},
"contains": {
"@reverse": "schema:containedIn"
},
"deathDate": {
"@id": "schema:deathDate",
"@type": "xsd:date"
},
"distance": {
"@id": "schema:distance",
"@type": "@id"
},
"doorTime": {
"@id": "schema:doorTime",
"@type": "xsd:dateTime"
},
"duration": {
"@id": "schema:duration",
"@type": "xsd:duration"
},
"endDate": {
"@id": "schema:endDate",
"@type": "xsd:date"
},
"endTime": {
"@id": "schema:endTime",
"@type": "xsd:dateTime"
},
"event": {
"@id": "schema:event",
"@type": "@id"
},
"eventIn": {
"@reverse": "schema:event"
},
"eventStatus": {
"@id": "schema:eventStatus",
"@type": "@id"
},
"followee": {
"@reverse": "schema:follows"
},
"founder": {
"@id": "schema:founder",
"@type": "@id"
},
"foundingDate": {
"@id": "schema:foundingDate",
"@type": "xsd:date"
},
"fromLocation": {
"@id": "schema:fromLocation",
"@type": "xsd:decimal"
},
"geo": {
"@id": "schema:geo",
"@type": "@id"
},
"homeLocation": {
"@id": "schema:homeLocation",
"@type": "@id"
},
"image": {
"@id": "schema:image",
"@type": "xsd:anyURI"
},
"knows": {
"@id": "schema:knows",
"@type": "@id"
},
"location": {
"@id": "schema:location",
"@type": "@id"
},
"logo": {
"@id": "schema:logo",
"@type": "@id"
},
"loser": {
"@id": "schema:loser",
"@type": "@id"
},
"map": {
"@id": "schema:map",
"@type": "xsd:anyURI"
},
"member": {
"@id": "schema:member",
"@type": "@id"
},
"memberOf": {
"@id": "schema:memberOf",
"@type": "@id"
},
"nationality": {
"@id": "schema:nationality",
"@type": "@id"
},
"object": {
"@id": "schema:object",
"@type": "@id"
},
"oponent": {
"@id": "schema:oponent",
"@type": "@id"
},
"owns": {
"@id": "schema:owns",
"@type": "@id"
},
"ownedBy": {
"@reverse": "schema:owns"
},
"participant": {
"@id": "schema:participant",
"@type": "@id"
},
"participatedIn": {
"@reverse": "schema:participant"
},
"photo": {
"@id": "schema:photo",
"@type": "@id"
},
"relatedTo": {
"@id": "schema:relatedTo",
"@type": "@id"
},
"review": {
"@id": "schema:review",
"@type": "@id"
},
"reviewOf": {
"@reverse": "schema:review"
},
"sameAs": {
"@id": "schema:sameAs",
"@type": "xsd:anyURI"
},
"sibling": {
"@id": "schema:sibling",
"@type": "@id"
},
"sportsActivityLocation": {
"@id": "schema:sportsActivityLocation",
"@type": "@id"
},
"sportsEvent": {
"@id": "schema:sportsEvent",
"@type": "@id"
},
"sportsTeam": {
"@id": "schema:sportsTeam",
"@type": "@id"
},
"spouse": {
"@id": "schema:spouse",
"@type": "@id"
},
"startDate": {
"@id": "schema:startDate",
"@type": "xsd:date"
},
"startTime": {
"@id": "schema:startTime",
"@type": "xsd:dateTime"
},
"subEvent": {
"@id": "schema:subEvent",
"@type": "@id"
},
"subOrganization": {
"@id": "schema:subOrganization",
"@type": "@id"
},
"url": {
"@id": "schema:url",
"@type": "xsd:anyURI"
},
"winner": {
"@id": "schema:winner",
"@type": "@id"
},
"team": {
"@id": "ys:team",
"@type": "@id"
},
"trophy": {
"@id": "ys:trophy",
"@type": "@id"
},
"trophyFrom": {
"@reverse": "ys:trophy"
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment