modular 0.1
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.
- 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
|