Class: Alexander::XslProcessor

Inherits:
Object
  • Object
show all
Defined in:
lib/alexander/xsl_processor.rb

Instance Method Summary collapse

Constructor Details

#initialize(app, options = {}) ⇒ XslProcessor

Returns a new instance of XslProcessor.



19
20
21
22
# File 'lib/alexander/xsl_processor.rb', line 19

def initialize(app, options = {})
  @app = app
  @options = options
end

Instance Method Details

#body_to_string(body) ⇒ Object



79
80
81
82
83
84
# File 'lib/alexander/xsl_processor.rb', line 79

def body_to_string(body)
  result = ""
  body.each { |it| result << it }
  body.close if body.respond_to? :close
  result
end

#call(env) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/alexander/xsl_processor.rb', line 24

def call(env)
  response = @app.call(env)
  status, headers, body = response

  return response unless xml?(headers)

  force = force_processing(env)
  return response if xlst_enable_browser?(env) && !force

  html_body = to_html(env, body)
  return response unless html_body

  headers["Content-type"] = "text/html"
  Rack::Response.new([html_body], status, headers).finish
end

#detect_xslt_processing_instruction(xml) ⇒ Object



74
75
76
77
# File 'lib/alexander/xsl_processor.rb', line 74

def detect_xslt_processing_instruction(xml)
  match = xml.match(/<\?xml-stylesheet.*href="([^"]+)"/)
  return match[1] if match
end

#force_processing(env) ⇒ Object



50
51
52
53
54
# File 'lib/alexander/xsl_processor.rb', line 50

def force_processing(env)
  return true if @options[FORCE_PROCESSING_PARAMETER.to_sym]
  request = Rack::Request.new(env)
  request.params[FORCE_PROCESSING_PARAMETER] == "true"
end

#to_html(env, body) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/alexander/xsl_processor.rb', line 56

def to_html(env, body)
  xml = body_to_string(body)
  xslt_request = detect_xslt_processing_instruction(xml)
  return unless xslt_request

  ask_xslt = env.dup
  ask_xslt["PATH_INFO"] = xslt_request
  ask_xslt["REQUEST_PATH"] = xslt_request
  ask_xslt["REQUEST_URI"] = xslt_request
  ask_xslt["QUERY_STRING"] = ""
  status, headers, xslt = @app.call(ask_xslt)
  return unless status == 200

  xml_parsed = Nokogiri::XML(xml)
  xsl_parsed = Nokogiri::XSLT(body_to_string(xslt))
  xsl_parsed.transform(xml_parsed).to_s
end

#xlst_enable_browser?(env) ⇒ Boolean

Returns:

  • (Boolean)


44
45
46
47
48
# File 'lib/alexander/xsl_processor.rb', line 44

def xlst_enable_browser?(env)
  return false unless env && env["HTTP_USER_AGENT"]
  user_agent = UserAgent.parse(env["HTTP_USER_AGENT"])
  XSLT_ENABLE_BROWSERS.detect { |browser| user_agent >= browser }
end

#xml?(headers) ⇒ Boolean

Returns:

  • (Boolean)


40
41
42
# File 'lib/alexander/xsl_processor.rb', line 40

def xml?(headers)
  headers["Content-Type"] =~ /\bapplication\/xml\b/
end