Class: Page
- Inherits:
-
Record
- Object
- AbstractRecord
- MongoRecord
- SiteRecord
- Record
- Page
- Includes:
- Authentication, HTMLDecorator
- Defined in:
- lib/yodel/models/pages/page.rb
Direct Known Subclasses
FacebookLoginPage, LoginPage, LogoutPage, PasswordResetPage, RecordProxyPage, RedirectPage, SearchPage
Constant Summary
Constants included from Authentication
Authentication::AUTHORIZATION_KEYS
Constants inherited from AbstractRecord
AbstractRecord::CALLBACKS, AbstractRecord::FIELD_CALLBACKS, AbstractRecord::ORDERS
Instance Attribute Summary
Attributes inherited from Record
#mixins, #model, #model_record, #real_record
Attributes inherited from SiteRecord
Attributes inherited from AbstractRecord
#changed, #errors, #stash, #typecast, #values
Class Method Summary collapse
-
.respond_to(http_method) ⇒ Object
—————————————- Response content —————————————-.
- .with(mime_type, &block) ⇒ Object
Instance Method Summary collapse
- #assign_child_paths ⇒ Object
- #assign_path(prefix = nil) ⇒ Object
- #assign_permalink ⇒ Object
- #content(*section) ⇒ Object
- #content_for(section, options = {}, &block) ⇒ Object
- #env ⇒ Object
- #flash ⇒ Object
-
#form_for(record, action, options = {}, &block) ⇒ Object
—————————————- Forms —————————————-.
-
#layout(mime_type, editing = false) ⇒ Object
FIXME: make layout take a string or symbol param, remove .to_s from render_or_default, change blog.rb layout to use a symbol not string, check all other calls to layout() and change appropriately Determine the first best layout to be used by this page for rendering.
- #menu(name) ⇒ Object
- #mime_type ⇒ Object
- #mime_type=(m) ⇒ Object
- #page(*args) ⇒ Object
- #params ⇒ Object
- #partial(name) ⇒ Object
- #render_layout(name, mime_type) ⇒ Object
-
#render_or_default(mime_type, &block) ⇒ Object
—————————————- Default request handling —————————————-.
-
#request ⇒ Object
basic environment accessors.
- #request=(r) ⇒ Object
-
#respond_to_request(request, response, mime_type) ⇒ Object
request handling.
- #response ⇒ Object
- #response=(r) ⇒ Object
- #session ⇒ Object
- #set_content(content) ⇒ Object
-
#snippet(name) ⇒ Object
—————————————- Layout helpers —————————————-.
-
#status(code) ⇒ Object
By default, responses are assumed to be 200 (successful).
- #user_allowed_to?(action) ⇒ Boolean
Methods included from HTMLDecorator
#delete_button, #delete_link, #form_for_page, #immediately, #on_click, #paragraph, #paragraphs_from
Methods included from Authentication
#current_user, #logged_in?, #login, #logout, #prompt_login, #store_authenticated_user
Methods inherited from Record
#all_children, #append_to_siblings, #children_and_self, #collection, #create_eigenmodel, #create_mixin_instances, #default_values, #delegate_mixins, #destroy_children, #field_sections, #fields, #first_non_blank_response_to, #first_parent, #first_response_to, #get_binding, #has_eigenmodel?, #initialize, #insert_in_siblings, #inspect_hash, #load_model, #model_name, #parent?, #parents, #perform_reload, #prepare_reload_params, #remove_eigenmodel, #remove_from_siblings, #root?, #run_record_after_create_callbacks, #run_record_after_destroy_callbacks, #run_record_after_save_callbacks, #run_record_after_update_callbacks, #run_record_after_validation_callbacks, #run_record_before_create_callbacks, #run_record_before_destroy_callbacks, #run_record_before_save_callbacks, #run_record_before_update_callbacks, #run_record_before_validation_callbacks, #siblings, #to_str, #update_search_keywords, #user_allowed_to_create?, #user_allowed_to_delete?, #user_allowed_to_update?, #user_allowed_to_view?
Methods inherited from SiteRecord
#default_values, #initialize, #inspect_hash, #perform_reload, #prepare_reload_params, #site_id
Methods included from SiteModel
Methods included from MongoModel
Methods included from AbstractModel
#embed_many, #embed_one, #field, #fields, #many, #modify_field, #one, #remove_field
Methods inherited from MongoRecord
#collection, #default_values, #fields, #id, #increment!, #inspect_hash, #load_from_mongo, #load_mongo_document, #perform_destroy, #perform_reload, #perform_save, #set_id
Methods inherited from AbstractRecord
#changed!, #changed?, #clear_key, #default_values, #destroy, #destroyed?, #eql?, #errors?, #field, #field?, #field_was, #fields, #from_json, #get, #get_meta, #get_raw, #hash, #id, #increment!, inherited, #initialize, #inspect, #inspect_hash, #inspect_value, #method_missing, #new?, #prepare_reload_params, #present?, #reload, #save, #save_without_validation, #search_terms, #set, #set_meta, #set_raw, #to_json, #to_str, #trigger_field_callback, #update, #valid?
Constructor Details
This class inherits a constructor from Record
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class AbstractRecord
Class Method Details
.respond_to(http_method) ⇒ Object
Response content
101 102 103 104 105 106 |
# File 'lib/yodel/models/pages/page.rb', line 101 def self.respond_to(http_method) # FIXME: this is not thread safe @_http_method = http_method yield @_http_method = nil end |
.with(mime_type, &block) ⇒ Object
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/yodel/models/pages/page.rb', line 108 def self.with(mime_type, &block) # two instance methods may be defined from the response definition action_name = "respond_to_#{@_http_method}_with_#{mime_type}" default_action_name = "default_response_to_#{@_http_method}" default_action_mime_var = "@default_response_to_#{@_http_method}_mime_type" # create or overwrite the main action for this http_method/mime_type pair define_method(action_name, block) # if this is the first response definition for the http_method, assign it # as the default response for requests matching the http_method, but not # matching a mime_type that has been responded to unless instance_methods(false).include?(default_action_name.to_sym) define_method(default_action_name, block) instance_variable_set(default_action_mime_var, Yodel.mime_types[mime_type]) end end |
Instance Method Details
#assign_child_paths ⇒ Object
60 61 62 63 64 |
# File 'lib/yodel/models/pages/page.rb', line 60 def assign_child_paths return unless path_changed? || (!path.nil? && values['path'].nil?) return unless @errors.empty? # @errors.present? == invalid children.each {|child| child.assign_path(path)} end |
#assign_path(prefix = nil) ⇒ Object
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/yodel/models/pages/page.rb', line 35 def assign_path(prefix=nil) if prefix prefix = '' if prefix == '/' # when the root page is parent, prefix will be "/" base = prefix + '/' + permalink else base = '/' + parents.reverse[1..-1].collect(&:permalink).join('/') end permalink_character = site.option('pages.permalink_character') || '-' self.path = base count = 0 while site.pages.where(:path => self.path, :_id.ne => self.id).exists? count += 1 self.path = "#{base}#{permalink_character}#{count}" end # child pages are called with prefix supplied # FIXME: with the identity map, this call could save another record which has been modified # elsewhere; change to update path only, not a full save save_without_validation unless prefix.nil? children.each {|child| child.assign_path(self.path)} end |
#assign_permalink ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/yodel/models/pages/page.rb', line 12 def assign_permalink return unless (title_changed? && title?) || (!title.nil? && values['title'].nil?) # until we detect changes to fields used by cached functions, force a refresh of the value generate_unloaded_field('title') if field('title').type == 'Function' permalink_character = site.option('pages.permalink_character') || '-' base_permalink = title.parameterize(permalink_character) suffix = '' count = 0 # ensure other pages don't have the same path as this page page_siblings = siblings.all.select {|record| record.field?('permalink')} while page_siblings.any? {|page| page.permalink == base_permalink + suffix} count += 1 suffix = "#{permalink_character}#{count}" end # set the page's permalink, then construct its path and reset any child paths self.permalink = base_permalink + suffix assign_path end |
#content(*section) ⇒ Object
230 231 232 233 234 235 236 |
# File 'lib/yodel/models/pages/page.rb', line 230 def content(*section) if section.empty? @content ||= get('content') else instance_variable_get("@content_for_#{section.first}") || '' end end |
#content_for(section, options = {}, &block) ⇒ Object
238 239 240 241 242 243 244 245 |
# File 'lib/yodel/models/pages/page.rb', line 238 def content_for(section, ={}, &block) if block_given? content = Ember::Template.content_from_block(block).join elsif .key?(:partial) content = partial([:partial]) end instance_variable_set("@content_for_#{section}", content) end |
#env ⇒ Object
171 |
# File 'lib/yodel/models/pages/page.rb', line 171 def env; @_request.env; end |
#flash ⇒ Object
78 79 80 |
# File 'lib/yodel/models/pages/page.rb', line 78 def flash @flash ||= Flash.new(session) end |
#form_for(record, action, options = {}, &block) ⇒ Object
Forms
86 87 88 89 90 91 92 93 94 95 |
# File 'lib/yodel/models/pages/page.rb', line 86 def form_for(record, action, ={}, &block) [:method] = record.new? ? 'post' : 'put' if [:remote] components = action.split('?') components[0] += '.json' unless components.first.end_with?('.json') action = components.join('?') [:success] = 'window.location = record.path;' if record.new? end FormBuilder.new(record, action, , &block).render end |
#layout(mime_type, editing = false) ⇒ Object
FIXME: make layout take a string or symbol param, remove .to_s from render_or_default, change blog.rb layout to use a symbol not string, check all other calls to layout() and change appropriately Determine the first best layout to be used by this page for rendering
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/yodel/models/pages/page.rb', line 187 def layout(mime_type, editing=false) # if we're in production we'll have a reference to a layout record #return page_layout_record if page_layout_record # FIXME: implement layout caching # try and return a layout by name or by the name of the page's class layout_name = editing ? edit_layout : page_layout layout = site.layouts.where(name: layout_name, mime_type: mime_type).first unless layout layout_name = model.name.underscore layout_name = "edit_#{layout_name}" if editing layout = site.layouts.where(name: layout_name, mime_type: mime_type).first end return layout if layout # otherwise fall back to the parent's layout return parent.layout(mime_type) unless parent.nil? raise LayoutNotFound end |
#menu(name) ⇒ Object
74 75 76 |
# File 'lib/yodel/models/pages/page.rb', line 74 def (name) site.[name.to_s].render(self) end |
#mime_type ⇒ Object
175 |
# File 'lib/yodel/models/pages/page.rb', line 175 def mime_type; @_mime_type; end |
#mime_type=(m) ⇒ Object
176 |
# File 'lib/yodel/models/pages/page.rb', line 176 def mime_type=(m); @_mime_type = m; end |
#page(*args) ⇒ Object
255 256 257 258 259 260 261 |
# File 'lib/yodel/models/pages/page.rb', line 255 def page(*args) if args.empty? self else site.pages.where(path: args.first).first end end |
#params ⇒ Object
172 |
# File 'lib/yodel/models/pages/page.rb', line 172 def params; @_request.params; end |
#partial(name) ⇒ Object
247 248 249 250 251 252 253 |
# File 'lib/yodel/models/pages/page.rb', line 247 def partial(name) name = name.to_s name = name + '.html' unless name.end_with?('.html') path = File.join(site.partials_directory, name) raise LayoutNotFound, path unless File.exist?(path) Ember::Template.new(IO.read(path), {source_file: path}).render(get_binding) end |
#render_layout(name, mime_type) ⇒ Object
208 209 210 211 212 |
# File 'lib/yodel/models/pages/page.rb', line 208 def render_layout(name, mime_type) layout_record = site.layouts.where(name: name, mime_type: mime_type.to_s).first raise LayoutNotFound if layout_record.nil? layout_record.render(self) end |
#render_or_default(mime_type, &block) ⇒ Object
Default request handling
218 219 220 221 222 223 224 |
# File 'lib/yodel/models/pages/page.rb', line 218 def render_or_default(mime_type, &block) @content ||= content editing = @_request && params && params['action'] == 'edit' layout(mime_type.to_s, editing).render(self) rescue LayoutNotFound yield end |
#request ⇒ Object
basic environment accessors
169 |
# File 'lib/yodel/models/pages/page.rb', line 169 def request; @_request; end |
#request=(r) ⇒ Object
170 |
# File 'lib/yodel/models/pages/page.rb', line 170 def request=(r); @_request = r; end |
#respond_to_request(request, response, mime_type) ⇒ Object
request handling
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/yodel/models/pages/page.rb', line 127 def respond_to_request(request, response, mime_type) # initialise request & response for use by the environment accessors @_request = request @_response = response @_mime_type = mime_type # determine the default action name for the request http_method = request.request_method.downcase action = "respond_to_#{http_method}_with_#{mime_type.name}" # if there is no action for the request, default to the first for the http_method of the request if !respond_to?(action) action = "default_response_to_#{http_method}" if !respond_to?(action) response.write "Unable to respond to a request using http method: #{http_method}" response['Content-Type'] = 'text/plain' return else default_mime = self.class.instance_variable_get("@default_response_to_#{http_method}_mime_type") mime_type = default_mime if mime_type != default_mime Yodel.config.logger.warn "No response matches this request, falling back to a default response." end end # only send a builder object as a parameter to the action if required if mime_type.has_builder? data = send(action, mime_type.create_builder) else data = send(action) end return if @finished # process the response and set headers response.write mime_type.process(data) response['Content-Type'] = "#{mime_type.default_mime_type}; charset=utf-8" # write the flash to the session if appropriate @flash.finalize if @flash end |
#response ⇒ Object
173 |
# File 'lib/yodel/models/pages/page.rb', line 173 def response; @_response; end |
#response=(r) ⇒ Object
174 |
# File 'lib/yodel/models/pages/page.rb', line 174 def response=(r); @_response = r; end |
#session ⇒ Object
177 |
# File 'lib/yodel/models/pages/page.rb', line 177 def session; @_request.env['rack.session'] ||= {}; end |
#set_content(content) ⇒ Object
226 227 228 |
# File 'lib/yodel/models/pages/page.rb', line 226 def set_content(content) @content = content end |
#snippet(name) ⇒ Object
Layout helpers
70 71 72 |
# File 'lib/yodel/models/pages/page.rb', line 70 def snippet(name) site.snippets[name.to_s].content end |
#status(code) ⇒ Object
By default, responses are assumed to be 200 (successful). Use status to change the code returned along with your response content.
181 182 183 |
# File 'lib/yodel/models/pages/page.rb', line 181 def status(code) response.status = code end |
#user_allowed_to?(action) ⇒ Boolean
263 264 265 266 267 268 269 270 |
# File 'lib/yodel/models/pages/page.rb', line 263 def user_allowed_to?(action) allowed = super(current_user(:page), action) return true if allowed prompt_login flash[:permission_denied] = action false end |