volt 0.2.9 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7be61678b8ab551460135dfeeaaab5060ed02f47
4
- data.tar.gz: cc56d76316db3a18138fcce5f9bae3b7e4d301d7
3
+ metadata.gz: 6c3db947b2a626b68ef6ed4d2a12b3724ee7d10c
4
+ data.tar.gz: cd9a7fc5cd979912a02ef3298c4d901d53166e4d
5
5
  SHA512:
6
- metadata.gz: 2cbbe9373a883d689ac88dfbc2d710a8c8e621de33e9baf90b1513b62c85021c7eda0ea21a8ed037d1d85a58149a64c71e742c681cd4ee5b5f591479ecf6df67
7
- data.tar.gz: 9052a27af07b504f5f765d5c9ad2c833efea2acecb60e820518cf9a5532198435be84b3c84cfdf64a750e35077f1ba4b1e026801d51108c58f2937fa70582bbd
6
+ metadata.gz: a2fa2133cf4ee62729a34d8fff30234cb81477b3817289a70c5d6d229fc39866b9e8c8b250b31e72cf476a6d6e6cc26008e7bed3f53c03a8a56fca6ac7ce92ff
7
+ data.tar.gz: a8f19f6779cfd3a34df76537c2f77df4760735ffea222d8c5b33ce297cd732adfd029ef7013860e70015c646acfbd284dc44cf6e1776ecad66394b1d35b9592e
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.9
1
+ 0.3.0
@@ -202,7 +202,6 @@ class Model
202
202
  end
203
203
 
204
204
  def __track_element(key, value)
205
- puts "TRACK: #{key} - #{value.inspect}"
206
205
  __setup_tracking(key, value) do |event, key, args|
207
206
  trigger_by_attribute!(event, key, *args)
208
207
  end
@@ -39,7 +39,7 @@ class URL
39
39
 
40
40
  path, params = @router.url_for_params(@params)
41
41
 
42
- new_url = "#{@scheme}://#{host_with_port}#{path || @path}"
42
+ new_url = "#{@scheme}://#{host_with_port}#{(path || @path).chomp('/')}"
43
43
 
44
44
  unless params.empty?
45
45
  new_url += '?'
@@ -1,8 +1,14 @@
1
+ require 'volt'
2
+
1
3
  class Routes
2
- attr_reader :routes
4
+ attr_reader :routes, :path_matchers
3
5
 
4
6
  def initialize
5
7
  @routes = []
8
+
9
+ if Volt.server?
10
+ @path_matchers = []
11
+ end
6
12
  end
7
13
 
8
14
  def define(&block)
@@ -11,7 +17,7 @@ class Routes
11
17
  return self
12
18
  end
13
19
 
14
- def get(path, options)
20
+ def get(path, options={})
15
21
  if path.index('{') && path.index('}')
16
22
  sections = path.split(/(\{[^\}]+\})/)
17
23
  sections = sections.reject {|v| v == '' }
@@ -21,6 +27,9 @@ class Routes
21
27
  options[section[1..-2]] = nil
22
28
  end
23
29
  end
30
+
31
+ add_path_matcher(sections) if Volt.server?
32
+
24
33
  path = Proc.new do |params|
25
34
  # Create a path using the params in the path
26
35
  sections.map do |section|
@@ -31,10 +40,26 @@ class Routes
31
40
  end
32
41
  end.join('')
33
42
  end
43
+ else
44
+ add_path_matcher([path]) if Volt.server?
34
45
  end
35
46
 
36
47
  @routes << [path, options]
37
48
  end
49
+
50
+ # TODO: This is slow, optimize with a DFA or NFA
51
+ def add_path_matcher(sections)
52
+ match_path = ''
53
+ sections.each do |section|
54
+ if section[0] == '{' && section[-1] == '}'
55
+ match_path << "[^\/]+"
56
+ else
57
+ match_path << section
58
+ end
59
+ end
60
+
61
+ @path_matchers << (/^#{match_path}$/)
62
+ end
38
63
 
39
64
  # Takes in params and generates a path and the remaining params
40
65
  # that should be shown in the url.
@@ -28,17 +28,18 @@ class Server
28
28
  @app.use Rack::CommonLogger
29
29
  @app.use Rack::ShowExceptions
30
30
 
31
+ component_paths = @component_paths
31
32
  @app.map '/components' do
32
- run ComponentHandler.new
33
+ run ComponentHandler.new(component_paths)
33
34
  end
35
+
36
+ # Serve the opal files
37
+ OpalFiles.new(@app, @app_path, @component_paths)
34
38
 
35
39
  # Serve the main html files from public, also figure out
36
40
  # which JS/CSS files to serve.
37
41
  @app.use IndexFiles, @component_paths
38
42
 
39
- # Serve the opal files
40
- OpalFiles.new(@app, @app_path, @component_paths)
41
-
42
43
  # Handle socks js connection
43
44
  if RUBY_PLATFORM != 'java'
44
45
  @app.map "/channel" do
@@ -1,88 +1,33 @@
1
1
  require 'stringio'
2
2
  require 'volt'
3
3
  require 'volt/server/template_parser'
4
+ require 'volt/server/component_templates'
5
+ require 'volt/server/rack/component_files'
4
6
 
5
7
  class ComponentHandler
8
+ def initialize(component_paths)
9
+ @component_paths = component_paths
10
+ end
11
+
6
12
  def call(env)
7
13
  req = Rack::Request.new(env)
8
14
 
9
15
  # TODO: Sanatize template path
10
- @component_path = req.path.strip.gsub(/^\/components\//, '').gsub(/[.]js$/, '')
16
+ component_name = req.path.strip.gsub(/^\/components\//, '').gsub(/[.]js$/, '')
11
17
 
12
- code = generate_controller_code + generate_view_code + generate_model_code + generate_routes_code
18
+ code = ''
13
19
 
20
+ component_files = ComponentFiles.new(component_name, @component_paths)
21
+ component_files.component_paths.each do |component_path, component_name|
22
+ code << ComponentTemplates.new(component_path, component_name).code
23
+ code << "\n\n"
24
+ end
25
+
14
26
  javascript_code = Opal.compile(code)
15
27
 
16
28
  # puts "ENV: #{env.inspect}"
17
29
  [200, {"Content-Type" => "text/html"}, StringIO.new(javascript_code)]
18
30
  end
19
31
 
20
- def generate_view_code
21
- code = ''
22
- views_path = Volt.root + "/app/#{@component_path}/views/"
23
-
24
- # Load all templates in the folder
25
- Dir["#{views_path}*/*.html"].each do |view_path|
26
- # Get the path for the template, supports templates in folders
27
- template_path = view_path[views_path.size..((-1 * ('.html'.size + 1)))]
28
- template_path = "#{@component_path}/#{template_path}"
29
- # puts "Template Path: #{template_path.inspect}"
30
-
31
- all_templates = TemplateParser.new(File.read(view_path), template_path)
32
32
 
33
- binding_initializers = []
34
- all_templates.templates.each_pair do |name, template|
35
- binding_code = []
36
-
37
- template['bindings'].each_pair do |key,value|
38
- binding_code << "#{key.inspect} => [#{value.join(', ')}]"
39
- end
40
-
41
- binding_code = "{#{binding_code.join(', ')}}"
42
-
43
- code << "$page.add_template(#{name.inspect}, #{template['html'].inspect}, #{binding_code})\n"
44
- end
45
- end
46
- # puts "--------------"
47
- # puts "CODE: #{code}"
48
-
49
- return code
50
- end
51
-
52
- def generate_controller_code
53
- code = ''
54
- controllers_path = Volt.root + "/app/#{@component_path}/controllers/"
55
-
56
- Dir["#{controllers_path}*_controller.rb"].each do |controller_path|
57
- code << File.read(controller_path) + "\n\n"
58
- end
59
-
60
- return code
61
- end
62
-
63
- def generate_model_code
64
- code = ''
65
- models_path = Volt.root + "/app/#{@component_path}/models/"
66
-
67
- Dir["#{models_path}*.rb"].each do |model_path|
68
- code << File.read(model_path) + "\n\n"
69
-
70
- model_name = model_path.match(/([^\/]+)[.]rb$/)[1]
71
-
72
- code << "$page.add_model(#{model_name.inspect})\n\n"
73
- end
74
-
75
- return code
76
- end
77
-
78
- def generate_routes_code
79
- code = ''
80
- routes_path = Volt.root + "/app/#{@component_path}/config/routes.rb"
81
-
82
- code << "$page.add_routes do\n"
83
- code << "\n" + File.read(routes_path) + "\n"
84
- code << "end\n\n"
85
-
86
- return code
87
- end
88
33
  end
@@ -0,0 +1,82 @@
1
+ # Initialize with the path to a component and returns all the front-end
2
+ # setup code (for controllers, models, views, and routes)
3
+ class ComponentTemplates
4
+ def initialize(component_path, component_name)
5
+ @component_path = component_path
6
+ @component_name = component_name
7
+ end
8
+
9
+ def code
10
+ return generate_controller_code + generate_view_code + generate_model_code + generate_routes_code
11
+ end
12
+
13
+ def generate_view_code
14
+ code = ''
15
+ views_path = "#{@component_path}/views/"
16
+
17
+ # Load all templates in the folder
18
+ Dir["#{views_path}*/*.html"].each do |view_path|
19
+ # Get the path for the template, supports templates in folders
20
+ template_path = view_path[views_path.size..((-1 * ('.html'.size + 1)))]
21
+ template_path = "#{@component_name}/#{template_path}"
22
+
23
+ all_templates = TemplateParser.new(File.read(view_path), template_path)
24
+
25
+ binding_initializers = []
26
+ all_templates.templates.each_pair do |name, template|
27
+ binding_code = []
28
+
29
+ template['bindings'].each_pair do |key,value|
30
+ binding_code << "#{key.inspect} => [#{value.join(', ')}]"
31
+ end
32
+
33
+ binding_code = "{#{binding_code.join(', ')}}"
34
+
35
+ code << "$page.add_template(#{name.inspect}, #{template['html'].inspect}, #{binding_code})\n"
36
+ end
37
+ end
38
+ # puts "--------------"
39
+ # puts "CODE: #{code}"
40
+
41
+ return code
42
+ end
43
+
44
+ def generate_controller_code
45
+ code = ''
46
+ controllers_path = "#{@component_path}/controllers/"
47
+
48
+ Dir["#{controllers_path}*_controller.rb"].each do |controller_path|
49
+ code << File.read(controller_path) + "\n\n"
50
+ end
51
+
52
+ return code
53
+ end
54
+
55
+ def generate_model_code
56
+ code = ''
57
+ models_path = "#{@component_path}/models/"
58
+
59
+ Dir["#{models_path}*.rb"].each do |model_path|
60
+ code << File.read(model_path) + "\n\n"
61
+
62
+ model_name = model_path.match(/([^\/]+)[.]rb$/)[1]
63
+
64
+ code << "$page.add_model(#{model_name.inspect})\n\n"
65
+ end
66
+
67
+ return code
68
+ end
69
+
70
+ def generate_routes_code
71
+ code = ''
72
+ routes_path = "#{@component_path}/config/routes.rb"
73
+
74
+ if File.exists?(routes_path)
75
+ code << "$page.add_routes do\n"
76
+ code << "\n" + File.read(routes_path) + "\n"
77
+ code << "end\n\n"
78
+ end
79
+
80
+ return code
81
+ end
82
+ end
@@ -51,6 +51,10 @@ class ComponentFiles
51
51
  @component_paths.component_path(name || @component_name)
52
52
  end
53
53
 
54
+ def component_paths
55
+ @components.map {|c| [path_to_component(c), c] }
56
+ end
57
+
54
58
  def load_child_components
55
59
  path = path_to_component
56
60
  if path
@@ -1,14 +1,29 @@
1
1
  require 'volt/server/rack/component_files'
2
+ require 'volt/router/routes'
2
3
 
3
4
  # Serves the main pages
4
5
  class IndexFiles
5
6
  def initialize(app, component_paths)
6
7
  @app = app
7
8
  @component_paths = component_paths
9
+
10
+ @@router ||= Routes.new.define do
11
+ # Find the route file
12
+ route_file = File.read('app/home/config/routes.rb')
13
+ eval(route_file)
14
+ end
15
+ end
16
+
17
+ def route_match?(path)
18
+ @@router.path_matchers.each do |path_matcher|
19
+ return true if path =~ path_matcher
20
+ end
21
+
22
+ return false
8
23
  end
9
24
 
10
25
  def call(env)
11
- if %w[/ /demo /blog /todos /page3 /page4].include?(env['PATH_INFO']) || env['PATH_INFO'][0..5] == '/todos'
26
+ if route_match?(env['PATH_INFO'])
12
27
  [200, { 'Content-Type' => 'text/html' }, [html]]
13
28
  else
14
29
  @app.call env
@@ -97,13 +97,13 @@ class TemplateBinding < BaseBinding
97
97
  controller = nil
98
98
  if path_position > 1
99
99
  # Lookup the controller
100
- controller = full_path[1]
100
+ controller = [full_path[0], full_path[1]]
101
101
  end
102
102
  return path, controller
103
103
  end
104
104
  end
105
105
 
106
- return nil
106
+ return nil, nil
107
107
  end
108
108
 
109
109
  def update
@@ -127,8 +127,19 @@ class TemplateBinding < BaseBinding
127
127
  if controller
128
128
  args = []
129
129
  args << SubContext.new(@model) if @model
130
+
131
+ name = controller[1].camelize
132
+
133
+ # For the home object, we do not need to namespace our controller
134
+ if controller[0] != 'home'
135
+ base_name = controller[0].camelize
136
+ base_object = Object.send(:const_get, base_name.to_sym)
137
+ else
138
+ base_object = Object
139
+ end
140
+
130
141
  # Initialize the new controller
131
- current_context = Object.send(:const_get, (controller.camelize + 'Controller').to_sym).new(*args)
142
+ current_context = base_object.send(:const_get, (name + 'Controller').to_sym).new(*args)
132
143
  elsif @model
133
144
  # Passed in attributes, but there is no controller
134
145
  current_context = SubContext.new(@model, current_context)
@@ -1 +1,4 @@
1
- get "/about", _controller: 'about'
1
+ get "/about", _controller: 'about'
2
+
3
+ # The main route
4
+ get '/'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: volt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.9
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Stout
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-13 00:00:00.000000000 Z
11
+ date: 2014-01-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -306,6 +306,7 @@ files:
306
306
  - lib/volt/server/binding_setup.rb
307
307
  - lib/volt/server/channel_handler.rb
308
308
  - lib/volt/server/component_handler.rb
309
+ - lib/volt/server/component_templates.rb
309
310
  - lib/volt/server/if_binding_setup.rb
310
311
  - lib/volt/server/rack/component_files.rb
311
312
  - lib/volt/server/rack/component_paths.rb