class Rackful::Serializer::XHTML

Public Class Methods

header(&block) click to toggle source

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

each() { |tmp| ... } click to toggle source

@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
each_nested(p = self.resource.to_rackful) { |"<a href=\"#{rel_path}\">" + escape_html( unescape) + '</a>'| ... } click to toggle source

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
header() click to toggle source

@api private

# File lib/rackful/serializer.rb, line 147
def header
  self.class.class_variable_defined?( :@@header ) && @@header ?
    @@header.call( self ) :
    "</head><body>"
end
html_base_uri() click to toggle source

@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
xsd_type(v) click to toggle source

@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