end_view 0.0.6 → 0.1.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: 22a3302ee1e926c3f9b9d8f51d5266a4f24d5108
4
- data.tar.gz: d9bd31ce7a5ee1ee9413c1fbc744c7ad880e41bc
3
+ metadata.gz: 2f3054dbb6674965ce22fdfeba1ecd14b6135299
4
+ data.tar.gz: 303127059c06331b85b75274e6362cadcae3e360
5
5
  SHA512:
6
- metadata.gz: 4be4d976261c57aae690fa9536f0f87ed5c16acae3151f0b9393afd1636aec3a2486da435ade5442786b99cc6edb72ee08c70a00bb7035064aaa5ab085e677d9
7
- data.tar.gz: cd5ecf094d52a11fb26655445f1eb4163c491a92313db4873f028021c06d06de008375d0b90aca1827d759656981153c06e70d3ba1fa98f5f44fe27d0c5f4513
6
+ metadata.gz: 3b179876261d57e25381eabbe1ab7be6d86599309542383e818c482ffe7bee2e0f0e61aac6513fff26b467e34b7b0ce295c7b140984142ca52922f974799d47d
7
+ data.tar.gz: 2ce08b9f83504d1d74b2734d790498337c26186571076362602d98cb2d109df6d8d223de4a28c0d6887786d48d4b70af70fee23b50894dfc11c9ff72aa222d68
data/README.md CHANGED
@@ -16,15 +16,15 @@ class Foo
16
16
  include EndView.new(__FILE__)
17
17
 
18
18
  def my_method
19
- 'World'
19
+ 'Hello World'
20
20
  end
21
21
  end
22
22
 
23
- Foo.new.render # Hello World
23
+ Foo.new.render # <h1>Hello World</h1>
24
24
 
25
25
  __END__
26
26
 
27
- Hello <%= my_method %>
27
+ %h1= my_method
28
28
  ```
29
29
 
30
30
  Alternatively, an instance of `EndView` can be extended:
@@ -34,26 +34,26 @@ module Baz
34
34
  extend EndView.new(__FILE__)
35
35
 
36
36
  def self.my_method
37
- 'World'
37
+ 'Howdy World'
38
38
  end
39
39
  end
40
40
 
41
- Baz.render # Howdy World
41
+ Baz.render # <h3>Howdy World</h3>
42
42
 
43
43
  __END__
44
44
 
45
- Howdy <%= my_method %>
45
+ %h3= my_method
46
46
  ```
47
47
 
48
48
  ### Template Engine
49
49
 
50
- By default Tilt's ERB template engine is used, but alternative engines can be passed in:
50
+ By default Tilt's Haml template engine is used, but alternative engines can be passed in:
51
51
 
52
52
  ``` ruby
53
- require 'tilt/haml'
53
+ require 'tilt/erb'
54
54
 
55
55
  class Ham
56
- include EndView.new(__FILE__, Tilt::HamlTemplate)
56
+ include EndView.new(__FILE__, Tilt::ERBTemplate)
57
57
 
58
58
  def my_method
59
59
  'Heya'
@@ -64,7 +64,7 @@ Ham.new.render # <h1>Heya</h1>
64
64
 
65
65
  __END__
66
66
 
67
- %h1= my_method
67
+ <h1><%= my_method %></h1>
68
68
  ```
69
69
 
70
70
  To change the default engine:
@@ -86,7 +86,8 @@ MyLayout.render { "S'up" } # <html>S'up</html>
86
86
 
87
87
  __END__
88
88
 
89
- <html><%= yield %></html>
89
+ %html
90
+ = yield
90
91
  ```
91
92
 
92
93
  These can then be used as layouts:
@@ -97,11 +98,11 @@ class Fizz
97
98
  self.layout = MyLayout
98
99
  end
99
100
 
100
- Fizz.new.render # <html>Goodbye</html>
101
+ Fizz.new.render # <html><h1>Goodbye</h1></html>
101
102
 
102
103
  __END__
103
104
 
104
- Goodbye
105
+ %h1 Goodbye
105
106
  ```
106
107
 
107
108
  For layouts that need to be dynamically initialized, `self.layout` can be passed a lambda:
@@ -117,7 +118,9 @@ end
117
118
 
118
119
  __END__
119
120
 
120
- <html><%= @title %><%= yield %></html>
121
+ %html
122
+ %h1= @title
123
+ = yield
121
124
  ```
122
125
 
123
126
  ``` ruby
@@ -126,11 +129,11 @@ class Whizz
126
129
  self.layout = -> { MyDynamicLayout.new('Hallo') }
127
130
  end
128
131
 
129
- Whizz.new.render # <html>Hallo Bonjour</html>
132
+ Whizz.new.render # <html> <h1>Hallo</h1> <p>Bonjour</p> </html>
130
133
 
131
134
  __END__
132
135
 
133
- Bonjour
136
+ %p Bonjour
134
137
  ```
135
138
 
136
139
  ### Inheritance
@@ -144,7 +147,7 @@ class Bar < Foo
144
147
  end
145
148
  end
146
149
 
147
- Bar.new.render # Hello Porridge
150
+ Bar.new.render # <h1>Porridge</h1>
148
151
  ```
149
152
 
150
153
  To override an inherited template, call the `compile` class method:
@@ -154,11 +157,11 @@ class Pop < Foo
154
157
  compile(__FILE__)
155
158
  end
156
159
 
157
- Pop.new.render # The World is too big!
160
+ Pop.new.render # <p class="inherited">Hello World</p>
158
161
 
159
162
  __END__
160
163
 
161
- The <%= my_method %> is too big!
164
+ %p.inherited= my_method
162
165
  ```
163
166
 
164
167
  ### locals
@@ -166,7 +169,7 @@ The <%= my_method %> is too big!
166
169
  Locals can be passed into the render method that override the view models:
167
170
 
168
171
  ``` ruby
169
- Foo.new.render(my_method: 'Stranger') # Hello Stranger
172
+ Foo.new.render(my_method: 'Stranger') # <h1>Stranger</h1>
170
173
  ```
171
174
 
172
175
  ## Installation
@@ -0,0 +1,82 @@
1
+ require 'end_view'
2
+ require 'attire'
3
+ require 'inflecto'
4
+
5
+ module EndView
6
+ module Bootstrap
7
+ class FormGroup
8
+ include EndView.new(__FILE__)
9
+ attr_method :render, :form_builder, :attribute, required: false,
10
+ label: nil,
11
+ left: nil,
12
+ right: nil,
13
+ input_opts: {},
14
+ label_opts: {}
15
+
16
+ private
17
+
18
+ def input_opts
19
+ form_builder.input_opts(attribute, @input_opts)
20
+ end
21
+
22
+ def label_opts
23
+ form_builder.label_opts(attribute, @label_opts)
24
+ end
25
+
26
+ def label
27
+ @label = default[:label] || Inflecto.humanize(attribute.to_s) if @label.nil?
28
+ @label
29
+ end
30
+
31
+ def left
32
+ @left ||= default[:left]
33
+ end
34
+
35
+ def right
36
+ @right ||= default[:right]
37
+ end
38
+
39
+ def required
40
+ @required ||= default[:required]
41
+ end
42
+
43
+ def default
44
+ @default ||= begin
45
+ match = defaults.find { |k, _v| k.any? { |w| attribute =~ /#{w}/ } }
46
+ match ? match[1] : {}
47
+ end
48
+ end
49
+
50
+ def defaults
51
+ @defaults ||= {
52
+ %w(email) => { left: icon('envelope') },
53
+ %w(phone) => { left: icon('earphone') },
54
+ %w(repeat confirm) => { left: icon('repeat'), required: true },
55
+ %w(password) => { left: icon('lock'), required: true },
56
+ %w(card) => { left: icon('credit-card'), required: true }
57
+ }
58
+ end
59
+
60
+ def icon(icon)
61
+ "<span class='glyphicon glyphicon-#{icon}' aria-hidden='true'></span>"
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ __END__
68
+
69
+ .form-group
70
+ - if label
71
+ %label{label_opts}= label
72
+ - if required
73
+ %span.required *
74
+ - if left || right
75
+ .input-group
76
+ - if left
77
+ .input-group-addon= left
78
+ %input.form-control{input_opts}/
79
+ - if right
80
+ .input-group-addon= right
81
+ - else
82
+ %input.form-control{input_opts}/
@@ -0,0 +1,46 @@
1
+ require 'end_view/bootstrap/modal'
2
+ require 'forwardable'
3
+
4
+ module EndView
5
+ module Bootstrap
6
+ class FormModal < Modal
7
+ compile(__FILE__)
8
+ extend Forwardable
9
+
10
+ def initialize(form_builder, opts = {})
11
+ super({ dismiss_value: 'Cancel' }.merge(opts))
12
+ @form_builder = form_builder
13
+ @submit_value = opts[:submit_value] || 'Okay'
14
+ end
15
+
16
+ private
17
+
18
+ attr_reader :form_builder, :submit_value
19
+ def_delegators :form_builder, :form_opts,
20
+ :authenticity_token_opts,
21
+ :form_method_opts
22
+
23
+ def submit_opts
24
+ { class: 'btn btn-primary', type: 'submit' }
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ __END__
31
+
32
+ .modal{modal_opts}
33
+ .modal-dialog{dialog_opts}
34
+ .modal-content
35
+ - if title
36
+ .modal-header
37
+ %button{close_opts}
38
+ %span(aria-hidden) &times;
39
+ %h4{title_opts}= title
40
+ %form{form_opts}
41
+ %input{authenticity_token_opts}
42
+ %input{form_method_opts}
43
+ .modal-body= yield
44
+ .modal-footer
45
+ %button{dismiss_opts}= dismiss_value
46
+ %button{submit_opts}= submit_value
@@ -0,0 +1,30 @@
1
+ require 'end_view/bootstrap/form_modal'
2
+ require 'end_view/bootstrap/form_group'
3
+ require 'end_view/form/record_builder'
4
+
5
+ module EndView
6
+ module Bootstrap
7
+ class LoginModal
8
+ attr_method :render, :user, :form_authenticty_token, form_opts: {},
9
+ modal_opts: {},
10
+ form_builder: nil
11
+
12
+ def render
13
+ FormModal.render(form_builder, modal_opts) do
14
+ form_group(:email) << form_group(:password)
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def form_builder
21
+ @form_builder ||=
22
+ Form::RecordBuilder.new(user, form_authenticty_token, form_opts)
23
+ end
24
+
25
+ def form_group(attribute)
26
+ FormGroup.render(form_builder, attribute)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,63 @@
1
+ require 'end_view'
2
+ require 'attire'
3
+
4
+ module EndView
5
+ module Bootstrap
6
+ class Modal
7
+ include EndView.new(__FILE__)
8
+ attr_init modal_id: "modal#{rand(10_000)}",
9
+ title: nil,
10
+ size: nil,
11
+ label: "label#{rand(10_000)}",
12
+ dismiss_value: 'Okay'
13
+
14
+ def self.render(*args, &b)
15
+ new(*args).render(&b)
16
+ end
17
+
18
+ public :modal_id
19
+
20
+ private
21
+
22
+ def modal_opts
23
+ { id: modal_id,
24
+ class: 'fade',
25
+ tabindex: -1,
26
+ role: 'dialog',
27
+ aria: { labelledby: label, hidden: true } }
28
+ end
29
+
30
+ def dialog_opts
31
+ { class: size }
32
+ end
33
+
34
+ def close_opts
35
+ { class: 'close',
36
+ 'data-dismiss' => 'modal',
37
+ aria: { hidden: true, label: 'Close' } }
38
+ end
39
+
40
+ def title_opts
41
+ { class: 'modal-title', id: label }
42
+ end
43
+
44
+ def dismiss_opts
45
+ { class: 'btn btn-default', 'data-dismiss' => :modal }
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ __END__
52
+
53
+ .modal{modal_opts}
54
+ .modal-dialog{dialog_opts}
55
+ .modal-content
56
+ - if title
57
+ .modal-header
58
+ %button{close_opts}
59
+ %span(aria-hidden) &times;
60
+ %h4{title_opts}= title
61
+ .modal-body= yield
62
+ .modal-footer
63
+ %button{dismiss_opts}= dismiss_value
@@ -0,0 +1,4 @@
1
+ require 'end_view/bootstrap/modal'
2
+ require 'end_view/bootstrap/form_modal'
3
+ require 'end_view/bootstrap/form_group'
4
+ require 'end_view/bootstrap/login_modal'
@@ -0,0 +1,60 @@
1
+ require 'attire'
2
+
3
+ module EndView
4
+ module Form
5
+ class Builder
6
+ attr_init :form_url, :form_authenticity_token, form_method: 'post'
7
+
8
+ def form_opts(opts = {})
9
+ { action: form_url, method: 'post' }.merge(opts)
10
+ end
11
+
12
+ def authenticity_token_opts(opts = {})
13
+ { name: 'authenticity_token',
14
+ type: 'hidden',
15
+ value: form_authenticity_token }.merge(opts)
16
+ end
17
+
18
+ def form_method_opts(opts = {})
19
+ { name: '_method', type: 'hidden', value: form_method }.merge(opts)
20
+ end
21
+
22
+ def label_opts(attribute, opts = {})
23
+ { for: attribute_id(attribute) }.merge(opts)
24
+ end
25
+
26
+ def input_opts(attribute, opts = {})
27
+ { id: attribute_id(attribute),
28
+ name: attribute_name(attribute),
29
+ type: 'text' }.merge(find_default(attribute)).merge(opts)
30
+ end
31
+
32
+ private
33
+
34
+ def attribute_id(attribute)
35
+ attribute.to_s
36
+ end
37
+
38
+ def attribute_name(attribute)
39
+ attribute.to_s
40
+ end
41
+
42
+ def input_defaults
43
+ @input_defaults ||= {
44
+ %w(email) => { type: 'email' },
45
+ %w(phone) => { type: 'tel' },
46
+ %w(password) => { type: 'password' },
47
+ %w(url) => { type: 'url' },
48
+ %w(search) => { type: 'search', placeholder: 'Search' },
49
+ %w(card) => { pattern: '[0-9]{13,16}', autocomplete: 'off' },
50
+ %w(security_code csc cvd cvn cvv cvc ccv spc) => { size: 5, autocomplete: 'off' }
51
+ }
52
+ end
53
+
54
+ def find_default(attribute)
55
+ input_defaults.each { |k, v| return v if k.any? { |w| attribute =~ /#{w}/ } }
56
+ {}
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,64 @@
1
+ require 'inflecto'
2
+ require 'end_view/form/builder'
3
+
4
+ module EndView
5
+ module Form
6
+ class RecordBuilder < Builder
7
+ attr_init :record, :form_authenticity_token, model_name: nil,
8
+ model_id: nil,
9
+ action: nil,
10
+ form_method: nil,
11
+ form_url: nil
12
+
13
+ def form_opts(opts = {})
14
+ super.merge(class: form_class, id: form_id).merge(opts)
15
+ end
16
+
17
+ def input_opts(attribute, opts = {})
18
+ super.merge(value: attribute_value(attribute)).merge(opts)
19
+ end
20
+
21
+ private
22
+
23
+ def model_name
24
+ @model_name ||= Inflecto.underscore(Inflecto.demodulize(record.class.to_s))
25
+ end
26
+
27
+ def model_id
28
+ @model_id ||= ((record.respond_to?(:to_key) && record.to_key) || []).first
29
+ end
30
+
31
+ def action
32
+ @action ||= model_id ? 'edit' : 'new'
33
+ end
34
+
35
+ def form_method
36
+ @form_method ||= model_id ? 'patch' : 'post'
37
+ end
38
+
39
+ def form_url
40
+ @form_url ||= "/#{Inflecto.pluralize(model_name)}/#{model_id}"
41
+ end
42
+
43
+ def form_class
44
+ @form_class ||= "#{action}_#{model_name}"
45
+ end
46
+
47
+ def form_id
48
+ @form_id ||= [action, model_name, model_id].compact.join('_')
49
+ end
50
+
51
+ def attribute_id(attribute)
52
+ "#{model_name}_#{attribute}"
53
+ end
54
+
55
+ def attribute_name(attribute)
56
+ "#{model_name}[#{attribute}]"
57
+ end
58
+
59
+ def attribute_value(attribute)
60
+ (record.respond_to?(attribute) && record.send(attribute)) || nil
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,2 @@
1
+ require 'end_view/form/builder'
2
+ require 'end_view/form/record_builder'
@@ -0,0 +1,42 @@
1
+ require 'end_view'
2
+ require 'forwardable'
3
+ require 'attire'
4
+
5
+ module EndView
6
+ module Rails
7
+ class Layout
8
+ include EndView.new(__FILE__)
9
+ extend Forwardable
10
+ attr_init :view_context, :title
11
+
12
+ def self.render(*args, &b)
13
+ new(*args).render(&b)
14
+ end
15
+
16
+ private
17
+
18
+ def_delegators :view_context, :stylesheet_link_tag,
19
+ :javascript_include_tag,
20
+ :csrf_meta_tags
21
+
22
+ def stylesheet_args
23
+ ['application', { media: 'all', 'data-turbolinks-track' => true }]
24
+ end
25
+
26
+ def javascript_args
27
+ ['application', { 'data-turbolinks-track' => true }]
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ __END__
34
+
35
+ !!! 5
36
+ %html
37
+ %head
38
+ %title= title
39
+ = stylesheet_link_tag(*stylesheet_args)
40
+ = javascript_include_tag(*javascript_args)
41
+ = csrf_meta_tags
42
+ %body= yield
@@ -0,0 +1 @@
1
+ require 'end_view/rails/layout'
data/lib/end_view.rb CHANGED
@@ -1,26 +1,29 @@
1
- require 'tilt'
1
+ require 'haml'
2
+ require 'tilt/haml'
2
3
 
3
- class EndView < Module
4
+ module EndView
4
5
  class << self
5
6
  attr_writer :default_engine
6
7
 
7
8
  def default_engine
8
- @default_engine ||= Tilt::ERBTemplate
9
+ @default_engine ||= Tilt::HamlTemplate
9
10
  end
10
- end
11
11
 
12
- def initialize(file, template_engine = EndView.default_engine)
13
- define_singleton_method(:included) do |base|
14
- base.extend ClassMethods
15
- base.compile(file, template_engine)
16
- base.send(:include, Methods)
17
- base.send(:include, InstanceMethods)
18
- end
12
+ def new(file, template_engine = EndView.default_engine)
13
+ Module.new do
14
+ define_singleton_method(:included) do |base|
15
+ base.extend ClassMethods
16
+ base.compile(file, template_engine)
17
+ base.send(:include, Methods)
18
+ base.send(:include, InstanceMethods)
19
+ end
19
20
 
20
- define_singleton_method(:extended) do |base|
21
- base.extend ClassMethods
22
- base.compile(file, template_engine)
23
- base.extend Methods
21
+ define_singleton_method(:extended) do |base|
22
+ base.extend ClassMethods
23
+ base.compile(file, template_engine)
24
+ base.extend Methods
25
+ end
26
+ end
24
27
  end
25
28
  end
26
29
 
@@ -46,6 +49,7 @@ class EndView < Module
46
49
  module Methods
47
50
  def render(*args, &b)
48
51
  rendered_template = template.render(self, *args, &b)
52
+ layout = self.layout
49
53
  layout ? layout.render { rendered_template } : rendered_template
50
54
  end
51
55
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: end_view
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Max White
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-04 00:00:00.000000000 Z
11
+ date: 2015-02-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tilt
@@ -24,6 +24,60 @@ dependencies:
24
24
  - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: haml
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: attire
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '0.1'
48
+ - - '>='
49
+ - !ruby/object:Gem::Version
50
+ version: 0.1.1
51
+ type: :runtime
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ~>
56
+ - !ruby/object:Gem::Version
57
+ version: '0.1'
58
+ - - '>='
59
+ - !ruby/object:Gem::Version
60
+ version: 0.1.1
61
+ - !ruby/object:Gem::Dependency
62
+ name: inflecto
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ~>
66
+ - !ruby/object:Gem::Version
67
+ version: '0.0'
68
+ - - '>='
69
+ - !ruby/object:Gem::Version
70
+ version: 0.0.2
71
+ type: :runtime
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '0.0'
78
+ - - '>='
79
+ - !ruby/object:Gem::Version
80
+ version: 0.0.2
27
81
  - !ruby/object:Gem::Dependency
28
82
  name: rspec
29
83
  requirement: !ruby/object:Gem::Requirement
@@ -45,19 +99,25 @@ dependencies:
45
99
  - !ruby/object:Gem::Version
46
100
  version: 3.1.0
47
101
  - !ruby/object:Gem::Dependency
48
- name: haml
102
+ name: rspec-html-matchers
49
103
  requirement: !ruby/object:Gem::Requirement
50
104
  requirements:
105
+ - - ~>
106
+ - !ruby/object:Gem::Version
107
+ version: '0.6'
51
108
  - - '>='
52
109
  - !ruby/object:Gem::Version
53
- version: '0'
110
+ version: 0.6.1
54
111
  type: :development
55
112
  prerelease: false
56
113
  version_requirements: !ruby/object:Gem::Requirement
57
114
  requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: '0.6'
58
118
  - - '>='
59
119
  - !ruby/object:Gem::Version
60
- version: '0'
120
+ version: 0.6.1
61
121
  description:
62
122
  email: mushishi78@gmail.com
63
123
  executables: []
@@ -67,6 +127,16 @@ files:
67
127
  - LICENSE.txt
68
128
  - README.md
69
129
  - lib/end_view.rb
130
+ - lib/end_view/bootstrap.rb
131
+ - lib/end_view/bootstrap/form_group.rb
132
+ - lib/end_view/bootstrap/form_modal.rb
133
+ - lib/end_view/bootstrap/login_modal.rb
134
+ - lib/end_view/bootstrap/modal.rb
135
+ - lib/end_view/form.rb
136
+ - lib/end_view/form/builder.rb
137
+ - lib/end_view/form/record_builder.rb
138
+ - lib/end_view/rails.rb
139
+ - lib/end_view/rails/layout.rb
70
140
  homepage: https://github.com/mushishi78/end_view
71
141
  licenses:
72
142
  - MIT