form builder works, blocks are properly saved

Oleg committed Aug 31, 2010
commit 89199e96e8223ec981494e6873cc45c748112647
Showing 13 changed files with 132 additions and 12 deletions
app/controllers/cms_admin/pages_controller.rb +16 -2
@@ @@ -1,6 +1,7 @@
class CmsAdmin::PagesController < CmsAdmin::BaseController
before_filter :build_cms_page, :only => [:new]
+ before_filter :load_cms_page, :only => [:edit]
def index
@cms_pages = CmsPage
@@ @@ -15,7 +16,12 @@ class CmsAdmin::PagesController < CmsAdmin::BaseController
end
def create
-
+ @cms_page = CmsPage.new(params[:cms_page])
+ @cms_page.save!
+ flash[:notice] = 'Page saved'
+ redirect_to :action => :edit, :id => @cms_page
+ rescue ActiveRecord::RecordInvalid
+ render :action => :edit
end
protected
@@ @@ -23,7 +29,15 @@ protected
def build_cms_page
@cms_page = CmsPage.new(params[:cms_page])
@cms_page.cms_layout = CmsLayout.first
- CmsTag.initialize_tags(@cms_page.cms_layout.content, :cms_page => @cms_page)
+ @cms_page.initialize_tags
+ end
+
+ def load_cms_page
+ @cms_page = CmsPage.find(params[:id])
+ @cms_page.initialize_tags
+ rescue ActiveRecord::RecordNotFound
+ flash[:error] = 'Page not found'
+ redirect_to :action => :index
end
end
app/helpers/cms_helper.rb +4 -1
@@ @@ -1,5 +1,8 @@
module CmsHelper
- # TODO
+ def cms_form_for(record_or_name_or_array, *args, &proc)
+ options = args.extract_options!
+ form_for(record_or_name_or_array, *(args << options.merge(:builder => CmsFormBuilder)), &proc)
+ end
end
app/models/cms_block.rb +12 -0
@@ @@ -8,4 +8,16 @@ class CmsBlock < ActiveRecord::Base
:presence => true,
:uniqueness => { :scope => :cms_page_id }
+ # -- Class Methods --------------------------------------------------------
+ class << self
+ # making sure that the correct class is initialized based on :type passed
+ # primarily important for form processing
+ def new_with_cast(*args, &block)
+ if (h = args.first).is_a?(Hash) && (type = h[:type] || h['type']) && (klass = type.constantize) != self
+ return klass.new(*args, &block)
+ end
+ new_without_cast(*args, &block)
+ end
+ alias_method_chain :new, :cast
+ end
end
app/models/cms_page.rb +10 -1
@@ @@ -3,6 +3,7 @@ class CmsPage < ActiveRecord::Base
# -- Relationships --------------------------------------------------------
belongs_to :cms_layout
has_many :cms_blocks, :dependent => :destroy
+ accepts_nested_attributes_for :cms_blocks
# -- Validations ----------------------------------------------------------
validates :label,
@@ @@ -10,14 +11,22 @@ class CmsPage < ActiveRecord::Base
validates :slug,
:presence => true,
:format => /^\w[a-z0-9_-]*$/i
+ validates :cms_layout,
+ :presence => true
# -- Instance Methods -----------------------------------------------------
def render_content
content = cms_layout.content.dup
- CmsTag.initialize_tags(content, :cms_page => self).each do |tag|
+ initialize_tags.each do |tag|
content.gsub!(tag.regex_tag_signature){ tag.render }
end
return content
end
+ # Returns an array of tag objects, at the same time populates #cms_blocks
+ # of the current page
+ def initialize_tags
+ CmsTag.initialize_tags(cms_layout.content, :cms_page => self)
+ end
+
end
app/views/cms_admin/pages/_form.html.erb +3 -4
@@ @@ -1,7 +1,6 @@
<%= form.text_field :label %>
<%= form.text_field :slug %>
-
-
- <%= debug @cms_page.cms_layout.content %>
- <%= debug @cms_page.cms_blocks %>
\ No newline at end of file
+ <% @cms_page.cms_blocks.each do |block| %>
+ <%= form.cms_block_field(block) %>
+ <% end %>
\ No newline at end of file
app/views/cms_admin/pages/edit.html.erb +6 -0
@@ @@ -0,0 +1,6 @@
+ <h1> Editing Page </h1>
+
+ <%= cms_form_for @cms_page, :url => {:action => :update} do |form| %>
+ <%= render :partial => 'form', :object => form %>
+ <%= form.submit 'Update Page' %>
+ <% end %>
\ No newline at end of file
app/views/cms_admin/pages/new.html.erb +2 -2
@@ @@ -1,6 +1,6 @@
<h1> New Page </h1>
- <%= form_for @cms_page, :url => {:action => :create} do |form| %>
- <%= render :partial => form %>
+ <%= cms_form_for @cms_page, :url => {:action => :create} do |form| %>
+ <%= render :partial => 'form', :object => form %>
<%= form.submit 'Create Page' %>
<% end %>
\ No newline at end of file
comfortable_mexican_sofa.rb b/lib/comfortable_mexican_sofa.rb +2 -0
@@ @@ -1,3 +1,5 @@
+ require File.join(File.dirname(__FILE__), 'comfortable_mexican_sofa', 'cms_form_builder')
+
require File.join(File.dirname(__FILE__), '..', 'app', 'models', 'cms_block')
require File.join(File.dirname(__FILE__), 'comfortable_mexican_sofa', 'cms_tag')
Dir.glob(File.join(File.dirname(__FILE__), 'comfortable_mexican_sofa', 'cms_tag', '*.rb')).each do |tag|
comfortable_mexican_sofa/cms_form_builder.rb b/lib/comfortable_mexican_sofa/cms_form_builder.rb +60 -0
@@ @@ -0,0 +1,60 @@
+ require 'action_view/helpers/form_helper'
+
+ class CmsFormBuilder < ActionView::Helpers::FormBuilder
+
+ helpers = field_helpers -
+ %w(hidden_field fields_for)
+
+ helpers.each do |name|
+ class_eval %Q^
+ def #{name}(field, *args)
+ options = args.extract_options!
+ args << options
+ return super if options.delete(:disable_builder)
+ default_field('#{name}', field, options){ super }
+ end
+ ^
+ end
+
+ def default_field(type, field, options = {}, &block)
+ %(
+ <div class='form_element #{type}_element'>
+ <div class='label'>#{label_for(field, options)}</div>
+ <div class='value'>#{yield}</div>
+ </div>
+ ).html_safe
+ end
+
+ def label_for(field, options)
+ label = options.delete(:label) || field.to_s.titleize.capitalize
+ "<label for=\"#{object_name}_#{field}\">#{label}</label>".html_safe
+ end
+
+ # Helper method for all block tags. You can define your own method based
+ # on tag type.
+ def cms_block_field(block, *args)
+ block_method = block.type.split('::').last.underscore.downcase
+ return send(block_method, block) if self.respond_to? block_method
+
+ form_method = case block
+ when CmsTag::PageText
+ :text_area_tag
+ when CmsTag::PageString
+ :text_field_tag
+ when CmsTag::PageInteger
+ :number_field_tag
+ end
+
+ %(
+ <div class='form_element #{block_method}_element'>
+ <div class='label'>#{block.label.to_s.titleize}</div>
+ <div class='value'>
+ #{@template.send(form_method, 'cms_page[cms_blocks_attributes][][content]', block.content)}
+ #{@template.hidden_field_tag('cms_page[cms_blocks_attributes][][label]', block.label)}
+ #{@template.hidden_field_tag('cms_page[cms_blocks_attributes][][type]', block.type)}
+ </div>
+ </div>
+ ).html_safe
+ end
+
+ end
\ No newline at end of file
comfortable_mexican_sofa/cms_tag.rb b/lib/comfortable_mexican_sofa/cms_tag.rb +5 -2
@@ @@ -46,9 +46,12 @@ module CmsTag
nil
end
- # Content that gets returned by the instance of the tag
+ def content=(value)
+ nil
+ end
+
def content
- ''
+ nil
end
# Content that is used during page rendering
comfortable_mexican_sofa/cms_tag/page_integer.rb b/lib/comfortable_mexican_sofa/cms_tag/page_integer.rb +4 -0
@@ @@ -11,6 +11,10 @@ class CmsTag::PageInteger < CmsBlock
self.class.regex_tag_signature(label)
end
+ def content=(value)
+ write_attribute(:content_integer, value)
+ end
+
def content
read_attribute(:content_integer)
end
comfortable_mexican_sofa/cms_tag/page_string.rb b/lib/comfortable_mexican_sofa/cms_tag/page_string.rb +4 -0
@@ @@ -11,6 +11,10 @@ class CmsTag::PageString < CmsBlock
self.class.regex_tag_signature(label)
end
+ def content=(value)
+ write_attribute(:content_string, value)
+ end
+
def content
read_attribute(:content_string)
end
comfortable_mexican_sofa/cms_tag/page_text.rb b/lib/comfortable_mexican_sofa/cms_tag/page_text.rb +4 -0
@@ @@ -11,6 +11,10 @@ class CmsTag::PageText < CmsBlock
self.class.regex_tag_signature(label)
end
+ def content=(value)
+ write_attribute(:content_text, value)
+ end
+
def content
read_attribute(:content_text)
end