sethyates-content_manager 0.4.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +253 -1
- data/VERSION +1 -1
- data/content_manager.gemspec +38 -2
- data/doc/created.rid +1 -0
- data/doc/files/README_rdoc.html +487 -0
- data/doc/fr_class_index.html +26 -0
- data/doc/fr_file_index.html +27 -0
- data/doc/fr_method_index.html +26 -0
- data/doc/index.html +24 -0
- data/doc/rdoc-style.css +208 -0
- data/generators/component_scaffold/USAGE +28 -0
- data/generators/component_scaffold/component_scaffold_generator.rb +84 -0
- data/generators/component_scaffold/templates/controller.rb +85 -0
- data/generators/component_scaffold/templates/model.rb +5 -0
- data/generators/component_scaffold/templates/style.css +1 -0
- data/generators/component_scaffold/templates/view_edit.html.erb +13 -0
- data/generators/component_scaffold/templates/view_index.html.erb +22 -0
- data/generators/component_scaffold/templates/view_new.html.erb +12 -0
- data/generators/component_scaffold/templates/view_show.html.erb +3 -0
- data/generators/content_scaffold/USAGE +28 -0
- data/generators/content_scaffold/content_scaffold_generator.rb +83 -0
- data/generators/content_scaffold/templates/controller.rb +85 -0
- data/generators/content_scaffold/templates/model.rb +8 -0
- data/generators/content_scaffold/templates/view_edit.html.erb +13 -0
- data/generators/content_scaffold/templates/view_index.html.erb +22 -0
- data/generators/content_scaffold/templates/view_new.html.erb +12 -0
- data/generators/content_scaffold/templates/view_show.html.erb +8 -0
- data/lib/component.rb +28 -0
- data/lib/content/adapters/base.rb +79 -0
- data/lib/content/adapters/cabinet_adapter.rb +62 -0
- data/lib/content/adapters/tyrant_adapter.rb +73 -0
- data/lib/content/item.rb +178 -0
- data/lib/content/item_association_class_methods.rb +148 -0
- data/lib/content/item_class_methods.rb +71 -0
- data/lib/content/item_dirty_methods.rb +171 -0
- data/lib/content/item_finder_class_methods.rb +203 -0
- data/lib/content/manager.rb +105 -0
- data/lib/content/sublayout.rb +44 -0
- data/lib/content/template.rb +24 -0
- metadata +38 -2
@@ -0,0 +1,71 @@
|
|
1
|
+
module Content
|
2
|
+
module ItemClassMethods
|
3
|
+
def establish_connection(options = {})
|
4
|
+
conn_options = ::YAML::load_file('config/content.yml')[::RAILS_ENV]
|
5
|
+
conn_options.merge!(options) unless options.nil?
|
6
|
+
conn_type = conn_options[:type] || conn_options["type"] || :cabinet
|
7
|
+
$adapter = "content/adapters/#{conn_type}_adapter".camelize.constantize.new(conn_options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def connection()
|
11
|
+
$adapter ||= establish_connection
|
12
|
+
end
|
13
|
+
|
14
|
+
def self_and_descendants_from_active_record#nodoc:
|
15
|
+
klass = self
|
16
|
+
classes = [klass]
|
17
|
+
while klass != klass.base_class
|
18
|
+
classes << klass = klass.superclass
|
19
|
+
end
|
20
|
+
classes
|
21
|
+
rescue
|
22
|
+
[self]
|
23
|
+
end
|
24
|
+
|
25
|
+
def human_name(options = {})
|
26
|
+
defaults = self_and_descendants_from_active_record.map do |klass|
|
27
|
+
:"#{klass.name.underscore}"
|
28
|
+
end
|
29
|
+
defaults << name
|
30
|
+
defaults.shift.to_s.humanize
|
31
|
+
end
|
32
|
+
|
33
|
+
def human_attribute_name(attr_name)
|
34
|
+
attr_name.to_s.humanize
|
35
|
+
end
|
36
|
+
|
37
|
+
def create(attributes = nil, &block)
|
38
|
+
if attributes.is_a?(Array)
|
39
|
+
attributes.collect { |attr| create(attr, &block) }
|
40
|
+
else
|
41
|
+
object = new(attributes)
|
42
|
+
yield(object) if block_given?
|
43
|
+
object.save
|
44
|
+
object
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def update(id, attributes)
|
49
|
+
if id.is_a?(Array)
|
50
|
+
idx = -1
|
51
|
+
id.collect { |one_id| idx += 1; update(one_id, attributes[idx]) }
|
52
|
+
else
|
53
|
+
object = find(id)
|
54
|
+
object.update_attributes(attributes)
|
55
|
+
object
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def destroy(id)
|
60
|
+
if id.is_a?(Array)
|
61
|
+
id.map { |one_id| destroy(one_id) }
|
62
|
+
else
|
63
|
+
find(id).destroy
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def delete(id)
|
68
|
+
destroy id
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,171 @@
|
|
1
|
+
module Content
|
2
|
+
# Track unsaved attribute changes.
|
3
|
+
#
|
4
|
+
# A newly instantiated object is unchanged:
|
5
|
+
# person = Person.find_by_name('uncle bob')
|
6
|
+
# person.changed? # => false
|
7
|
+
#
|
8
|
+
# Change the name:
|
9
|
+
# person.name = 'Bob'
|
10
|
+
# person.changed? # => true
|
11
|
+
# person.name_changed? # => true
|
12
|
+
# person.name_was # => 'uncle bob'
|
13
|
+
# person.name_change # => ['uncle bob', 'Bob']
|
14
|
+
# person.name = 'Bill'
|
15
|
+
# person.name_change # => ['uncle bob', 'Bill']
|
16
|
+
#
|
17
|
+
# Save the changes:
|
18
|
+
# person.save
|
19
|
+
# person.changed? # => false
|
20
|
+
# person.name_changed? # => false
|
21
|
+
#
|
22
|
+
# Assigning the same value leaves the attribute unchanged:
|
23
|
+
# person.name = 'Bill'
|
24
|
+
# person.name_changed? # => false
|
25
|
+
# person.name_change # => nil
|
26
|
+
#
|
27
|
+
# Which attributes have changed?
|
28
|
+
# person.name = 'bob'
|
29
|
+
# person.changed # => ['name']
|
30
|
+
# person.changes # => { 'name' => ['Bill', 'bob'] }
|
31
|
+
#
|
32
|
+
# Before modifying an attribute in-place:
|
33
|
+
# person.name_will_change!
|
34
|
+
# person.name << 'by'
|
35
|
+
# person.name_change # => ['uncle bob', 'uncle bobby']
|
36
|
+
module ItemDirtyMethods
|
37
|
+
DIRTY_SUFFIXES = ['_changed?', '_change', '_will_change!', '_was']
|
38
|
+
|
39
|
+
def self.included(base)
|
40
|
+
# base.attribute_method_suffix *DIRTY_SUFFIXES
|
41
|
+
base.alias_method_chain :write_attribute, :dirty
|
42
|
+
base.alias_method_chain :save, :dirty
|
43
|
+
base.alias_method_chain :save!, :dirty
|
44
|
+
base.alias_method_chain :update, :dirty
|
45
|
+
# base.alias_method_chain :reload, :dirty
|
46
|
+
|
47
|
+
base.send(:extend, ClassMethods)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Do any attributes have unsaved changes?
|
51
|
+
# person.changed? # => false
|
52
|
+
# person.name = 'bob'
|
53
|
+
# person.changed? # => true
|
54
|
+
def changed?
|
55
|
+
!changed_attributes.empty?
|
56
|
+
end
|
57
|
+
|
58
|
+
# List of attributes with unsaved changes.
|
59
|
+
# person.changed # => []
|
60
|
+
# person.name = 'bob'
|
61
|
+
# person.changed # => ['name']
|
62
|
+
def changed
|
63
|
+
changed_attributes.keys
|
64
|
+
end
|
65
|
+
|
66
|
+
# Map of changed attrs => [original value, new value].
|
67
|
+
# person.changes # => {}
|
68
|
+
# person.name = 'bob'
|
69
|
+
# person.changes # => { 'name' => ['bill', 'bob'] }
|
70
|
+
def changes
|
71
|
+
changed.inject({}) { |h, attr| h[attr] = attribute_change(attr); h }
|
72
|
+
end
|
73
|
+
|
74
|
+
# Attempts to +save+ the record and clears changed attributes if successful.
|
75
|
+
def save_with_dirty(*args) #:nodoc:
|
76
|
+
if status = save_without_dirty(*args)
|
77
|
+
changed_attributes.clear
|
78
|
+
end
|
79
|
+
status
|
80
|
+
end
|
81
|
+
|
82
|
+
# Attempts to <tt>save!</tt> the record and clears changed attributes if successful.
|
83
|
+
def save_with_dirty!(*args) #:nodoc:
|
84
|
+
status = save_without_dirty!(*args)
|
85
|
+
changed_attributes.clear
|
86
|
+
status
|
87
|
+
end
|
88
|
+
|
89
|
+
# <tt>reload</tt> the record and clears changed attributes.
|
90
|
+
def reload_with_dirty(*args) #:nodoc:
|
91
|
+
record = reload_without_dirty(*args)
|
92
|
+
changed_attributes.clear
|
93
|
+
record
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
# Map of change <tt>attr => original value</tt>.
|
98
|
+
def changed_attributes
|
99
|
+
@changed_attributes ||= {}
|
100
|
+
end
|
101
|
+
|
102
|
+
# Handle <tt>*_changed?</tt> for +method_missing+.
|
103
|
+
def attribute_changed?(attr)
|
104
|
+
changed_attributes.include?(attr)
|
105
|
+
end
|
106
|
+
|
107
|
+
# Handle <tt>*_change</tt> for +method_missing+.
|
108
|
+
def attribute_change(attr)
|
109
|
+
[changed_attributes[attr], __send__(attr)] if attribute_changed?(attr)
|
110
|
+
end
|
111
|
+
|
112
|
+
# Handle <tt>*_was</tt> for +method_missing+.
|
113
|
+
def attribute_was(attr)
|
114
|
+
attribute_changed?(attr) ? changed_attributes[attr] : __send__(attr)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Handle <tt>*_will_change!</tt> for +method_missing+.
|
118
|
+
def attribute_will_change!(attr)
|
119
|
+
changed_attributes[attr] = clone_attribute_value(:read_attribute, attr)
|
120
|
+
end
|
121
|
+
|
122
|
+
def clone_attribute_value(method, attr)
|
123
|
+
val = __send__(method, attr)
|
124
|
+
val.dup unless val.nil?
|
125
|
+
end
|
126
|
+
|
127
|
+
# Wrap write_attribute to remember original attribute value.
|
128
|
+
def write_attribute_with_dirty(attr, value)
|
129
|
+
# The attribute already has an unsaved change.
|
130
|
+
if changed_attributes.include?(attr)
|
131
|
+
old = changed_attributes[attr]
|
132
|
+
changed_attributes.delete(attr) unless field_changed?(attr, old, value)
|
133
|
+
else
|
134
|
+
old = clone_attribute_value(:read_attribute, attr)
|
135
|
+
changed_attributes[attr] = old if field_changed?(attr, old, value)
|
136
|
+
end
|
137
|
+
|
138
|
+
# Carry on.
|
139
|
+
write_attribute_without_dirty(attr, value)
|
140
|
+
end
|
141
|
+
|
142
|
+
def update_with_dirty
|
143
|
+
if partial_updates?
|
144
|
+
# Serialized attributes should always be written in case they've been
|
145
|
+
# changed in place.
|
146
|
+
update_without_dirty(changed | self.class.serialized_attributes.keys)
|
147
|
+
else
|
148
|
+
update_without_dirty
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def field_changed?(attr, old, value)
|
153
|
+
old != value
|
154
|
+
end
|
155
|
+
|
156
|
+
module ClassMethods
|
157
|
+
def self.extended(base)
|
158
|
+
base.metaclass.alias_method_chain(:alias_attribute, :dirty)
|
159
|
+
end
|
160
|
+
|
161
|
+
def alias_attribute_with_dirty(new_name, old_name)
|
162
|
+
alias_attribute_without_dirty(new_name, old_name)
|
163
|
+
DIRTY_SUFFIXES.each do |suffix|
|
164
|
+
module_eval <<-STR, __FILE__, __LINE__+1
|
165
|
+
def #{new_name}#{suffix}; self.#{old_name}#{suffix}; end # def subject_changed?; self.title_changed?; end
|
166
|
+
STR
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
@@ -0,0 +1,203 @@
|
|
1
|
+
module Content
|
2
|
+
module ItemFinderClassMethods
|
3
|
+
# Find operates with four different retrieval approaches:
|
4
|
+
#
|
5
|
+
# * Find by id - This can either be a specific id (1), a list of ids (1, 5, 6), or an array of ids ([5, 6, 10]).
|
6
|
+
# If no record can be found for all of the listed ids, then RecordNotFound will be raised.
|
7
|
+
# * Find first - This will return the first record matched by the options used. These options can either be specific
|
8
|
+
# conditions or merely an order. If no record can be matched, +nil+ is returned. Use
|
9
|
+
# <tt>Model.find(:first, *args)</tt> or its shortcut <tt>Model.first(*args)</tt>.
|
10
|
+
# * Find last - This will return the last record matched by the options used. These options can either be specific
|
11
|
+
# conditions or merely an order. If no record can be matched, +nil+ is returned. Use
|
12
|
+
# <tt>Model.find(:last, *args)</tt> or its shortcut <tt>Model.last(*args)</tt>.
|
13
|
+
# * Find all - This will return all the records matched by the options used.
|
14
|
+
# If no records are found, an empty array is returned. Use
|
15
|
+
# <tt>Model.find(:all, *args)</tt> or its shortcut <tt>Model.all(*args)</tt>.
|
16
|
+
#
|
17
|
+
# All approaches accept an options hash as their last parameter.
|
18
|
+
#
|
19
|
+
# ==== Parameters
|
20
|
+
#
|
21
|
+
# * <tt>:conditions</tt> - An SQL fragment like "administrator = 1", <tt>[ "user_name = ?", username ]</tt>, or <tt>["user_name = :user_name", { :user_name => user_name }]</tt>. See conditions in the intro.
|
22
|
+
# * <tt>:order</tt> - An SQL fragment like "created_at DESC, name".
|
23
|
+
# * <tt>:limit</tt> - An integer determining the limit on the number of rows that should be returned.
|
24
|
+
# * <tt>:offset</tt> - An integer determining the offset from where the rows should be fetched. So at 5, it would skip rows 0 through 4.
|
25
|
+
# * <tt>:select</tt> - By default, this is "*" as in "SELECT * FROM", but can be changed if you, for example, want to do a join but not
|
26
|
+
# include the joined columns. Takes a string with the SELECT SQL fragment (e.g. "id, name").
|
27
|
+
#
|
28
|
+
# ==== Examples
|
29
|
+
#
|
30
|
+
# # find by id
|
31
|
+
# Person.find(1) # returns the object for ID = 1
|
32
|
+
# Person.find(1, 2, 6) # returns an array for objects with IDs in (1, 2, 6)
|
33
|
+
# Person.find([7, 17]) # returns an array for objects with IDs in (7, 17)
|
34
|
+
# Person.find([1]) # returns an array for the object with ID = 1
|
35
|
+
# Person.find(1, :conditions => "administrator = 1", :order => "created_on DESC")
|
36
|
+
#
|
37
|
+
# Note that returned records may not be in the same order as the ids you
|
38
|
+
# provide since database rows are unordered. Give an explicit <tt>:order</tt>
|
39
|
+
# to ensure the results are sorted.
|
40
|
+
#
|
41
|
+
# ==== Examples
|
42
|
+
#
|
43
|
+
# # find first
|
44
|
+
# Person.find(:first) # returns the first object fetched by SELECT * FROM people
|
45
|
+
# Person.find(:first, :conditions => [ "user_name = ?", user_name])
|
46
|
+
# Person.find(:first, :conditions => [ "user_name = :u", { :u => user_name }])
|
47
|
+
# Person.find(:first, :order => "created_on DESC", :offset => 5)
|
48
|
+
#
|
49
|
+
# # find last
|
50
|
+
# Person.find(:last) # returns the last object fetched by SELECT * FROM people
|
51
|
+
# Person.find(:last, :conditions => [ "user_name = ?", user_name])
|
52
|
+
# Person.find(:last, :order => "created_on DESC", :offset => 5)
|
53
|
+
#
|
54
|
+
# # find all
|
55
|
+
# Person.find(:all) # returns an array of objects for all the rows fetched by SELECT * FROM people
|
56
|
+
# Person.find(:all, :conditions => [ "category IN (?)", categories], :limit => 50)
|
57
|
+
# Person.find(:all, :conditions => { :friends => ["Bob", "Steve", "Fred"] }
|
58
|
+
# Person.find(:all, :offset => 10, :limit => 10)
|
59
|
+
# Person.find(:all, :include => [ :account, :friends ])
|
60
|
+
# Person.find(:all, :group => "category")
|
61
|
+
#
|
62
|
+
def find(*args)
|
63
|
+
options = {}
|
64
|
+
which = args.shift
|
65
|
+
if which.is_a? Symbol
|
66
|
+
given_options = args.shift
|
67
|
+
options.merge!(given_options) unless given_options.nil?
|
68
|
+
else
|
69
|
+
id = which
|
70
|
+
which = :first
|
71
|
+
given_options = args.shift
|
72
|
+
options.merge!(given_options) unless given_options.nil?
|
73
|
+
end
|
74
|
+
|
75
|
+
options[:limit] = 1 if which == :first
|
76
|
+
|
77
|
+
if id.nil?
|
78
|
+
wrap_result which, connection.run_query(self, options)
|
79
|
+
elsif id.is_a? Array
|
80
|
+
id.collect {|one_id| find_by_id one_id}.compact
|
81
|
+
elsif options.keys.length == 0
|
82
|
+
find_by_id id
|
83
|
+
else
|
84
|
+
if options.has_key? :conditions
|
85
|
+
options[:conditions].merge!(:__id => id)
|
86
|
+
else
|
87
|
+
options[:conditions] = {:__id => id}
|
88
|
+
end
|
89
|
+
wrap_result which, connection.run_query(self, options)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def count(options)
|
94
|
+
connection.count(self, options)
|
95
|
+
end
|
96
|
+
|
97
|
+
def paginate(*args)
|
98
|
+
options = args.first.dup
|
99
|
+
options[:conditions] = (options[:conditions] || {}).merge(:content_type => name)
|
100
|
+
options[:limit] = (options[:per_page] || 25)
|
101
|
+
options[:offset] = ((options[:page] || 1) - 1) * options[:limit]
|
102
|
+
options.delete :page
|
103
|
+
options.delete :per_page
|
104
|
+
find(:all, options)
|
105
|
+
end
|
106
|
+
|
107
|
+
def find_by_id(id)
|
108
|
+
wrap_result :first, connection.get_record_by_id(self, id.to_i)
|
109
|
+
end
|
110
|
+
|
111
|
+
def find_each(options)
|
112
|
+
#TODO - run the query
|
113
|
+
if block_given?
|
114
|
+
#each ... yield(row)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def all
|
119
|
+
if name == "Content::Item"
|
120
|
+
find :all
|
121
|
+
else
|
122
|
+
find_all_by_content_type name
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def first
|
127
|
+
if name == "Content::Item"
|
128
|
+
find :first
|
129
|
+
else
|
130
|
+
find_by_content_type name
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def last
|
135
|
+
all.last
|
136
|
+
end
|
137
|
+
|
138
|
+
def method_missing(name, *arguments, &block)
|
139
|
+
name_s = name.to_s
|
140
|
+
if name_s =~ /^find_all(_by)?_(.+)$/
|
141
|
+
obj = polymorphic_finder :all, $2, arguments
|
142
|
+
elsif name_s =~ /^find_by_(.+)$/
|
143
|
+
obj = polymorphic_finder :first, $1, arguments
|
144
|
+
elsif name_s =~ /^find_last(_by)?_(.+)$/
|
145
|
+
obj = polymorphic_finder :last, $2, arguments
|
146
|
+
elsif name_s =~ /^find_or_create_by_(.+)$/
|
147
|
+
obj = polymorphic_finder :first, $1, arguments
|
148
|
+
if obj.nil?
|
149
|
+
self.create(arguments, &block)
|
150
|
+
end
|
151
|
+
elsif name_s =~ /^paginate_by_(.+)$/
|
152
|
+
obj = polymorphic_pager $1, arguments
|
153
|
+
else
|
154
|
+
obj = super
|
155
|
+
end
|
156
|
+
yield(obj) if !obj.nil? and block_given?
|
157
|
+
obj
|
158
|
+
end
|
159
|
+
|
160
|
+
protected
|
161
|
+
def hash_zip(keys, values, default=nil, &block)
|
162
|
+
hash = block_given? ? Hash.new(&block) : Hash.new(default)
|
163
|
+
keys.zip(values) { |k,v| hash[k]=v }
|
164
|
+
hash
|
165
|
+
end
|
166
|
+
|
167
|
+
def polymorphic_finder(which, name, arguments)
|
168
|
+
find which, :conditions => hash_zip(name.split(/_and_/), arguments)
|
169
|
+
end
|
170
|
+
|
171
|
+
def polymorphic_pager(name, arguments)
|
172
|
+
names = name.split(/_and_/)
|
173
|
+
options = arguments.length > names.length ? arguments.last : {}
|
174
|
+
if options.has_key? :conditions
|
175
|
+
options[:conditions].merge! hash_zip(names, arguments)
|
176
|
+
else
|
177
|
+
options.merge!({:conditions => hash_zip(names, arguments)})
|
178
|
+
end
|
179
|
+
paginate options
|
180
|
+
end
|
181
|
+
|
182
|
+
def create_item(attrs)
|
183
|
+
if attrs.nil?
|
184
|
+
nil
|
185
|
+
elsif !attrs[:content_type].nil?
|
186
|
+
attrs[:content_type].to_s.camelize.constantize.new(attrs)
|
187
|
+
elsif self == Content::Item
|
188
|
+
Content::Item.new(attrs)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def wrap_result(which, attrs)
|
193
|
+
unless attrs.nil?
|
194
|
+
attrs = [attrs] unless attrs.is_a?(Array)
|
195
|
+
case which
|
196
|
+
when :first then create_item attrs.first
|
197
|
+
when :last then create_item attrs.last
|
198
|
+
else attrs.collect { |item| create_item(item) }.compact
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Content
|
2
|
+
module Manager
|
3
|
+
def self.load_content_item(params)
|
4
|
+
url = params["content_item_url"]
|
5
|
+
unless url.nil?
|
6
|
+
if url.is_a? Array
|
7
|
+
url = "/#{url.join('/')}"
|
8
|
+
end
|
9
|
+
if url.match(/^(.+)\.([a-z]+)$/i)
|
10
|
+
params[:format] = $2
|
11
|
+
url = $1
|
12
|
+
end
|
13
|
+
params["content_item_url"] = url
|
14
|
+
Content::Item.find_by_url(url)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def show
|
19
|
+
render404 and return if current_content_item.nil? or current_content_item.template.nil? or current_content_item.template.sublayout.nil?
|
20
|
+
respond_to do |format|
|
21
|
+
format.html { prerender_containers and render :template => "sublayouts/#{current_content_item.template.sublayout}", :layout => false }
|
22
|
+
format.xml { render :xml => current_content_item }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
def prerender_containers
|
28
|
+
begin
|
29
|
+
sublayout = Content::Sublayout.find_by_path(current_content_item.template.sublayout)
|
30
|
+
sublayout.containers.each {|name| content_for name, render_container(name) }
|
31
|
+
rescue RuntimeError => err
|
32
|
+
render500(err) and return false
|
33
|
+
end
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
def content_for(name, content)
|
38
|
+
name = "layout" if name.to_s == "contents"
|
39
|
+
ivar = "@content_for_#{name}"
|
40
|
+
instance_variable_set(ivar, "#{instance_variable_get(ivar)}#{content}")
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# Renders the given component
|
45
|
+
#
|
46
|
+
# url_options the options that would be passed to url_for
|
47
|
+
#
|
48
|
+
def render_component(url_options)
|
49
|
+
url = url_for(url_options)
|
50
|
+
querystring = URI.parse(url).query
|
51
|
+
|
52
|
+
env = {
|
53
|
+
"rack.version" => [0, 1],
|
54
|
+
"rack.input" => StringIO.new(""),
|
55
|
+
"rack.errors" => $stderr,
|
56
|
+
"rack.url_scheme" => "http",
|
57
|
+
"rack.run_once" => false,
|
58
|
+
"rack.multithread" => false,
|
59
|
+
"rack.multiprocess" => false,
|
60
|
+
"QUERY_STRING" => querystring,
|
61
|
+
"REQUEST_METHOD" => "GET",
|
62
|
+
"PATH_INFO" => url,
|
63
|
+
"REQUEST_PATH" => url,
|
64
|
+
"REQUEST_URI" => url
|
65
|
+
}
|
66
|
+
|
67
|
+
%w(SERVER_SOFTWARE HTTP_USER_AGENT HTTP_ACCEPT_ENCODING HTTP_ACCEPT_CHARSET
|
68
|
+
HTTP_ACCEPT_LANGUAGE HTTP_KEEP_ALIVE HTTP_COOKIE HTTP_VERSION SERVER_PROTOCOL HTTP_HOST
|
69
|
+
SERVER_NAME SERVER_PORT REMOTE_ADDR SCRIPT_NAME).each { |key| env[key] = request.env[key] }
|
70
|
+
|
71
|
+
resp = ActionController::Routing::Routes.call(env)
|
72
|
+
raise resp[2].body unless resp[0] == 200
|
73
|
+
resp[2].body
|
74
|
+
end
|
75
|
+
|
76
|
+
#
|
77
|
+
# Renders a container
|
78
|
+
#
|
79
|
+
# name the name of the container to render
|
80
|
+
#
|
81
|
+
def render_container(name)
|
82
|
+
unless current_content_item.nil? or current_content_item.template.nil? or current_content_item.template[name].nil?
|
83
|
+
current_content_item.template.get_container(name).collect {|component|
|
84
|
+
render_component(:controller => "components/#{component.keys.first.to_s.pluralize}", :action => "show", :id => component.values.first)
|
85
|
+
}
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def render404
|
90
|
+
respond_to do |format|
|
91
|
+
format.html { render :template => "errors/error_404", :status => 404 }
|
92
|
+
format.all { render :nothing => true, :status => 404 }
|
93
|
+
end
|
94
|
+
true
|
95
|
+
end
|
96
|
+
|
97
|
+
def render500(err)
|
98
|
+
respond_to do |format|
|
99
|
+
format.html { render :text => err, :layout => false, :status => 500 }
|
100
|
+
format.all { render :nothing => true, :status => 500 }
|
101
|
+
end
|
102
|
+
true
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|