modular 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +4 -0
- data/README +0 -0
- data/Rakefile +2 -0
- data/TODO +2 -0
- data/autotest/discover.rb +12 -0
- data/lib/generators/component/USAGE +9 -0
- data/lib/generators/component/component_generator.rb +16 -0
- data/lib/generators/component/templates/component.rb.erb +6 -0
- data/lib/generators/component/templates/template.erb +2 -0
- data/lib/modular/abstract_model.rb +74 -0
- data/lib/modular/caching.rb +62 -0
- data/lib/modular/components/base.rb +29 -0
- data/lib/modular/components/container.rb +39 -0
- data/lib/modular/components/main_content.rb +9 -0
- data/lib/modular/configuration.rb +31 -0
- data/lib/modular/layout_generator.rb +66 -0
- data/lib/modular/rails.rb +16 -0
- data/lib/modular/rendering.rb +72 -0
- data/lib/modular/version.rb +3 -0
- data/lib/modular.rb +57 -0
- data/modular-app/Gemfile +20 -0
- data/modular-app/Rakefile +7 -0
- data/modular-app/app/components/cached_for_time.rb +10 -0
- data/modular-app/app/components/cached_forever.rb +10 -0
- data/modular-app/app/components/fake_news_feed.rb +9 -0
- data/modular-app/app/components/foobar.rb +7 -0
- data/modular-app/app/components/heavy_task.rb +5 -0
- data/modular-app/app/components/validated.rb +10 -0
- data/modular-app/app/components/vertical.rb +4 -0
- data/modular-app/app/controllers/application_controller.rb +3 -0
- data/modular-app/app/controllers/cached_for_time_controller.rb +7 -0
- data/modular-app/app/controllers/cached_forever_controller.rb +6 -0
- data/modular-app/app/controllers/callback_layout_controller.rb +11 -0
- data/modular-app/app/controllers/example_controller.rb +5 -0
- data/modular-app/app/controllers/indirect_render_controller.rb +7 -0
- data/modular-app/app/controllers/layout_test_controller.rb +6 -0
- data/modular-app/app/helpers/application_helper.rb +2 -0
- data/modular-app/app/helpers/callback_layout_helper.rb +2 -0
- data/modular-app/app/helpers/example_helper.rb +2 -0
- data/modular-app/app/helpers/indirect_render_helper.rb +2 -0
- data/modular-app/app/models/simple_model.rb +14 -0
- data/modular-app/app/views/cached_for_time/index.html.erb +2 -0
- data/modular-app/app/views/cached_forever/index.html.erb +0 -0
- data/modular-app/app/views/callback_layout/index.html.erb +2 -0
- data/modular-app/app/views/components/cached_for_time.html.erb +2 -0
- data/modular-app/app/views/components/cached_forever.html.erb +2 -0
- data/modular-app/app/views/components/container.html.erb +7 -0
- data/modular-app/app/views/components/fake_news_feed.html.erb +1 -0
- data/modular-app/app/views/components/foobar.html.erb +4 -0
- data/modular-app/app/views/components/heavy_task.html.erb +1 -0
- data/modular-app/app/views/components/validated.html.erb +2 -0
- data/modular-app/app/views/components/vertical.html.erb +2 -0
- data/modular-app/app/views/example/index.html.erb +2 -0
- data/modular-app/app/views/indirect_render/index.html.erb +2 -0
- data/modular-app/app/views/layout_test/index.html.erb +1 -0
- data/modular-app/app/views/layouts/application.html.erb +16 -0
- data/modular-app/config/application.rb +42 -0
- data/modular-app/config/boot.rb +6 -0
- data/modular-app/config/database.yml +22 -0
- data/modular-app/config/environment.rb +5 -0
- data/modular-app/config/environments/development.rb +26 -0
- data/modular-app/config/environments/production.rb +49 -0
- data/modular-app/config/environments/test.rb +35 -0
- data/modular-app/config/initializers/backtrace_silencers.rb +7 -0
- data/modular-app/config/initializers/inflections.rb +10 -0
- data/modular-app/config/initializers/mime_types.rb +5 -0
- data/modular-app/config/initializers/modular.rb +20 -0
- data/modular-app/config/initializers/secret_token.rb +7 -0
- data/modular-app/config/initializers/session_store.rb +8 -0
- data/modular-app/config/locales/en.yml +5 -0
- data/modular-app/config/routes.rb +7 -0
- data/modular-app/config.ru +4 -0
- data/modular-app/db/migrate/20110721090602_create_simple_models.rb +12 -0
- data/modular-app/db/schema.rb +20 -0
- data/modular-app/db/seeds.rb +7 -0
- data/modular-app/script/rails +6 -0
- data/modular-app/spec/components/base.rb +33 -0
- data/modular-app/spec/components/container.rb +34 -0
- data/modular-app/spec/components/validated.rb +15 -0
- data/modular-app/spec/controllers/cached_for_time_controller_spec.rb +20 -0
- data/modular-app/spec/controllers/cached_forever_controller_spec.rb +17 -0
- data/modular-app/spec/controllers/callback_layout_controller_spec.rb +12 -0
- data/modular-app/spec/controllers/example_controller_spec.rb +12 -0
- data/modular-app/spec/controllers/indirect_render_controller_spec.rb +13 -0
- data/modular-app/spec/controllers/layout_test_controller_spec.rb +38 -0
- data/modular-app/spec/helpers/indirect_render_helper_spec.rb +14 -0
- data/modular-app/spec/spec_helper.rb +27 -0
- data/modular-app/spec/views/indirect_render/index.html.erb_spec.rb +4 -0
- data/modular.gemspec +25 -0
- data/spec/base.rb +37 -0
- data/spec/configuration.rb +74 -0
- data/spec/spec_helper.rb +7 -0
- data/templates/layout.erb +17 -0
- metadata +202 -0
data/Gemfile
ADDED
data/README
ADDED
File without changes
|
data/Rakefile
ADDED
data/TODO
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
Autotest.add_discovery { "rspec2" }
|
2
|
+
|
3
|
+
Autotest.add_hook :initialize do |at|
|
4
|
+
at.add_mapping(%r%^spec/.*\.rb$%) { |filename, _|
|
5
|
+
|
6
|
+
filename
|
7
|
+
}
|
8
|
+
|
9
|
+
%w{.git .svn .hg .DS_Store ._* spec/helpers spec/testdata}.each do |exception|
|
10
|
+
at.add_exception(exception)
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class ComponentGenerator < Rails::Generators::NamedBase
|
2
|
+
source_root File.expand_path('../templates', __FILE__)
|
3
|
+
|
4
|
+
def generate_template
|
5
|
+
template "component.rb.erb", "app/components/#{filename}.rb"
|
6
|
+
end
|
7
|
+
|
8
|
+
def generate_controller
|
9
|
+
template "template.erb", "app/views/components/#{filename}.html.erb"
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
def filename
|
14
|
+
name.underscore
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'active_model'
|
2
|
+
|
3
|
+
module Modular
|
4
|
+
module Helpers
|
5
|
+
class AbstractModel
|
6
|
+
include ActiveModel::Validations
|
7
|
+
include ActiveModel::Conversion
|
8
|
+
extend ActiveModel::Naming
|
9
|
+
|
10
|
+
def initialize(attributes = {})
|
11
|
+
@attributes ||= ActiveSupport::HashWithIndifferentAccess.new
|
12
|
+
|
13
|
+
attributes.each do |name, value|
|
14
|
+
@attributes[name.to_s] = value
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def persisted?
|
19
|
+
false
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_json
|
23
|
+
ActiveSupport::JSON.encode @attributes.merge({:type => type})
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.attr_reader(*fields)
|
27
|
+
fields.each do |field|
|
28
|
+
class_eval <<EOF
|
29
|
+
def #{field}
|
30
|
+
@attributes['#{field}']
|
31
|
+
end
|
32
|
+
EOF
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.attr_writer(*fields)
|
37
|
+
fields.each do |field|
|
38
|
+
class_eval <<EOF
|
39
|
+
def #{field}=(value)
|
40
|
+
@attributes['#{field}']=value
|
41
|
+
end
|
42
|
+
EOF
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.attr_accessor(*fields)
|
47
|
+
fields.each do |field|
|
48
|
+
attr_writer field
|
49
|
+
attr_reader field
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.attr_accessor_with_default(sym, default = Proc.new)
|
54
|
+
define_method(sym, block_given? ? default : Proc.new { default })
|
55
|
+
module_eval(<<-EVAL, __FILE__, __LINE__ + 1)
|
56
|
+
def #{sym}=(value) # def age=(value)
|
57
|
+
class << self; attr_accessor :#{sym} end # class << self; attr_accessor :age end
|
58
|
+
@attributes['#{sym}']=value # @attributes['age'] = value
|
59
|
+
end # end
|
60
|
+
EVAL
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.attr_reader_with_default(sym, default = Proc.new)
|
64
|
+
define_method(sym, block_given? ? default : Proc.new { default })
|
65
|
+
module_eval(<<-EVAL, __FILE__, __LINE__ + 1)
|
66
|
+
def #{sym}=(value) # def age=(value)
|
67
|
+
class << self; attr_reader :#{sym} end # class << self; attr_accessor :age end
|
68
|
+
@attributes['#{sym}']=value # @attributes['age'] = value
|
69
|
+
end # end
|
70
|
+
EVAL
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Modular
|
2
|
+
module Components
|
3
|
+
module Caching
|
4
|
+
def self.included(base)
|
5
|
+
base.cattr_accessor :cache_options
|
6
|
+
|
7
|
+
base.class_eval do
|
8
|
+
def self.cache(*args, &block)
|
9
|
+
self.cache_options = args.extract_options!
|
10
|
+
self.cache_options[:cache_key] = block if block_given?
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def render
|
16
|
+
if cache_options.nil?
|
17
|
+
super
|
18
|
+
elsif cached?
|
19
|
+
get_cached
|
20
|
+
else
|
21
|
+
data = super
|
22
|
+
do_caching data
|
23
|
+
data
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def cache_store
|
28
|
+
::ActionController::Base.cache_store
|
29
|
+
end
|
30
|
+
|
31
|
+
def cache_options
|
32
|
+
self.class.cache_options
|
33
|
+
end
|
34
|
+
|
35
|
+
def clear_cache
|
36
|
+
cache_store.delete cache_key
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
def cache_key
|
41
|
+
key = cache_options[:cache_key]
|
42
|
+
key = key.call(self) if key.is_a? Proc
|
43
|
+
key = self.to_json if key.nil?
|
44
|
+
|
45
|
+
::ActiveSupport::Cache.expand_cache_key key, :modular
|
46
|
+
end
|
47
|
+
|
48
|
+
def cached?
|
49
|
+
cache_store.exist? cache_key
|
50
|
+
end
|
51
|
+
|
52
|
+
def get_cached
|
53
|
+
cache_store.read cache_key
|
54
|
+
end
|
55
|
+
|
56
|
+
def do_caching(data)
|
57
|
+
cache_store.write cache_key, data, cache_options
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'abstract_controller'
|
2
|
+
require "modular/abstract_model"
|
3
|
+
require "modular/rendering"
|
4
|
+
require "modular/caching"
|
5
|
+
|
6
|
+
module Modular
|
7
|
+
module Components
|
8
|
+
class Base < Modular::Helpers::AbstractModel
|
9
|
+
#rendering
|
10
|
+
include AbstractController::Rendering
|
11
|
+
include Modular::Components::DirectRender
|
12
|
+
|
13
|
+
#slug
|
14
|
+
def self.type
|
15
|
+
self.name.rpartition("::").last
|
16
|
+
end
|
17
|
+
|
18
|
+
def type
|
19
|
+
self.class.type
|
20
|
+
end
|
21
|
+
|
22
|
+
#params for element itself
|
23
|
+
attr_reader_with_default :width, 300
|
24
|
+
attr_reader :title
|
25
|
+
|
26
|
+
validates :title, :length => {:maximum => 64}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Modular
|
2
|
+
module Components
|
3
|
+
class Container < Base
|
4
|
+
include Modular::Components::IndirectRender
|
5
|
+
|
6
|
+
attr_accessor :components
|
7
|
+
|
8
|
+
def initialize(attributes = {})
|
9
|
+
@attributes = ActiveSupport::HashWithIndifferentAccess.new(:components => [])
|
10
|
+
attributes = attributes.with_indifferent_access
|
11
|
+
attributes["components"] ||= []
|
12
|
+
|
13
|
+
attributes["components"].each do |value|
|
14
|
+
if value.is_a? Modular::Components::Base
|
15
|
+
@attributes[:components].push value
|
16
|
+
else
|
17
|
+
@attributes[:components].push(Modular.from_json(value)) rescue ''
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
super(attributes.except("components"))
|
22
|
+
end
|
23
|
+
|
24
|
+
def add(type, args = {}, &block)
|
25
|
+
cont = Modular.create(type, args)
|
26
|
+
cont.instance_eval &block if block_given?
|
27
|
+
components.push cont
|
28
|
+
end
|
29
|
+
|
30
|
+
# def render_child(component, render_type)
|
31
|
+
# if component.is_a?(Modular::Components::IndirectRender)&&(render_type == :indirect)
|
32
|
+
# component.indirect_render.html_safe
|
33
|
+
# else
|
34
|
+
# ("<%= Modular.from_json('" + component.to_json.html_safe + "').render %>").html_safe
|
35
|
+
# end
|
36
|
+
# end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Modular
|
2
|
+
class Configuration
|
3
|
+
attr_accessor_with_default :columns, 12
|
4
|
+
attr_accessor_with_default :column_width, 68
|
5
|
+
attr_accessor_with_default :padding_width, 15
|
6
|
+
attr_reader :layouts
|
7
|
+
|
8
|
+
def self.config
|
9
|
+
@@config ||= new
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.configure(&block)
|
13
|
+
@@config = new
|
14
|
+
@@config.instance_eval &block if block_given?
|
15
|
+
@@config
|
16
|
+
end
|
17
|
+
|
18
|
+
def register_layout(layout, mod = :Container, params = {}, &block)
|
19
|
+
@layouts ||= {}.with_indifferent_access
|
20
|
+
|
21
|
+
if mod.is_a? Components::Base
|
22
|
+
@layouts[layout.to_s] = mod
|
23
|
+
else
|
24
|
+
root_layout = Modular.create mod, params
|
25
|
+
root_layout.instance_eval &block if block_given?
|
26
|
+
@layouts[layout.to_s] = root_layout
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module Modular
|
4
|
+
class LayoutGenerator
|
5
|
+
class ERBContext
|
6
|
+
def initialize(hash)
|
7
|
+
hash.each_pair do |key, value|
|
8
|
+
instance_variable_set('@' + key.to_s, value)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def get_binding
|
13
|
+
binding
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.generate(id, params = {})
|
18
|
+
new(id, params).generate
|
19
|
+
end
|
20
|
+
|
21
|
+
def generate
|
22
|
+
write_layout unless layout_exists?
|
23
|
+
filename.to_s
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize(id, params)
|
27
|
+
@id = id
|
28
|
+
@params = params
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
def foldername
|
33
|
+
'tmp/modular/'
|
34
|
+
end
|
35
|
+
|
36
|
+
def filename
|
37
|
+
foldername + (@id.to_s + (@params[:cache_key].to_s) + '.html.erb')
|
38
|
+
end
|
39
|
+
|
40
|
+
def layout_exists?
|
41
|
+
if (defined? Rails) && (Rails.configuration.action_controller.perform_caching)
|
42
|
+
File.exists?(filename)
|
43
|
+
else
|
44
|
+
false
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def write_layout
|
49
|
+
folder = self.foldername
|
50
|
+
filename = self.filename
|
51
|
+
|
52
|
+
Dir.mkdir(folder) unless File.exists? folder
|
53
|
+
|
54
|
+
template = ERB.new File.new(Gem.loaded_specs['modular'].full_gem_path + '/templates/layout.erb').read
|
55
|
+
output = template.result(ERBContext.new(template_variables).get_binding)
|
56
|
+
|
57
|
+
File.open(filename, 'w') do |f|
|
58
|
+
f.write(output)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def template_variables
|
63
|
+
@params.merge :layout_id => @id
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'action_controller'
|
2
|
+
|
3
|
+
class ActionController::Base
|
4
|
+
def render_modular_layout(name)
|
5
|
+
layout = Modular.layout name
|
6
|
+
render :text => layout.render
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.modular_layout(name, params = {})
|
10
|
+
proc = Proc.new do |controller|
|
11
|
+
'../../../' + Modular.generate_rails_layout(name.is_a?(Symbol) ? controller.__send__(name) : name, params)
|
12
|
+
end
|
13
|
+
|
14
|
+
layout proc
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Modular
|
2
|
+
module Components
|
3
|
+
module DirectRender
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
module InstanceMethods
|
7
|
+
|
8
|
+
def controller_path
|
9
|
+
'components'
|
10
|
+
end
|
11
|
+
|
12
|
+
def action_name
|
13
|
+
type.underscore
|
14
|
+
end
|
15
|
+
|
16
|
+
def execute
|
17
|
+
end
|
18
|
+
|
19
|
+
def render
|
20
|
+
execute
|
21
|
+
modular_render :render_type => :direct
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(attributes = {})
|
25
|
+
append_view_path File.join('app', 'views')
|
26
|
+
super
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
def modular_render(args = {})
|
31
|
+
render_to_string :file => 'components/' + action_name, :locals => args
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
module ClassMethods
|
37
|
+
def view_context_class
|
38
|
+
context = super
|
39
|
+
|
40
|
+
context.send :define_method, :render_component do |component|
|
41
|
+
if component.is_a?(Modular::Components::IndirectRender)
|
42
|
+
component.indirect_render
|
43
|
+
else
|
44
|
+
a = "<%= Modular.from_json('"+ component.to_json + "').render %>"
|
45
|
+
a.html_safe
|
46
|
+
end
|
47
|
+
end
|
48
|
+
context
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
module IndirectRender
|
55
|
+
def execute
|
56
|
+
end
|
57
|
+
|
58
|
+
def indirect_render
|
59
|
+
execute
|
60
|
+
modular_render :render_type => :indirect
|
61
|
+
end
|
62
|
+
|
63
|
+
def render(args = {})
|
64
|
+
throw "Direct render unavailible for this component"
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.included(base)
|
68
|
+
thow "Unable to use indirect render without direct render" unless base.ancestors.include? Modular::Components::DirectRender
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/lib/modular.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require "active_support/all"
|
2
|
+
|
3
|
+
module Modular
|
4
|
+
extend ActiveSupport::Autoload
|
5
|
+
|
6
|
+
eager_autoload do
|
7
|
+
autoload :Configuration
|
8
|
+
autoload :LayoutGenerator
|
9
|
+
end
|
10
|
+
|
11
|
+
def create(typ, params = {})
|
12
|
+
return typ if typ.is_a? Components::Base
|
13
|
+
|
14
|
+
begin
|
15
|
+
begin
|
16
|
+
component = typ.to_s.camelize.constantize.new params
|
17
|
+
rescue NameError
|
18
|
+
component = (Components.name + '::' + typ.to_s.camelize).constantize.new params
|
19
|
+
end
|
20
|
+
rescue Exception => e
|
21
|
+
raise "Unable to create element " + typ.to_s
|
22
|
+
end
|
23
|
+
|
24
|
+
raise "Component has errors: " + component.errors.to_s unless component.valid?
|
25
|
+
|
26
|
+
component
|
27
|
+
end
|
28
|
+
|
29
|
+
def from_json(text)
|
30
|
+
obj = ActiveSupport::JSON.decode text
|
31
|
+
raise "Type expected in json string" unless obj['type']
|
32
|
+
create(obj['type'], obj.except('type'))
|
33
|
+
end
|
34
|
+
|
35
|
+
delegate :config, :configure, :to => Configuration
|
36
|
+
|
37
|
+
def layout(id)
|
38
|
+
Configuration.config.layouts[id]
|
39
|
+
end
|
40
|
+
|
41
|
+
def layouts
|
42
|
+
Configuration.config.layouts.keys
|
43
|
+
end
|
44
|
+
|
45
|
+
def generate_rails_layout(id, params = {})
|
46
|
+
LayoutGenerator.generate(id, params)
|
47
|
+
end
|
48
|
+
|
49
|
+
extend self
|
50
|
+
end
|
51
|
+
|
52
|
+
require "modular/components/base"
|
53
|
+
require "modular/components/container"
|
54
|
+
require "modular/components/main_content"
|
55
|
+
require "modular/version"
|
56
|
+
|
57
|
+
require "modular/rails" if defined? Rails
|
data/modular-app/Gemfile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
source 'http://rubygems.org'
|
2
|
+
|
3
|
+
gem 'rails'
|
4
|
+
# gem 'rails', :git => 'git://github.com/rails/rails.git'
|
5
|
+
|
6
|
+
gem 'sqlite3'
|
7
|
+
gem 'mongrel'
|
8
|
+
|
9
|
+
gem "modular", :path => ".."
|
10
|
+
|
11
|
+
group :development, :test do
|
12
|
+
gem 'autotest-standalone'
|
13
|
+
gem 'autotest-rails-pure'
|
14
|
+
|
15
|
+
gem 'rspec-rails', '~> 2.5.0'
|
16
|
+
gem 'ruby-debug'
|
17
|
+
gem 'webrat'
|
18
|
+
|
19
|
+
gem 'autotest-growl', :require => false
|
20
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
2
|
+
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
3
|
+
|
4
|
+
require File.expand_path('../config/application', __FILE__)
|
5
|
+
require 'rake'
|
6
|
+
|
7
|
+
ModularApp::Application.load_tasks
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class Modular::Components::CachedForTime < Modular::Components::Base
|
2
|
+
include Modular::Components::Caching
|
3
|
+
cache :expires_in => 2.seconds
|
4
|
+
|
5
|
+
def execute
|
6
|
+
SimpleModel.called_by_cached_for_time
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
CachedForTime = Modular::Components::CachedForTime
|