BrianTheCoder-ratpack 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.
- data/LICENSE +20 -0
- data/README.rdoc +47 -0
- data/VERSION.yml +4 -0
- data/lib/ratpack/forms.rb +199 -0
- data/lib/ratpack/html_helpers.rb +49 -0
- data/lib/ratpack/routes.rb +12 -0
- data/lib/ratpack/tag.rb +21 -0
- data/lib/ratpack.rb +30 -0
- data/lib/sinatra/ratpack.rb +17 -0
- data/test/ratpack_test.rb +7 -0
- data/test/test_helper.rb +10 -0
- metadata +67 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 brianthecoder
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
= RatPack
|
2
|
+
|
3
|
+
Collection of helpers for sinatra mainly for links, css, js, images, and form stuff. Most of this was stolen/modified from merb. Much love to the merb-core team. Peace.
|
4
|
+
|
5
|
+
== What's included
|
6
|
+
|
7
|
+
=== Forms
|
8
|
+
|
9
|
+
* text_field
|
10
|
+
* password_field
|
11
|
+
* hidden_field
|
12
|
+
* password_field
|
13
|
+
* check_box
|
14
|
+
* radio_button
|
15
|
+
* radio_group - same as above but takes an array of names
|
16
|
+
* text_area
|
17
|
+
* label
|
18
|
+
* select
|
19
|
+
* button
|
20
|
+
* submit
|
21
|
+
|
22
|
+
=== Routing helpers
|
23
|
+
|
24
|
+
* subdomains - takes tld length as an arg
|
25
|
+
|
26
|
+
=== Html Helpers
|
27
|
+
|
28
|
+
* link_to
|
29
|
+
* js_link - only accepts one file name
|
30
|
+
* css_link - only accepts one file name
|
31
|
+
* partial - specify template parser via :template param, defaults to erb looks for partials in a views/partials
|
32
|
+
* tag
|
33
|
+
* open_tag
|
34
|
+
* close_tag
|
35
|
+
* self_closing_tag
|
36
|
+
|
37
|
+
==== Coming Soon
|
38
|
+
|
39
|
+
Need to figure out how to detect rendering engine
|
40
|
+
|
41
|
+
* form
|
42
|
+
* fieldset
|
43
|
+
* better partial
|
44
|
+
|
45
|
+
== Copyright
|
46
|
+
|
47
|
+
Copyright (c) 2009 brianthecoder. See LICENSE for details.
|
data/VERSION.yml
ADDED
@@ -0,0 +1,199 @@
|
|
1
|
+
module RatPack
|
2
|
+
module Forms
|
3
|
+
# def error_messages_for(obj = nil, opts = {})
|
4
|
+
# current_form_context.error_messages_for(obj, opts[:error_class] || "error",
|
5
|
+
# opts[:build_li] || "<li>%s</li>",
|
6
|
+
# opts[:header] || "<h2>Form submission failed because of %s problem%s</h2>",
|
7
|
+
# opts.key?(:before) ? opts[:before] : true)
|
8
|
+
# end
|
9
|
+
|
10
|
+
%w(text password hidden file).each do |kind|
|
11
|
+
self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
12
|
+
def #{kind}_field(attrs)
|
13
|
+
update_unbound_controls(attrs, "#{kind}")
|
14
|
+
label = "#{kind}" == "hidden" ? "" : unbound_label(attrs)
|
15
|
+
label + self_closing_tag(:input, {:type => "#{kind}"}.merge(attrs))
|
16
|
+
end
|
17
|
+
RUBY
|
18
|
+
end
|
19
|
+
|
20
|
+
def check_box(attrs)
|
21
|
+
update_unbound_controls(attrs, "checkbox")
|
22
|
+
if attrs.delete(:boolean)
|
23
|
+
on, off = attrs.delete(:on), attrs.delete(:off)
|
24
|
+
unbound_hidden_field(:name => attrs[:name], :value => off) <<
|
25
|
+
self_closing_tag(:input, {:type => "checkbox", :value => on}.merge(attrs)) + unbound_label(attrs)
|
26
|
+
else
|
27
|
+
self_closing_tag(:input, {:type => "checkbox"}.merge(attrs)) + unbound_label(attrs)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def radio_button(attrs)
|
32
|
+
update_unbound_controls(attrs, "radio")
|
33
|
+
self_closing_tag(:input, {:type => "radio"}.merge(attrs)) + unbound_label(attrs)
|
34
|
+
end
|
35
|
+
|
36
|
+
def radio_group(arr, attrs = {})
|
37
|
+
arr.map do |ind_attrs|
|
38
|
+
ind_attrs = {:value => ind_attrs} unless ind_attrs.is_a?(Hash)
|
39
|
+
joined = attrs.merge(ind_attrs)
|
40
|
+
joined.merge!(:label => joined[:label] || joined[:value])
|
41
|
+
radio_button(joined)
|
42
|
+
end.join
|
43
|
+
end
|
44
|
+
|
45
|
+
def text_area(contents, attrs)
|
46
|
+
update_unbound_controls(attrs, "text_area")
|
47
|
+
unbound_label(attrs) + tag(:textarea, contents, attrs)
|
48
|
+
end
|
49
|
+
|
50
|
+
def label(contents, attrs = {})
|
51
|
+
if contents
|
52
|
+
if contents.is_a?(Hash)
|
53
|
+
label_attrs = contents
|
54
|
+
contents = label_attrs.delete(:title)
|
55
|
+
else
|
56
|
+
label_attrs = attrs
|
57
|
+
end
|
58
|
+
tag(:label, contents, label_attrs)
|
59
|
+
else
|
60
|
+
""
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def select(attrs = {})
|
65
|
+
update_unbound_controls(attrs, "select")
|
66
|
+
attrs[:name] << "[]" if attrs[:multiple] && !(attrs[:name] =~ /\[\]$/)
|
67
|
+
tag(:select, options_for(attrs), attrs)
|
68
|
+
end
|
69
|
+
|
70
|
+
def button(contents, attrs)
|
71
|
+
update_unbound_controls(attrs, "button")
|
72
|
+
tag(:button, contents, attrs)
|
73
|
+
end
|
74
|
+
|
75
|
+
def submit(value, attrs)
|
76
|
+
attrs[:type] ||= "submit"
|
77
|
+
attrs[:name] ||= "submit"
|
78
|
+
attrs[:value] ||= value
|
79
|
+
update_unbound_controls(attrs, "submit")
|
80
|
+
self_closing_tag(:input, attrs)
|
81
|
+
end
|
82
|
+
|
83
|
+
# def form(attrs = {}, &blk)
|
84
|
+
# captured = @origin.capture(&blk)
|
85
|
+
# fake_method_tag = process_form_attrs(attrs)
|
86
|
+
# tag(:form, fake_method_tag + captured, attrs)
|
87
|
+
# end
|
88
|
+
#
|
89
|
+
# def fieldset(attrs, &blk)
|
90
|
+
# captured = @origin.capture(&blk)
|
91
|
+
# legend = (l_attr = attrs.delete(:legend)) ? tag(:legend, l_attr) : ""
|
92
|
+
# tag(:fieldset, legend + captured, attrs)
|
93
|
+
# end
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
def process_form_attrs(attrs)
|
98
|
+
method = attrs[:method] || :post
|
99
|
+
attrs[:enctype] = "multipart/form-data" if attrs.delete(:multipart) || @multipart
|
100
|
+
method == :post || method == :get ? "" : fake_out_method(attrs, method)
|
101
|
+
end
|
102
|
+
|
103
|
+
# This can be overridden to use another method to fake out methods
|
104
|
+
def fake_out_method(attrs, method)
|
105
|
+
self_closing_tag(:input, :type => "hidden", :name => "_method", :value => method)
|
106
|
+
end
|
107
|
+
|
108
|
+
def update_unbound_controls(attrs, type)
|
109
|
+
case type
|
110
|
+
when "checkbox"
|
111
|
+
update_unbound_check_box(attrs)
|
112
|
+
when "radio"
|
113
|
+
update_unbound_radio_button(attrs)
|
114
|
+
when "file"
|
115
|
+
@multipart = true
|
116
|
+
when "text","password"
|
117
|
+
attrs[:class] = "text"
|
118
|
+
end
|
119
|
+
|
120
|
+
attrs[:disabled] ? attrs[:disabled] = "disabled" : attrs.delete(:disabled)
|
121
|
+
end
|
122
|
+
|
123
|
+
def unbound_label(attrs = {})
|
124
|
+
if attrs[:id]
|
125
|
+
label_attrs = {:for => attrs[:id]}
|
126
|
+
elsif attrs[:name]
|
127
|
+
label_attrs = {:for => attrs[:name]}
|
128
|
+
else
|
129
|
+
label_attrs = {}
|
130
|
+
end
|
131
|
+
|
132
|
+
label_option = attrs.delete(:label)
|
133
|
+
if label_option.is_a? Hash
|
134
|
+
label(label_attrs.merge(label_option))
|
135
|
+
else
|
136
|
+
label(label_option, label_attrs)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def update_unbound_check_box(attrs)
|
141
|
+
boolean = attrs[:boolean] || (attrs[:on] && attrs[:off]) ? true : false
|
142
|
+
|
143
|
+
case
|
144
|
+
when attrs.key?(:on) ^ attrs.key?(:off)
|
145
|
+
raise ArgumentError, ":on and :off must be specified together"
|
146
|
+
when (attrs[:boolean] == false) && (attrs.key?(:on))
|
147
|
+
raise ArgumentError, ":boolean => false cannot be used with :on and :off"
|
148
|
+
when boolean && attrs.key?(:value)
|
149
|
+
raise ArgumentError, ":value can't be used with a boolean checkbox"
|
150
|
+
end
|
151
|
+
|
152
|
+
if attrs[:boolean] = boolean
|
153
|
+
attrs[:on] ||= "1"; attrs[:off] ||= "0"
|
154
|
+
end
|
155
|
+
|
156
|
+
attrs[:checked] = "checked" if attrs.delete(:checked)
|
157
|
+
end
|
158
|
+
|
159
|
+
def update_unbound_radio_button(attrs)
|
160
|
+
attrs[:checked] = "checked" if attrs.delete(:checked)
|
161
|
+
end
|
162
|
+
|
163
|
+
def options_for(attrs)
|
164
|
+
blank, prompt = attrs.delete(:include_blank), attrs.delete(:prompt)
|
165
|
+
b = blank || prompt ? tag(:option, prompt || "", :value => "") : ""
|
166
|
+
|
167
|
+
# yank out the options attrs
|
168
|
+
collection, selected, text_method, value_method =
|
169
|
+
attrs.extract!(:collection, :selected, :text_method, :value_method)
|
170
|
+
|
171
|
+
# if the collection is a Hash, optgroups are a-coming
|
172
|
+
if collection.is_a?(Hash)
|
173
|
+
([b] + collection.map do |g,col|
|
174
|
+
tag(:optgroup, options(col, text_method, value_method, selected), :label => g)
|
175
|
+
end).join
|
176
|
+
else
|
177
|
+
options(collection || [], text_method, value_method, selected, b)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def options(col, text_meth, value_meth, sel, b = nil)
|
182
|
+
([b] + col.map do |item|
|
183
|
+
text_meth = text_meth && item.respond_to?(text_meth) ? text_meth : :last
|
184
|
+
value_meth = value_meth && item.respond_to?(value_meth) ? value_meth : :first
|
185
|
+
|
186
|
+
text = item.is_a?(String) ? item : item.send(text_meth)
|
187
|
+
value = item.is_a?(String) ? item : item.send(value_meth)
|
188
|
+
|
189
|
+
option_attrs = {:value => value}
|
190
|
+
if sel.is_a?(Array)
|
191
|
+
option_attrs.merge!(:selected => "selected") if value.in? sel
|
192
|
+
else
|
193
|
+
option_attrs.merge!(:selected => "selected") if value == sel
|
194
|
+
end
|
195
|
+
tag(:option, text, option_attrs)
|
196
|
+
end).join
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module RatPack
|
2
|
+
module HtmlHelpers
|
3
|
+
def link_to(name, url, options = {})
|
4
|
+
defaults = {:href => url}
|
5
|
+
tag(:a,name,defaults.merge(options))
|
6
|
+
end
|
7
|
+
|
8
|
+
def image_tag(file,attrs = {})
|
9
|
+
defaults = {:src => "/images/#{file}"}
|
10
|
+
self_closing_tag(:img,defaults.merge(options))
|
11
|
+
end
|
12
|
+
|
13
|
+
def css_link(name, options = {})
|
14
|
+
name = "/stylesheets/#{name}.css" unless remote_asset?(name)
|
15
|
+
defaults = {:href => name, :media => "screen",
|
16
|
+
:rel => "stylesheet", :type => "text/css"}
|
17
|
+
self_closing_tag(:link,defaults.merge(options))
|
18
|
+
end
|
19
|
+
|
20
|
+
def js_link(name, options = {})
|
21
|
+
name = "/javascripts/#{name}.js" unless remote_asset?(name)
|
22
|
+
defaults = {:src => name, :type => "text/javascript"}
|
23
|
+
tag(:script,defaults.merge(options))
|
24
|
+
end
|
25
|
+
|
26
|
+
def partial(template, opts = {})
|
27
|
+
template_engine = opts.delete(:template) || :erb
|
28
|
+
opts.merge!(:layout => false)
|
29
|
+
template = :"partials/#{template}"
|
30
|
+
if collection = opts.delete(:collection) then
|
31
|
+
collection.inject([]) do |buffer, member|
|
32
|
+
buffer << send(template_engine,template, opts.merge(
|
33
|
+
:layout => false,
|
34
|
+
:locals => {template.to_sym => member}
|
35
|
+
)
|
36
|
+
)
|
37
|
+
end.join("\n")
|
38
|
+
else
|
39
|
+
send(template_engine,template, opts)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def remote_asset?(uri)
|
46
|
+
uri =~ %r[^\w+://.+]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module RatPack
|
2
|
+
module Routes
|
3
|
+
def subdomains(tld_len=1) # we set tld_len to 1, use 2 for co.uk or similar
|
4
|
+
subdomain_regex = /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/
|
5
|
+
@subdomains ||= if (request.host.nil? ||subdomain_regex.match(request.host))
|
6
|
+
request.host.split('.')[0...(1 - tld_len - 2)]
|
7
|
+
else
|
8
|
+
[]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/ratpack/tag.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
module RatPack
|
2
|
+
module Tag
|
3
|
+
def tag(name, contents = nil, attrs = {}, &block)
|
4
|
+
attrs, contents = contents, nil if contents.is_a?(Hash)
|
5
|
+
contents = capture(&block) if block_given?
|
6
|
+
open_tag(name, attrs) + contents.to_s + close_tag(name)
|
7
|
+
end
|
8
|
+
|
9
|
+
def open_tag(name, attrs = nil)
|
10
|
+
"<#{name}#{' ' + attrs.to_html_attributes unless attrs.blank?}>"
|
11
|
+
end
|
12
|
+
|
13
|
+
def close_tag(name)
|
14
|
+
"</#{name}>"
|
15
|
+
end
|
16
|
+
|
17
|
+
def self_closing_tag(name, attrs = nil)
|
18
|
+
"<#{name}#{' ' + attrs.to_html_attributes if attrs && !attrs.empty?}/>"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/ratpack.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'extlib'
|
3
|
+
|
4
|
+
module RatPack
|
5
|
+
VERSION = '0.0.1'
|
6
|
+
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
|
7
|
+
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
|
8
|
+
|
9
|
+
def self.version
|
10
|
+
VERSION
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.libpath( *args )
|
14
|
+
args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.path( *args )
|
18
|
+
args.empty? ? PATH : ::File.join(PATH, args.flatten)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.require_all_libs_relative_to( fname, dir = nil )
|
22
|
+
dir ||= ::File.basename(fname, '.*')
|
23
|
+
search_me = ::File.expand_path(
|
24
|
+
::File.join(::File.dirname(fname), dir, '**', '*.rb'))
|
25
|
+
|
26
|
+
Dir.glob(search_me).sort.each {|rb| require rb}
|
27
|
+
end
|
28
|
+
end # module VelvetRope
|
29
|
+
|
30
|
+
RatPack.require_all_libs_relative_to(__FILE__)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Sinatra
|
2
|
+
module Ratpack
|
3
|
+
module Helpers
|
4
|
+
include RatPack::Tag
|
5
|
+
include RatPack::HtmlHelpers
|
6
|
+
include RatPack::Forms
|
7
|
+
include RatPack::Routes
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.registered(app)
|
11
|
+
puts 'loading ratpack'
|
12
|
+
app.helpers Helpers
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
register Ratpack
|
17
|
+
end # Sinatra
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: BrianTheCoder-ratpack
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- brianthecoder
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-04-07 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: wbsmith83@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.rdoc
|
24
|
+
- LICENSE
|
25
|
+
files:
|
26
|
+
- README.rdoc
|
27
|
+
- VERSION.yml
|
28
|
+
- lib/ratpack
|
29
|
+
- lib/ratpack/forms.rb
|
30
|
+
- lib/ratpack/html_helpers.rb
|
31
|
+
- lib/ratpack/routes.rb
|
32
|
+
- lib/ratpack/tag.rb
|
33
|
+
- lib/ratpack.rb
|
34
|
+
- lib/sinatra
|
35
|
+
- lib/sinatra/ratpack.rb
|
36
|
+
- test/ratpack_test.rb
|
37
|
+
- test/test_helper.rb
|
38
|
+
- LICENSE
|
39
|
+
has_rdoc: true
|
40
|
+
homepage: http://github.com/BrianTheCoder/ratpack
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options:
|
43
|
+
- --inline-source
|
44
|
+
- --charset=UTF-8
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: "0"
|
52
|
+
version:
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
version:
|
59
|
+
requirements: []
|
60
|
+
|
61
|
+
rubyforge_project:
|
62
|
+
rubygems_version: 1.2.0
|
63
|
+
signing_key:
|
64
|
+
specification_version: 2
|
65
|
+
summary: A collection of helpers I wanted for sinatra, thought I'd share
|
66
|
+
test_files: []
|
67
|
+
|