rack-xslview 0.1.3 → 0.2.0
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.
- data/Rakefile +8 -7
- data/VERSION +1 -1
- data/lib/rack-xslview.rb +68 -43
- data/test/rack-xslview_test.rb +12 -1
- data/test/test_install.rb +1 -2
- metadata +2 -2
data/Rakefile
CHANGED
@@ -7,19 +7,19 @@ begin
|
|
7
7
|
gem.name = "rack-xslview"
|
8
8
|
gem.summary = %Q{XSL rack middleware.}
|
9
9
|
gem.description = %Q{A rack middleware for transforming XML with XSL.}
|
10
|
-
gem.email =
|
11
|
-
gem.homepage =
|
12
|
-
gem.authors = [
|
13
|
-
gem.rubyforge_project =
|
14
|
-
gem.add_development_dependency
|
10
|
+
gem.email = 'albert.lash@docunext.com'
|
11
|
+
gem.homepage = 'http://www.docunext.com/wiki/Rack-XSLView'
|
12
|
+
gem.authors = ['Albert Lash']
|
13
|
+
gem.rubyforge_project = ''
|
14
|
+
gem.add_development_dependency 'shoulda'
|
15
15
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
16
16
|
end
|
17
17
|
Jeweler::GemcutterTasks.new
|
18
18
|
Jeweler::RubyforgeTasks.new do |rubyforge|
|
19
|
-
rubyforge.doc_task =
|
19
|
+
rubyforge.doc_task = 'rdoc'
|
20
20
|
end
|
21
21
|
rescue LoadError
|
22
|
-
puts
|
22
|
+
puts 'Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler'
|
23
23
|
end
|
24
24
|
|
25
25
|
|
@@ -46,6 +46,7 @@ end
|
|
46
46
|
task :test => :check_dependencies
|
47
47
|
|
48
48
|
task :default => :test
|
49
|
+
task :spec => :test
|
49
50
|
|
50
51
|
require 'rake/rdoctask'
|
51
52
|
Rake::RDocTask.new do |rdoc|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/lib/rack-xslview.rb
CHANGED
@@ -1,12 +1,16 @@
|
|
1
|
-
#
|
1
|
+
# Copyright 2010 Savonix Corporation
|
2
|
+
# Author Albert L. Lash, IV
|
3
|
+
# License MIT
|
2
4
|
module Rack
|
3
5
|
class XSLView
|
6
|
+
|
7
|
+
class XSLViewError < StandardError ; end
|
8
|
+
|
4
9
|
def initialize(app, options)
|
5
|
-
@my_path_info = String.new
|
6
10
|
@app = app
|
7
|
-
@myhash = {}
|
8
11
|
@options = {:myxsl => nil}.merge(options)
|
9
|
-
if @options[:myxsl]
|
12
|
+
if @options[:myxsl].nil?
|
13
|
+
require 'rexml/document'
|
10
14
|
@xslt = XML::XSLT.new()
|
11
15
|
@xslt.xsl = REXML::Document.new '<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml"><xsl:import href="http://github.com/docunext/1bb02b59/raw/master/standard.html.xsl"/><xsl:output method="xml" encoding="UTF-8" omit-xml-declaration="no" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" indent="yes"/></xsl:stylesheet>'
|
12
16
|
else
|
@@ -15,44 +19,73 @@ module Rack
|
|
15
19
|
end
|
16
20
|
|
17
21
|
def call(env)
|
18
|
-
|
19
|
-
|
20
|
-
else
|
21
|
-
if @options[:reload] == true
|
22
|
-
puts @options[:filepath]
|
23
|
-
@xslt = XML::XSLT.new()
|
24
|
-
@xslt.xsl = REXML::Document.new @options[:xslfile]
|
25
|
-
end
|
26
|
-
unless @options[:passenv] == nil
|
27
|
-
@options[:passenv].each { |envkey|
|
28
|
-
if (mp = env[envkey])
|
29
|
-
@myhash[envkey] = "#{mp}"
|
30
|
-
end
|
31
|
-
}
|
32
|
-
@xslt.parameters = @myhash
|
33
|
-
end
|
34
|
-
status, headers, body = @app.call(env)
|
22
|
+
# No matter what, @app will be called
|
23
|
+
status, headers, body = @app.call(env)
|
35
24
|
|
36
|
-
|
37
|
-
|
38
|
-
body.each { |part| parts << part.to_s }
|
25
|
+
# If setup includes paths to exclude from xslt processing, check them
|
26
|
+
checknoxsl(env) if @options[:noxsl]
|
39
27
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
newbody << @xslt.serve
|
48
|
-
headers['Content-Length'] = newbody[0].length.to_s
|
49
|
-
[status, headers, newbody]
|
50
|
-
end
|
28
|
+
# Obtain entire request body, check to make sure it can be processed
|
29
|
+
myxml = getResponse(body)
|
30
|
+
|
31
|
+
# Should XSL file be reloaded?
|
32
|
+
if @options[:reload] == true
|
33
|
+
@xslt = XML::XSLT.new()
|
34
|
+
@xslt.xsl = REXML::Document.new @options[:xslfile]
|
51
35
|
end
|
36
|
+
|
37
|
+
# Set XML for stylesheet
|
38
|
+
@xslt.xml = myxml
|
39
|
+
|
40
|
+
# If setup includes env vars to pass through as params, do so
|
41
|
+
unless @options[:passenv].nil?
|
42
|
+
@myhash = {}
|
43
|
+
@options[:passenv].each { |envkey|
|
44
|
+
# Does env var exist?
|
45
|
+
@myhash[envkey] = "#{env[envkey]}" if env[envkey]
|
46
|
+
}
|
47
|
+
@xslt.parameters = @myhash unless @myhash.empty?
|
48
|
+
end
|
49
|
+
|
50
|
+
# Perform the transformation
|
51
|
+
newbody = Array.[](@xslt.serve)
|
52
|
+
|
53
|
+
# If we've made it this far, we can alter the headers
|
54
|
+
headers.delete('Content-Length')
|
55
|
+
headers['Content-Length'] = newbody[0].length.to_s
|
56
|
+
[status, headers, newbody]
|
57
|
+
|
58
|
+
rescue XSLViewError
|
59
|
+
# TODO Logging: "Rack XSLView not processed" if env['RACK_ENV'] == 'development'
|
60
|
+
[status, headers, body]
|
52
61
|
end
|
53
62
|
|
54
63
|
private
|
64
|
+
def checknoxsl(env)
|
65
|
+
@options[:noxsl].each { |path|
|
66
|
+
raise XSLViewError if env["PATH_INFO"].index(path)
|
67
|
+
}
|
68
|
+
end
|
69
|
+
def getResponse(body)
|
70
|
+
raise XSLViewError if body.nil?
|
71
|
+
newbody = ''
|
72
|
+
body.each { |part|
|
73
|
+
# Only check the first chunk to ensure 1) its not HTML and 2) its XML
|
74
|
+
checkForXml(part) if newbody.empty?
|
75
|
+
newbody << part.to_s
|
76
|
+
}
|
77
|
+
return newbody
|
78
|
+
end
|
79
|
+
def checkForXml(x)
|
80
|
+
# Abort processing if content cannot be processed by libxslt
|
81
|
+
raise XSLViewError unless x[0,1] == '<'
|
82
|
+
if @options[:excludehtml] == true
|
83
|
+
raise XSLViewError if x.include? '<html'
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
55
87
|
def choosesheet(env)
|
88
|
+
# Not used yet, this may be used to match stylesheets with paths
|
56
89
|
@options[:xslhash].each_key { |path|
|
57
90
|
if env["PATH_INFO"].index(path)
|
58
91
|
return @options[:xslhash][path]
|
@@ -60,14 +93,6 @@ module Rack
|
|
60
93
|
}
|
61
94
|
return false
|
62
95
|
end
|
63
|
-
def checknoxsl(env)
|
64
|
-
@options[:noxsl].each { |path|
|
65
|
-
if env["PATH_INFO"].index(path)
|
66
|
-
return true
|
67
|
-
end
|
68
|
-
}
|
69
|
-
return false
|
70
|
-
end
|
71
96
|
end
|
72
97
|
end
|
73
98
|
|
data/test/rack-xslview_test.rb
CHANGED
@@ -8,6 +8,7 @@ class RackXslviewTest < Test::Unit::TestCase
|
|
8
8
|
|
9
9
|
end
|
10
10
|
|
11
|
+
|
11
12
|
def self.should_not_halt
|
12
13
|
should "not halt the rack chain" do
|
13
14
|
@app.expects(:call).once
|
@@ -15,6 +16,15 @@ class RackXslviewTest < Test::Unit::TestCase
|
|
15
16
|
end
|
16
17
|
end
|
17
18
|
|
19
|
+
def self.should_be_a_rack_response
|
20
|
+
should 'be a rack a response' do
|
21
|
+
ret = @rack.call(call_args)
|
22
|
+
assert ret.is_a?(Array), 'return value is not a valid rack response'
|
23
|
+
assert_equal 3, ret.size, 'should have 3 arguments'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
18
28
|
context 'Given an app' do
|
19
29
|
setup do
|
20
30
|
@app = Class.new { def call(app); true; end }.new
|
@@ -26,6 +36,7 @@ class RackXslviewTest < Test::Unit::TestCase
|
|
26
36
|
passenv = ['PATH_INFO', 'RACK_MOUNT_PATH']
|
27
37
|
@rack = Rack::XSLView.new(@app, :noxsl => omitpaths, :passenv => passenv)
|
28
38
|
}
|
39
|
+
should_be_a_rack_response
|
29
40
|
should_not_halt
|
30
41
|
end
|
31
42
|
context 'Trying out the xslhash' do
|
@@ -35,7 +46,7 @@ class RackXslviewTest < Test::Unit::TestCase
|
|
35
46
|
xslhash.default("/path/to/output.xhtml10.xsl")
|
36
47
|
@rack = Rack::XSLView.new(@app, :noxsl => omitpaths, :xslhash => xslhash)
|
37
48
|
}
|
38
|
-
|
49
|
+
should_be_a_rack_response
|
39
50
|
end
|
40
51
|
end
|
41
52
|
end
|
data/test/test_install.rb
CHANGED
@@ -1,2 +1 @@
|
|
1
|
-
|
2
|
-
require 'rack-xslview'
|
1
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-xslview
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Albert Lash
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-03-
|
12
|
+
date: 2010-03-20 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|