widgetz 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/README +91 -0
  2. data/README.html +60 -0
  3. data/gemspec.rb +28 -0
  4. data/install.rb +210 -0
  5. data/lib/widgets.rb +154 -0
  6. data/sample/rails/README +182 -0
  7. data/sample/rails/Rakefile +10 -0
  8. data/sample/rails/app/controllers/application.rb +11 -0
  9. data/sample/rails/app/controllers/sample_controller.rb +30 -0
  10. data/sample/rails/app/helpers/application_helper.rb +3 -0
  11. data/sample/rails/app/views/layouts/application.rhtml +1 -0
  12. data/sample/rails/app/views/sample/b.rhtml +2 -0
  13. data/sample/rails/app/views/widgets/b.rhtml +3 -0
  14. data/sample/rails/app/views/widgets/c.rhtml +3 -0
  15. data/sample/rails/app/views/widgets/page.rhtml +15 -0
  16. data/sample/rails/config/boot.rb +45 -0
  17. data/sample/rails/config/database.yml +16 -0
  18. data/sample/rails/config/environment.rb +62 -0
  19. data/sample/rails/config/environments/development.rb +21 -0
  20. data/sample/rails/config/environments/production.rb +18 -0
  21. data/sample/rails/config/environments/test.rb +19 -0
  22. data/sample/rails/config/lighttpd.conf +54 -0
  23. data/sample/rails/config/routes.rb +23 -0
  24. data/sample/rails/doc/README_FOR_APP +2 -0
  25. data/sample/rails/lib/widgets/b.rb +8 -0
  26. data/sample/rails/lib/widgets/c.rb +7 -0
  27. data/sample/rails/lib/widgets/page.rb +7 -0
  28. data/sample/rails/log/development.log +1616 -0
  29. data/sample/rails/log/fastcgi.crash.log +48 -0
  30. data/sample/rails/log/lighttpd.access.log +59 -0
  31. data/sample/rails/log/lighttpd.error.log +42 -0
  32. data/sample/rails/log/production.log +0 -0
  33. data/sample/rails/log/server.log +0 -0
  34. data/sample/rails/log/test.log +0 -0
  35. data/sample/rails/public/404.html +30 -0
  36. data/sample/rails/public/500.html +30 -0
  37. data/sample/rails/public/dispatch.cgi +10 -0
  38. data/sample/rails/public/dispatch.fcgi +24 -0
  39. data/sample/rails/public/dispatch.rb +10 -0
  40. data/sample/rails/public/favicon.ico +0 -0
  41. data/sample/rails/public/images/rails.png +0 -0
  42. data/sample/rails/public/index.html +277 -0
  43. data/sample/rails/public/javascripts/application.js +2 -0
  44. data/sample/rails/public/javascripts/controls.js +833 -0
  45. data/sample/rails/public/javascripts/dragdrop.js +942 -0
  46. data/sample/rails/public/javascripts/effects.js +1088 -0
  47. data/sample/rails/public/javascripts/prototype.js +2515 -0
  48. data/sample/rails/public/robots.txt +1 -0
  49. data/sample/rails/script/about +3 -0
  50. data/sample/rails/script/breakpointer +3 -0
  51. data/sample/rails/script/console +3 -0
  52. data/sample/rails/script/destroy +3 -0
  53. data/sample/rails/script/generate +3 -0
  54. data/sample/rails/script/performance/benchmarker +3 -0
  55. data/sample/rails/script/performance/profiler +3 -0
  56. data/sample/rails/script/plugin +3 -0
  57. data/sample/rails/script/process/inspector +3 -0
  58. data/sample/rails/script/process/reaper +3 -0
  59. data/sample/rails/script/process/spawner +3 -0
  60. data/sample/rails/script/runner +3 -0
  61. data/sample/rails/script/server +3 -0
  62. data/sample/rails/test/test_helper.rb +28 -0
  63. data/sample/rails/tmp/sessions/ruby_sess.45bcc3811314bce8 +0 -0
  64. data/sample/rails/tmp/sessions/ruby_sess.b741114026a9d990 +0 -0
  65. data/widgetz-0.0.1.gem +0 -0
  66. metadata +160 -0
data/README ADDED
@@ -0,0 +1,91 @@
1
+ NAME
2
+
3
+ widgetz.rb
4
+
5
+ SYNOPSIS
6
+
7
+ simple widgets for rails
8
+
9
+ INSTALL
10
+
11
+ gem install widgetz
12
+
13
+ URIS
14
+ http://rubyforge.org/projects/codeforpeople/
15
+ http://codeforpeople.com/lib/ruby/widgetz/
16
+ http://drawohara.tumblr.com/post/6060120
17
+
18
+ DESCRIPTION
19
+
20
+ widgetz.rb aims to fix two problems with factoring and abstracting html
21
+ generation in rails using the normal 'helper' methodolgy:
22
+
23
+ 1) helper methods are purely procedural and provide no state. ruby is an
24
+ object oriented language and we like to use objects to abstract things
25
+ where possible. widgetz lets you do just that. some people call this
26
+ encapsulation.
27
+
28
+ 2) by using the normal rendering chain in rails, widgetz makes sure you
29
+ get a nice stack stace from the location in the widgetz template where
30
+ you used ruby's power blow your leg off instead of some esoteric message
31
+ from an anonymous module you barely knew.
32
+
33
+ widgetz are essentailly bags of data that use a controller to render
34
+ themselves. all the state of the widget is made available in the view as
35
+ local variables, while the normal @variables set in a controller remain
36
+ visible as normal. one special local variable, 'widget', is set in the view's
37
+ local vars so you have a handle on the widget in order to use it for some evil
38
+ purpose.
39
+
40
+ SAMPLE
41
+ #
42
+ # app/controllers/sample_controller.rb
43
+ #
44
+ def c
45
+ @var = 42
46
+ @c = widget 'c'
47
+
48
+ render :layout => 'application', :inline => <<-rhtml
49
+ var: <%= @var %>
50
+
51
+ <hr>
52
+
53
+ <%= @c %>
54
+ rhtml
55
+ end
56
+
57
+ #
58
+ # lib/widgets/c.rb
59
+ #
60
+ Widget 'c' do
61
+ attribute 'var' => 'forty-two'
62
+
63
+ def answer
64
+ 42.0
65
+ end
66
+ end
67
+
68
+ #
69
+ # app/views/widgets/c.rhtml
70
+ #
71
+ controller var : <%= @var %> <br>
72
+ widget var : <%= var %> <br>
73
+ widget method : <%= widget.answer %> <br>
74
+
75
+ #
76
+ # output
77
+ #
78
+ var: 42
79
+ ----------------------
80
+ controller var : 42
81
+ widget var : forty-two
82
+ widget method : 42.0
83
+
84
+ DOCS
85
+
86
+ lib/*
87
+ sample/rails/*
88
+
89
+ AUTHOR
90
+
91
+ a @ http://drawohara.com/
data/README.html ADDED
@@ -0,0 +1,60 @@
1
+ <pre>
2
+ NAME
3
+
4
+ widgetz.rb
5
+
6
+ SYNOPSIS
7
+
8
+ simple widgets for rails
9
+
10
+ INSTALL
11
+
12
+ gem install widgetz
13
+
14
+ URIS
15
+ <a href="http://rubyforge.org/projects/codeforpeople/">http://rubyforge.org/projects/codeforpeople/</a>
16
+ <a href="http://codeforpeople.com/lib/ruby/widgetz/">http://codeforpeople.com/lib/ruby/widgetz/</a>
17
+ <a href="http://drawohara.tumblr.com/post/6060120">http://drawohara.tumblr.com/post/6060120</a>
18
+
19
+ DESCRIPTION
20
+
21
+ widgetz.rb aims to fix two problems with factoring and abstracting html
22
+ generation in rails using the normal 'helper' methodolgy:
23
+
24
+ 1) helper methods are purely procedural and provide no state. ruby is an
25
+ object oriented language and we like to use objects to abstract things
26
+ where possible. widgetz lets you do just that. some people call this
27
+ encapsulation.
28
+
29
+ 2) by using the normal rendering chain in rails, widgetz makes sure you
30
+ get a nice stack stace from the location in the widgetz template where
31
+ you used ruby's power blow your leg off instead of some esoteric message
32
+ from an anonymous module you barely knew.
33
+
34
+ widgetz are essentailly bags of data that use a controller to render
35
+ themselves. all the state of the widget is made available in the view as
36
+ local variables, while the normal @variables set in a controller remain
37
+ visible as normal. one special local variable, 'widget', is set in the view's
38
+ local vars so you have a handle on the widget in order to use it for some evil
39
+ purpose.
40
+
41
+ SAMPLE
42
+ </pre>
43
+ <div style="background:black;color:white;padding:10px;border-style:solid;border-color:gray;"><font face="monospace"> &nbsp;&nbsp;<font color="#00ffff">#</font><br> &nbsp;&nbsp;<font color="#00ffff"># app/controllers/sample_controller.rb</font><br> &nbsp;&nbsp;<font color="#00ffff">#</font><br> <font color="#5fd7ff">&nbsp;&nbsp;&nbsp;&nbsp;def </font><font color="#00ffff"><b>c</b></font><br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#00ffff"><b>@var</b></font>&nbsp;= <font color="#ff40ff">42</font><br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#00ffff"><b>@c</b></font>&nbsp;= widget <font color="#ffd7d7">'</font><font color="#ff40ff">c</font><font color="#ffd7d7">'</font><br> <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;render <font color="#00ffff"><b>:layout</b></font>&nbsp;=&gt; <font color="#ffd7d7">'</font><font color="#ff40ff">application</font><font color="#ffd7d7">'</font>, <font color="#00ffff"><b>:inline</b></font>&nbsp;=&gt; &lt;&lt;-<font color="#ffd7d7">rhtml</font><br> <font color="#ff40ff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var: &lt;%= @var %&gt;</font><br> <br> <font color="#ff40ff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;hr&gt;</font><br> <br> <font color="#ff40ff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;%= @c %&gt;</font><br> <font color="#ffd7d7">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rhtml</font><br> &nbsp;&nbsp;&nbsp;&nbsp;<font color="#5fd7ff">end</font><br> </font></div>
44
+ <br>
45
+ <div style="background:black;color:white;padding:10px;border-style:solid;border-color:gray;"><font face="monospace"> &nbsp;&nbsp;<font color="#00ffff">#</font><br> &nbsp;&nbsp;<font color="#00ffff"># lib/widgets/c.rb</font><br> &nbsp;&nbsp;<font color="#00ffff">#</font><br> &nbsp;&nbsp;&nbsp;&nbsp;<font color="#00ffff"><b>Widget</b></font>&nbsp;<font color="#ffd7d7">'</font><font color="#ff40ff">c</font><font color="#ffd7d7">'</font>&nbsp;<font color="#ffff00">do</font><br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;attribute <font color="#ffd7d7">'</font><font color="#ff40ff">var</font><font color="#ffd7d7">'</font>&nbsp;=&gt; <font color="#ffd7d7">'</font><font color="#ff40ff">forty-two</font><font color="#ffd7d7">'</font><br> <br> <font color="#5fd7ff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def </font><font color="#00ffff"><b>answer</b></font><br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff40ff">42.0</font><br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#5fd7ff">end</font><br> &nbsp;&nbsp;&nbsp;&nbsp;<font color="#ffff00">end</font><br> </font></div>
46
+ <br>
47
+ <div style="background:black;color:white;padding:10px;border-style:solid;border-color:gray;"><font face="monospace"> &nbsp;&nbsp;<font color="#00ffff">#</font><br> &nbsp;&nbsp;<font color="#00ffff"># app/views/widgets/c.rhtml</font><br> &nbsp;&nbsp;<font color="#00ffff">#</font><br> &nbsp;&nbsp;&nbsp;&nbsp;controller var : &lt;%= <font color="#00ffff"><b>@var</b></font>&nbsp;%&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;br&gt; <br> &nbsp;&nbsp;&nbsp;&nbsp;widget var&nbsp;&nbsp;&nbsp;&nbsp; : &lt;%= var %&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;br&gt; <br> &nbsp;&nbsp;&nbsp;&nbsp;widget method&nbsp;&nbsp;: &lt;%= widget.answer %&gt; &lt;br&gt; <br> </font></div>
48
+ <br>
49
+ <div style="background:black;color:white;padding:10px;border-style:solid;border-color:gray;"><font face="monospace"> &nbsp;&nbsp;<font color="#00ffff">#</font><br> &nbsp;&nbsp;<font color="#00ffff"># output</font><br> &nbsp;&nbsp;<font color="#00ffff">#</font><br> &nbsp;&nbsp;&nbsp;&nbsp;&lt;&lt;-<font color="#ffd7d7">html</font><br> <font color="#ff40ff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var: 42&nbsp;&nbsp;</font><br> <font color="#ff40ff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;----------------------</font><br> <font color="#ff40ff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;controller var : 42</font><br> <font color="#ff40ff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;widget var&nbsp;&nbsp;&nbsp;&nbsp; : forty-two</font><br> <font color="#ff40ff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;widget method&nbsp;&nbsp;: 42.0</font><br> <font color="#ffd7d7">&nbsp;&nbsp;&nbsp;&nbsp;html</font><br> </font></div>
50
+ <br>
51
+ <pre>
52
+ DOCS
53
+
54
+ lib/*
55
+ sample/rails/*
56
+
57
+ AUTHOR
58
+
59
+ a @ http://drawohara.com/
60
+ </pre>
data/gemspec.rb ADDED
@@ -0,0 +1,28 @@
1
+
2
+ lib, version = File::basename(File::dirname(File::expand_path(__FILE__))).split %r/-/, 2
3
+
4
+ require 'rubygems'
5
+
6
+ Gem::Specification::new do |spec|
7
+ $VERBOSE = nil
8
+ spec.name = lib
9
+ spec.version = version
10
+ spec.platform = Gem::Platform::RUBY
11
+ spec.summary = lib
12
+
13
+ spec.files = Dir::glob "**/**"
14
+ spec.executables = Dir::glob("bin/*").map{|exe| File::basename exe}
15
+
16
+ spec.require_path = "lib"
17
+ spec.autorequire = lib
18
+
19
+ spec.has_rdoc = File::exist? "doc"
20
+ spec.test_suite_file = "test/#{ lib }.rb" if File::directory? "test"
21
+ spec.add_dependency 'attributes'
22
+
23
+ spec.extensions << "extconf.rb" if File::exists? "extconf.rb"
24
+
25
+ spec.author = "Ara T. Howard"
26
+ spec.email = "ara.t.howard@gmail.com"
27
+ spec.homepage = "http://codeforpeople.com/lib/ruby/#{ lib }/"
28
+ end
data/install.rb ADDED
@@ -0,0 +1,210 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rbconfig'
3
+ require 'find'
4
+ require 'ftools'
5
+ require 'tempfile'
6
+ include Config
7
+
8
+ LIBDIR = "lib"
9
+ LIBDIR_MODE = 0644
10
+
11
+ BINDIR = "bin"
12
+ BINDIR_MODE = 0755
13
+
14
+
15
+ $srcdir = CONFIG["srcdir"]
16
+ $version = CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
17
+ $libdir = File.join(CONFIG["libdir"], "ruby", $version)
18
+ $archdir = File.join($libdir, CONFIG["arch"])
19
+ $site_libdir = $:.find {|x| x =~ /site_ruby$/}
20
+ $bindir = CONFIG["bindir"] || CONFIG['BINDIR']
21
+ $ruby_install_name = CONFIG['ruby_install_name'] || CONFIG['RUBY_INSTALL_NAME'] || 'ruby'
22
+ $ruby_ext = CONFIG['EXEEXT'] || ''
23
+ $ruby = File.join($bindir, ($ruby_install_name + $ruby_ext))
24
+
25
+ if !$site_libdir
26
+ $site_libdir = File.join($libdir, "site_ruby")
27
+ elsif $site_libdir !~ %r/#{Regexp.quote($version)}/
28
+ $site_libdir = File.join($site_libdir, $version)
29
+ end
30
+
31
+ def install_rb(srcdir=nil, destdir=nil, mode=nil, bin=nil)
32
+ #{{{
33
+ path = []
34
+ dir = []
35
+ Find.find(srcdir) do |f|
36
+ next unless FileTest.file?(f)
37
+ next if (f = f[srcdir.length+1..-1]) == nil
38
+ next if (/CVS$/ =~ File.dirname(f))
39
+ next if f =~ %r/\.lnk/
40
+ path.push f
41
+ dir |= [File.dirname(f)]
42
+ end
43
+ for f in dir
44
+ next if f == "."
45
+ next if f == "CVS"
46
+ File::makedirs(File.join(destdir, f))
47
+ end
48
+ for f in path
49
+ next if (/\~$/ =~ f)
50
+ next if (/^\./ =~ File.basename(f))
51
+ unless bin
52
+ File::install(File.join(srcdir, f), File.join(destdir, f), mode, true)
53
+ else
54
+ from = File.join(srcdir, f)
55
+ to = File.join(destdir, f)
56
+ shebangify(from) do |sf|
57
+ $deferr.print from, " -> ", File::catname(from, to), "\n"
58
+ $deferr.printf "chmod %04o %s\n", mode, to
59
+ File::install(sf, to, mode, false)
60
+ end
61
+ end
62
+ end
63
+ #}}}
64
+ end
65
+ def shebangify f
66
+ #{{{
67
+ open(f) do |fd|
68
+ buf = fd.read 42
69
+ if buf =~ %r/^\s*#\s*!.*ruby/o
70
+ ftmp = Tempfile::new("#{ $$ }_#{ File::basename(f) }")
71
+ begin
72
+ fd.rewind
73
+ ftmp.puts "#!#{ $ruby }"
74
+ while((buf = fd.read(8192)))
75
+ ftmp.write buf
76
+ end
77
+ ftmp.close
78
+ yield ftmp.path
79
+ ensure
80
+ ftmp.close!
81
+ end
82
+ else
83
+ yield f
84
+ end
85
+ end
86
+ #}}}
87
+ end
88
+ def ARGV.switch
89
+ #{{{
90
+ return nil if self.empty?
91
+ arg = self.shift
92
+ return nil if arg == '--'
93
+ if arg =~ /^-(.)(.*)/
94
+ return arg if $1 == '-'
95
+ raise 'unknown switch "-"' if $2.index('-')
96
+ self.unshift "-#{$2}" if $2.size > 0
97
+ "-#{$1}"
98
+ else
99
+ self.unshift arg
100
+ nil
101
+ end
102
+ #}}}
103
+ end
104
+ def ARGV.req_arg
105
+ #{{{
106
+ self.shift || raise('missing argument')
107
+ #}}}
108
+ end
109
+ def linkify d, linked = []
110
+ #--{{{
111
+ if test ?d, d
112
+ versioned = Dir[ File::join(d, "*-[0-9].[0-9].[0-9].rb") ]
113
+ versioned.each do |v|
114
+ src, dst = v, v.gsub(%r/\-[\d\.]+\.rb$/, '.rb')
115
+ lnk = nil
116
+ begin
117
+ if test ?l, dst
118
+ lnk = "#{ dst }.lnk"
119
+ puts "#{ dst } -> #{ lnk }"
120
+ File::rename dst, lnk
121
+ end
122
+ unless test ?e, dst
123
+ puts "#{ src } -> #{ dst }"
124
+ File::copy src, dst
125
+ linked << dst
126
+ end
127
+ ensure
128
+ if lnk
129
+ at_exit do
130
+ puts "#{ lnk } -> #{ dst }"
131
+ File::rename lnk, dst
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
137
+ linked
138
+ #--}}}
139
+ end
140
+
141
+
142
+ #
143
+ # main program
144
+ #
145
+
146
+ libdir = $site_libdir
147
+ bindir = $bindir
148
+ no_linkify = false
149
+ linked = nil
150
+ help = false
151
+
152
+ usage = <<-usage
153
+ #{ File::basename $0 }
154
+ -d, --destdir <destdir>
155
+ -l, --libdir <libdir>
156
+ -b, --bindir <bindir>
157
+ -r, --ruby <ruby>
158
+ -n, --no_linkify
159
+ -s, --sudo
160
+ -h, --help
161
+ usage
162
+
163
+ begin
164
+ while switch = ARGV.switch
165
+ case switch
166
+ when '-d', '--destdir'
167
+ libdir = ARGV.req_arg
168
+ when '-l', '--libdir'
169
+ libdir = ARGV.req_arg
170
+ when '-b', '--bindir'
171
+ bindir = ARGV.req_arg
172
+ when '-r', '--ruby'
173
+ $ruby = ARGV.req_arg
174
+ when '-n', '--no_linkify'
175
+ no_linkify = true
176
+ when '-s', '--sudo'
177
+ sudo = 'sudo'
178
+ when '-h', '--help'
179
+ help = true
180
+ else
181
+ raise "unknown switch #{switch.dump}"
182
+ end
183
+ end
184
+ rescue
185
+ STDERR.puts $!.to_s
186
+ STDERR.puts usage
187
+ exit 1
188
+ end
189
+
190
+ if help
191
+ STDOUT.puts usage
192
+ exit
193
+ end
194
+
195
+ system "#{ sudo } #{ $ruby } pre-install.rb" if test(?s, 'pre-install.rb')
196
+
197
+ unless no_linkify
198
+ linked = linkify('lib') + linkify('bin')
199
+ end
200
+
201
+ system "#{ $ruby } extconf.rb && make && #{ sudo } make install" if test(?s, 'extconf.rb')
202
+
203
+ install_rb(LIBDIR, libdir, LIBDIR_MODE)
204
+ install_rb(BINDIR, bindir, BINDIR_MODE, bin=true)
205
+
206
+ if linked
207
+ linked.each{|path| File::rm_f path}
208
+ end
209
+
210
+ system "#{ sudo } #{ $ruby } post-install.rb" if test(?s, 'post-install.rb')
data/lib/widgets.rb ADDED
@@ -0,0 +1,154 @@
1
+ require 'fileutils'
2
+ require 'attributes'
3
+
4
+ class Widget
5
+ #--{{{
6
+ VERSION = '0.0.1' unless defined? Widget::VERSION
7
+ def self.version() VERSION end
8
+
9
+ class << self
10
+ attribute('libdir'){ File.join RAILS_ROOT, 'lib', 'widgets' }
11
+
12
+ def for_controller controller, name, *a, &b
13
+ klass = Widget.load name
14
+ returning(klass.new(*a, &b)){|widget| widget.controller = controller}
15
+ end
16
+
17
+ def load name
18
+ lib = File.join libdir, "#{ name }.rb"
19
+ RAILS_ENV == "development" ? Kernel.load(lib) : Kernel.require(lib)
20
+ #RAILS_ENV == "development" ? eval(IO.read((lib))) : Kernel.require(lib)
21
+ #eval(IO.read((lib)))
22
+ begin
23
+ const_for name
24
+ rescue
25
+ raise "wtf? Widget '#{ name }' was not defined in #{ lib }"
26
+ end
27
+ end
28
+
29
+ def const_for name
30
+ consts = name.camelize.split %r/::/
31
+ klass = Widget
32
+ consts.each{|const| klass = klass.const_get(const)}
33
+ klass
34
+ end
35
+
36
+ def new *a, &b
37
+ returning( allocate ) do |obj|
38
+ obj.instance_eval do
39
+ @in_render = false
40
+ initialize *a, &b
41
+ end
42
+ end
43
+ end
44
+ end
45
+ FileUtils.mkdir_p libdir rescue nil
46
+
47
+
48
+ attribute('name'){ self.class.name.gsub(%r/^.*Widget::/, '').underscore }
49
+ attribute 'controller'
50
+ attribute 'template'
51
+ attribute 'show' => true
52
+ attribute 'content' => ''
53
+
54
+ def inspect
55
+ "#{ name }=#{ super }"
56
+ end
57
+
58
+ def template
59
+ "widgets/#{ name }"
60
+ end
61
+
62
+ def configure options = {} , &block
63
+ options.to_options!
64
+ has_attribute = attributes.inject({}){|h,k| h.update k.to_s => true, k.to_sym => true}
65
+ options.each do |k,v|
66
+ if has_attribute[k]
67
+ send k, v
68
+ else
69
+ attribute k => v
70
+ end
71
+ end
72
+ instance_eval &block if block
73
+ self
74
+ end
75
+
76
+ def inherited_attributes
77
+ ancestors = self.class.ancestors
78
+ offset = ancestors.index Widget
79
+ ancestors = ancestors[0, offset + 1].compact if offset
80
+ ancestors.reverse.map do |ancestor|
81
+ ancestor.attributes
82
+ end.flatten.uniq
83
+ end
84
+
85
+ def to_hash
86
+ inherited_attributes.inject({}){|h,a| h.update a.to_sym => send(a)}
87
+ end
88
+
89
+ def render options = {}
90
+ raise "recursive render of #{ name }" if @in_render
91
+ @in_render = true
92
+ begin
93
+ return '' unless show?
94
+ widget = self
95
+ template = widget.template
96
+ locals = widget.to_hash.update options.to_options!
97
+ locals[:widget] = locals['widget'] = locals[:w] = locals['w'] = widget
98
+ controller.instance_eval do
99
+ render_to_string :file => template, :use_full_path => true, :locals => locals
100
+ end
101
+ ensure
102
+ @in_render = false
103
+ end
104
+ end
105
+ alias_method "to_s", "render"
106
+
107
+ def with_content
108
+ content yield
109
+ render
110
+ end
111
+ alias_method "for_content", "with_content"
112
+
113
+ def [] k
114
+ send k
115
+ end
116
+
117
+ def []= k, v
118
+ send k, v
119
+ end
120
+
121
+ def widget name, *a, &b
122
+ controller.widget name, *a, &b
123
+ end
124
+
125
+ def self.Class path, &block
126
+ classes = path.camelize.split %r/::/
127
+ klass = Widget
128
+ classes.each do |const|
129
+ subklass = Class.new Widget
130
+ klass.module_eval{
131
+ remove_const const if const_defined? const
132
+ const_set const, subklass
133
+ }
134
+ klass = subklass
135
+ end
136
+ klass.module_eval &block
137
+ klass
138
+ end
139
+ #--}}}
140
+ end
141
+
142
+ if defined?(Rails)
143
+ class ActionController::Base
144
+ def widget name = '', *a, &b
145
+ Widget.for_controller self, name, *a, &b
146
+ end
147
+ helper_method 'widget'
148
+ end
149
+ end
150
+
151
+ def Widget(*a, &b) Widget.Class(*a, &b) end
152
+
153
+ Widgetz = Widget unless defined? Widgetz
154
+ def Widgetz(*a, &b) Widgetz.Class(*a, &b) end