sequent-sinatra 0.1.0 → 0.1.1

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: 3a73084ee9f260f29469a257639ec887e5c7a537
4
- data.tar.gz: 85aa9e6af284495f7d33f8153460b8c43d8c1b3f
3
+ metadata.gz: c6370a605d3032c7a3703e6b3d0ab82d4ac39f7c
4
+ data.tar.gz: 9d78a48b9878443e3b88b1c2f3b4f9b54acad5dc
5
5
  SHA512:
6
- metadata.gz: bb42453351dffb2645e22763510c9833b535a0348b7d41d3894aa7d941ead955dfd5cdd3154c5d4412a28be88cf24c3e3c3e3baceaf495a23c312ed13d13c2ca
7
- data.tar.gz: fe7c9d65de1bae9b9ae48ee604acdf83774b0e5e4b74faf7f4985e7e59ab931155dbe5875526dbd67351ec5a82dd3d055f2d6d5c89c68b1ec2f5ecfb5dde47d8
6
+ metadata.gz: 27aa83a9d1ed558bb83b046ceb4c6164bde37ea756bb980af508260dae753f69e5f61e96a2a1e0b847dd702f09977c57b5f08e89dfcf3241cffcf686508d8769
7
+ data.tar.gz: d46569e2c082c724ca22a55d28b35875d0efc3551257e071ca64ef75d1245ec3b55b72177d580b5173e258e0b58afa6a8f8e5807713b9f41ab315cbeec2946dc
@@ -0,0 +1,35 @@
1
+ require 'sinatra'
2
+ module Sequent
3
+ module Web
4
+ module Sinatra
5
+ # Allows for easy integration with Sinatra apps.
6
+ # Provides:
7
+ #
8
+ # +Sequent::Core::Helpers::UuidHelper+
9
+ # +FormHelpers+
10
+ # +SimpleCommandServiceHelpers+
11
+ #
12
+ # The +sequent_config_dir+ allows you to specify the directory containing the
13
+ # 'initializers/sequent' file that initializes the +EventStore+ and +CommandService+ for your webapp.
14
+ #
15
+ # class MySinatraApp < Sinatra::Base
16
+ # set :sequent_config_dir, root
17
+ # register Sequent::Web::Sinatra::App
18
+ # end
19
+ module App
20
+ def self.registered(app)
21
+ app.helpers Sequent::Core::Helpers::UuidHelper
22
+ app.helpers Sequent::Web::Sinatra::FormHelpers
23
+ app.helpers Sequent::Web::Sinatra::SimpleCommandServiceHelpers
24
+
25
+ app.before do
26
+ require File.join(app.sequent_config_dir || app.root, 'initializers/sequent')
27
+ @command_service = Sequent::Core::CommandService.instance
28
+ end
29
+
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ Sinatra.register Sequent::Web::Sinatra::App
@@ -0,0 +1,37 @@
1
+ require_relative 'tag_helper'
2
+ require_relative 'fieldset'
3
+
4
+ module Sequent
5
+ module Web
6
+ module Sinatra
7
+ class Fieldset
8
+ include Sequent::Web::Sinatra::TagHelper
9
+
10
+ attr_reader :path, :parent
11
+
12
+ def initialize(parent, path, params, errors, options = {})
13
+ raise "params are empty while creating new fieldset path #{path}" unless params
14
+ @values = params.has_key?(path) ? (params[path] || {}) : {}
15
+ @parent = parent
16
+ @path = path.to_s.gsub(/\W+/, '')
17
+ @errors = errors
18
+ @options = options
19
+ end
20
+
21
+ def nested(name)
22
+ yield Fieldset.new(self, name, @values, @errors, @options)
23
+ end
24
+
25
+ def method_missing(method, *args, &block)
26
+ @parent.send(method, *args)
27
+ end
28
+
29
+ def path_for(field_name)
30
+ css_id @path, field_name
31
+ end
32
+
33
+ end
34
+
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,77 @@
1
+ require_relative 'tag_helper'
2
+ require_relative 'fieldset'
3
+
4
+ module Sequent
5
+ module Web
6
+ module Sinatra
7
+ class Form
8
+ include TagHelper
9
+
10
+ def initialize(context, for_object, action, method=:get, options = {})
11
+ @context = context
12
+ @values = params
13
+ @errors = @context.instance_variable_get("@errors")
14
+ @for_object = for_object
15
+ @action = action
16
+ @method = method
17
+ @options = options
18
+ end
19
+
20
+ def path_for(field_name)
21
+ css_id field_name
22
+ end
23
+
24
+ def method_missing(method, *args, &block)
25
+ @context.send(method, *args)
26
+ end
27
+
28
+ def render(&block)
29
+ method_input = ''
30
+ if @method.is_a? Symbol
31
+ case @method.to_s.downcase
32
+ when 'delete', 'update'
33
+ method_input = %Q(<input type="hidden" name="_method" value="#{@method}" />)
34
+ @method = :post
35
+ when 'create'
36
+ @method = :post
37
+ end
38
+ end
39
+
40
+ inner_html = capture_erb(self, &block)
41
+ out = tag(:form, nil, {:action => @action, :method => @method.to_s.upcase}.merge(@options)) + method_input + csrf_tag
42
+ out << inner_html
43
+ out << '</form>'
44
+ buf = @context.instance_variable_get("@_out_buf")
45
+ buf << out
46
+
47
+ end
48
+
49
+ def fieldset(obj_name, options = {}, &block)
50
+ raise ArgumentError, "Missing block to fieldset()" unless block_given?
51
+ raise "can not create a fieldset without a form backing object" unless @for_object
52
+ params.merge!(params.nil? ? {obj_name.to_s => @for_object.as_params} : params.merge({obj_name.to_s => @for_object.as_params}))
53
+ yield Fieldset.new(@context, obj_name, HashWithIndifferentAccess.new(params), @errors, options)
54
+ end
55
+
56
+
57
+ private
58
+ def capture_erb(*args, &block)
59
+ erb_with_output_buffer { block_given? && block.call(*args) }
60
+ end
61
+
62
+ def erb_with_output_buffer(buf = '')
63
+ old_buffer = @context.instance_variable_get("@_out_buf")
64
+ @context.instance_variable_set "@_out_buf", buf
65
+ yield
66
+ @context.instance_variable_get("@_out_buf")
67
+ ensure
68
+ @context.instance_variable_set "@_out_buf", old_buffer
69
+ end
70
+
71
+
72
+ end
73
+
74
+ end
75
+ end
76
+ end
77
+
@@ -0,0 +1,30 @@
1
+ require_relative 'form'
2
+ require 'rack/csrf'
3
+
4
+ module Sequent
5
+ module Web
6
+ module Sinatra
7
+ module FormHelpers
8
+ def html_form(action, method=:get, options={}, &block)
9
+ html_form_for nil, action, method, options, &block
10
+ end
11
+
12
+ def html_form_for(for_object, action, method=:get, options={}, &block)
13
+ raise "Given object of class #{for_object.class} does not respond to :as_params. Are you including Sequent::Core::Helpers::ParamSupport?" if (for_object and !for_object.respond_to? :as_params)
14
+ form = Form.new(self, for_object, action, method, options.merge(role: "form"))
15
+ form.render(&block)
16
+ end
17
+
18
+ def h(text)
19
+ Rack::Utils.escape_html(text)
20
+ end
21
+
22
+ def csrf_tag
23
+ raise "You must enable sessions to use FormHelpers" unless env
24
+ Rack::Csrf.csrf_tag(env)
25
+ end
26
+
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,6 @@
1
+ require_relative 'form_helpers'
2
+ require_relative 'tag_helper'
3
+ require_relative 'fieldset'
4
+ require_relative 'form'
5
+ require_relative 'simple_command_service_helpers'
6
+ require_relative 'app'
@@ -0,0 +1,23 @@
1
+ module Sequent
2
+ module Web
3
+ module Sinatra
4
+ module SimpleCommandServiceHelpers
5
+ #
6
+ # execute a single command. Since it is default for most cases a CommandNotValid exception is handled in this method.
7
+ #
8
+ # Example usage:
9
+ #
10
+ # post '/foo' do
11
+ # @command = FooCommand.from_params(params)
12
+ # execute_command(@command, :erb_name)
13
+ # end
14
+ def execute_command(command)
15
+ @command_service.execute_commands(command)
16
+ yield if block_given?
17
+ rescue Sequent::Core::CommandNotValid => e
18
+ yield e.errors_with_command_prefix if block_given?
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,155 @@
1
+ module Sequent
2
+ module Web
3
+ module Sinatra
4
+ module TagHelper
5
+ def raw_checkbox(field, options={})
6
+ id = css_id(@path, field)
7
+ value = param_or_default(field, options[:value]) || id
8
+ values = [value].compact
9
+ single_tag :input, options.merge(
10
+ :type => "checkbox", :id => id,
11
+ :name => calculate_name(field),
12
+ :value => value, checked: (values.include?(@values[field.to_s])) ? "checked" : nil
13
+ )
14
+ end
15
+
16
+ def raw_input(field, options={})
17
+ raw_field(field, "text", options)
18
+ end
19
+
20
+ def raw_password(field, options={})
21
+ raw_field(field, "password", options)
22
+ end
23
+
24
+ def raw_textarea(field, options={})
25
+ value = param_or_default(field, options[:value])
26
+
27
+ with_closing_tag :textarea, value, {rows: "3"}.merge(options.merge(
28
+ :id => css_id(@path, field),
29
+ :name => calculate_name(field)
30
+ ))
31
+ end
32
+
33
+ def raw_hidden(field, options={})
34
+ raw_field(field, "hidden", options)
35
+ end
36
+
37
+ def raw_select(field, values, options={})
38
+ value = param_or_default(field, options[:value])
39
+ content = ""
40
+ Array(values).each do |val|
41
+ id, text = id_and_text_from_value(val)
42
+ option_values = {value: id}
43
+ option_values.merge!(selected: "selected") if (id == value)
44
+ option_values.merge!(disabled: "disabled") if options[:disable].try(:include?, id)
45
+ content << tag(:option, text, option_values)
46
+ end
47
+ tag :select, content, options.merge(:id => css_id(@path, field), :name => calculate_name(field))
48
+ end
49
+
50
+ def calculate_name(field)
51
+ reverse_names = tree_in_names(field)
52
+ "#{reverse_names.first}#{reverse_names[1..-1].map { |n| "[#{n}]" }.join}"
53
+ end
54
+
55
+ def full_path(field)
56
+ tree_in_names(field).join('_')
57
+ end
58
+
59
+ alias_method :calculate_id, :full_path
60
+
61
+ def tree_in_names(field)
62
+ if respond_to? :path
63
+ names = [field, path]
64
+ parent = @parent
65
+ while parent.is_a? Fieldset
66
+ names << parent.path
67
+ parent = parent.parent
68
+ end
69
+ names.reverse
70
+ else
71
+ [field]
72
+ end
73
+ end
74
+
75
+ def param_or_default(field, default)
76
+ @values.nil? ? default : @values.has_key?(field.to_s) ? @values[field.to_s] || default : default
77
+ end
78
+
79
+
80
+ def id_and_text_from_value(val)
81
+ if val.is_a? Array
82
+ [val[0], val[1]]
83
+ else
84
+ [val, val]
85
+ end
86
+ end
87
+
88
+ def css_id(*things)
89
+ things.compact.map { |t| t.to_s }.join('_').downcase.gsub(/\W/, '_')
90
+ end
91
+
92
+ def tag(name, content, options={})
93
+ "<#{name.to_s}" +
94
+ (options.length > 0 ? " #{hash_to_html_attrs(options)}" : '') +
95
+ (content.nil? ? '>' : ">#{content}</#{name}>")
96
+ end
97
+
98
+ def single_tag(name, options={})
99
+ "<#{name.to_s} #{hash_to_html_attrs(options)} />"
100
+ end
101
+
102
+ def with_closing_tag(name, value, options={})
103
+ %Q{<#{name.to_s} #{hash_to_html_attrs(options)} >#{h value}</#{name.to_s}>}
104
+ end
105
+
106
+ def hash_to_html_attrs(options={})
107
+ raise %Q{Keys used in options must be a Symbol. Don't use {"class" => "col-md-4"} but use {class: "col-md-4"}} if options.keys.find { |k| not k.kind_of? Symbol }
108
+ html_attrs = ""
109
+ options.keys.sort.each do |key|
110
+ next if options[key].nil? # do not include empty attributes
111
+ html_attrs << %Q(#{key}="#{h(options[key])}" )
112
+ end
113
+ html_attrs.chop
114
+ end
115
+
116
+ def merge_and_append_class_attributes(to_append, options = {})
117
+ to_append.merge(options) do |key, oldval, newval|
118
+ key == :class ? "#{oldval} #{newval}" : newval
119
+ end
120
+ end
121
+
122
+ def i18n_name(field)
123
+ if @path
124
+ "#{@path}.#{field}"
125
+ else
126
+ field.to_s
127
+ end
128
+ end
129
+
130
+ def has_form_error?(name)
131
+ @errors.try(:has_key?, name.to_sym)
132
+ end
133
+
134
+ private
135
+ def raw_field(field, field_type, options)
136
+ value = param_or_default(field, options[:value])
137
+ if options[:formatter]
138
+ value = self.send(options[:formatter], value)
139
+ options.delete(:formatter)
140
+ end
141
+ id = options[:id] || css_id(@path, field)
142
+ single_tag :input, options.merge(
143
+ :type => field_type,
144
+ :id => id,
145
+ :name => calculate_name(field),
146
+ :value => value
147
+ )
148
+ end
149
+
150
+
151
+ end
152
+ end
153
+ end
154
+ end
155
+
data/lib/version.rb ADDED
@@ -0,0 +1,3 @@
1
+ module SequentSinatra
2
+ VERSION='0.1.1'
3
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequent-sinatra
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lars Vonk
@@ -135,6 +135,14 @@ extensions: []
135
135
  extra_rdoc_files: []
136
136
  files:
137
137
  - lib/sequent-sinatra.rb
138
+ - lib/sequent-sinatra/app.rb
139
+ - lib/sequent-sinatra/fieldset.rb
140
+ - lib/sequent-sinatra/form.rb
141
+ - lib/sequent-sinatra/form_helpers.rb
142
+ - lib/sequent-sinatra/sequent-sinatra.rb
143
+ - lib/sequent-sinatra/simple_command_service_helpers.rb
144
+ - lib/sequent-sinatra/tag_helper.rb
145
+ - lib/version.rb
138
146
  homepage: https://github.com/zilverline/sequent-sinatra
139
147
  licenses:
140
148
  - MIT