volt 0.7.0 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Readme.md +29 -7
- data/VERSION +1 -1
- data/lib/volt/cli/asset_compile.rb +44 -4
- data/lib/volt/models.rb +1 -0
- data/lib/volt/models/persistors/local_store.rb +65 -0
- data/lib/volt/page/page.rb +13 -3
- data/lib/volt/server/component_handler.rb +2 -10
- data/lib/volt/server/component_templates.rb +22 -8
- data/lib/volt/server/rack/asset_files.rb +2 -1
- data/lib/volt/server/rack/component_code.rb +25 -0
- data/lib/volt/server/rack/component_html_renderer.rb +21 -0
- data/lib/volt/utils/local_storage.rb +49 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1ee2e73e30b22aed5bdde21f95777558f38b2922
|
4
|
+
data.tar.gz: b0a44bf831aff120f0209c2ea8a4ab49190ea06e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0340cad62884b63d9c757754582696aaaf5c66fe06b8263591782944b9af667ed60d33a3acc2a185140d4d0600415fe64237af54f6b1ef0f91aed20062a159b1
|
7
|
+
data.tar.gz: 379371a5cf9dca4819d648acd08760b9b685d3b5ac73c865397245e2f3dddf1b41954c62896c8f0ec49898af3b1853561939792571dbded97d5aa98e734af485
|
data/Readme.md
CHANGED
@@ -68,25 +68,27 @@ You can access the volt console with:
|
|
68
68
|
2. [Rendering](#rendering)
|
69
69
|
1. [Reactive Values](#reactive-values)
|
70
70
|
1. [ReactiveValue Gotchyas](#reactivevalue-gotchyas)
|
71
|
-
|
71
|
+
3. [Views](#views)
|
72
|
+
1. [Bindings](#bindings)
|
72
73
|
1. [Content Binding](#content-binding)
|
73
74
|
2. [If Binding](#if-binding)
|
74
75
|
3. [Each Binding](#each-binding)
|
75
76
|
4. [Attribute Bindings](#attribute-bindings)
|
76
|
-
|
77
|
+
5. [Escaping](#escaping)
|
78
|
+
4. [Models](#models)
|
77
79
|
1. [Provided Collections](#provided-collections)
|
78
80
|
2. [Reactive Models](#reactive-models)
|
79
81
|
3. [Model Events](#model-events)
|
80
82
|
4. [Automatic Model Conversion](#automatic-model-conversion)
|
81
|
-
|
82
|
-
|
83
|
+
5. [Controllers](#controllers)
|
84
|
+
6. [Components](#components)
|
83
85
|
1. [Assets](#assets)
|
84
86
|
2. [Component Generator](#component-generator)
|
85
87
|
3. [Provided Components](#provided-components)
|
86
88
|
1. [Notices](#notices)
|
87
89
|
2. [Flash](#flash)
|
88
|
-
|
89
|
-
|
90
|
+
7. [Controls](#controls)
|
91
|
+
8. [Routes](#routes)
|
90
92
|
1. [Routes file](#routes-file)
|
91
93
|
|
92
94
|
|
@@ -238,9 +240,21 @@ You can call .with on any ReactiveValue. .with will return a new ReactiveValue
|
|
238
240
|
# => 15
|
239
241
|
```
|
240
242
|
|
243
|
+
# Views
|
244
|
+
|
245
|
+
Views in Volt are use a templating language similar to handlebars. They can be broken up into sections, a section header looks like the following:
|
246
|
+
|
247
|
+
```html
|
248
|
+
<:Body>
|
249
|
+
```
|
250
|
+
|
251
|
+
Section headers should start with a capital letter so as not to be confused with [controls](#controls). Section headers do not use close tags. If section headers are not provided, the body section is assumed.
|
252
|
+
|
253
|
+
Section's help you split up different parts of the same content (title and body usually), but within the same file.
|
254
|
+
|
241
255
|
## Bindings
|
242
256
|
|
243
|
-
|
257
|
+
One you understand the basics of ReactiveValue's, we can discuss bindings. In Volt, you code your views in a handlebar's like template language. Volt provides severial bindings, which handle rendering of something for you. Content bindings are anything inbetween { and }
|
244
258
|
|
245
259
|
### Content binding
|
246
260
|
|
@@ -318,6 +332,14 @@ If the value of a checked attribute is true, the checkbox will be shown checked.
|
|
318
332
|
|
319
333
|
If you have a controller at app/home/controller/index_controller.rb, and a view at app/home/views/index/index.html, all methods called are called on the controller.
|
320
334
|
|
335
|
+
## Escaping
|
336
|
+
|
337
|
+
When you need to use { and } outside of bindings. Anything in a triple mustache will be escaped and not processed as a binding:
|
338
|
+
|
339
|
+
```html
|
340
|
+
{{{ bindings look like: {this} }}}
|
341
|
+
```
|
342
|
+
|
321
343
|
# Models
|
322
344
|
|
323
345
|
Volt's concept of a model is slightly different from many frameworks where a model is the name for the ORM to the database. In Volt a model is a class where you can store data easily. Where that data stored is not the concern of the model, but the class that created the model. Lets first see how to use a model.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.7.
|
1
|
+
0.7.1
|
@@ -1,11 +1,51 @@
|
|
1
1
|
class CLI
|
2
|
-
|
2
|
+
|
3
3
|
desc "precompile", "precompile all application assets"
|
4
4
|
def precompile
|
5
|
+
require 'fileutils'
|
6
|
+
require 'opal'
|
5
7
|
require 'volt'
|
6
8
|
require 'volt/server/rack/component_paths'
|
7
|
-
|
8
|
-
|
9
|
+
require 'volt/server/rack/component_code'
|
10
|
+
require 'volt/server/rack/opal_files'
|
11
|
+
|
12
|
+
|
13
|
+
write_component_js
|
14
|
+
write_sprockets
|
9
15
|
end
|
10
|
-
|
16
|
+
|
17
|
+
private
|
18
|
+
def write_sprockets
|
19
|
+
root_path ||= Dir.pwd
|
20
|
+
Volt.root = root_path
|
21
|
+
|
22
|
+
@app_path = File.expand_path(File.join(root_path, "app"))
|
23
|
+
|
24
|
+
@component_paths = ComponentPaths.new(root_path)
|
25
|
+
@app = Rack::Builder.new
|
26
|
+
|
27
|
+
# Serve the opal files
|
28
|
+
opal_files = OpalFiles.new(@app, @app_path, @component_paths)
|
29
|
+
opal_files.environment.each_file do |file_path|
|
30
|
+
unless file_path.to_s[/[.]rb$/]
|
31
|
+
puts "FILE: #{file_path}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def write_component_js
|
37
|
+
component_paths = ComponentPaths.new(Volt.root)
|
38
|
+
|
39
|
+
code = ComponentCode.new('home', component_paths).code
|
40
|
+
|
41
|
+
javascript_code = Opal.compile(code)
|
42
|
+
|
43
|
+
components_folder = File.join(Volt.root, '/public/components')
|
44
|
+
puts "CF: #{components_folder}"
|
45
|
+
FileUtils.mkdir_p(components_folder)
|
46
|
+
File.open(File.join(components_folder, '/home.js'), 'w') do |file|
|
47
|
+
file.write(javascript_code)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
11
51
|
end
|
data/lib/volt/models.rb
CHANGED
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'volt/models/persistors/base'
|
2
|
+
require 'volt/utils/local_storage'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Persistors
|
6
|
+
|
7
|
+
# Backs a collection in the local store
|
8
|
+
class LocalStore < Base
|
9
|
+
def initialize(model)
|
10
|
+
@model = model
|
11
|
+
end
|
12
|
+
|
13
|
+
# Find the root for this model
|
14
|
+
def root_model
|
15
|
+
node = @model
|
16
|
+
|
17
|
+
loop do
|
18
|
+
parent = node.parent
|
19
|
+
if parent
|
20
|
+
node = parent
|
21
|
+
else
|
22
|
+
break
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
return node
|
27
|
+
end
|
28
|
+
|
29
|
+
# Called when a model is added to the collection
|
30
|
+
def added(model, index)
|
31
|
+
root_model.persistor.save_all
|
32
|
+
end
|
33
|
+
|
34
|
+
def loaded
|
35
|
+
# When the main model is first loaded, we pull in the data from the
|
36
|
+
# store if it exists
|
37
|
+
if @model.path == []
|
38
|
+
json_data = LocalStorage['volt-store']
|
39
|
+
if json_data
|
40
|
+
root_attributes = JSON.parse(json_data)
|
41
|
+
|
42
|
+
@loading_data = true
|
43
|
+
root_attributes.each_pair do |key, value|
|
44
|
+
@model.send(:"#{key}=", value)
|
45
|
+
end
|
46
|
+
@loading_data = nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Callled when an item is changed (or removed)
|
52
|
+
def changed(attribute_name)
|
53
|
+
root_model.persistor.save_all
|
54
|
+
end
|
55
|
+
|
56
|
+
# Called on the root
|
57
|
+
def save_all
|
58
|
+
return if @loading_data
|
59
|
+
|
60
|
+
json_data = JSON.dump(@model.to_h.deep_cur)
|
61
|
+
|
62
|
+
LocalStorage['volt-store'] = json_data
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/volt/page/page.rb
CHANGED
@@ -32,7 +32,7 @@ require 'volt/page/draw_cycle'
|
|
32
32
|
require 'volt/page/tasks'
|
33
33
|
|
34
34
|
class Page
|
35
|
-
attr_reader :url, :params, :page, :
|
35
|
+
attr_reader :url, :params, :page, :templates, :routes, :draw_cycle, :events
|
36
36
|
|
37
37
|
def initialize
|
38
38
|
# debugger
|
@@ -41,8 +41,6 @@ class Page
|
|
41
41
|
|
42
42
|
# Run the code to setup the page
|
43
43
|
@page = ReactiveValue.new(Model.new)
|
44
|
-
@flash = ReactiveValue.new(Model.new({}, persistor: Persistors::Flash))
|
45
|
-
@store = ReactiveValue.new(Model.new({}, persistor: Persistors::StoreFactory.new(tasks)))
|
46
44
|
|
47
45
|
@url = ReactiveValue.new(URL.new)
|
48
46
|
@params = @url.params
|
@@ -67,6 +65,18 @@ class Page
|
|
67
65
|
end
|
68
66
|
end
|
69
67
|
|
68
|
+
def flash
|
69
|
+
@flash ||= ReactiveValue.new(Model.new({}, persistor: Persistors::Flash))
|
70
|
+
end
|
71
|
+
|
72
|
+
def store
|
73
|
+
@store ||= ReactiveValue.new(Model.new({}, persistor: Persistors::StoreFactory.new(tasks)))
|
74
|
+
end
|
75
|
+
|
76
|
+
def local_store
|
77
|
+
@local_store ||= ReactiveValue.new(Model.new({}, persistor: Persistors::LocalStore))
|
78
|
+
end
|
79
|
+
|
70
80
|
def tasks
|
71
81
|
@tasks ||= Tasks.new(self)
|
72
82
|
end
|
@@ -1,8 +1,6 @@
|
|
1
1
|
require 'stringio'
|
2
2
|
require 'volt'
|
3
|
-
require 'volt/server/
|
4
|
-
require 'volt/server/component_templates'
|
5
|
-
require 'volt/server/rack/asset_files'
|
3
|
+
require 'volt/server/rack/component_code'
|
6
4
|
|
7
5
|
class ComponentHandler
|
8
6
|
def initialize(component_paths)
|
@@ -15,13 +13,7 @@ class ComponentHandler
|
|
15
13
|
# TODO: Sanatize template path
|
16
14
|
component_name = req.path.strip.gsub(/^\/components\//, '').gsub(/[.]js$/, '')
|
17
15
|
|
18
|
-
code =
|
19
|
-
|
20
|
-
asset_files = AssetFiles.new(component_name, @component_paths)
|
21
|
-
asset_files.component_paths.each do |component_path, component_name|
|
22
|
-
code << ComponentTemplates.new(component_path, component_name).code
|
23
|
-
code << "\n\n"
|
24
|
-
end
|
16
|
+
code = ComponentCode.new(component_name, @component_paths).code
|
25
17
|
|
26
18
|
javascript_code = Opal.compile(code)
|
27
19
|
|
@@ -1,13 +1,30 @@
|
|
1
|
+
require 'volt/server/html_parser/view_parser'
|
2
|
+
|
1
3
|
# Initialize with the path to a component and returns all the front-end
|
2
4
|
# setup code (for controllers, models, views, and routes)
|
3
5
|
class ComponentTemplates
|
4
|
-
def initialize(component_path, component_name)
|
6
|
+
def initialize(component_path, component_name, client=true)
|
5
7
|
@component_path = component_path
|
6
8
|
@component_name = component_name
|
9
|
+
@client = true
|
7
10
|
end
|
8
11
|
|
9
12
|
def code
|
10
|
-
|
13
|
+
code = generate_view_code
|
14
|
+
if @client
|
15
|
+
# On the backend, we just need the views
|
16
|
+
code << generate_controller_code + generate_model_code + generate_routes_code
|
17
|
+
end
|
18
|
+
|
19
|
+
return code
|
20
|
+
end
|
21
|
+
|
22
|
+
def page_reference
|
23
|
+
if @client
|
24
|
+
'$page'
|
25
|
+
else
|
26
|
+
'page'
|
27
|
+
end
|
11
28
|
end
|
12
29
|
|
13
30
|
def generate_view_code
|
@@ -20,7 +37,6 @@ class ComponentTemplates
|
|
20
37
|
template_path = view_path[views_path.size..((-1 * ('.html'.size + 1)))]
|
21
38
|
template_path = "#{@component_name}/#{template_path}"
|
22
39
|
|
23
|
-
# all_templates = TemplateParser.new(File.read(view_path), template_path)
|
24
40
|
all_templates = ViewParser.new(File.read(view_path), template_path)
|
25
41
|
|
26
42
|
binding_initializers = []
|
@@ -35,11 +51,9 @@ class ComponentTemplates
|
|
35
51
|
|
36
52
|
binding_code = "{#{binding_code.join(', ')}}"
|
37
53
|
|
38
|
-
code << "
|
54
|
+
code << "#{page_reference}.add_template(#{name.inspect}, #{template['html'].inspect}, #{binding_code})\n"
|
39
55
|
end
|
40
56
|
end
|
41
|
-
# puts "--------------"
|
42
|
-
# puts "CODE: #{code}"
|
43
57
|
|
44
58
|
return code
|
45
59
|
end
|
@@ -64,7 +78,7 @@ class ComponentTemplates
|
|
64
78
|
|
65
79
|
model_name = model_path.match(/([^\/]+)[.]rb$/)[1]
|
66
80
|
|
67
|
-
code << "
|
81
|
+
code << "#{page_reference}.add_model(#{model_name.inspect})\n\n"
|
68
82
|
end
|
69
83
|
|
70
84
|
return code
|
@@ -75,7 +89,7 @@ class ComponentTemplates
|
|
75
89
|
routes_path = "#{@component_path}/config/routes.rb"
|
76
90
|
|
77
91
|
if File.exists?(routes_path)
|
78
|
-
code << "
|
92
|
+
code << "#{page_reference}.add_routes do\n"
|
79
93
|
code << "\n" + File.read(routes_path) + "\n"
|
80
94
|
code << "end\n\n"
|
81
95
|
end
|
@@ -1,4 +1,5 @@
|
|
1
|
-
# Used to get a list of the assets
|
1
|
+
# Used to get a list of the assets and other included components
|
2
|
+
# from the dependencies.rb files.
|
2
3
|
class AssetFiles
|
3
4
|
def initialize(component_name, component_paths)
|
4
5
|
@component_paths = component_paths
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'volt/server/html_parser/view_parser'
|
2
|
+
require 'volt/server/component_templates'
|
3
|
+
require 'volt/server/rack/asset_files'
|
4
|
+
|
5
|
+
# Takes in the name and all component paths and has a .code
|
6
|
+
# method that returns all of the ruby setup code for the component.
|
7
|
+
class ComponentCode
|
8
|
+
def initialize(component_name, component_paths, client=true)
|
9
|
+
@component_name = component_name
|
10
|
+
@component_paths = component_paths
|
11
|
+
@client = client
|
12
|
+
end
|
13
|
+
|
14
|
+
def code
|
15
|
+
code = ''
|
16
|
+
|
17
|
+
asset_files = AssetFiles.new(@component_name, @component_paths)
|
18
|
+
asset_files.component_paths.each do |component_path, component_name|
|
19
|
+
code << ComponentTemplates.new(component_path, component_name, @client).code
|
20
|
+
code << "\n\n"
|
21
|
+
end
|
22
|
+
|
23
|
+
return code
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'volt/page/page'
|
2
|
+
|
3
|
+
# A rack app that renders the html for a component on the backend.
|
4
|
+
class ComponentHtmlRenderer
|
5
|
+
def initialize
|
6
|
+
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
req = Rack::Request.new(env)
|
11
|
+
path = req.path
|
12
|
+
|
13
|
+
# For now just assume home
|
14
|
+
component_name = 'home'
|
15
|
+
|
16
|
+
page = Page.new
|
17
|
+
|
18
|
+
component_paths = ComponentPaths.new(Volt.root)
|
19
|
+
code = ComponentCode.new(component_name, component_paths).code
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
if RUBY_PLATFORM == 'opal'
|
2
|
+
module LocalStorage
|
3
|
+
def self.[](key)
|
4
|
+
%x{
|
5
|
+
var val = localStorage.getItem(key);
|
6
|
+
return val === null ? nil : val;
|
7
|
+
}
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.[]=(key, value)
|
11
|
+
`localStorage.setItem(key, value)`
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.clear
|
15
|
+
`localStorage.clear()`
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.delete(key)
|
20
|
+
%x{
|
21
|
+
var val = localStorage.getItem(key);
|
22
|
+
localStorage.removeItem(key);
|
23
|
+
return val === null ? nil : val;
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
else
|
28
|
+
module LocalStorage
|
29
|
+
@@store = {}
|
30
|
+
def self.[](key)
|
31
|
+
@@store[key]
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.[]=(key, value)
|
35
|
+
@@store[key] = value
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.clear
|
39
|
+
@@store = {}
|
40
|
+
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.delete(key)
|
45
|
+
@@store.delete(key)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
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.7.
|
4
|
+
version: 0.7.1
|
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-02-
|
11
|
+
date: 2014-02-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -450,6 +450,7 @@ files:
|
|
450
450
|
- lib/volt/models/persistors/array_store.rb
|
451
451
|
- lib/volt/models/persistors/base.rb
|
452
452
|
- lib/volt/models/persistors/flash.rb
|
453
|
+
- lib/volt/models/persistors/local_store.rb
|
453
454
|
- lib/volt/models/persistors/model_identity_map.rb
|
454
455
|
- lib/volt/models/persistors/model_store.rb
|
455
456
|
- lib/volt/models/persistors/params.rb
|
@@ -510,6 +511,8 @@ files:
|
|
510
511
|
- lib/volt/server/html_parser/view_parser.rb
|
511
512
|
- lib/volt/server/html_parser/view_scope.rb
|
512
513
|
- lib/volt/server/rack/asset_files.rb
|
514
|
+
- lib/volt/server/rack/component_code.rb
|
515
|
+
- lib/volt/server/rack/component_html_renderer.rb
|
513
516
|
- lib/volt/server/rack/component_paths.rb
|
514
517
|
- lib/volt/server/rack/index_files.rb
|
515
518
|
- lib/volt/server/rack/opal_files.rb
|
@@ -521,6 +524,7 @@ files:
|
|
521
524
|
- lib/volt/utils/ejson.rb
|
522
525
|
- lib/volt/utils/generic_counting_pool.rb
|
523
526
|
- lib/volt/utils/generic_pool.rb
|
527
|
+
- lib/volt/utils/local_storage.rb
|
524
528
|
- lib/volt/volt/environment.rb
|
525
529
|
- spec/apps/file_loading/app/bootstrap/assets/js/bootstrap.js
|
526
530
|
- spec/apps/file_loading/app/main/assets/js/test1.js
|