reactive-mvc 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. data/LICENSE +21 -0
  2. data/Manifest +34 -0
  3. data/README +30 -0
  4. data/Rakefile +5 -0
  5. data/lib/reactive-mvc.rb +26 -0
  6. data/lib/reactive-mvc/controller.rb +16 -0
  7. data/lib/reactive-mvc/controller/base.rb +405 -0
  8. data/lib/reactive-mvc/controller/filters.rb +767 -0
  9. data/lib/reactive-mvc/controller/flash.rb +161 -0
  10. data/lib/reactive-mvc/controller/helpers.rb +203 -0
  11. data/lib/reactive-mvc/controller/layout.rb +285 -0
  12. data/lib/reactive-mvc/controller/output.rb +262 -0
  13. data/lib/reactive-mvc/controller/rescue.rb +208 -0
  14. data/lib/reactive-mvc/dispatcher.rb +133 -0
  15. data/lib/reactive-mvc/view.rb +18 -0
  16. data/lib/reactive-mvc/view/base.rb +388 -0
  17. data/lib/reactive-mvc/view/helpers.rb +38 -0
  18. data/lib/reactive-mvc/view/partials.rb +207 -0
  19. data/lib/reactive-mvc/view/paths.rb +125 -0
  20. data/lib/reactive-mvc/view/renderable.rb +98 -0
  21. data/lib/reactive-mvc/view/renderable_partial.rb +49 -0
  22. data/lib/reactive-mvc/view/template.rb +110 -0
  23. data/lib/reactive-mvc/view/template_error.rb +9 -0
  24. data/lib/reactive-mvc/view/template_handler.rb +9 -0
  25. data/lib/reactive-mvc/view/template_handlers.rb +43 -0
  26. data/lib/reactive-mvc/view/template_handlers/builder.rb +15 -0
  27. data/lib/reactive-mvc/view/template_handlers/erb.rb +20 -0
  28. data/lib/reactive-mvc/view/template_handlers/ruby_code.rb +9 -0
  29. data/reactive_app_generators/mvc/USAGE +10 -0
  30. data/reactive_app_generators/mvc/mvc_generator.rb +48 -0
  31. data/reactive_app_generators/mvc/templates/application_controller.rb +2 -0
  32. data/reactive_generators/controller/USAGE +7 -0
  33. data/reactive_generators/controller/controller_generator.rb +24 -0
  34. data/reactive_generators/controller/templates/controller.rb +2 -0
  35. metadata +113 -0
@@ -0,0 +1,49 @@
1
+ module Reactive::Mvc::View
2
+ # NOTE: The template that this mixin is being included into is frozen
3
+ # so you cannot set or modify any instance variables
4
+ module RenderablePartial #:nodoc:
5
+ extend ActiveSupport::Memoizable
6
+
7
+ def variable_name
8
+ name.sub(/\A_/, '').to_sym
9
+ end
10
+ memoize :variable_name
11
+
12
+ def counter_name
13
+ "#{variable_name}_counter".to_sym
14
+ end
15
+ memoize :counter_name
16
+
17
+ =begin
18
+ def render(view, local_assigns = {})
19
+ if defined? ActionController
20
+ ActionController::Base.benchmark("Rendered #{path_without_format_and_extension}", Logger::DEBUG, false) do
21
+ super
22
+ end
23
+ else
24
+ super
25
+ end
26
+ end
27
+ =end
28
+ def render_partial(view, object = nil, local_assigns = {}, as = nil)
29
+ object ||= local_assigns[:object] ||
30
+ local_assigns[variable_name]
31
+
32
+ if view.respond_to?(:controller)
33
+ ivar = :"@#{variable_name}"
34
+ object ||=
35
+ if view.controller.instance_variable_defined?(ivar)
36
+ ActiveSupport::Deprecation::DeprecatedObjectProxy.new(
37
+ view.controller.instance_variable_get(ivar),
38
+ "#{ivar} will no longer be implicitly assigned to #{variable_name}")
39
+ end
40
+ end
41
+
42
+ # Ensure correct object is reassigned to other accessors
43
+ local_assigns[:object] = local_assigns[variable_name] = object
44
+ local_assigns[as] = object if as
45
+
46
+ render_template(view, local_assigns)
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,110 @@
1
+ module Reactive::Mvc
2
+ module View #:nodoc:
3
+ class Template
4
+ extend TemplateHandlers
5
+ extend ActiveSupport::Memoizable
6
+ include Renderable
7
+
8
+ attr_accessor :filename, :load_path, :base_path, :name, :format, :extension
9
+ delegate :to_s, :to => :path
10
+
11
+ def initialize(template_path, load_paths = [])
12
+ template_path = template_path.dup
13
+ @base_path, @name, @format, @extension = split(template_path)
14
+ @base_path.to_s.gsub!(/\/$/, '') # Push to split method
15
+ @load_path, @filename = find_full_path(template_path, load_paths)
16
+
17
+ # Extend with partial super powers
18
+ extend RenderablePartial if @name =~ /^_/
19
+ end
20
+
21
+ def format_and_extension
22
+ (extensions = [format, extension].compact.join(".")).blank? ? nil : extensions
23
+ end
24
+ memoize :format_and_extension
25
+
26
+ def multipart?
27
+ format && format.include?('.')
28
+ end
29
+
30
+ def content_type
31
+ format.gsub('.', '/')
32
+ end
33
+
34
+ def path
35
+ [base_path, [name, format, extension].compact.join('.')].compact.join('/')
36
+ end
37
+ memoize :path
38
+
39
+ def path_without_extension
40
+ [base_path, [name, format].compact.join('.')].compact.join('/')
41
+ end
42
+ memoize :path_without_extension
43
+
44
+ def path_without_format_and_extension
45
+ [base_path, name].compact.join('/')
46
+ end
47
+ memoize :path_without_format_and_extension
48
+
49
+ def relative_path
50
+ path = File.expand_path(filename)
51
+ path.sub(/^#{Regexp.escape(Reactive.configuration.root_dir)}\//, '')
52
+ end
53
+ memoize :relative_path
54
+
55
+ def source
56
+ File.read(filename)
57
+ end
58
+ memoize :source
59
+
60
+ def method_segment
61
+ relative_path.to_s.gsub(/([^a-zA-Z0-9_])/) { $1.ord }
62
+ end
63
+ memoize :method_segment
64
+
65
+ def render_template(view, local_assigns = {})
66
+ render(view, local_assigns)
67
+ rescue Exception => e
68
+ raise e unless filename
69
+ if TemplateError === e
70
+ e.sub_template_of(relative_path)
71
+ raise e
72
+ else
73
+ raise TemplateError.new(relative_path, source, e)
74
+ end
75
+ end
76
+
77
+ private
78
+ def valid_extension?(extension)
79
+ Template.template_handler_extensions.include?(extension)
80
+ end
81
+
82
+ def find_full_path(path, load_paths)
83
+ load_paths = Array(load_paths) + [nil]
84
+ load_paths.each do |load_path|
85
+ file = [load_path, path].compact.join('/')
86
+ return load_path, file if File.file?(file)
87
+ end
88
+ raise MissingTemplate.new(load_paths, path)
89
+ end
90
+
91
+ # Returns file split into an array
92
+ # [base_path, name, format, extension]
93
+ def split(file)
94
+ if m = file.match(/^(.*\/)?([^\.]+)\.?(\w+)?\.?(\w+)?\.?(\w+)?$/)
95
+ if m[5] # Multipart formats
96
+ [m[1], m[2], "#{m[3]}.#{m[4]}", m[5]]
97
+ elsif m[4] # Single format
98
+ [m[1], m[2], m[3], m[4]]
99
+ else
100
+ if valid_extension?(m[3]) # No format
101
+ [m[1], m[2], nil, m[3]]
102
+ else # No extension
103
+ [m[1], m[2], m[3], nil]
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,9 @@
1
+ module Reactive::Mvc
2
+ module View
3
+ # The TemplateError exception is raised when the compilation of the template fails. This exception then gathers a
4
+ # bunch of intimate details and uses it to report a very precise exception message.
5
+ class TemplateError < Error #:nodoc:
6
+ include Reactive::TemplateError
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # Legacy TemplateHandler stub
2
+
3
+ module Reactive::Mvc::View
4
+ class TemplateHandler
5
+ def self.call(template)
6
+ new.compile(template)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,43 @@
1
+ require 'reactive-mvc/view/template_handler'
2
+ #require 'reactive-mvc/view/template_handlers/builder'
3
+ require 'reactive-mvc/view/template_handlers/erb'
4
+ require 'reactive-mvc/view/template_handlers/ruby_code'
5
+
6
+ module Reactive::Mvc
7
+ module View #:nodoc:
8
+ module TemplateHandlers #:nodoc:
9
+ def self.extended(base)
10
+ base.register_default_template_handler :rb, TemplateHandlers::RubyCode
11
+ base.register_template_handler :erb, TemplateHandlers::ERB
12
+ # base.register_template_handler :builder, TemplateHandlers::Builder
13
+ end
14
+
15
+ @@template_handlers = {}
16
+ @@default_template_handlers = nil
17
+
18
+ # Register a class that knows how to handle template files with the given
19
+ # extension. This can be used to implement new template types.
20
+ # The constructor for the class must take the Reactive::View::Base instance
21
+ # as a parameter, and the class must implement a +render+ method that
22
+ # takes the contents of the template to render as well as the Hash of
23
+ # local assigns available to the template. The +render+ method ought to
24
+ # return the rendered template as a string.
25
+ def register_template_handler(extension, klass)
26
+ @@template_handlers[extension.to_sym] = klass
27
+ end
28
+
29
+ def template_handler_extensions
30
+ @@template_handlers.keys.map(&:to_s).sort
31
+ end
32
+
33
+ def register_default_template_handler(extension, klass)
34
+ register_template_handler(extension, klass)
35
+ @@default_template_handlers = klass
36
+ end
37
+
38
+ def handler_class_for_extension(extension)
39
+ (extension && @@template_handlers[extension.to_sym]) || @@default_template_handlers
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,15 @@
1
+ require 'builder'
2
+
3
+ module Reactive::Mvc::View
4
+ module TemplateHandlers
5
+ class Builder < TemplateHandler
6
+ def compile(template)
7
+ "_set_controller_content_type(Mime::XML);" +
8
+ "xml = ::Builder::XmlMarkup.new(:indent => 2);" +
9
+ "self.output_buffer = xml.target!;" +
10
+ template.source +
11
+ ";xml.target!;"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,20 @@
1
+ require 'erb'
2
+
3
+ module Reactive::Mvc::View
4
+ module TemplateHandlers
5
+ class ERB < TemplateHandler
6
+ # Specify trim mode for the ERB compiler. Defaults to '-'.
7
+ # See ERb documentation for suitable values.
8
+ cattr_accessor :erb_trim_mode
9
+ self.erb_trim_mode = '-'
10
+
11
+ def compile(template)
12
+ src = ::ERB.new("<% __in_erb_template=true %>#{template.source}", nil, erb_trim_mode, '@output_buffer').src
13
+
14
+ # Ruby 1.9 prepends an encoding to the source. However this is
15
+ # useless because you can only set an encoding on the first line
16
+ RUBY_VERSION >= '1.9' ? src.sub(/\A#coding:.*\n/, '') : src
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,9 @@
1
+ module Reactive::Mvc::View
2
+ module TemplateHandlers
3
+ class RubyCode < TemplateHandler
4
+ def compile(template)
5
+ template.source.inspect
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ Description:
2
+ Creates the required directories for MVC files which by default are:
3
+ app/models
4
+ app/controllers
5
+ app/helpers
6
+ app/views
7
+
8
+ Creates the application controller.
9
+
10
+ Modifies the config file to setup the default dispatcher (see config/config.rb)
@@ -0,0 +1,48 @@
1
+ class MvcGenerator < RubiGen::Base
2
+ attr_reader :app_name
3
+
4
+ def initialize(runtime_args, runtime_options = {})
5
+ super
6
+ @destination_root = runtime_args.shift || '.'
7
+ @app_name = File.basename(File.expand_path(@destination_root))
8
+ extract_options
9
+ end
10
+
11
+ def manifest
12
+ record do |m|
13
+ [:mvc, :views, :model, :helper, :controller, :test].each do |dir_id|
14
+ m.directory(Reactive.relative_path_for(dir_id))
15
+ end
16
+
17
+ m.file "application_controller.rb", Reactive.relative_path_for(:controller, "application_controller.rb")
18
+
19
+ unless options[:pretend]
20
+ # Find the beginning of the config block, then skip all gems statments, insert here.
21
+ m.gsub_file Reactive.relative_path_for(:config, "config.rb"), /with Reactive\.configuration do \|config\|.*config.gem.*?$/mi do |match|
22
+ "#{match}\n\n config.dispatcher.default_dispatcher = :mvc\n"
23
+ end
24
+ end
25
+
26
+ end
27
+ end
28
+
29
+ protected
30
+
31
+ def add_options!(opts)
32
+ # opts.separator ''
33
+ # opts.separator 'Options:'
34
+ # # For each option below, place the default
35
+ # # at the top of the file next to "default_options"
36
+ # opts.on("-r", "--ruby=path", String,
37
+ # "Path to the Ruby binary of your choice (otherwise scripts use env, dispatchers current path).",
38
+ # "Default: #{DEFAULT_SHEBANG}") { |options[:shebang]| }
39
+ end
40
+
41
+ def extract_options
42
+ # for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
43
+ # Templates can access these value via the attr_reader-generated methods, but not the
44
+ # raw instance variable value.
45
+ # @author = options[:author]
46
+ end
47
+
48
+ end
@@ -0,0 +1,2 @@
1
+ class ApplicationController < Reactive::Mvc::Controller::Base
2
+ end
@@ -0,0 +1,7 @@
1
+ Description:
2
+ Generate an empty controller.
3
+
4
+ Pass the name of the controller as the first argument.
5
+
6
+ Examples:
7
+ `./script/generate controller product`
@@ -0,0 +1,24 @@
1
+ class ControllerGenerator < Reactive::NamedBaseGenerator
2
+ def manifest
3
+ record do |m|
4
+ # Check for class naming collisions.
5
+ m.class_collisions(path, "#{plural_class_name}Controller")
6
+
7
+ # Controller, helper, views, and test directories.
8
+ m.directory(Reactive.relative_path_for(:controller, path))
9
+
10
+ m.template('controller.rb', Reactive.relative_path_for(:controller, path, "#{plural_name}_controller.rb"))
11
+ # m.template('functional_test.rb', File.join('test/functional', controller_class_path, "#{controller_file_name}_controller_test.rb"))
12
+ end
13
+ end
14
+
15
+ protected
16
+ # Override with your own usage banner.
17
+ def banner
18
+ "Usage: #{$0} controller [name]"
19
+ end
20
+
21
+ def add_options!(opt)
22
+ end
23
+
24
+ end
@@ -0,0 +1,2 @@
1
+ class <%= plural_class_name %>Controller < ApplicationController
2
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: reactive-mvc
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Pascal Hurni
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-05-12 00:00:00 +02:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: reactive-core
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.2.0
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: activesupport
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 2.0.0
34
+ version:
35
+ description: Provides a local MVC machinery to handle requests of the reactive application. The machinery is mapped to what is done in RubyOnRails, so you'll have rails like controllers, rails like views and helpers. Because Reactive is Model and View agnostic, this plugin alone will not do the complete job.
36
+ email: phi@ruby-reactive.org
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - README
43
+ - LICENSE
44
+ files:
45
+ - README
46
+ - LICENSE
47
+ - Manifest
48
+ - Rakefile
49
+ - lib/reactive-mvc.rb
50
+ - lib/reactive-mvc/controller.rb
51
+ - lib/reactive-mvc/controller/base.rb
52
+ - lib/reactive-mvc/controller/filters.rb
53
+ - lib/reactive-mvc/controller/flash.rb
54
+ - lib/reactive-mvc/controller/helpers.rb
55
+ - lib/reactive-mvc/controller/layout.rb
56
+ - lib/reactive-mvc/controller/output.rb
57
+ - lib/reactive-mvc/controller/rescue.rb
58
+ - lib/reactive-mvc/dispatcher.rb
59
+ - lib/reactive-mvc/view.rb
60
+ - lib/reactive-mvc/view/base.rb
61
+ - lib/reactive-mvc/view/helpers.rb
62
+ - lib/reactive-mvc/view/partials.rb
63
+ - lib/reactive-mvc/view/paths.rb
64
+ - lib/reactive-mvc/view/renderable.rb
65
+ - lib/reactive-mvc/view/renderable_partial.rb
66
+ - lib/reactive-mvc/view/template.rb
67
+ - lib/reactive-mvc/view/template_error.rb
68
+ - lib/reactive-mvc/view/template_handler.rb
69
+ - lib/reactive-mvc/view/template_handlers.rb
70
+ - lib/reactive-mvc/view/template_handlers/builder.rb
71
+ - lib/reactive-mvc/view/template_handlers/erb.rb
72
+ - lib/reactive-mvc/view/template_handlers/ruby_code.rb
73
+ - reactive_app_generators/mvc/USAGE
74
+ - reactive_app_generators/mvc/mvc_generator.rb
75
+ - reactive_app_generators/mvc/templates/application_controller.rb
76
+ - reactive_generators/controller/USAGE
77
+ - reactive_generators/controller/controller_generator.rb
78
+ - reactive_generators/controller/templates/controller.rb
79
+ has_rdoc: true
80
+ homepage: http://www.ruby-reactive.org
81
+ post_install_message:
82
+ rdoc_options:
83
+ - -x
84
+ - Manifest
85
+ - -x
86
+ - Rakefile
87
+ - -x
88
+ - .*\.rake
89
+ - -m
90
+ - README
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: "0"
98
+ version:
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: "0"
104
+ version:
105
+ requirements: []
106
+
107
+ rubyforge_project: reactive-mvc
108
+ rubygems_version: 1.3.1
109
+ signing_key:
110
+ specification_version: 2
111
+ summary: Reactive plugin that dispatches requests to a local MVC machinery.
112
+ test_files: []
113
+