ramaze 2009.05 → 2009.06

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. data/.gitignore +3 -0
  2. data/MANIFEST +11 -7
  3. data/README.md +3 -3
  4. data/Rakefile +17 -15
  5. data/bin/ramaze +7 -2
  6. data/doc/AUTHORS +6 -5
  7. data/doc/CHANGELOG +10057 -12259
  8. data/doc/meta/announcement.txt +93 -46
  9. data/doc/tutorial/todolist.html +22 -58
  10. data/doc/tutorial/todolist.txt +20 -39
  11. data/examples/app/wikore/src/model.rb +7 -1
  12. data/examples/app/wiktacular/template/html_layout.xhtml +1 -1
  13. data/lib/proto/config.ru +5 -1
  14. data/lib/ramaze/cache/localmemcache.rb +1 -1
  15. data/lib/ramaze/cache/memcache.rb +26 -1
  16. data/lib/ramaze/cache/sequel.rb +9 -6
  17. data/lib/ramaze/contrib/addressable_route.rb +55 -0
  18. data/lib/ramaze/contrib/facebook/facebook.rb +4 -4
  19. data/lib/ramaze/controller.rb +28 -18
  20. data/lib/ramaze/gestalt.rb +1 -1
  21. data/lib/ramaze/helper/auth.rb +0 -5
  22. data/lib/ramaze/helper/cache.rb +0 -9
  23. data/lib/ramaze/helper/form.rb +14 -2
  24. data/lib/ramaze/helper/formatting.rb +1 -1
  25. data/lib/ramaze/helper/layout.rb +97 -0
  26. data/lib/ramaze/helper/link.rb +6 -25
  27. data/lib/ramaze/helper/paginate.rb +2 -2
  28. data/lib/ramaze/helper/user.rb +3 -3
  29. data/lib/ramaze/helper.rb +1 -0
  30. data/lib/ramaze/setup.rb +22 -9
  31. data/lib/ramaze/spec/bacon.rb +34 -0
  32. data/lib/ramaze/spec/helper/template_examples.rb +13 -23
  33. data/lib/ramaze/spec.rb +8 -9
  34. data/lib/ramaze/tool/bin.rb +16 -6
  35. data/lib/ramaze/tool/project_creator.rb +1 -1
  36. data/lib/ramaze/version.rb +1 -1
  37. data/lib/ramaze.rb +8 -8
  38. data/lib/vendor/etag.rb +4 -2
  39. data/lib/vendor/route_exceptions.rb +6 -11
  40. data/ramaze.gemspec +52 -8
  41. data/spec/contrib/addressable_route.rb +32 -0
  42. data/spec/contrib/rest.rb +1 -1
  43. data/spec/examples/caching.rb +1 -1
  44. data/spec/examples/css.rb +1 -1
  45. data/spec/examples/element.rb +1 -1
  46. data/spec/examples/hello.rb +1 -1
  47. data/spec/examples/helpers/httpdigest.rb +1 -1
  48. data/spec/examples/linking.rb +1 -1
  49. data/spec/examples/simple.rb +1 -1
  50. data/spec/examples/templates/template_erubis.rb +3 -2
  51. data/spec/examples/templates/template_ezamar.rb +3 -2
  52. data/spec/examples/templates/template_haml.rb +3 -2
  53. data/spec/examples/templates/template_liquid.rb +3 -2
  54. data/spec/examples/templates/template_markaby.rb +5 -4
  55. data/spec/examples/templates/template_nagoro.rb +3 -3
  56. data/spec/examples/templates/template_redcloth.rb +3 -2
  57. data/spec/examples/templates/template_remarkably.rb +3 -2
  58. data/spec/examples/templates/template_tenjin.rb +3 -2
  59. data/spec/helper.rb +1 -2
  60. data/spec/ramaze/app.rb +1 -1
  61. data/spec/ramaze/bin/ramaze.rb +91 -0
  62. data/spec/ramaze/cache/memcache.rb +6 -0
  63. data/spec/ramaze/controller/actionless_templates.rb +1 -1
  64. data/spec/ramaze/controller/lonely_mapping.rb +16 -0
  65. data/spec/ramaze/controller/mapping.rb +0 -14
  66. data/spec/ramaze/controller/provide_inheritance.rb +1 -1
  67. data/spec/ramaze/controller/resolve.rb +1 -1
  68. data/spec/ramaze/controller/subclass.rb +1 -1
  69. data/spec/ramaze/controller/template_resolving.rb +1 -1
  70. data/spec/ramaze/dispatcher/directory.rb +1 -1
  71. data/spec/ramaze/dispatcher/file.rb +7 -7
  72. data/spec/ramaze/error.rb +2 -2
  73. data/spec/ramaze/files.rb +1 -1
  74. data/spec/ramaze/helper/auth.rb +1 -1
  75. data/spec/ramaze/helper/bench.rb +2 -1
  76. data/spec/ramaze/helper/cache.rb +1 -1
  77. data/spec/ramaze/helper/flash.rb +1 -1
  78. data/spec/ramaze/helper/form.rb +2 -2
  79. data/spec/ramaze/helper/httpdigest.rb +3 -3
  80. data/spec/ramaze/helper/layout/default.xhtml +5 -0
  81. data/spec/ramaze/helper/layout.rb +79 -0
  82. data/spec/ramaze/helper/link.rb +32 -11
  83. data/spec/ramaze/helper/localize.rb +1 -1
  84. data/spec/ramaze/helper/maruku.rb +1 -1
  85. data/spec/ramaze/helper/pager.rb +1 -1
  86. data/spec/ramaze/helper/paginate.rb +1 -1
  87. data/spec/ramaze/helper/request_accessor.rb +1 -1
  88. data/spec/ramaze/helper/sequel_form.rb +1 -1
  89. data/spec/ramaze/helper/simple_captcha.rb +1 -1
  90. data/spec/ramaze/helper/stack.rb +1 -1
  91. data/spec/ramaze/helper/user.rb +1 -1
  92. data/spec/ramaze/params.rb +4 -5
  93. data/spec/ramaze/session/memcache.rb +66 -0
  94. data/spec/ramaze/view/erubis.rb +1 -1
  95. data/spec/ramaze/view/ezamar.rb +1 -1
  96. data/spec/ramaze/view/gestalt.rb +1 -1
  97. data/spec/ramaze/view/haml.rb +1 -1
  98. data/spec/ramaze/view/liquid.rb +1 -1
  99. data/spec/ramaze/view/nagoro.rb +1 -1
  100. data/spec/ramaze/view/redcloth.rb +1 -1
  101. data/spec/ramaze/view/remarkably.rb +1 -1
  102. data/spec/ramaze/view/sass.rb +1 -1
  103. data/spec/ramaze/view/tagz.rb +1 -1
  104. data/spec/ramaze/view/tenjin.rb +1 -1
  105. data/spec/ramaze/view.rb +1 -1
  106. data/tasks/changelog.rake +3 -1
  107. data/tasks/{gem_installer.rake → gem_setup.rake} +45 -22
  108. data/tasks/release.rake +6 -4
  109. data/tasks/setup.rake +3 -21
  110. data/tasks/todo.rake +2 -4
  111. metadata +164 -10
  112. data/CHANGELOG +0 -16918
  113. data/doc/tutorial/todolist.mkd +0 -787
  114. data/lib/ramaze/snippets/divide.rb +0 -22
  115. data/lib/ramaze/snippets/object/acquire.rb +0 -37
  116. data/spec/snippets/kernel/constant.rb +0 -23
  117. data/tasks/install_dependencies.rake +0 -6
@@ -45,6 +45,12 @@ module Model
45
45
  end
46
46
 
47
47
  [Page, OldPage].each do |klass|
48
- klass.create_table unless klass.table_exists?
48
+ begin
49
+ klass.create_table
50
+ rescue Sequel::DatabaseError => e
51
+ if e.message !~ /table.*already exists/
52
+ raise e
53
+ end
54
+ end
49
55
  end
50
56
  end
@@ -22,6 +22,6 @@
22
22
  <div id="content">
23
23
  #@content
24
24
  </div>
25
- <div id="copyright">Wiktacular is powered by <a href="http://ramaze.rubyforge.org/">Ramaze</a></div>
25
+ <div id="copyright">Wiktacular is powered by <a href="http://ramaze.net">Ramaze</a></div>
26
26
  </body>
27
27
  </html>
data/lib/proto/config.ru CHANGED
@@ -10,7 +10,11 @@
10
10
  # rackup automatically figures out the environment it is run in, and runs your
11
11
  # application as FastCGI, CGI, or standalone with Mongrel or WEBrick -- all from
12
12
  # the same configuration.
13
+ #
14
+ # Do not set the adapter.handler in here, it will be ignored.
15
+ # You can choose the adapter like `ramaze start -s mongrel` or set it in the
16
+ # 'start.rb' and use `ruby start.rb` instead.
13
17
 
14
- require File.expand_path('app', File.dirname(__FILE__))
18
+ require ::File.expand_path('app', ::File.dirname(__FILE__))
15
19
  Ramaze.start(:file => __FILE__, :started => true)
16
20
  run Ramaze
@@ -31,7 +31,7 @@ module Ramaze
31
31
 
32
32
  # Wipe out _all_ data in localmemcached, use with care.
33
33
  def cache_clear
34
- ::LocalMemCache.clear_namespace(@namespace)
34
+ @store.clear
35
35
  end
36
36
 
37
37
  def cache_delete(*args)
@@ -13,7 +13,20 @@ module Ramaze
13
13
  #
14
14
  # It is highly recommended to install memcache-client_extensions for
15
15
  # a bit of speedup and more functionality
16
+ #
17
+ # NOTE: There is a big issue with persisting sessions in memcache, not only
18
+ # can they be dropped at any time, essentially logging the user out
19
+ # without them noticing, but there is also a low limit to the maximum
20
+ # time-to-live. After 30 days, your session will be dropped, no
21
+ # matter what.
22
+ # Please remember that memcache is, first of all, a cache, not a
23
+ # persistence mechanism.
24
+ #
25
+ # NOTE: If you try to set a higher ttl than allowed, your stored key/value
26
+ # will be expired immediately.
16
27
  class MemCache
28
+ MAX_TTL = 2592000
29
+
17
30
  include Cache::API
18
31
 
19
32
  # +:multithread+: May be turned off at your own risk.
@@ -34,6 +47,7 @@ module Ramaze
34
47
  options = {:namespace => @namespace}.merge(OPTIONS)
35
48
  servers = options.delete(:servers)
36
49
  @store = ::MemCache.new(servers, options)
50
+ @warned = false
37
51
  end
38
52
 
39
53
  # Wipe out _all_ data in memcached, use with care.
@@ -46,7 +60,7 @@ module Ramaze
46
60
 
47
61
  #
48
62
  def cache_delete(*keys)
49
- super{|key| @store.delete(key) }
63
+ super{|key| @store.delete(key); nil }
50
64
  rescue ::MemCache::MemCacheError => e
51
65
  Log.error(e)
52
66
  nil
@@ -65,6 +79,17 @@ module Ramaze
65
79
 
66
80
  def cache_store(key, value, options = {})
67
81
  ttl = options[:ttl] || 0
82
+
83
+ if ttl > MAX_TTL
84
+ unless @warned
85
+ Log.warn('MemCache cannot set a ttl greater than 2592000 seconds.')
86
+ Log.warn('Modify Ramaze.options.session.ttl to a value <= of that.')
87
+ @warned = true
88
+ end
89
+
90
+ ttl = MAX_TTL
91
+ end
92
+
68
93
  @store.set(key, value, ttl)
69
94
  value
70
95
  rescue ::MemCache::MemCacheError => e
@@ -16,19 +16,22 @@ module Ramaze
16
16
 
17
17
  class Table < ::Sequel::Model(:ramaze_cache)
18
18
  plugin :schema
19
- plugin :serialization, :marshal, :value
19
+ plugin :serialization
20
+
21
+ serialize_attributes :marshal, :value
20
22
 
21
23
  set_schema do
22
24
  primary_key :id
23
- string :key
24
- string :value
25
- time :expires
26
25
  index :key, :unique => true
26
+
27
+ String :key
28
+ String :value
29
+ Time :expires
27
30
  end
28
31
 
29
32
  def [](column)
30
33
  if column == :value
31
- deserialized_values[column] = deserialize_value(@values[column])
34
+ deserialized_values[column] = deserialize_value(column, @values[column])
32
35
  else
33
36
  super
34
37
  end
@@ -38,7 +41,7 @@ module Ramaze
38
41
  # Setup the table, not suitable for multiple apps yet.
39
42
  def cache_setup(host, user, app, name)
40
43
  @namespace = [host, user, app, name].compact.join(':')
41
- Table.create_table unless Table.table_exists?
44
+ Table.create_table?
42
45
  @store = Table
43
46
  end
44
47
 
@@ -0,0 +1,55 @@
1
+ require "addressable/template"
2
+
3
+ module Ramaze
4
+ # This is a simple prototype-implementation of how we could do routing
5
+ # supported by URI templates.
6
+ #
7
+ # Please see the spec for example usage as it's not integrated yet in any way.
8
+ #
9
+ # What it does is basically that you can give it any URI template and a final
10
+ # mapping, and it will extract the variables from the URI and merge them into
11
+ # the QUERY_STRING, which is parsed again in Ramaze if you issue
12
+ # Request#params.
13
+ #
14
+ # @example given mapping like:
15
+ #
16
+ # map('/customer/{customer_id}/order/{order_id}', '/order/show')
17
+ #
18
+ # @example output of request.params at '/order/show'
19
+ #
20
+ # {'customer_id => '12', 'order_id' => '15'}
21
+ #
22
+ # I haven't explored the full capabilities of the templates yet, but the
23
+ # specs of Addressable::Template suggest that there is a lot to be
24
+ # discovered.
25
+ class AddressableRoute
26
+ ROUTES = {}
27
+
28
+ def self.map(from, to)
29
+ ROUTES[Addressable::Template.new(from)] = to
30
+ end
31
+
32
+ def initialize(app)
33
+ @app = app
34
+ end
35
+
36
+ def call(env)
37
+ path_info = env['PATH_INFO']
38
+
39
+ ROUTES.each do |template, target|
40
+ extracted = template.extract(path_info)
41
+ return dispatch(env, target, extracted) if extracted
42
+ end
43
+
44
+ @app.call(env)
45
+ end
46
+
47
+ def dispatch(env, target, extracted)
48
+ env['PATH_INFO'] = target
49
+ original = Rack::Utils.parse_query(env['QUERY_STRING'])
50
+ env['QUERY_STRING'] = Rack::Utils.build_query(original.merge(extracted))
51
+
52
+ @app.call(env)
53
+ end
54
+ end
55
+ end
@@ -59,9 +59,9 @@ module Facebook
59
59
  end while ret.empty? and @server = connect
60
60
 
61
61
  ret = case
62
- when ret == 'true': true
63
- when ret == 'false': false
64
- when ret[0..0] == '"': ret[1..-2]
62
+ when ret == 'true'; true
63
+ when ret == 'false'; false
64
+ when ret[0..0] == '"'; ret[1..-2]
65
65
  else
66
66
  begin
67
67
  JSON::parse(ret)
@@ -168,4 +168,4 @@ module Facebook
168
168
  buf
169
169
  end
170
170
  end
171
- end
171
+ end
@@ -19,23 +19,43 @@ module Ramaze
19
19
 
20
20
  def self.inherited(into)
21
21
  Innate::Node.included(into)
22
+ into.helper(:layout)
22
23
  CONTROLLER_LIST << into
23
24
  into.trait :skip_node_map => true
24
25
  end
25
26
 
26
27
  def self.setup
27
- require 'ramaze/controller/default' if CONTROLLER_LIST.empty?
28
+ case CONTROLLER_LIST.size
29
+ when 0
30
+ require 'ramaze/controller/default'
31
+ when 1
32
+ controller = CONTROLLER_LIST.first
33
+
34
+ begin
35
+ controller.mapping
36
+ rescue
37
+ controller.map '/'
38
+ end
28
39
 
29
- CONTROLLER_LIST.each do |controller|
30
- unless controller.ancestral_trait[:provide_set]
31
- controller.engine(:Etanni)
32
- controller.trait(:provide_set => false)
40
+ controller.setup_procedure
41
+ else
42
+ CONTROLLER_LIST.each do |controller|
43
+ controller.setup_procedure
33
44
  end
34
- next if controller.trait[:skip_controller_map]
35
- controller.map(generate_mapping(controller.name))
36
45
  end
37
46
  end
38
47
 
48
+ def self.setup_procedure
49
+ unless ancestral_trait[:provide_set]
50
+ engine(:Etanni)
51
+ trait(:provide_set => false)
52
+ end
53
+
54
+ return if trait[:skip_controller_map]
55
+
56
+ map(generate_mapping(name))
57
+ end
58
+
39
59
  def self.engine(name)
40
60
  provide(:html, name.to_sym)
41
61
  end
@@ -50,7 +70,7 @@ module Ramaze
50
70
  }
51
71
 
52
72
  def self.generate_mapping(klass_name = self.name)
53
- chunks = klass_name.split(/::/)
73
+ chunks = klass_name.to_s.split(/::/)
54
74
  return if chunks.empty?
55
75
 
56
76
  last = chunks.last
@@ -80,15 +100,5 @@ module Ramaze
80
100
  return unless app = self.app
81
101
  app.options
82
102
  end
83
-
84
- def self.template(*args)
85
- Ramaze.deprecated('Controller::template', 'Controller::alias_view')
86
- alias_view(*args)
87
- end
88
-
89
- def self.view_root(*locations)
90
- Ramaze.deprecated('Controller::view_root', 'Controller::map_views')
91
- map_views(*locations)
92
- end
93
103
  end
94
104
  end
@@ -98,7 +98,7 @@ module Ramaze
98
98
 
99
99
  def _gestalt_build_tag(name, attr = {}, text = [])
100
100
  @out << "<#{name}"
101
- @out << attr.map{|k,v| %[ #{k}="#{_gestalt_escape_entities(v)}"] }.join
101
+ @out << attr.map{|(k,v)| %[ #{k}="#{_gestalt_escape_entities(v)}"] }.join
102
102
  if text != [] or block_given?
103
103
  @out << ">"
104
104
  @out << _gestalt_escape_entities([text].join)
@@ -43,11 +43,6 @@ module Ramaze
43
43
  !!session[:logged_in]
44
44
  end
45
45
 
46
- def check_auth(user, pass)
47
- Ramaze.deprecated('Helper::User#check_auth', 'Helper::User#auth_login')
48
- auth_login(user, pass)
49
- end
50
-
51
46
  # @return
52
47
  def auth_login(user, pass)
53
48
  return unless user and pass
@@ -65,15 +65,6 @@ module Ramaze
65
65
  Ramaze::Cache.action_value
66
66
  end
67
67
 
68
-
69
- # @deprecated Use the #cache_value method instead
70
- # @author manveru
71
- def value_cache
72
- Ramaze::deprecated('Innate::Helper::Cache#value_cache',
73
- 'Innate::Helper::Cache#cache_value')
74
- cache_value
75
- end
76
-
77
68
  module SingletonMethods
78
69
  def cache(name, hash = {})
79
70
  Ramaze.deprecated('Helper::Cache::cache', 'Helper::Cache::cache_action')
@@ -35,13 +35,25 @@ module Ramaze
35
35
  Ramaze::Gestalt.build{ tr{ td(:colspan => 2){ input(hash) }}}
36
36
  end
37
37
 
38
+ # @example usage, normal select drop-down
39
+ #
40
+ # form_select('Favourite colors', :colors, @colors, :selected => @color)
41
+ #
42
+ # @example usage for pre-selected value
43
+ #
44
+ # form_select('Favourite colors', :colors, @colors, :selected => @color)
45
+ #
46
+ # @example usage, allow selecting multiple
47
+ #
48
+ # form_select('Cups', :cups, @cups, :selected => @cup, :multiple => 5)
38
49
  def form_select(label, name, values, hash = {})
39
50
  name = name.to_sym
40
51
  id = "form-#{name}"
52
+ multiple, size = hash.values_at(:multiple, :size)
41
53
 
42
54
  s_args = {:name => name, :id => id}.merge(form_tabindex)
43
- s_args[:multiple] = :multiple if hash[:multiple]
44
- s_args[:size] = hash[:size] || 1
55
+ s_args[:multiple] = :multiple if multiple
56
+ s_args[:size] = (size || multiple || 1).to_i
45
57
 
46
58
  has_selected, selected = hash.key?(:selected), hash[:selected]
47
59
  error = form_errors[name.to_s]
@@ -115,7 +115,7 @@ module Ramaze
115
115
  [-\w]+ # subdomain or domain
116
116
  (?:\.[-\w]+)* # remaining subdomains or domain
117
117
  (?::\d+)? # port
118
- (?:/(?:(?:[~\w\+@%-]|(?:[,.;:][^\s$]))+)?)* # path
118
+ (?:/(?:(?:[~\w\+@%-]|(?:[,.;:][^\s$])))?)* # path
119
119
  (?:\?[\w\+@%&=.;-]+)? # query string
120
120
  (?:\#[\w\-]*)? # trailing anchor
121
121
  )
@@ -0,0 +1,97 @@
1
+ module Ramaze
2
+ module Helper
3
+
4
+ # Provides wrapper methods for a higher-level approach than the core layout
5
+ # method. These are useful for simpler layout needs, particularly:
6
+ #
7
+ # * layout all actions
8
+ # * layout a whitelist of actions
9
+ # * layout all but a blacklist of actions
10
+ #
11
+ # As with the core layout method, the layout rules apply only to the
12
+ # controller on which they are applied. Furthermore, multiple layout
13
+ # definitions are not combined; only the last definition will be used.
14
+ #
15
+ # This helper is one of the default helpers, so no explicit helper call
16
+ # is necessary before using it in your controllers.
17
+ #
18
+ # Usage:
19
+ #
20
+ # class MainController < Controller
21
+ # # Apply the default layout (e.g. ./layout/default.xhtml) to all
22
+ # # three actions.
23
+ # set_layout 'default'
24
+ # def action1; end
25
+ # def action2; end
26
+ # def action3; end
27
+ # end
28
+ #
29
+ # class MainController < Controller
30
+ # # These two layout definitions accomplish the same thing. The
31
+ # # first uses a whitelist, the second uses a blacklist.
32
+ # set_layout 'default' => [:laid_out1, :laid_out2]
33
+ # set_layout_except 'default' => [:not_laid_out1, :not_laid_out2]
34
+ #
35
+ # def laid_out1; end
36
+ # def laid_out2; end
37
+ #
38
+ # def not_laid_out1; end
39
+ # def not_laid_out2; end
40
+ # end
41
+ module Layout
42
+ def self.included(into)
43
+ into.extend SingletonMethods
44
+ end
45
+
46
+ module SingletonMethods
47
+ # @param [String Hash] Either a layout name, or a single-element Hash
48
+ # which maps a layout name to an Array containing a whitelist of
49
+ # action names
50
+ # @see set_layout_except Innate::Node::layout
51
+ # @author Pistos, manveru
52
+ # @example Use a layout named 'default' on all actions of the controller:
53
+ # set_layout 'default'
54
+ # @example Use a layout named 'default' on just the index and admin actions:
55
+ # set_layout 'default' => [ :index, :admin ]
56
+ def set_layout(hash_or_the_layout)
57
+ if hash_or_the_layout.respond_to?(:to_hash)
58
+ f = hash_or_the_layout.first
59
+ the_layout = f[0]
60
+ whitelist = f[1].map{|action| action.to_s }
61
+ else
62
+ the_layout = hash_or_the_layout
63
+ end
64
+
65
+ layout do |path, wish|
66
+ if whitelist.nil? || whitelist.include?(path.to_s)
67
+ the_layout
68
+ end
69
+ end
70
+ end
71
+
72
+ # @param [String Hash] Either a layout name, or a single-element Hash
73
+ # which maps a layout name to an Array containing a blacklist of
74
+ # action names
75
+ # @see set_layout Innate::Node::layout
76
+ # @author Pistos, manveru
77
+ # @example Use a layout named 'default' on all actions except the user_data action:
78
+ # set_layout_except 'default' => [ :user_data ]
79
+ def set_layout_except(hash_or_the_layout)
80
+ if hash_or_the_layout.respond_to?(:to_hash)
81
+ f = hash_or_the_layout.to_hash.first
82
+ the_layout = f[0]
83
+ blacklist = f[1].map{|action| action.to_s }
84
+ else
85
+ the_layout = hash_or_the_layout
86
+ end
87
+
88
+ layout do |path, wish|
89
+ if blacklist.nil? || !blacklist.include?(path.to_s)
90
+ the_layout
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end