ramaze 0.0.6
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/Rakefile +360 -0
- data/bin/ramaze +152 -0
- data/doc/CHANGELOG +2021 -0
- data/doc/COPYING +56 -0
- data/doc/COPYING.ja +51 -0
- data/doc/README +275 -0
- data/doc/TODO +33 -0
- data/doc/allison/LICENSE +184 -0
- data/doc/allison/README +37 -0
- data/doc/allison/allison.css +300 -0
- data/doc/allison/allison.gif +0 -0
- data/doc/allison/allison.js +307 -0
- data/doc/allison/allison.rb +287 -0
- data/doc/allison/cache/BODY +588 -0
- data/doc/allison/cache/CLASS_INDEX +4 -0
- data/doc/allison/cache/CLASS_PAGE +1 -0
- data/doc/allison/cache/FILE_INDEX +4 -0
- data/doc/allison/cache/FILE_PAGE +1 -0
- data/doc/allison/cache/FONTS +1 -0
- data/doc/allison/cache/FR_INDEX_BODY +1 -0
- data/doc/allison/cache/IMGPATH +1 -0
- data/doc/allison/cache/INDEX +1 -0
- data/doc/allison/cache/JAVASCRIPT +307 -0
- data/doc/allison/cache/METHOD_INDEX +4 -0
- data/doc/allison/cache/METHOD_LIST +1 -0
- data/doc/allison/cache/SRC_PAGE +1 -0
- data/doc/allison/cache/STYLE +322 -0
- data/doc/allison/cache/URL +1 -0
- data/examples/blog/main.rb +16 -0
- data/examples/blog/public/screen.css +106 -0
- data/examples/blog/src/controller.rb +50 -0
- data/examples/blog/src/element.rb +53 -0
- data/examples/blog/src/model.rb +29 -0
- data/examples/blog/template/edit.xhtml +6 -0
- data/examples/blog/template/index.xhtml +24 -0
- data/examples/blog/template/new.xhtml +5 -0
- data/examples/blog/template/view.xhtml +15 -0
- data/examples/blog/test/tc_entry.rb +18 -0
- data/examples/caching.rb +23 -0
- data/examples/element.rb +40 -0
- data/examples/hello.rb +23 -0
- data/examples/simple.rb +60 -0
- data/examples/templates/template/external.haml +21 -0
- data/examples/templates/template/external.liquid +28 -0
- data/examples/templates/template/external.mab +27 -0
- data/examples/templates/template/external.rhtml +29 -0
- data/examples/templates/template/external.rmze +24 -0
- data/examples/templates/template_erubis.rb +50 -0
- data/examples/templates/template_haml.rb +48 -0
- data/examples/templates/template_liquid.rb +64 -0
- data/examples/templates/template_markaby.rb +52 -0
- data/examples/templates/template_ramaze.rb +49 -0
- data/examples/whywiki/main.rb +56 -0
- data/examples/whywiki/template/edit.xhtml +14 -0
- data/examples/whywiki/template/show.xhtml +17 -0
- data/lib/proto/conf/benchmark.yaml +35 -0
- data/lib/proto/conf/debug.yaml +34 -0
- data/lib/proto/conf/live.yaml +33 -0
- data/lib/proto/conf/silent.yaml +31 -0
- data/lib/proto/conf/stage.yaml +33 -0
- data/lib/proto/main.rb +18 -0
- data/lib/proto/public/404.jpg +0 -0
- data/lib/proto/public/css/coderay.css +105 -0
- data/lib/proto/public/css/ramaze_error.css +42 -0
- data/lib/proto/public/error.xhtml +74 -0
- data/lib/proto/public/favicon.ico +0 -0
- data/lib/proto/public/js/jquery.js +1923 -0
- data/lib/proto/public/ramaze.png +0 -0
- data/lib/proto/src/controller/main.rb +7 -0
- data/lib/proto/src/element/page.rb +16 -0
- data/lib/proto/src/model.rb +5 -0
- data/lib/proto/template/index.xhtml +6 -0
- data/lib/ramaze.rb +317 -0
- data/lib/ramaze/adapter/mongrel.rb +111 -0
- data/lib/ramaze/adapter/webrick.rb +161 -0
- data/lib/ramaze/cache.rb +11 -0
- data/lib/ramaze/cache/memcached.rb +52 -0
- data/lib/ramaze/cache/memory.rb +6 -0
- data/lib/ramaze/cache/yaml_store.rb +37 -0
- data/lib/ramaze/controller.rb +10 -0
- data/lib/ramaze/dispatcher.rb +315 -0
- data/lib/ramaze/error.rb +11 -0
- data/lib/ramaze/gestalt.rb +108 -0
- data/lib/ramaze/global.rb +120 -0
- data/lib/ramaze/helper.rb +32 -0
- data/lib/ramaze/helper/aspect.rb +189 -0
- data/lib/ramaze/helper/auth.rb +120 -0
- data/lib/ramaze/helper/cache.rb +52 -0
- data/lib/ramaze/helper/feed.rb +135 -0
- data/lib/ramaze/helper/form.rb +204 -0
- data/lib/ramaze/helper/link.rb +80 -0
- data/lib/ramaze/helper/redirect.rb +48 -0
- data/lib/ramaze/helper/stack.rb +67 -0
- data/lib/ramaze/http_status.rb +66 -0
- data/lib/ramaze/inform.rb +166 -0
- data/lib/ramaze/snippets.rb +5 -0
- data/lib/ramaze/snippets/hash/keys_to_sym.rb +19 -0
- data/lib/ramaze/snippets/kernel/aquire.rb +22 -0
- data/lib/ramaze/snippets/kernel/autoreload.rb +79 -0
- data/lib/ramaze/snippets/kernel/caller_lines.rb +58 -0
- data/lib/ramaze/snippets/kernel/constant.rb +24 -0
- data/lib/ramaze/snippets/kernel/rescue_require.rb +12 -0
- data/lib/ramaze/snippets/kernel/self_method.rb +41 -0
- data/lib/ramaze/snippets/kernel/silently.rb +13 -0
- data/lib/ramaze/snippets/object/traits.rb +60 -0
- data/lib/ramaze/snippets/openstruct/temp.rb +10 -0
- data/lib/ramaze/snippets/string/DIVIDE.rb +16 -0
- data/lib/ramaze/snippets/string/camel_case.rb +14 -0
- data/lib/ramaze/snippets/string/snake_case.rb +12 -0
- data/lib/ramaze/snippets/symbol/to_proc.rb +14 -0
- data/lib/ramaze/snippets/thread/deadQUESTIONMARK.rb +11 -0
- data/lib/ramaze/store/default.rb +48 -0
- data/lib/ramaze/template.rb +102 -0
- data/lib/ramaze/template/amrita2.rb +40 -0
- data/lib/ramaze/template/erubis.rb +58 -0
- data/lib/ramaze/template/haml.rb +65 -0
- data/lib/ramaze/template/haml/actionview_stub.rb +20 -0
- data/lib/ramaze/template/liquid.rb +74 -0
- data/lib/ramaze/template/markaby.rb +68 -0
- data/lib/ramaze/template/ramaze.rb +177 -0
- data/lib/ramaze/template/ramaze/element.rb +166 -0
- data/lib/ramaze/template/ramaze/morpher.rb +156 -0
- data/lib/ramaze/tool/create.rb +70 -0
- data/lib/ramaze/tool/tidy.rb +71 -0
- data/lib/ramaze/trinity.rb +38 -0
- data/lib/ramaze/trinity/request.rb +244 -0
- data/lib/ramaze/trinity/response.rb +41 -0
- data/lib/ramaze/trinity/session.rb +129 -0
- data/lib/ramaze/version.rb +14 -0
- data/spec/spec_all.rb +73 -0
- data/spec/spec_helper.rb +215 -0
- data/spec/tc_adapter_mongrel.rb +24 -0
- data/spec/tc_adapter_webrick.rb +22 -0
- data/spec/tc_cache.rb +79 -0
- data/spec/tc_controller.rb +39 -0
- data/spec/tc_element.rb +100 -0
- data/spec/tc_error.rb +23 -0
- data/spec/tc_gestalt.rb +90 -0
- data/spec/tc_global.rb +46 -0
- data/spec/tc_helper_aspect.rb +65 -0
- data/spec/tc_helper_auth.rb +61 -0
- data/spec/tc_helper_cache.rb +81 -0
- data/spec/tc_helper_feed.rb +129 -0
- data/spec/tc_helper_form.rb +146 -0
- data/spec/tc_helper_link.rb +58 -0
- data/spec/tc_helper_redirect.rb +51 -0
- data/spec/tc_helper_stack.rb +55 -0
- data/spec/tc_morpher.rb +90 -0
- data/spec/tc_params.rb +84 -0
- data/spec/tc_request.rb +111 -0
- data/spec/tc_session.rb +56 -0
- data/spec/tc_store.rb +25 -0
- data/spec/tc_template_amrita2.rb +34 -0
- data/spec/tc_template_erubis.rb +41 -0
- data/spec/tc_template_haml.rb +44 -0
- data/spec/tc_template_liquid.rb +98 -0
- data/spec/tc_template_markaby.rb +74 -0
- data/spec/tc_template_ramaze.rb +54 -0
- data/spec/tc_tidy.rb +14 -0
- data/spec/template/amrita2/data.html +6 -0
- data/spec/template/amrita2/index.html +1 -0
- data/spec/template/amrita2/sum.html +1 -0
- data/spec/template/erubis/sum.rhtml +1 -0
- data/spec/template/haml/index.haml +5 -0
- data/spec/template/haml/with_vars.haml +4 -0
- data/spec/template/liquid/index.liquid +1 -0
- data/spec/template/liquid/products.liquid +45 -0
- data/spec/template/markaby/external.mab +8 -0
- data/spec/template/markaby/sum.mab +1 -0
- data/spec/template/ramaze/file_only.rmze +1 -0
- data/spec/template/ramaze/index.rmze +1 -0
- data/spec/template/ramaze/nested.rmze +1 -0
- data/spec/template/ramaze/sum.rmze +1 -0
- metadata +317 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
|
|
2
|
+
# All files in this distribution are subject to the terms of the Ruby license.
|
|
3
|
+
|
|
4
|
+
require 'digest/sha1'
|
|
5
|
+
|
|
6
|
+
module Ramaze
|
|
7
|
+
|
|
8
|
+
# A really, really, totally stupid way to do authentication. It has no
|
|
9
|
+
# roles and only a single password without usernames.
|
|
10
|
+
#
|
|
11
|
+
# It is intended to be a simple way to protect various partions of a page
|
|
12
|
+
# when you start working on it. Also it is a nice way to see how you could
|
|
13
|
+
# implement your own authentication.
|
|
14
|
+
|
|
15
|
+
module AuthHelper
|
|
16
|
+
def self.included(klass)
|
|
17
|
+
klass.class_eval do
|
|
18
|
+
helper :aspect, :stack
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# The default Element to use (if any)
|
|
23
|
+
|
|
24
|
+
AUTH_ELEMENT = 'Page'
|
|
25
|
+
|
|
26
|
+
# action for login, takes a password
|
|
27
|
+
# ( ?password=passwort or /login/passwort or via a form )
|
|
28
|
+
# if no password given, shows a simple form to input it.
|
|
29
|
+
|
|
30
|
+
def login
|
|
31
|
+
if check_auth(request['username'], request['password'])
|
|
32
|
+
session[:logged_in] = true
|
|
33
|
+
inside_stack? ? answer : redirect( R(self) )
|
|
34
|
+
else
|
|
35
|
+
%{
|
|
36
|
+
<#{AUTH_ELEMENT}>
|
|
37
|
+
<form method="POST" action="#{R(self, :login)}"
|
|
38
|
+
<ul style="list-style:none;">
|
|
39
|
+
<li>Username: <input type="text" name="username" /></li>
|
|
40
|
+
<li>Password: <input type="password" name="password" /></li>
|
|
41
|
+
<li><input type="submit" /></li>
|
|
42
|
+
</ul>
|
|
43
|
+
</form>
|
|
44
|
+
</#{AUTH_ELEMENT}>
|
|
45
|
+
}
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# clear the session and redirect to the index action of the mapping of the
|
|
50
|
+
# current controller.
|
|
51
|
+
|
|
52
|
+
def logout
|
|
53
|
+
session.clear
|
|
54
|
+
redirect_referer
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
# call( R(self, :login) ) if not logged in
|
|
60
|
+
|
|
61
|
+
def login_required
|
|
62
|
+
call(R(self, :login)) unless logged_in?
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# checks if the user is already logged in.
|
|
66
|
+
# session[:logged_in] is not nil/false
|
|
67
|
+
|
|
68
|
+
def logged_in?
|
|
69
|
+
!!session[:logged_in]
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# check the authentication (username and password) against the auth_table.
|
|
73
|
+
#
|
|
74
|
+
# auth_table is a trait, it may be the name of a method, a Proc or a simple
|
|
75
|
+
# Hash.
|
|
76
|
+
# If it is neither of the above it has at least to respond to #[]
|
|
77
|
+
# which will pass it the username as key and it should answer with the
|
|
78
|
+
# password as a SHA1.hexdigest.
|
|
79
|
+
#
|
|
80
|
+
# The method and Proc are both called on demand.
|
|
81
|
+
#
|
|
82
|
+
# If you want to change the way the password is hashed, change
|
|
83
|
+
# trait[:auth_hashify]
|
|
84
|
+
#
|
|
85
|
+
# The default looks like:
|
|
86
|
+
# lambda{ |pass| Digest::SHA1.hexdigest(pass.to_s) }
|
|
87
|
+
#
|
|
88
|
+
# As with the auth_table, this has to be an object that responds to #[]
|
|
89
|
+
#
|
|
90
|
+
# If you want all your controllers to use the same mechanism set the trait
|
|
91
|
+
# on one of the ancestors, the traits are looked up by #ancestral_trait
|
|
92
|
+
#
|
|
93
|
+
# Examples:
|
|
94
|
+
#
|
|
95
|
+
# # The method to be called.
|
|
96
|
+
# trait :auth_table => :auth_table
|
|
97
|
+
# trait :auth_tagle => 'auth_table'
|
|
98
|
+
#
|
|
99
|
+
# # Lambda that will be called upon demand
|
|
100
|
+
# trait :auth_table => lambda{ {'manveru' => SHA1.hexdigest 'password'} }
|
|
101
|
+
#
|
|
102
|
+
# # Hash holding the data.
|
|
103
|
+
# trait :auth_table => {'manveru' => SHA1.hexdigest('password')}
|
|
104
|
+
|
|
105
|
+
def check_auth user, pass
|
|
106
|
+
auth_table = ancestral_trait[:auth_table] ||= {}
|
|
107
|
+
|
|
108
|
+
auth_table = method(auth_table) if auth_table.is_a?(Symbol)
|
|
109
|
+
auth_table = method(auth_table) if auth_table.respond_to?(:to_str)
|
|
110
|
+
auth_table = auth_table.call if auth_table.respond_to?(:call)
|
|
111
|
+
|
|
112
|
+
default_hashify = lambda{ |pass| Digest::SHA1.hexdigest(pass.to_s) }
|
|
113
|
+
|
|
114
|
+
hashify = (ancestral_trait[:auth_hashify] ||= default_hashify)
|
|
115
|
+
password = hashify[pass.to_s]
|
|
116
|
+
|
|
117
|
+
auth_table[user.to_s] == password
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
|
|
2
|
+
# All files in this distribution are subject to the terms of the Ruby license.
|
|
3
|
+
module Ramaze
|
|
4
|
+
module CacheHelper
|
|
5
|
+
private
|
|
6
|
+
|
|
7
|
+
# a simple cache for values based on Global.cache
|
|
8
|
+
|
|
9
|
+
def value_cache
|
|
10
|
+
@@cache ||= Global.cache.new
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# forget about one cached action
|
|
14
|
+
|
|
15
|
+
def uncache action
|
|
16
|
+
Global.cached_actions[self.class].each do |e|
|
|
17
|
+
e.include?(action.to_s)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# uncache all actions
|
|
22
|
+
|
|
23
|
+
def uncache_all
|
|
24
|
+
Global.cached_actions.delete(self.class)
|
|
25
|
+
end
|
|
26
|
+
alias uncache_all_actions uncache_all
|
|
27
|
+
|
|
28
|
+
# cache all given methods
|
|
29
|
+
|
|
30
|
+
def cache(*actions)
|
|
31
|
+
self.class.cache(*actions)
|
|
32
|
+
end
|
|
33
|
+
alias cache_actions cache
|
|
34
|
+
|
|
35
|
+
# define the cache class-method on inclusion
|
|
36
|
+
|
|
37
|
+
def self.included(klass)
|
|
38
|
+
klass.class_eval do
|
|
39
|
+
class << self
|
|
40
|
+
|
|
41
|
+
# mark actions for caching
|
|
42
|
+
|
|
43
|
+
def cache(*actions)
|
|
44
|
+
Global.cache_actions[self].merge(*actions.flatten.map{|a| a.to_s })
|
|
45
|
+
end
|
|
46
|
+
alias cache_actions cache
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
|
|
2
|
+
# All files in this distribution are subject to the terms of the Ruby license.
|
|
3
|
+
|
|
4
|
+
module Ramaze
|
|
5
|
+
module FeedHelper
|
|
6
|
+
|
|
7
|
+
# just a stub, for the moment, doing nothing more than calling
|
|
8
|
+
# #to_xml on the object you pass
|
|
9
|
+
|
|
10
|
+
def feed object
|
|
11
|
+
object.to_xml
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
module ReFeed
|
|
17
|
+
|
|
18
|
+
# Does a couple of things on include.
|
|
19
|
+
#
|
|
20
|
+
# defines #xml_accessor, which in turn offers a way to define
|
|
21
|
+
# both an attr_accessor and xml-annotation.
|
|
22
|
+
# xml_accessor :name, :age
|
|
23
|
+
#
|
|
24
|
+
# defines #xml, a little DSLy way to add an attribute that
|
|
25
|
+
# is later used to generate/read XML
|
|
26
|
+
# xml :name, :age
|
|
27
|
+
#
|
|
28
|
+
# defines #from_xml, which takes XML and maps the structure of the
|
|
29
|
+
# XML to your instances accessors.
|
|
30
|
+
# Foo.new.from_xml('<name>manveru</name><age>22</age>')
|
|
31
|
+
# # #<Foo @name='manveru', @age=22>
|
|
32
|
+
|
|
33
|
+
def self.included(klass)
|
|
34
|
+
klass.class_eval do
|
|
35
|
+
const_set('XML_ATTRIBUTES', {})
|
|
36
|
+
|
|
37
|
+
class << self
|
|
38
|
+
|
|
39
|
+
# Offers a way to define
|
|
40
|
+
# both an attr_accessor and xml-annotation.
|
|
41
|
+
# xml_accessor :name, :age
|
|
42
|
+
|
|
43
|
+
def xml_accessor(*args)
|
|
44
|
+
args = xml(*args)
|
|
45
|
+
attr_accessor(*args)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# A little DSLy way to add an attribute that
|
|
49
|
+
# is later used to generate/read XML
|
|
50
|
+
# xml :name, :age
|
|
51
|
+
|
|
52
|
+
def xml(*arguments)
|
|
53
|
+
args = []
|
|
54
|
+
hash = nil
|
|
55
|
+
klass = Object.const_get(self.to_s)
|
|
56
|
+
|
|
57
|
+
arguments.each do |arg|
|
|
58
|
+
if arg.respond_to?(:to_sym)
|
|
59
|
+
args << arg.to_sym
|
|
60
|
+
elsif arg.respond_to?(:to_hash)
|
|
61
|
+
hash = arg
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
args.each do |arg|
|
|
66
|
+
klass::XML_ATTRIBUTES[arg] = hash
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Which takes XML and maps the structure of the
|
|
71
|
+
# XML to your instances accessors.
|
|
72
|
+
# Foo.new.from_xml('<name>manveru</name><age>22</age>')
|
|
73
|
+
# # #<Foo @name='manveru', @age=22>
|
|
74
|
+
|
|
75
|
+
def from_xml(text)
|
|
76
|
+
instance = self.new
|
|
77
|
+
|
|
78
|
+
require 'hpricot'
|
|
79
|
+
|
|
80
|
+
xml = Hpricot(text.to_s)
|
|
81
|
+
attributes = instance.xml_attributes
|
|
82
|
+
|
|
83
|
+
attributes.each do |attribute, opts|
|
|
84
|
+
value = xml.at(attribute)
|
|
85
|
+
instance.send("#{attribute}=", value.inner_html) if value
|
|
86
|
+
end
|
|
87
|
+
instance
|
|
88
|
+
rescue LoadError => ex
|
|
89
|
+
error ex
|
|
90
|
+
ensure
|
|
91
|
+
instance
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# return the XML_ATTRIBUTES of self.class
|
|
98
|
+
|
|
99
|
+
def xml_attributes
|
|
100
|
+
self.class::XML_ATTRIBUTES
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# convert this instance to XML
|
|
104
|
+
|
|
105
|
+
def to_xml
|
|
106
|
+
name = self.class.name
|
|
107
|
+
xml = xml_attributes.map do |key, opts|
|
|
108
|
+
value = send(key)
|
|
109
|
+
|
|
110
|
+
next unless value
|
|
111
|
+
next if (opts[:type] == :attribute rescue false)
|
|
112
|
+
|
|
113
|
+
if opts and not opts.empty?
|
|
114
|
+
case opts[:type]
|
|
115
|
+
when nil, :text : "<#{key}>#{value}</#{key}>"
|
|
116
|
+
when :cdata : "<#{key}><![CDATA[#{value}]]></#{key}>"
|
|
117
|
+
when :collection : value.map{|v| v.to_xml }
|
|
118
|
+
end
|
|
119
|
+
elsif value.respond_to?(:to_xml)
|
|
120
|
+
value.to_xml
|
|
121
|
+
elsif value.respond_to?(:all?) and value.all?{|v| v.respond_to?(:to_xml) }
|
|
122
|
+
value.map{|v| v.to_xml }
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
attributes = xml_attributes.select{|k, o| o && o[:type] == :attribute}
|
|
127
|
+
attributes.map!{|k, o| %{#{k}="#{send(k)}"} }
|
|
128
|
+
|
|
129
|
+
unless attributes or attributes.empty?
|
|
130
|
+
"<#{name}>#{xml}</#{name}>"
|
|
131
|
+
else
|
|
132
|
+
"<#{name} #{attributes.join(' ')}><#{xml}></#{name}>"
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
|
|
2
|
+
# All files in this distribution are subject to the terms of the Ruby license.
|
|
3
|
+
|
|
4
|
+
module Ramaze
|
|
5
|
+
module FormHelper
|
|
6
|
+
|
|
7
|
+
# Mapping different classes to an specific method on FormHelper::Control.
|
|
8
|
+
|
|
9
|
+
ClassMap = {
|
|
10
|
+
String => :text,
|
|
11
|
+
Time => :time,
|
|
12
|
+
Date => :date,
|
|
13
|
+
Fixnum => :number,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
# Create the contents of a <form> for Og-objects.
|
|
17
|
+
# This can be an instance or the class itself. Depending if you
|
|
18
|
+
# want to edit an object or create a new one.
|
|
19
|
+
#
|
|
20
|
+
# Please note that the enclosing <form> itself is not (yet) generated.
|
|
21
|
+
#
|
|
22
|
+
# attributes that have no mapping in ClassMap are silently ignored.
|
|
23
|
+
|
|
24
|
+
def form obj, options = {}
|
|
25
|
+
default = {:deny => /oid/, :submit => true}
|
|
26
|
+
options = default.merge(options)
|
|
27
|
+
|
|
28
|
+
if obj.respond_to? :serializable_attributes
|
|
29
|
+
instance = obj.new
|
|
30
|
+
else
|
|
31
|
+
instance = obj
|
|
32
|
+
obj = obj.class
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
attributes = obj.serializable_attributes
|
|
36
|
+
out = []
|
|
37
|
+
|
|
38
|
+
chosen_attributes(attributes, options).each do |attribute|
|
|
39
|
+
|
|
40
|
+
o = OpenStruct.new :klass => obj.ann[attribute].class,
|
|
41
|
+
:value => (instance.send(attribute) rescue nil),
|
|
42
|
+
:name => attribute.to_s,
|
|
43
|
+
:title => (options.has_key?(attribute) ? options[attribute] : attribute)
|
|
44
|
+
|
|
45
|
+
control = obj.ann[attribute].control
|
|
46
|
+
control = ClassMap[o.klass] unless control.is_a?(Symbol)
|
|
47
|
+
|
|
48
|
+
out << Control.send(control, o) unless control.nil? or control == :none
|
|
49
|
+
end
|
|
50
|
+
if options[:submit] == true
|
|
51
|
+
out << %{<input type="submit" />}
|
|
52
|
+
elsif options[:submit]
|
|
53
|
+
out << %{<input type="submit" value="#{options[:submit]}" />}
|
|
54
|
+
end
|
|
55
|
+
out.join("<br />\n")
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# options #=>
|
|
59
|
+
# { :deny => /oid/ }
|
|
60
|
+
# { :deny => [/time/, /oid/]}
|
|
61
|
+
|
|
62
|
+
def chosen_attributes(attributes, options)
|
|
63
|
+
attributes.reject do |attribute|
|
|
64
|
+
attribute = attribute.to_s
|
|
65
|
+
[options[:deny]].flatten.find do |d|
|
|
66
|
+
first_comp = attribute =~ d rescue attribute == d
|
|
67
|
+
first_comp || attribute == d
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Home of all the methods that output a tag for a specific
|
|
73
|
+
# attribute.
|
|
74
|
+
# They take objects that respond to :value and :name, preferably
|
|
75
|
+
# an modified OpenStruct that responds to :temp to allow for easy
|
|
76
|
+
# forking. ( lib/ramaze/snippets/openstruct/temp.rb )
|
|
77
|
+
|
|
78
|
+
module Control
|
|
79
|
+
class << self
|
|
80
|
+
|
|
81
|
+
# A simple text-control, default to 0
|
|
82
|
+
|
|
83
|
+
def number o
|
|
84
|
+
o.value ||= 0
|
|
85
|
+
text(o)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# <input type="text" />
|
|
89
|
+
|
|
90
|
+
def text o
|
|
91
|
+
o.value ||= ""
|
|
92
|
+
tag = ''
|
|
93
|
+
tag << "#{o.title}: " if o.title
|
|
94
|
+
tag << %{<input type="text" name="#{o.name}" value="#{o.value}" />}
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# <textarea></textarea>
|
|
98
|
+
|
|
99
|
+
def textarea o
|
|
100
|
+
o.value ||= ""
|
|
101
|
+
%{<textarea name="#{o.name}">#{o.value}</textarea>}
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# compound of #date_day, #date_month, #date_year, #time_hour,
|
|
105
|
+
# #time_minute and #time_second
|
|
106
|
+
|
|
107
|
+
def time o
|
|
108
|
+
o.value ||= Time.now
|
|
109
|
+
[
|
|
110
|
+
date_day(o.temp(:value => o.value.day)),
|
|
111
|
+
date_month(o.temp(:value => o.value.month)),
|
|
112
|
+
date_year(o.temp(:value => o.value.year)),
|
|
113
|
+
time_hour(o.temp(:value => o.value.hour)),
|
|
114
|
+
time_minute(o.temp(:value => o.value.min)),
|
|
115
|
+
time_second(o.temp(:value => o.value.sec)),
|
|
116
|
+
].join("\n")
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# <select name="xxx[sec]">
|
|
120
|
+
# <option value="0">0</option>
|
|
121
|
+
# ...
|
|
122
|
+
# <option value="60">60</option>
|
|
123
|
+
# </select>
|
|
124
|
+
|
|
125
|
+
def time_second(o)
|
|
126
|
+
select(o.name + '[sec]', (0...60), o.value)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# <select name="xxx[min]">
|
|
130
|
+
# <option value="0">0</option>
|
|
131
|
+
# ...
|
|
132
|
+
# <option value="60">60</option>
|
|
133
|
+
# </select>
|
|
134
|
+
|
|
135
|
+
def time_minute(o)
|
|
136
|
+
select(o.name + '[min]', (0...60), o.value)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# <select name="xxx[hour]">
|
|
140
|
+
# <option value="1">1</option>
|
|
141
|
+
# ...
|
|
142
|
+
# <option value="23">23</option>
|
|
143
|
+
# </select>
|
|
144
|
+
|
|
145
|
+
def time_hour(o)
|
|
146
|
+
select(o.name + '[hour]', (0...23), o.value)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# compound of #date_day, #date_month and #date_year
|
|
150
|
+
|
|
151
|
+
def date o
|
|
152
|
+
o.value ||= Date.today
|
|
153
|
+
[
|
|
154
|
+
date_day(o.temp(:value => o.value.day)),
|
|
155
|
+
date_month(o.temp(:value => o.value.month)),
|
|
156
|
+
date_year(o.temp(:value => o.value.year)),
|
|
157
|
+
].join("\n")
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# <select name="xxx[day]">
|
|
161
|
+
# <option value="1">1</option>
|
|
162
|
+
# ...
|
|
163
|
+
# <option value="31">31</option>
|
|
164
|
+
# </select>
|
|
165
|
+
|
|
166
|
+
def date_day(o)
|
|
167
|
+
select(o.name + '[day]', (1..31), o.value)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# <select name="xxx[month]">
|
|
171
|
+
# <option value="1">1950</option>
|
|
172
|
+
# ...
|
|
173
|
+
# <option value="12">12</option>
|
|
174
|
+
# </select>
|
|
175
|
+
|
|
176
|
+
def date_month(o)
|
|
177
|
+
select(o.name + '[month]', (1..12), o.value)
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# <select name="xxx[year]">
|
|
181
|
+
# <option value="1950">1950</option>
|
|
182
|
+
# ...
|
|
183
|
+
# <option value="2050">2050</option>
|
|
184
|
+
# </select>
|
|
185
|
+
|
|
186
|
+
def date_year(o)
|
|
187
|
+
select(o.name + '[year]', (1950..2050), o.value)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# <select>
|
|
191
|
+
# <option></option>
|
|
192
|
+
# </select>
|
|
193
|
+
|
|
194
|
+
def select name, range, default
|
|
195
|
+
out = %{<select name="#{name}">\n}
|
|
196
|
+
range.each do |i|
|
|
197
|
+
out << %{<option value="#{i}"#{' selected="selected"' if default == i}>#{i}</option>\n}
|
|
198
|
+
end
|
|
199
|
+
out << "</select>\n"
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
end
|