roadforest 0.0.3 → 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/examples/file-management.rb +7 -9
- data/lib/roadforest/application/dispatcher.rb +44 -31
- data/lib/roadforest/application/parameters.rb +5 -4
- data/lib/roadforest/application/path-provider.rb +14 -1
- data/lib/roadforest/application/route-adapter.rb +15 -4
- data/lib/roadforest/application/services-host.rb +41 -7
- data/lib/roadforest/application.rb +4 -8
- data/lib/roadforest/authorization.rb +231 -0
- data/lib/roadforest/blob-model.rb +2 -11
- data/lib/roadforest/content-handling/engine.rb +12 -6
- data/lib/roadforest/content-handling/handler-wrap.rb +45 -0
- data/lib/roadforest/content-handling/media-type.rb +20 -12
- data/lib/roadforest/content-handling/type-handler.rb +76 -0
- data/lib/roadforest/content-handling/type-handlers/jsonld.rb +2 -146
- data/lib/roadforest/content-handling/type-handlers/rdf-handler.rb +38 -0
- data/lib/roadforest/content-handling/type-handlers/rdfa-writer/document-environment.rb +34 -0
- data/lib/roadforest/content-handling/type-handlers/rdfa-writer/object-environment.rb +62 -0
- data/lib/roadforest/content-handling/type-handlers/rdfa-writer/property-environment.rb +46 -0
- data/lib/roadforest/content-handling/type-handlers/rdfa-writer/render-engine.rb +574 -0
- data/lib/roadforest/content-handling/type-handlers/rdfa-writer/render-environment.rb +144 -0
- data/lib/roadforest/content-handling/type-handlers/rdfa-writer/subject-environment.rb +80 -0
- data/lib/roadforest/content-handling/type-handlers/rdfa-writer.rb +163 -0
- data/lib/roadforest/content-handling/type-handlers/rdfa.rb +175 -0
- data/lib/roadforest/content-handling/type-handlers/rdfpost.rb +297 -0
- data/lib/roadforest/debug.rb +10 -0
- data/lib/roadforest/http/graph-response.rb +3 -7
- data/lib/roadforest/http/graph-transfer.rb +28 -106
- data/lib/roadforest/http/keychain.rb +79 -0
- data/lib/roadforest/http/message.rb +9 -1
- data/lib/roadforest/http/user-agent.rb +115 -0
- data/lib/roadforest/http.rb +8 -0
- data/lib/roadforest/model.rb +48 -3
- data/lib/roadforest/rdf/graph-focus.rb +5 -3
- data/lib/roadforest/rdf/graph-store.rb +4 -2
- data/lib/roadforest/rdf/normalization.rb +6 -1
- data/lib/roadforest/remote-host.rb +22 -7
- data/lib/roadforest/resource/rdf/read-only.rb +15 -1
- data/lib/roadforest/templates/base/doc.haml +13 -0
- data/lib/roadforest/templates/base/property_value.haml +12 -0
- data/lib/roadforest/templates/base/property_values.haml +6 -0
- data/lib/roadforest/templates/base/subject.haml +4 -0
- data/lib/roadforest/templates/distiller/doc.haml +20 -0
- data/lib/roadforest/templates/distiller/nil-object.haml +1 -0
- data/lib/roadforest/templates/distiller/property_value.haml +7 -0
- data/lib/roadforest/templates/distiller/property_values.haml +7 -0
- data/lib/roadforest/templates/distiller/subject.haml +5 -0
- data/lib/roadforest/templates/min/doc.haml +10 -0
- data/lib/roadforest/templates/min/property_values.haml +7 -0
- data/lib/roadforest/templates/min/subject.haml +2 -0
- data/lib/roadforest/templates/nil-object.haml +0 -0
- data/lib/roadforest/templates/node-object.haml +1 -0
- data/lib/roadforest/templates/object.haml +1 -0
- data/lib/roadforest/templates/uri-object.haml +1 -0
- data/lib/roadforest/templates/xml-literal-object.haml +1 -0
- data/lib/roadforest/utility/class-registry.rb +4 -0
- data/spec/client.rb +119 -77
- data/spec/{excon-adapater.rb → excon-adapter.rb} +4 -0
- data/spec/full-integration.rb +6 -2
- data/spec/graph-store.rb +1 -1
- data/spec/media-types.rb +29 -2
- metadata +102 -125
@@ -0,0 +1,144 @@
|
|
1
|
+
require 'roadforest/content-handling/type-handlers/rdfa-writer'
|
2
|
+
module RoadForest::MediaType
|
3
|
+
class RDFaWriter
|
4
|
+
class RenderEnvironment
|
5
|
+
attr_accessor :heading_predicates, :lang
|
6
|
+
|
7
|
+
def initialize(engine)
|
8
|
+
@_engine = engine
|
9
|
+
end
|
10
|
+
|
11
|
+
def add_debug(msg = nil, &block)
|
12
|
+
@_engine.add_debug(msg, &block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def inspect
|
16
|
+
"<#{self.class.name}:#{"%x" % self.object_id} #{instance_variables.map do |name|
|
17
|
+
next if name == :@_engine
|
18
|
+
"#{name}=#{instance_variable_get(name).inspect}"
|
19
|
+
end.compact.join(" ")}>"
|
20
|
+
end
|
21
|
+
# Display a subject.
|
22
|
+
#
|
23
|
+
# If the Haml template contains an entry matching the subject's rdf:type URI, that entry will be used as the template for this subject and it's properties.
|
24
|
+
#
|
25
|
+
# @example Displays a subject as a Resource Definition:
|
26
|
+
# <div typeof="rdfs:Resource" about="http://example.com/resource">
|
27
|
+
# <h1 property="dc:title">label</h1>
|
28
|
+
# <ul>
|
29
|
+
# <li content="2009-04-30T06:15:51Z" property="dc:created">2009-04-30T06:15:51+00:00</li>
|
30
|
+
# </ul>
|
31
|
+
# </div>
|
32
|
+
#
|
33
|
+
# @param [RDF::Resource] subject
|
34
|
+
# @param [Hash{Symbol => Object}] options
|
35
|
+
# @option options [:li, nil] :element(:div)
|
36
|
+
# Serialize using <li> rather than template default element
|
37
|
+
# @option options [RDF::Resource] :rel (nil)
|
38
|
+
# Optional @rel property
|
39
|
+
# @return [String]
|
40
|
+
def subject(subject, &block)
|
41
|
+
@_engine.render_subject(subject, &block)
|
42
|
+
end
|
43
|
+
|
44
|
+
def is_subject?
|
45
|
+
false
|
46
|
+
end
|
47
|
+
|
48
|
+
def literal?
|
49
|
+
false
|
50
|
+
end
|
51
|
+
|
52
|
+
def render_checked
|
53
|
+
false
|
54
|
+
end
|
55
|
+
|
56
|
+
# Haml rendering helper. Return CURIE for the literal datatype, if the
|
57
|
+
# literal is a typed literal.
|
58
|
+
#
|
59
|
+
# @param [RDF::Resource] literal
|
60
|
+
# @return [String, nil]
|
61
|
+
# @raise [RDF::WriterError]
|
62
|
+
def get_dt_curie(literal)
|
63
|
+
raise RDF::WriterError, "Getting datatype CURIE for #{literal.inspect}, which must be a literal" unless literal.is_a?(RDF::Literal)
|
64
|
+
get_curie(literal.datatype) if literal.literal? && literal.datatype?
|
65
|
+
end
|
66
|
+
|
67
|
+
# Haml rendering helper. Return language for plain literal, if there is no language, or it is the same as the document, return nil
|
68
|
+
#
|
69
|
+
# @param [RDF::Literal] literal
|
70
|
+
# @return [Symbol, nil]
|
71
|
+
# @raise [RDF::WriterError]
|
72
|
+
def get_lang(literal)
|
73
|
+
raise RDF::WriterError, "Getting datatype CURIE for #{literal.inspect}, which must be a literal" unless literal.is_a?(RDF::Literal)
|
74
|
+
literal.language if literal.literal? && literal.language && literal.language.to_s != @_engine.lang.to_s
|
75
|
+
end
|
76
|
+
|
77
|
+
# Haml rendering helper. Data to be added to a @content value
|
78
|
+
#
|
79
|
+
# @param [RDF::Literal] literal
|
80
|
+
# @return [String, nil]
|
81
|
+
# @raise [RDF::WriterError]
|
82
|
+
def get_content(literal)
|
83
|
+
raise RDF::WriterError, "Getting content for #{literal.inspect}, which must be a literal" unless literal.is_a?(RDF::Literal)
|
84
|
+
case literal
|
85
|
+
when RDF::Literal::Date, RDF::Literal::Time, RDF::Literal::DateTime
|
86
|
+
literal.to_s
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Haml rendering helper. Display value for object, may be non-canonical if get_content returns a non-nil value
|
91
|
+
#
|
92
|
+
# @param [RDF::Literal] literal
|
93
|
+
# @return [String]
|
94
|
+
# @raise [RDF::WriterError]
|
95
|
+
def get_value(literal)
|
96
|
+
raise RDF::WriterError, "Getting value for #{literal.inspect}, which must be a literal" unless literal.is_a?(RDF::Literal)
|
97
|
+
case literal
|
98
|
+
when RDF::Literal::Date
|
99
|
+
literal.object.strftime("%A, %d %B %Y")
|
100
|
+
when RDF::Literal::Time
|
101
|
+
literal.object.strftime("%H:%M:%S %Z").sub(/\+00:00/, "UTC")
|
102
|
+
when RDF::Literal::DateTime
|
103
|
+
literal.object.strftime("%H:%M:%S %Z on %A, %d %B %Y").sub(/\+00:00/, "UTC")
|
104
|
+
else
|
105
|
+
literal.to_s
|
106
|
+
end
|
107
|
+
rescue
|
108
|
+
literal.to_s # When all else fails ...
|
109
|
+
end
|
110
|
+
|
111
|
+
# Haml rendering helper. Return an appropriate label for a resource.
|
112
|
+
#
|
113
|
+
# @param [RDF::Resource] resource
|
114
|
+
# @return [String]
|
115
|
+
# @raise [RDF::WriterError]
|
116
|
+
def get_predicate_name(resource)
|
117
|
+
raise RDF::WriterError, "Getting predicate name for #{resource.inspect}, which must be a resource" unless resource.is_a?(RDF::Resource)
|
118
|
+
get_curie(resource)
|
119
|
+
end
|
120
|
+
|
121
|
+
# rendering helper. Return appropriate, term, CURIE or URI for the given
|
122
|
+
# resource.
|
123
|
+
#
|
124
|
+
# @param [RDF::Value] resource
|
125
|
+
# @return [String] value to use to identify URI
|
126
|
+
# @raise [RDF::WriterError]
|
127
|
+
def get_curie(resource)
|
128
|
+
@_engine.get_curie(resource)
|
129
|
+
end
|
130
|
+
|
131
|
+
##
|
132
|
+
# Haml rendering helper. Escape entities to avoid whitespace issues.
|
133
|
+
#
|
134
|
+
# # In addtion to "&<>, encode \n and \r to ensure that whitespace is properly preserved
|
135
|
+
#
|
136
|
+
# @param [String] str
|
137
|
+
# @return [String]
|
138
|
+
# Entity-encoded string
|
139
|
+
def escape_entities(str)
|
140
|
+
CGI.escapeHTML(str).gsub(/[\n\r]/) {|c| '&#x' + c.unpack('h').first + ';'}
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'roadforest/content-handling/type-handlers/rdfa-writer/render-environment'
|
2
|
+
module RoadForest::MediaType
|
3
|
+
class RDFaWriter
|
4
|
+
class SubjectEnvironment < RenderEnvironment
|
5
|
+
attr_accessor :base, :element, :predicate_terms, :property_objects, :rel, :inlist, :subject, :typeof
|
6
|
+
|
7
|
+
# Write a predicate with one or more values.
|
8
|
+
#
|
9
|
+
# Values may be a combination of Literal and Resource (Node or URI).
|
10
|
+
# @param [RDF::Resource] predicate
|
11
|
+
# Predicate to serialize
|
12
|
+
# @param [Array<RDF::Resource>] objects
|
13
|
+
# Objects to serialize
|
14
|
+
# @return [String]
|
15
|
+
def predicate(predicate)
|
16
|
+
@_engine.render_predicate(subject, predicate)
|
17
|
+
end
|
18
|
+
|
19
|
+
def attrs
|
20
|
+
{:rel => rel, :resource => (about || resource), :typeof => typeof, :inlist => inlist}
|
21
|
+
end
|
22
|
+
|
23
|
+
def is_subject?
|
24
|
+
true
|
25
|
+
end
|
26
|
+
|
27
|
+
def predicates
|
28
|
+
enum_for(:each_predicate)
|
29
|
+
end
|
30
|
+
|
31
|
+
def each_predicate
|
32
|
+
predicate_terms.each do |predicate|
|
33
|
+
predicate = RDF::URI(predicate) if predicate.is_a?(String)
|
34
|
+
objects = property_objects[predicate.to_s]
|
35
|
+
next if objects.nil? or objects.empty?
|
36
|
+
|
37
|
+
nonlists, lists = objects.partition do |object|
|
38
|
+
!@_engine.is_list?(object)
|
39
|
+
end
|
40
|
+
|
41
|
+
add_debug {"properties with lists: #{lists} non-lists: #{nonlists}"}
|
42
|
+
|
43
|
+
([@_engine.simple_property_env(predicate, nonlists)] + @_engine.list_property_envs(predicate, lists)).compact.each do |env|
|
44
|
+
yield(env)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def template_kinds
|
50
|
+
%w{subject}
|
51
|
+
end
|
52
|
+
|
53
|
+
def render_checked
|
54
|
+
return true if @_engine.is_done?(subject)
|
55
|
+
@_engine.subject_done(subject)
|
56
|
+
return false
|
57
|
+
end
|
58
|
+
|
59
|
+
def about
|
60
|
+
if rel.nil?
|
61
|
+
get_curie(subject)
|
62
|
+
else
|
63
|
+
nil
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def resource
|
68
|
+
if rel.nil?
|
69
|
+
nil
|
70
|
+
else
|
71
|
+
get_curie(subject)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def yielded(pred)
|
76
|
+
@_engine.render(pred)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,163 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
require 'roadforest/debug'
|
3
|
+
require 'rdf/rdfa'
|
4
|
+
|
5
|
+
module RoadForest::MediaType
|
6
|
+
##
|
7
|
+
# An RDFa 1.1 serialiser in Ruby. The RDFa serializer makes use of Haml templates, allowing runtime-replacement with alternate templates. Note, however, that templates should be checked against the W3C test suite to ensure that valid RDFa is emitted.
|
8
|
+
#
|
9
|
+
# Note that the natural interface is to write a whole graph at a time. Writing statements or Triples will create a graph to add them to and then serialize the graph.
|
10
|
+
#
|
11
|
+
# The writer will add prefix definitions, and use them for creating @prefix definitions, and minting CURIEs
|
12
|
+
#
|
13
|
+
# @example Obtaining a RDFa writer class
|
14
|
+
# RDF::Writer.for(:html) => RDF::RDFa::Writer
|
15
|
+
# RDF::Writer.for("etc/test.html")
|
16
|
+
# RDF::Writer.for(:file_name => "etc/test.html")
|
17
|
+
# RDF::Writer.for(:file_extension => "html")
|
18
|
+
# RDF::Writer.for(:content_type => "application/xhtml+xml")
|
19
|
+
# RDF::Writer.for(:content_type => "text/html")
|
20
|
+
#
|
21
|
+
# @example Serializing RDF graph into an XHTML+RDFa file
|
22
|
+
# RDF::RDFa::Write.open("etc/test.html") do |writer|
|
23
|
+
# writer << graph
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# @example Serializing RDF statements into an XHTML+RDFa file
|
27
|
+
# RDF::RDFa::Writer.open("etc/test.html") do |writer|
|
28
|
+
# graph.each_statement do |statement|
|
29
|
+
# writer << statement
|
30
|
+
# end
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# @example Serializing RDF statements into an XHTML+RDFa string
|
34
|
+
# RDF::RDFa::Writer.buffer do |writer|
|
35
|
+
# graph.each_statement do |statement|
|
36
|
+
# writer << statement
|
37
|
+
# end
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# @example Creating @base and @prefix definitions in output
|
41
|
+
# RDF::RDFa::Writer.buffer(:base_uri => "http://example.com/", :prefixes => {
|
42
|
+
# :foaf => "http://xmlns.com/foaf/0.1/"}
|
43
|
+
# ) do |writer|
|
44
|
+
# graph.each_statement do |statement|
|
45
|
+
# writer << statement
|
46
|
+
# end
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# @author [Gregg Kellogg](http://kellogg-assoc.com/)
|
50
|
+
class RDFaWriter < RDF::Writer
|
51
|
+
HAML_OPTIONS = {
|
52
|
+
:ugly => true, # to preserve whitespace without using entities
|
53
|
+
}
|
54
|
+
|
55
|
+
# @return [Graph] Graph of statements serialized
|
56
|
+
attr_accessor :graph
|
57
|
+
|
58
|
+
# @return [RDF::URI] Base URI used for relativizing URIs
|
59
|
+
attr_accessor :base_uri
|
60
|
+
|
61
|
+
##
|
62
|
+
# Initializes the RDFa writer instance.
|
63
|
+
#
|
64
|
+
# @param [IO, File] output
|
65
|
+
# the output stream
|
66
|
+
# @param [Hash{Symbol => Object}] options
|
67
|
+
# any additional options
|
68
|
+
# @option options [Boolean] :canonicalize (false)
|
69
|
+
# whether to canonicalize literals when serializing
|
70
|
+
# @option options [Hash] :prefixes (Hash.new)
|
71
|
+
# the prefix mappings to use
|
72
|
+
# @option options [#to_s] :base_uri (nil)
|
73
|
+
# the base URI to use when constructing relative URIs, set as html>head>base.href
|
74
|
+
# @option options [Boolean] :validate (false)
|
75
|
+
# whether to validate terms when serializing
|
76
|
+
# @option options [#to_s] :lang (nil)
|
77
|
+
# Output as root @lang attribute, and avoid generation _@lang_ where possible
|
78
|
+
# @option options [Boolean] :standard_prefixes (false)
|
79
|
+
# Add standard prefixes to _prefixes_, if necessary.
|
80
|
+
# @option options [Array<RDF::URI>] :top_classes ([RDF::RDFS.Class])
|
81
|
+
# Defines rdf:type of subjects to be emitted at the beginning of the document.
|
82
|
+
# @option options [Array<RDF::URI>] :predicate_order ([RDF.type, RDF::RDFS.label, RDF::DC.title])
|
83
|
+
# Defines order of predicates to to emit at begninning of a resource description..
|
84
|
+
# @option options [Array<RDF::URI>] :heading_predicates ([RDF::RDFS.label, RDF::DC.title])
|
85
|
+
# Defines order of predicates to use in heading.
|
86
|
+
# @option options [String, Symbol, Hash{Symbol => String}] :haml (DEFAULT_HAML) HAML templates used for generating code
|
87
|
+
# @option options [Hash] :haml_options (HAML_OPTIONS)
|
88
|
+
# Options to pass to Haml::Engine.new. Default options set `:ugly => false` to ensure that whitespace in literals with newlines is properly preserved.
|
89
|
+
# @yield [writer]
|
90
|
+
# @yieldparam [RDF::Writer] writer
|
91
|
+
def initialize(output = $stdout, options = {}, &block)
|
92
|
+
super do
|
93
|
+
@graph = RDF::Graph.new
|
94
|
+
@valise = nil
|
95
|
+
|
96
|
+
block.call(self) if block_given?
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
##
|
101
|
+
# Write whole graph
|
102
|
+
#
|
103
|
+
# @param [Graph] graph
|
104
|
+
# @return [void]
|
105
|
+
def write_graph(graph)
|
106
|
+
@graph = graph
|
107
|
+
end
|
108
|
+
|
109
|
+
##
|
110
|
+
# Addes a statement to be serialized
|
111
|
+
# @param [RDF::Statement] statement
|
112
|
+
# @return [void]
|
113
|
+
# @raise [RDF::WriterError] if validating and attempting to write an invalid {RDF::Term}.
|
114
|
+
def write_statement(statement)
|
115
|
+
raise RDF::WriterError, "Statement #{statement.inspect} is invalid" if validate? && statement.invalid?
|
116
|
+
@graph.insert(statement)
|
117
|
+
end
|
118
|
+
|
119
|
+
##
|
120
|
+
# Addes a triple to be serialized
|
121
|
+
# @param [RDF::Resource] subject
|
122
|
+
# @param [RDF::URI] predicate
|
123
|
+
# @param [RDF::Value] object
|
124
|
+
# @return [void]
|
125
|
+
# @raise [NotImplementedError] unless implemented in subclass
|
126
|
+
# @abstract
|
127
|
+
# @raise [RDF::WriterError] if validating and attempting to write an invalid {RDF::Term}.
|
128
|
+
def write_triple(subject, predicate, object)
|
129
|
+
write_statement Statement.new(subject, predicate, object)
|
130
|
+
end
|
131
|
+
|
132
|
+
##
|
133
|
+
# Outputs the XHTML+RDFa representation of all stored triples.
|
134
|
+
#
|
135
|
+
# @return [void]
|
136
|
+
def write_epilogue
|
137
|
+
require 'roadforest/content-handling/type-handlers/rdfa-writer/render-engine'
|
138
|
+
@base_uri = RDF::URI(@options[:base_uri]) if @options[:base_uri]
|
139
|
+
@lang = @options[:lang]
|
140
|
+
@debug = @options[:debug]
|
141
|
+
engine = RenderEngine.new(@graph, @debug) do |engine|
|
142
|
+
engine.valise = Valise.define do
|
143
|
+
ro up_to("lib") + "roadforest"
|
144
|
+
end
|
145
|
+
engine.style_name = @options[:haml]
|
146
|
+
engine.base_uri = base_uri
|
147
|
+
engine.lang = @lang
|
148
|
+
engine.standard_prefixes = @options[:standard_prefixes]
|
149
|
+
engine.top_classes = @options[:top_classes] || [RDF::RDFS.Class]
|
150
|
+
engine.predicate_order = @options[:predicate_order] || [RDF.type, RDF::RDFS.label, RDF::DC.title]
|
151
|
+
engine.heading_predicates = @options[:heading_predicates] || [RDF::RDFS.label, RDF::DC.title]
|
152
|
+
engine.haml_options = @options[:haml_options]
|
153
|
+
end
|
154
|
+
|
155
|
+
engine.prefixes.merge! @options[:prefixes] unless @options[:prefixes].nil?
|
156
|
+
|
157
|
+
# Generate document
|
158
|
+
rendered = engine.render_document
|
159
|
+
|
160
|
+
@output.write(rendered)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
@@ -0,0 +1,175 @@
|
|
1
|
+
require 'rdf/rdfa' #XXX Otherwise json-ld grabs RDFa documents. Awaiting fix upstream
|
2
|
+
require 'roadforest/content-handling/type-handlers/rdf-handler'
|
3
|
+
module RoadForest
|
4
|
+
module MediaType
|
5
|
+
module Handlers
|
6
|
+
class RESTfulRDFaWriter < ::RDF::RDFa::Writer
|
7
|
+
HAML = ::RDF::RDFa::Writer::BASE_HAML.merge(:property_values => %q{
|
8
|
+
- objects.each do |object|
|
9
|
+
/
|
10
|
+
= object.inspect
|
11
|
+
%div.property
|
12
|
+
%span.label
|
13
|
+
= get_predicate_name(predicate)
|
14
|
+
%ul
|
15
|
+
- objects.each do |object|
|
16
|
+
- if res = yield(object, :inlist => inlist, :element => :li)
|
17
|
+
!= res
|
18
|
+
- elsif object.node?
|
19
|
+
%li{:property => get_curie(predicate), :resource => get_curie(object), :inlist => inlist}= get_curie(object)
|
20
|
+
- elsif object.uri?
|
21
|
+
%li
|
22
|
+
%a{:property => get_curie(predicate), :href => object.to_s, :inlist => inlist}= object.to_s
|
23
|
+
- elsif object.datatype == RDF.XMLLiteral
|
24
|
+
%li{:property => get_curie(predicate), :lang => get_lang(object), :datatype => get_curie(object.datatype), :inlist => inlist}<!= get_value(object)
|
25
|
+
- else
|
26
|
+
%li{:property => get_curie(predicate), :content => get_content(object), :lang => get_lang(object), :datatype => get_dt_curie(object), :inlist => inlist}= escape_entities(get_value(object))
|
27
|
+
})
|
28
|
+
|
29
|
+
def initialize(output = $stdout, options = nil, &block)
|
30
|
+
options ||= {}
|
31
|
+
options = {:haml => HAML}
|
32
|
+
super(output, options, &block)
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
# Write a predicate with one or more values.
|
37
|
+
#
|
38
|
+
# Values may be a combination of Literal and Resource (Node or URI).
|
39
|
+
# @param [RDF::Resource] predicate
|
40
|
+
# Predicate to serialize
|
41
|
+
# @param [Array<RDF::Resource>] objects
|
42
|
+
# Objects to serialize
|
43
|
+
# @return [String]
|
44
|
+
def predicate(predicate, objects, options = nil)
|
45
|
+
add_debug {"predicate: #{predicate.inspect}, objects: #{objects}"}
|
46
|
+
|
47
|
+
return if objects.to_a.empty?
|
48
|
+
|
49
|
+
add_debug {"predicate: #{get_curie(predicate)}"}
|
50
|
+
render_property(predicate, objects, options || {}) do |o, opts|
|
51
|
+
# Yields each object, for potential recursive definition.
|
52
|
+
# If nil is returned, a leaf is produced
|
53
|
+
opts = {:rel => get_curie(predicate), :element => (:li if objects.length > 1)}.merge(opts||{})
|
54
|
+
|
55
|
+
if !is_done?(o) && @subjects.include?(o)
|
56
|
+
depth {subject(o, opts)}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
# Render a single- or multi-valued predicate using
|
63
|
+
# `haml_template[:property_value]` or
|
64
|
+
# `haml_template[:property_values]`. Yields each object for optional
|
65
|
+
# rendering. The block should only render for recursive subject
|
66
|
+
# definitions (i.e., where the object is also a subject and is rendered
|
67
|
+
# underneath the first referencing subject).
|
68
|
+
#
|
69
|
+
# If a multi-valued property definition is not found within the template, the writer will use the single-valued property definition multiple times.
|
70
|
+
#
|
71
|
+
# @param [Array<RDF::Resource>] predicate
|
72
|
+
# Predicate to render.
|
73
|
+
# @param [Array<RDF::Resource>] objects
|
74
|
+
# List of objects to render. If the list contains only a single element, the :property_value template will be used. Otherwise, the :property_values template is used.
|
75
|
+
# @param [Hash{Symbol => Object}] options Rendering options passed to Haml render.
|
76
|
+
# @option options [String] haml (haml_template[:property_value], haml_template[:property_values])
|
77
|
+
# Haml template to render. Otherwise, uses `haml_template[:property_value] or haml_template[:property_values]`
|
78
|
+
# depending on the cardinality of objects.
|
79
|
+
# @yield [object]
|
80
|
+
# Yields object.
|
81
|
+
# @yieldparam [RDF::Resource] object
|
82
|
+
# @yieldreturn [String, nil]
|
83
|
+
# The block should only return a string for recursive object definitions.
|
84
|
+
# @return String
|
85
|
+
# The rendered document is returned as a string
|
86
|
+
def render_property(predicate, objects, options = {}, &block)
|
87
|
+
add_debug {"render_property(#{predicate}): #{objects.inspect}"}
|
88
|
+
# If there are multiple objects, and no :property_values is defined, call recursively with
|
89
|
+
# each object
|
90
|
+
|
91
|
+
template = options[:haml]
|
92
|
+
template ||= objects.length > 1 ? haml_template[:property_values] : haml_template[:property_value]
|
93
|
+
|
94
|
+
# Separate out the objects which are lists and render separately
|
95
|
+
list_objects = objects.select {|o| o != ::RDF.nil && ::RDF::List.new(o, @graph).valid?}
|
96
|
+
unless list_objects.empty?
|
97
|
+
# Render non-list objects
|
98
|
+
add_debug {"properties with lists: non-lists: #{objects - list_objects} lists: #{list_objects}"}
|
99
|
+
nl = render_property(predicate, objects - list_objects, options, &block) unless objects == list_objects
|
100
|
+
return nl.to_s + list_objects.map do |object|
|
101
|
+
# Render each list as multiple properties and set :inlist to true
|
102
|
+
list = ::RDF::List.new(object, @graph)
|
103
|
+
list.each_statement {|st| subject_done(st.subject)}
|
104
|
+
|
105
|
+
add_debug {"list: #{list.inspect} #{list.to_a}"}
|
106
|
+
render_property(predicate, list.to_a, options.merge(:inlist => "true"), &block)
|
107
|
+
end.join(" ")
|
108
|
+
end
|
109
|
+
|
110
|
+
if objects.length > 1 && template.nil?
|
111
|
+
# Uf there is no property_values template, render each property using property_value template
|
112
|
+
objects.map do |object|
|
113
|
+
render_property(predicate, [object], options, &block)
|
114
|
+
end.join(" ")
|
115
|
+
else
|
116
|
+
raise ::RDF::WriterError, "Missing property template" if template.nil?
|
117
|
+
|
118
|
+
template = options[:haml] || (
|
119
|
+
objects.to_a.length > 1 &&
|
120
|
+
haml_template.has_key?(:property_values) ?
|
121
|
+
:property_values :
|
122
|
+
:property_value)
|
123
|
+
options = {
|
124
|
+
:objects => objects,
|
125
|
+
:object => objects.first,
|
126
|
+
:predicate => predicate,
|
127
|
+
:property => get_curie(predicate),
|
128
|
+
:rel => get_curie(predicate),
|
129
|
+
:inlist => nil,
|
130
|
+
}.merge(options)
|
131
|
+
hamlify(template, options) do |object, options|
|
132
|
+
yield(object, options) if block_given?
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
#text/html;q=1;rdfa
|
140
|
+
#image/svg+xml;q=1;rdfa
|
141
|
+
#application/xhtml+xml;q=1;rdfa
|
142
|
+
#text/html
|
143
|
+
#image/svg+xml
|
144
|
+
#application/xhtml+xml
|
145
|
+
class RDFa < RDFHandler
|
146
|
+
include RDF::Normalization
|
147
|
+
|
148
|
+
def local_to_network(base_uri, rdf)
|
149
|
+
raise "Invalid base uri: #{base_uri}" if base_uri.nil?
|
150
|
+
prefixes = relevant_prefixes_for_graph(rdf)
|
151
|
+
prefixes.keys.each do |prefix|
|
152
|
+
prefixes[prefix.to_sym] = prefixes[prefix]
|
153
|
+
end
|
154
|
+
#::RDF::RDFa.debug = true
|
155
|
+
RESTfulRDFaWriter.buffer(:base_uri => base_uri.to_s,
|
156
|
+
:prefixes => prefixes) do |writer|
|
157
|
+
rdf.each_statement do |statement|
|
158
|
+
writer << statement
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def network_to_local(base_uri, source)
|
164
|
+
raise "Invalid base uri: #{base_uri.inspect}" if base_uri.nil?
|
165
|
+
graph = ::RDF::Graph.new
|
166
|
+
reader = ::RDF::RDFa::Reader.new(source.to_s, :base_uri => base_uri.to_s)
|
167
|
+
reader.each_statement do |statement|
|
168
|
+
graph.insert(statement)
|
169
|
+
end
|
170
|
+
graph
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|