lipa-web 0.1.1 → 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.
@@ -25,14 +25,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
25
 
26
26
  module Lipa
27
27
  module Web
28
- module HtmlHelper
29
- # Make link for node
30
- #
31
- # @param node [Lipa::Node] linking node
32
- # @return [String] html <a href='path/to/node'>name_of_node</a>
33
- def link_to(node)
34
- %(<a href="#{node.full_name}">#{node.name}</a>)
28
+ module Helpers
29
+ module Response
30
+ def read_template(path)
31
+ File.open(path).read
32
+ end
35
33
  end
36
34
  end
37
35
  end
38
36
  end
37
+
@@ -0,0 +1,49 @@
1
+ =begin
2
+ Web access to Lipa
3
+
4
+ Copyright (c) 2011 Aleksey Timin
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ 'Software'), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+ =end
25
+
26
+ require "lipa/web/response/html"
27
+ require "lipa/web/response/json"
28
+ require "lipa/web/response/xml"
29
+
30
+ module Lipa
31
+ module Web
32
+ module Response
33
+ # Rendering node data in format
34
+ #
35
+ # @param node [Lipa::Node] node for rendering
36
+ # @param format of rendering
37
+ def respond(node, format)
38
+ case format.to_s
39
+ when "json"
40
+ JSON::response(node)
41
+ when "xml"
42
+ XML::response(node)
43
+ else
44
+ HTML::response(node)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,90 @@
1
+ =begin
2
+ Web access to Lipa
3
+
4
+ Copyright (c) 2011 Aleksey Timin
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ 'Software'), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+ =end
25
+
26
+ module Lipa
27
+ module Web
28
+ module Response
29
+ module HTML
30
+ extend Helpers::Response
31
+
32
+ def self.response(node)
33
+ header = {}
34
+
35
+ html = node.html
36
+ if html
37
+ if html[:block]
38
+ body = html[:block].call
39
+ else
40
+ case html[:render]
41
+ when :erb
42
+ body = render_erb(node)
43
+ header["Content-Type"] = "text/html"
44
+ when :text
45
+ body = html[:msg]
46
+ header["Content-Type"] = "text/plain"
47
+ end
48
+ end
49
+ else
50
+ body = render_default_template(node)
51
+ end
52
+ [ 200, header, [body]]
53
+ end
54
+
55
+ private
56
+ def self.context(node)
57
+ node.instance_eval("def binding_for(#{node.attrs.keys.join(",")}) binding; end")
58
+ node.extend(Helpers::HTML)
59
+ block = block_given? ? Proc.new : nil
60
+ node.binding_for(*node.eval_attrs.values, &block)
61
+ end
62
+
63
+ def self.render_default_template(node)
64
+ path = File.join(File.dirname(__FILE__), '..', 'views', 'node.html.erb') # default path
65
+ default_template = read_template(path)
66
+
67
+ path = File.join(File.dirname(__FILE__), '..', 'views', 'layout.html.erb') # default path
68
+ default_layout = read_template(path)
69
+
70
+ ERB.new(default_layout).result(
71
+ context(node) do
72
+ ERB.new(default_template).result(context(node))
73
+ end
74
+ )
75
+ end
76
+
77
+ def self.render_erb(node)
78
+ template = read_template(node.html[:template])
79
+ root = node.root
80
+ if root.layout
81
+ layout = read_template(File.join(root.views, root.layout))
82
+ ERB.new(layout).result(context(node) { ERB.new(template).result(context(node)) })
83
+ else
84
+ ERB.new(template).result(context(node))
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -23,58 +23,40 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23
23
  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
24
  =end
25
25
 
26
+ require "json"
26
27
  module Lipa
27
28
  module Web
28
- module NodeHelper
29
+ module Response
30
+ module JSON
31
+ def self.response(node)
32
+ body = if node.json
33
+ j = {}
34
+ node.json[:block].call(j)
35
+ j.to_json
36
+ else
37
+ render_default_json(node)
38
+ end
29
39
 
30
- # Assignment erb template fot html response
31
- #
32
- # @param path [String] path about views directory
33
- #
34
- # @examnple
35
- # node :page_1 do
36
- # html erb("page.html.erb")
37
- # end
38
- def erb(path)
39
- { :render => :erb, :template => File.join(root.attrs[:views], path) }
40
- end
40
+ [ 200, { "Content-Type" => "application/json" }, [body]]
41
+ end
41
42
 
42
- # Assignment text for html response
43
- #
44
- # @param msg [String] text message
45
- #
46
- # @examnple
47
- # node :page_1 do
48
- # html text("Hello World!")
49
- # end
50
- def text(msg)
51
- { :render => :text, :msg => msg }
52
- end
43
+ private
44
+ def self.render_default_json(node)
45
+ j = {}
46
+ j[:name] = node.name
47
+ j[:full_name] = node.full_name
48
+ j[:parent] = json_link_to(node.parent)
49
+ j[:children] = node.children.values.each.map {|ch| json_link_to(ch) }
53
50
 
54
- # Definition html response
55
- #
56
- # @see NodeHelpers#erb
57
- # @see NodeHelpers#text
58
- def html(opts=nil)
59
- if opts.nil?
60
- @html
61
- else
62
- @html = opts
51
+ node.eval_attrs.each_pair do |k,v|
52
+ j[k] = v.kind_of?(Lipa::Node) ? json_link_to(v) : v
53
+ end
54
+
55
+ j.to_json
63
56
  end
64
- end
65
57
 
66
- # Definition json response
67
- #
68
- # @example
69
- # node :josn_1 do
70
- # json { |j| j[:name] = name }
71
- # end
72
- # # => { "name":"json_1" }
73
- def json(&block)
74
- if block_given?
75
- @json = {:block => block}
76
- else
77
- @json
58
+ def self.json_link_to(node)
59
+ { :name => node.name, :full_name => node.full_name }
78
60
  end
79
61
  end
80
62
  end
@@ -0,0 +1,68 @@
1
+ =begin
2
+ Web access to Lipa
3
+
4
+ Copyright (c) 2011 Aleksey Timin
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ 'Software'), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+ =end
25
+
26
+ require "builder"
27
+
28
+ module Lipa
29
+ module Web
30
+ module Response
31
+ module XML
32
+ extend Helpers::Response
33
+
34
+ def self.response(node)
35
+ xml = Builder::XmlMarkup.new
36
+ if node.xml
37
+ if node.xml[:block]
38
+ node.xml[:block].call(xml)
39
+ else
40
+ case node.xml[:render]
41
+ when :builder
42
+ template = read_template(node.xml[:template])
43
+ end
44
+ eval(template, context(node,xml))
45
+ end
46
+ else
47
+ eval(default_template, context(node,xml))
48
+ end
49
+
50
+ [200, {"Content-Type" => "application/xml"}, [ xml.target!]]
51
+ end
52
+
53
+ private
54
+ def self.context(node,xml)
55
+ node.instance_eval("def binding_for(#{(node.attrs.keys << "xml").join(",")}) binding; end")
56
+ block = block_given? ? Proc.new : nil
57
+ node.binding_for(*(node.eval_attrs.values << xml), &block)
58
+ end
59
+
60
+ def self.default_template
61
+ path = File.join(File.dirname(__FILE__), '..', 'views', 'node.builder') # default path
62
+ template = read_template(path)
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+
@@ -25,6 +25,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
25
 
26
26
  module Lipa
27
27
  module Web
28
- VERSION = "0.1.1"
28
+ VERSION = "0.2.0"
29
29
  end
30
30
  end
@@ -1,36 +1,17 @@
1
- require "lipa/web"
2
- require "rack/test"
1
+ require File.join(File.dirname(__FILE__), "spec_helper")
3
2
 
4
3
  describe Lipa::Web::Application do
5
4
  include Rack::Test::Methods
6
5
 
7
6
  before :each do
8
7
  @srv = root :srv do
9
- views File.join(File.dirname(__FILE__), "views")
10
- layout "layout.html.erb"
8
+ static_folder File.join(File.dirname(__FILE__), "public")
11
9
 
12
10
  node :group do
13
11
  node :test_node do
14
- param_int 20
15
- param_bool false
16
- param_float 32.2
17
- param_string "Hello"
18
- param_time Time.new(2000,"jan",1,20,15,1,0)
19
- param_proc run{5+3}
20
- param_ref ref("../node_with_template")
21
-
22
12
  node :child_1
23
13
  node :child_2
24
14
  end
25
-
26
- node :node_with_template do
27
- html erb("./my_template.html.erb")
28
- json { |j| j[:name] = name }
29
- end
30
-
31
- node :node_greater do
32
- html text("Hello world!")
33
- end
34
15
  end
35
16
  end
36
17
  end
@@ -56,44 +37,10 @@ describe Lipa::Web::Application do
56
37
  last_response.body.should eql("Node is not existence")
57
38
  end
58
39
 
59
- it 'should render default html template' do
60
- get "/group/test_node"
61
-
62
- last_response.header['Content-Type'].should eql( "text/html")
63
- last_response.body.gsub(/^\s*\n/, '').should == fixture("node.html")
64
- end
65
-
66
- it 'should render user html template' do
67
- get "/group/node_with_template"
68
-
69
- last_response.header['Content-Type'].should eql("text/html")
70
- last_response.body.gsub(/^\s*\n/, '').should == fixture("node_with_template.html")
71
- end
72
-
73
- it 'should render text' do
74
- get "/group/node_greater"
75
-
76
- last_response.header['Content-Type'].should eql("text/plain")
77
- last_response.body.should == "Hello world!"
78
- end
79
-
80
- it 'should response in default json format' do
81
- get "group/test_node.json"
82
-
83
- last_response.header['Content-Type'].should eql("application/json")
84
- last_response.body.gsub(/\s*/,'').should == fixture("node.json").gsub(/\s*/,'')
85
- end
86
-
87
- it 'should response in default json format' do
88
- get "group/node_with_template.json"
89
-
90
- last_response.header['Content-Type'].should eql("application/json")
91
- last_response.body.should == '{"name":"node_with_template"}'
92
- end
93
-
94
- def fixture(name)
95
- path = File.join(File.dirname(__FILE__), "fixtures", name)
96
- File.open(path).read.gsub(/^\s*\n/,'')
40
+ it 'should serve statics files in public folder' do
41
+ get "/css/style.css"
42
+ last_response.header["Content-Type"].should eql("text/css")
43
+ last_response.body.should eql(".h1 { color: #fff; }\n")
97
44
  end
98
45
  end
99
46
 
@@ -0,0 +1,62 @@
1
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
2
+
3
+ describe Lipa::Web::Application do
4
+ include Rack::Test::Methods
5
+
6
+ before :each do
7
+ @srv = root :srv do
8
+ views File.join(File.dirname(__FILE__), "views")
9
+ layout "layout.html.erb"
10
+
11
+ example_node
12
+
13
+ node :node_with_template do
14
+ html erb("./my_template.html.erb")
15
+ end
16
+
17
+ node :node_greater do
18
+ html text("Hello world!")
19
+ end
20
+
21
+ node :node_man_html do
22
+ say "Hello"
23
+ html { "<h1>#{say}</h1>" }
24
+ end
25
+ end
26
+ end
27
+
28
+ def app
29
+ Lipa::Web::Application.new(@srv)
30
+ end
31
+
32
+ it 'should render default html template' do
33
+ get "/group/test_node"
34
+
35
+ last_response.header['Content-Type'].should eql( "text/html")
36
+ last_response.body.gsub(/^\s*\n/, '').should == fixture("node.html")
37
+ end
38
+
39
+ it 'should render custom html template' do
40
+ get "/node_with_template"
41
+
42
+ last_response.header['Content-Type'].should eql("text/html")
43
+ last_response.body.gsub(/^\s*\n/, '').should == fixture("node_with_template.html")
44
+ end
45
+
46
+ it 'should render text' do
47
+ get "/node_greater"
48
+
49
+ last_response.header['Content-Type'].should eql("text/plain")
50
+ last_response.body.should == "Hello world!"
51
+ end
52
+
53
+
54
+ it 'should have custom html response' do
55
+ get "/node_man_html"
56
+
57
+ last_response.header['Content-Type'].should eql("text/html")
58
+ last_response.body.should == '<h1>Hello</h1>'
59
+ end
60
+ end
61
+
62
+