class Rackful::Serializer::XHTML
Public Class Methods
Set a header generator. @yieldparam serializer [Serializer::XHTML] This serializer @yieldreturn [String] some XHTML
# File lib/rackful/serializer.rb, line 157 def self.header &block @@header = block self end
Public Instance Methods
@yieldparam xhtml [String]
# File lib/rackful/serializer.rb, line 120 def each &block tmp = '' # The XML header is only sent for XML media types: if /xml/ === self.content_type tmp += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" end tmp += <<EOS <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <head> <title>#{ Rack::Utils.escape_html(self.resource.title) }</title> <base href="#{self.html_base_uri}"/> EOS unless '/' == self.request.canonical_uri.path tmp += <<EOS <link rel="contents" href="#{'/' === self.request.canonical_uri.path[-1] ? '../' : './' }"/> EOS end r = self.resource.to_rackful tmp += self.header + '<div id="rackful-content"' + self.xsd_type( r ) + '>' yield tmp each_nested( r, &block ) yield '</div>' + footer end
Serializes many kinds of objects to XHTML
.
How an object is serialized, depends:
-
A *{Resource}* will be serialized by its own {Resource#serializer serializer}.
-
A *{URI}* will be serialized as a hyperlink.
-
An Object responding to *‘#each_pair`* (i.e. something {Hash}-like) will be represented by
-
a descriptive list, with
-
-
An Object responding to *‘#each`* (i.e. something {Enumerable}) will be represented as a JSON array.
-
A *binary encoded {String}* (i.e. a blob} is represented by a JSON string, containing the base64 encoded version of the data.
-
A *{Time}* is represented by a string containing a dateTime as defined by XMLSchema.
-
On *all the rest,* method ‘#to_json` is invoked.
@overload each_nested
@yieldparam xhtml [String]
@api private
# File lib/rackful/serializer.rb, line 199 def each_nested p = self.resource.to_rackful, &block # A Resource: if p.kind_of?( Resource ) && ! p.equal?( self.resource ) p.serializer( self.request, self.content_type ).each_nested( &block ) # A URI: elsif p.kind_of?( URI ) rel_path = p.relative? ? p : p.route_from( self.html_base_uri ) yield "<a href=\"#{rel_path}\">" + Rack::Utils.escape_html( Rack::Utils.unescape( rel_path.to_s ) ) + '</a>' # An Object: elsif p.respond_to?( :each_pair ) yield '<br/><dl>' p.each_pair do |key, value| yield '<dt xs:type="xs:string">' + Rack::Utils.escape_html( key.to_s.split('_').join(' ') ) + "</dt><dd#{self.xsd_type(value)}>" self.each_nested value, &block yield "</dd>\n" end yield '</dl>' # A List of Objects with identical keys: elsif p.kind_of?( Enumerable ) and ( q = p.first ) and ( q.respond_to?( :keys ) && ( keys = q.keys ) && p.all? { |r| r.respond_to?( :keys ) && r.keys == keys } ) yield '<table><thead><tr>' + keys.collect { |column| '<th xs:type="xs:string">' + Rack::Utils.escape_html( column.to_s.split('_').join(' ') ) + "</th>\n" }.join + '</tr></thead><tbody>' p.each do |h| yield '<tr>' h.each_pair do |key, value| yield "<td#{self.xsd_type(value)}>" self.each_nested value, &block yield "</td>\n" end yield '</tr>' end yield "</tbody></table>" # A List: elsif p.kind_of?( Enumerable ) yield '<ul>' p.each do |value| yield "<li#{self.xsd_type(value)}>" self.each_nested value, &block yield "</li>\n" end yield '</ul>' # A Time: elsif p.kind_of?( Time ) yield p.utc.xmlschema # A Blob: elsif p.kind_of?( String ) && p.encoding == Encoding::BINARY yield Base64.encode64(p).chomp # Something serializable (including nil, true, false, Numeric): else yield Rack::Utils.escape_html( p.to_s ) end end
@api private
# File lib/rackful/serializer.rb, line 147 def header self.class.class_variable_defined?( :@@header ) && @@header ? @@header.call( self ) : "</head><body>" end
@api private @return [URI::HTTP]
# File lib/rackful/serializer.rb, line 110 def html_base_uri @html_base_uri ||= begin retval = self.request.canonical_uri.dup retval.path = retval.path.sub( %r{[^/]+\z}, '' ) retval.query = nil retval end end
@api private
# File lib/rackful/serializer.rb, line 279 def xsd_type v if v.respond_to? :to_rackful v = v.to_rackful end if [nil, true, false].include? v ' xs:type="xs:boolean" xs:nil="true"' elsif v.kind_of? Integer ' xs:type="xs:integer"' elsif v.kind_of? Numeric ' xs:type="xs:decimal"' elsif v.kind_of? Time ' xs:type="xs:dateTime"' elsif v.kind_of?( String ) && v.encoding == Encoding::BINARY ' xs:type="xs:base64Binary"' elsif v.kind_of?( String ) ' xs:type="xs:string"' else '' end end