ramaze 0.1.1 → 0.1.2

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.
Files changed (89) hide show
  1. data/Rakefile +14 -29
  2. data/bin/ramaze +2 -3
  3. data/doc/AUTHORS +5 -2
  4. data/doc/CHANGELOG +262 -9
  5. data/doc/FAQ +6 -6
  6. data/doc/meta/announcement.txt +5 -19
  7. data/doc/tutorial/todolist.html +47 -57
  8. data/doc/tutorial/todolist.mkd +47 -55
  9. data/examples/memleak_detector.rb +31 -0
  10. data/examples/todolist/src/controller/main.rb +14 -13
  11. data/examples/todolist/src/element/page.rb +2 -2
  12. data/examples/todolist/src/model.rb +2 -2
  13. data/examples/todolist/todolist.db +0 -4
  14. data/examples/whywiki/main.rb +2 -2
  15. data/examples/whywiki/template/edit.xhtml +1 -1
  16. data/examples/whywiki/template/show.xhtml +3 -3
  17. data/lib/proto/src/controller/main.rb +18 -1
  18. data/lib/proto/template/index.xhtml +11 -2
  19. data/lib/ramaze.rb +1 -1
  20. data/lib/ramaze/action.rb +104 -5
  21. data/lib/ramaze/action/render.rb +54 -0
  22. data/lib/ramaze/adapter.rb +2 -1
  23. data/lib/ramaze/adapter/mongrel.rb +13 -4
  24. data/lib/ramaze/cache.rb +17 -8
  25. data/lib/ramaze/cache/memcached.rb +1 -5
  26. data/lib/ramaze/controller.rb +51 -18
  27. data/lib/ramaze/controller/resolve.rb +19 -14
  28. data/lib/ramaze/dispatcher.rb +13 -16
  29. data/lib/ramaze/dispatcher/action.rb +2 -3
  30. data/lib/ramaze/dispatcher/error.rb +8 -3
  31. data/lib/ramaze/dispatcher/file.rb +1 -4
  32. data/lib/ramaze/error.rb +5 -5
  33. data/lib/ramaze/global.rb +7 -1
  34. data/lib/ramaze/global/globalstruct.rb +1 -3
  35. data/lib/ramaze/helper/aspect.rb +8 -10
  36. data/lib/ramaze/helper/cgi.rb +21 -3
  37. data/lib/ramaze/helper/identity.rb +4 -6
  38. data/lib/ramaze/helper/link.rb +4 -4
  39. data/lib/ramaze/helper/pager.rb +316 -0
  40. data/lib/ramaze/helper/partial.rb +37 -0
  41. data/lib/ramaze/helper/stack.rb +1 -1
  42. data/lib/ramaze/inform.rb +9 -0
  43. data/lib/ramaze/inform/hub.rb +5 -0
  44. data/lib/ramaze/inform/informer.rb +12 -6
  45. data/lib/ramaze/inform/informing.rb +32 -7
  46. data/lib/ramaze/inform/knotify.rb +21 -0
  47. data/lib/ramaze/inform/xosd.rb +58 -24
  48. data/lib/ramaze/sourcereload.rb +30 -1
  49. data/lib/ramaze/template.rb +33 -12
  50. data/lib/ramaze/template/amrita2.rb +21 -20
  51. data/lib/ramaze/template/erubis.rb +18 -14
  52. data/lib/ramaze/template/ezamar.rb +15 -26
  53. data/lib/ramaze/template/ezamar/element.rb +1 -1
  54. data/lib/ramaze/template/ezamar/engine.rb +45 -36
  55. data/lib/ramaze/template/ezamar/morpher.rb +3 -3
  56. data/lib/ramaze/template/ezamar/render_partial.rb +26 -0
  57. data/lib/ramaze/template/haml.rb +23 -18
  58. data/lib/ramaze/template/liquid.rb +5 -3
  59. data/lib/ramaze/template/markaby.rb +14 -11
  60. data/lib/ramaze/template/remarkably.rb +11 -5
  61. data/lib/ramaze/tool/localize.rb +12 -4
  62. data/lib/ramaze/tool/tidy.rb +26 -23
  63. data/lib/ramaze/trinity/request.rb +11 -7
  64. data/lib/ramaze/trinity/session.rb +24 -8
  65. data/lib/ramaze/version.rb +1 -1
  66. data/rake_tasks/maintaince.rake +136 -11
  67. data/spec/examples/templates/template_liquid.rb +6 -3
  68. data/spec/examples/todolist.rb +1 -2
  69. data/spec/helper/minimal.rb +7 -7
  70. data/spec/ramaze/action/basics.rb +19 -0
  71. data/spec/ramaze/action/render.rb +18 -0
  72. data/spec/ramaze/controller.rb +1 -1
  73. data/spec/ramaze/controller/template_resolving.rb +1 -1
  74. data/spec/ramaze/dispatcher/file.rb +24 -0
  75. data/spec/ramaze/error.rb +28 -29
  76. data/spec/ramaze/helper/cgi.rb +43 -0
  77. data/spec/ramaze/helper/pager.rb +27 -0
  78. data/spec/ramaze/helper/partial.rb +38 -0
  79. data/spec/ramaze/helper/template/partial.xhtml +1 -0
  80. data/spec/ramaze/inform/informer.rb +1 -1
  81. data/spec/ramaze/localize.rb +1 -1
  82. data/spec/ramaze/morpher.rb +3 -3
  83. data/spec/ramaze/request.rb +1 -3
  84. data/spec/ramaze/template.rb +9 -7
  85. data/spec/ramaze/template/haml.rb +2 -1
  86. metadata +21 -7
  87. data/examples/todolist/public/404.jpg +0 -0
  88. data/examples/todolist/public/error.xhtml +0 -74
  89. data/lib/ramaze/controller/render.rb +0 -90
@@ -5,8 +5,17 @@ require 'ramaze/inform/informing'
5
5
  require 'ramaze/inform/hub'
6
6
  require 'ramaze/inform/informer'
7
7
 
8
+ begin
9
+ require 'win32console' if RUBY_PLATFORM =~ /win32/i
10
+ rescue LoadError => ex
11
+ puts ex
12
+ puts "For nice colors on windows, please `gem install win32console`"
13
+ Ramaze::Informer.trait[:colorize] = false
14
+ end
15
+
8
16
  module Ramaze
9
17
  autoload :Analogger, "ramaze/inform/analogger.rb"
18
+ autoload :Knotify, "ramaze/inform/knotify.rb"
10
19
  autoload :Syslog, "ramaze/inform/syslog.rb"
11
20
  autoload :Growl, "ramaze/inform/growl.rb"
12
21
  autoload :Xosd, "ramaze/inform/xosd.rb"
@@ -1,14 +1,18 @@
1
1
  # Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
2
2
  # All files in this distribution are subject to the terms of the Ruby license.
3
3
 
4
+ require 'set'
5
+
4
6
  module Ramaze
5
7
  class LogHub
6
8
  include Informing
7
9
 
8
10
  attr_accessor :loggers
11
+ attr_accessor :ignored_tags
9
12
 
10
13
  def initialize(*loggers)
11
14
  @loggers = loggers
15
+ @ignored_tags = Set.new
12
16
  @loggers.map! do |logger|
13
17
  next(nil) if logger == self
14
18
  logger.is_a?(Class) ? logger.new : logger
@@ -18,6 +22,7 @@ module Ramaze
18
22
  end
19
23
 
20
24
  def inform(tag, *args)
25
+ return if @ignored_tags.include?(tag)
21
26
  @loggers.each do |logger|
22
27
  logger.inform(tag, *args)
23
28
  end
@@ -5,7 +5,10 @@ module Ramaze
5
5
  class Informer
6
6
  include Informing
7
7
 
8
- attr_accessor :colorize, :out
8
+ attr_accessor :out, :colorize
9
+
10
+ # Should Ramaze try to use colors?
11
+ trait :colorize => true
9
12
 
10
13
  # parameter for Time.now.strftime
11
14
  trait :timestamp => "%Y-%m-%d %H:%M:%S"
@@ -14,14 +17,16 @@ module Ramaze
14
17
  trait :format => "[%time] %prefix %text"
15
18
 
16
19
  # Which tag should be in what color
17
- trait :colors => {
20
+ COLORS = {
18
21
  :info => :green,
19
22
  :debug => :yellow,
20
23
  :warn => :red,
21
24
  :error => :red,
22
25
  }
23
26
 
24
- def initialize(out = $stdout, colorize = nil)
27
+ def initialize(out = $stdout)
28
+ @colorize = false
29
+
25
30
  @out =
26
31
  case out
27
32
  when STDOUT, :stdout, 'stdout'
@@ -34,12 +39,13 @@ module Ramaze
34
39
  if out.respond_to?(:puts)
35
40
  out
36
41
  else
37
- colorize = false
38
42
  File.open(out.to_s, 'ab+')
39
43
  end
40
44
  end
41
45
 
42
- @colorize = @out.tty? rescue false if colorize.nil?
46
+ if @out.respond_to?(:tty?) and class_trait[:colorize]
47
+ @colorize = @out.tty?
48
+ end
43
49
  end
44
50
 
45
51
  def shutdown
@@ -56,7 +62,7 @@ module Ramaze
56
62
  prefix = tag.to_s.upcase.ljust(5)
57
63
 
58
64
  if @colorize
59
- color = class_trait[:colors][tag] ||= :white
65
+ color = COLORS[tag] ||= :white
60
66
  prefix.replace prefix.send(color)
61
67
  end
62
68
 
@@ -2,6 +2,18 @@
2
2
  # All files in this distribution are subject to the terms of the Ruby license.
3
3
 
4
4
  module Ramaze
5
+
6
+ # This module provides a basic skeleton for your own loggers to be compatible.
7
+ # The minimal usage is like this:
8
+ #
9
+ # class MyLogger
10
+ # include Informing
11
+ #
12
+ # def inform(tag, *args)
13
+ # p tag => args
14
+ # end
15
+ # end
16
+
5
17
  module Informing
6
18
  def tag_inform(tag, meth, *strings)
7
19
  strings.each do |string|
@@ -10,24 +22,33 @@ module Ramaze
10
22
  end
11
23
  end
12
24
 
13
- def info(*strings)
14
- tag_inform(:info, :to_s, *strings)
25
+ # Converts everything given to strings and passes them on with :info
26
+
27
+ def info(*objects)
28
+ tag_inform(:info, :to_s, *objects)
15
29
  end
16
30
 
17
- def warn(*strings)
18
- tag_inform(:warn, :to_s, *strings)
31
+ # Converts everything given to strings and passes them on with :warn
32
+
33
+ def warn(*objects)
34
+ tag_inform(:warn, :to_s, *objects)
19
35
  end
20
36
 
21
- def debug(*strings)
22
- tag_inform(:debug, :inspect, *strings)
37
+ # inspects objects if they are no strings. Tag is :debug
38
+
39
+ def debug(*objects)
40
+ tag_inform(:debug, :inspect, *objects)
23
41
  end
24
42
 
25
43
  alias << debug
26
44
 
45
+ # Takes either an Exception or just a String, formats backtraces to be a bit
46
+ # more readable and passes all of this on to tag_inform :error
47
+
27
48
  def error(ex)
28
49
  if ex.respond_to?(:exception)
29
50
  message = ex.backtrace[0..Global.backtrace_size]
30
- message.map!{|m| m.gsub(/^#{Dir.pwd}/, '.') }
51
+ message.map{|m| m.gsub!(/^#{Dir.pwd}/, '.') }
31
52
  message.unshift(ex.inspect)
32
53
  else
33
54
  message = ex.to_s
@@ -35,10 +56,14 @@ module Ramaze
35
56
  tag_inform(:error, :to_s, *message)
36
57
  end
37
58
 
59
+ # raises
60
+
38
61
  def inform(*args)
39
62
  raise "#inform should be implemented by an instance including this module (#{self})"
40
63
  end
41
64
 
65
+ # nothing
66
+
42
67
  def shutdown
43
68
  end
44
69
 
@@ -0,0 +1,21 @@
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
+
6
+ class Knotify
7
+ include Informing
8
+
9
+ trait :present => 16
10
+
11
+ # Please see for more information:
12
+ # http://lukeplant.me.uk/articles.php?id=3
13
+ def inform(tag, *messages)
14
+ present = class_trait[:present]
15
+ tag = tag.to_s.capitalize
16
+ messages.flatten.each do |message|
17
+ system(%{dcop knotify default notify Ramaze "#{tag}" "#{message}" '' '' #{present} 0})
18
+ end
19
+ end
20
+ end
21
+ end
@@ -2,40 +2,74 @@
2
2
  # All files in this distribution are subject to the terms of the Ruby license.
3
3
 
4
4
  require 'xosd'
5
+ require 'thread'
5
6
 
6
7
  module Ramaze
7
8
 
8
9
  class Xosd < ::Xosd
9
- include Informing
10
+ attr_accessor :options
10
11
 
11
- trait :timeout => 3
12
- trait :lines => 3
12
+ include Informing
13
13
 
14
- trait :colors => {
15
- :error => "#FF0000",
16
- :info => "#00FF00",
17
- :warn => "#EAA61E",
18
- :debug => "#FFFFFF"
14
+ DEFAULT = {
15
+ :font_size => 20,
16
+ :font => "-*-*-*-*-*-*-%d-*-*-*-*-*-*-*",
17
+ :align => 'center',
18
+ :color => '#FFFFFF',
19
+ :lines => 3,
20
+ :valign => 'top',
21
+ :timeout => 3,
22
+ :outline_color => "#000000",
23
+ :outline_width => 1,
24
+ :vertical_offset => 20,
25
+ :colors => {
26
+ :error => "#FF0000",
27
+ :info => "#00FF00",
28
+ :warn => "#EAA61E",
29
+ :debug => "#FFFF00"
30
+ },
19
31
  }
20
32
 
21
- def initialize
22
- super(class_trait[:lines])
23
-
24
- self.font = "-*-*-*-*-*-*-24-*-*-*-*-*-*-*"
25
- self.align = 'center'
26
- self.color = '#FFFFFF'
27
- self.valign = 'top'
28
- self.timeout = class_trait[:timeout]
29
- self.outline_color = "#000000"
30
- self.outline_width = 1
31
- self.vertical_offset = 20
32
- end
33
+ # keys to ignore when setting the options to the instance.
34
+ IGNORE = [:colors, :font_size, :lines]
35
+
36
+ # Here new messages are pushed to eventually displaying them.
37
+ QUEUE = Queue.new
38
+
39
+ def initialize(options = {})
40
+ @options = DEFAULT.merge(options)
41
+
42
+ super(@options[:lines])
33
43
 
34
- def inform(tag, *args)
35
- self.color = class_trait[:colors][tag.to_sym]
44
+ @options.each do |key, value|
45
+ next if IGNORE.include?(key)
46
+ value %= @options[:font_size] if key == :font
47
+ send("#{key}=", value)
48
+ end
49
+
50
+ Thread.new(self) do |xosd|
51
+ loop do
52
+ items = []
53
+ lines = xosd.options[:lines]
54
+ items << QUEUE.shift until QUEUE.empty? or items.size >= lines
55
+
56
+ unless items.empty?
57
+ # pad up with empty lines to avoid dragging around old messages.
58
+ items << [:info, ' '] until items.size >= lines
59
+
60
+ items.each_with_index do |(tag, message), i|
61
+ xosd.color = xosd.options[:colors][tag.to_sym]
62
+ xosd.display(message, i)
63
+ end
64
+ end
65
+ sleep xosd.options[:timeout]
66
+ end
67
+ end
68
+ end
36
69
 
37
- args.each_with_index do |arg, i|
38
- display(arg, i)
70
+ def inform(tag, *messages)
71
+ messages.each do |message|
72
+ QUEUE << [tag, message]
39
73
  end
40
74
  end
41
75
  end
@@ -9,7 +9,8 @@ module Ramaze
9
9
 
10
10
  def initialize interval = 1, reload_glob = %r{(^\./)|#{Dir.pwd}|ramaze}
11
11
  @interval, @reload_glob = interval, reload_glob
12
- @mtimes, @map = {}, []
12
+ @map, @files, @paths = [], [], []
13
+ @mtimes = {}
13
14
  end
14
15
 
15
16
  def start
@@ -45,6 +46,7 @@ module Ramaze
45
46
  #
46
47
 
47
48
  def reload
49
+ SourceReloadHooks.before_reload
48
50
  all_reload_files.each do |file|
49
51
  mtime = mtime(file)
50
52
 
@@ -53,6 +55,7 @@ module Ramaze
53
55
  Inform.debug("reload #{file}")
54
56
  @mtimes[file] = mtime if safe_load(file)
55
57
  end
58
+ SourceReloadHooks.after_reload
56
59
  end
57
60
 
58
61
  def all_reload_files
@@ -79,11 +82,37 @@ module Ramaze
79
82
  end
80
83
 
81
84
  def safe_load(file)
85
+ SourceReloadHooks.before_safe_load(file)
82
86
  load(file)
87
+ SourceReloadHooks.after_safe_load_succeed(file)
83
88
  true
84
89
  rescue Object => ex
85
90
  Inform.error(ex)
91
+ SourceReloadHooks.after_safe_load_failed(file, ex)
86
92
  false
87
93
  end
88
94
  end
95
+
96
+ # Holds hooks that are called before and after #reload and #safe_load
97
+
98
+ module SourceReloadHooks
99
+ module_function
100
+
101
+ def before_reload
102
+ end
103
+
104
+ def after_reload
105
+ end
106
+
107
+ def before_safe_load(file)
108
+ end
109
+
110
+ def after_safe_load_succeed(file)
111
+ Cache.compiled.clear
112
+ Cache.resolved.clear
113
+ end
114
+
115
+ def after_safe_load_failed(file, error)
116
+ end
117
+ end
89
118
  end
@@ -7,31 +7,35 @@
7
7
  module Ramaze
8
8
  module Template
9
9
 
10
+ COMPILED = {} unless defined?(COMPILED)
11
+
12
+ # Place register_engine puts the class and extensions for templating engines
13
+
14
+ ENGINES = {} unless defined?(ENGINES)
15
+
10
16
  %w[ Amrita2 Erubis Haml Liquid Markaby Remarkably ].each do |const|
11
17
  autoload(const, "ramaze/template/#{const.downcase}")
12
18
  end
13
19
 
14
- # The superclass for all templates, doesn't do much more than including
15
- # Ramaze::Helper and defining #reaction_or_file
20
+ # The superclass for all templates, contains the shared behaviour of
21
+ # the templates and includes Ramaze::Helper
16
22
 
17
23
  class Template
18
24
  include Ramaze::Helper
19
25
 
20
26
  class << self
21
27
 
22
- # pass it the results of the method of the controller
23
- # and a possible file, it will see if the file is an actual file
28
+ # calls result_and_file with the given action and returns the first of
29
+ # the result of the controller or content of the file.
24
30
 
25
31
  def reaction_or_file action
26
- reaction = render_method(action)
27
-
28
- if file = action.template
29
- File.read(file)
30
- else
31
- reaction.to_s
32
- end
32
+ result_and_file(action).reverse.compact.first
33
33
  end
34
34
 
35
+ # Takes an Action and returns the result from sending the action.method
36
+ # to the controller via render_method and reads the contents of the file
37
+ # if given.
38
+
35
39
  def result_and_file(action)
36
40
  result = render_method(action)
37
41
 
@@ -42,9 +46,26 @@ module Ramaze
42
46
  [result, content]
43
47
  end
44
48
 
49
+ # returns nil if no method is on the action, otherwise it will send the
50
+ # action and optional parameters to the controller via __send__ and
51
+ # return the unaltered result
52
+
45
53
  def render_method(action)
46
54
  return unless method = action.method
47
- action.controller.__send__(method, *action.params)
55
+ action.instance.__send__(method, *action.params)
56
+ end
57
+
58
+ # This is a wrapper to use Global.compile without even thinking about it.
59
+ # Don't use it if your engine is not based on a compile/eval principle.
60
+
61
+ def wrap_compile(action, template = nil)
62
+ template ||= reaction_or_file(action).to_s
63
+
64
+ if Global.compile
65
+ Cache.compiled[action.relaxed_hash] ||= compile(action, template)
66
+ else
67
+ compile(action, template)
68
+ end
48
69
  end
49
70
  end
50
71
  end
@@ -3,32 +3,33 @@
3
3
 
4
4
  require 'amrita2/template'
5
5
 
6
- module Ramaze::Template
6
+ module Ramaze
7
+ module Template
8
+ # Is responsible for compiling a template using the Amrita2 templating engine.
7
9
 
8
- # Is responsible for compiling a template using the Amrita2 templating engine.
10
+ class Amrita2 < Template
9
11
 
10
- class Amrita2 < Template
12
+ ENGINES[self] = %w[ amrita amr ]
11
13
 
12
- Ramaze::Controller.register_engine self, %w[ amrita ]
14
+ class << self
13
15
 
14
- class << self
16
+ # Takes an Action
17
+ # The file is rendered using Amrita2::TemplateFile.
18
+ # The Controller is used as the object for expansion.
19
+ #
20
+ # The parameters are set to @params in the controller before expansion.
15
21
 
16
- # Takes an Action
17
- # The file is rendered using Amrita2::TemplateFile.
18
- # The Controller is used as the object for expansion.
19
- #
20
- # The parameters are set to @params in the controller before expansion.
22
+ def transform action
23
+ instance, params, file =
24
+ action.instance, action.params, action.template
25
+ raise_no_action(action) unless file
21
26
 
22
- def transform action
23
- controller, params, file =
24
- action.controller, action.params, action.template
25
- raise_no_action(action) unless file
26
-
27
- template = ::Amrita2::TemplateFile.new(file)
28
- out = ''
29
- controller.instance_variable_set('@params', params)
30
- template.expand(out, controller)
31
- out
27
+ template = ::Amrita2::TemplateFile.new(file)
28
+ out = ''
29
+ instance.instance_variable_set('@params', params)
30
+ template.expand(out, instance)
31
+ out
32
+ end
32
33
  end
33
34
  end
34
35
  end