reactive-mvc 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +21 -0
- data/Manifest +34 -0
- data/README +30 -0
- data/Rakefile +5 -0
- data/lib/reactive-mvc.rb +26 -0
- data/lib/reactive-mvc/controller.rb +16 -0
- data/lib/reactive-mvc/controller/base.rb +405 -0
- data/lib/reactive-mvc/controller/filters.rb +767 -0
- data/lib/reactive-mvc/controller/flash.rb +161 -0
- data/lib/reactive-mvc/controller/helpers.rb +203 -0
- data/lib/reactive-mvc/controller/layout.rb +285 -0
- data/lib/reactive-mvc/controller/output.rb +262 -0
- data/lib/reactive-mvc/controller/rescue.rb +208 -0
- data/lib/reactive-mvc/dispatcher.rb +133 -0
- data/lib/reactive-mvc/view.rb +18 -0
- data/lib/reactive-mvc/view/base.rb +388 -0
- data/lib/reactive-mvc/view/helpers.rb +38 -0
- data/lib/reactive-mvc/view/partials.rb +207 -0
- data/lib/reactive-mvc/view/paths.rb +125 -0
- data/lib/reactive-mvc/view/renderable.rb +98 -0
- data/lib/reactive-mvc/view/renderable_partial.rb +49 -0
- data/lib/reactive-mvc/view/template.rb +110 -0
- data/lib/reactive-mvc/view/template_error.rb +9 -0
- data/lib/reactive-mvc/view/template_handler.rb +9 -0
- data/lib/reactive-mvc/view/template_handlers.rb +43 -0
- data/lib/reactive-mvc/view/template_handlers/builder.rb +15 -0
- data/lib/reactive-mvc/view/template_handlers/erb.rb +20 -0
- data/lib/reactive-mvc/view/template_handlers/ruby_code.rb +9 -0
- data/reactive_app_generators/mvc/USAGE +10 -0
- data/reactive_app_generators/mvc/mvc_generator.rb +48 -0
- data/reactive_app_generators/mvc/templates/application_controller.rb +2 -0
- data/reactive_generators/controller/USAGE +7 -0
- data/reactive_generators/controller/controller_generator.rb +24 -0
- data/reactive_generators/controller/templates/controller.rb +2 -0
- 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,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,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,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
|
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
|
+
|