Skip to content

Commit

Permalink
Added ajax support and page_connection_hash support
Browse files Browse the repository at this point in the history
changed comments to add in ajax support
  • Loading branch information
cykod committed Apr 16, 2010
1 parent 54feaa3 commit 5d1e39b
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 39 deletions.
2 changes: 1 addition & 1 deletion app/controllers/page_controller.rb
Expand Up @@ -33,7 +33,7 @@ def paragraph #:nodoc:
@result = engine.run_paragraph(para,self,myself)

if @result
render :text => webiva_post_process_paragraph(render_paragraph(container.is_a?(SiteNode) ? container : container.site_node, revision, @result))
render :text => webiva_post_process_paragraph(render_paragraph(container.is_a?(SiteNode) ? container : container.site_node, revision, @result, :ajax => true))
else
render :nothing => true
end
Expand Down
13 changes: 12 additions & 1 deletion app/controllers/paragraph_feature.rb
Expand Up @@ -721,6 +721,14 @@ def define_form_tag(frm,name) #:nodoc:
end
end

def define_ajax_form_for_tag(name,arg,options = {},&block)
options[:html] ||= {}
options[:html][:onsubmit] ||= ''
options[:html][:onsubmit] += " new Ajax.Updater('cmspara_#{paragraph.id}','#{ajax_url}',{ evalScripts: true, parameters: Form.serialize(this) }); return false;"
define_form_for_tag(name,arg,options,&block)
require_js('prototype')
end

# Creates a cms_unstyled_form_for object that can be used
# in combination with define_field_tag to allows users to
# custom style a form
Expand All @@ -742,7 +750,10 @@ def define_form_for_tag(name,arg,options = {})
frm_opts[:method] = 'post'
html_options = html_options_for_form(options.delete(:url),frm_opts)
html_options['action'] ||= ''
frm_tag = tag(:form,html_options,true) + "<CMS:AUTHENTICITY_TOKEN/>" + opts.delete(:code).to_s
if pch = opts.delete(:page_connection_hash)
pch = "<input type='hidden' name='page_connection_hash' value='#{pch}' />"
end
frm_tag = tag(:form,html_options,true) + "<CMS:AUTHENTICITY_TOKEN/>" + pch.to_s + opts.delete(:code).to_s
cms_unstyled_fields_for(arg,obj,opts) do |f|
tag.locals.send("#{frm_obj}=",f)
frm_tag + tag.expand + "</form>"
Expand Down
69 changes: 67 additions & 2 deletions app/controllers/paragraph_renderer.rb
Expand Up @@ -30,6 +30,7 @@ def initialize(rnd,args)
attr_accessor :paction
attr_accessor :paction_data
attr_accessor :content_nodes
attr_accessor :paragraph_id

def method_missing(method,args)
@rnd.send(method)
Expand Down Expand Up @@ -61,7 +62,7 @@ def initialize(output,includes,page_connections,page_title=nil)
@page_connections = page_connections
@page_title = page_title
end

attr_accessor :output
attr_accessor :includes
attr_accessor :page_connections
Expand Down Expand Up @@ -453,7 +454,71 @@ def ajax_url(opts={})
:page_revision => self.paragraph.page_revision.id,
:paragraph => self.paragraph.id)
paragraph_action_url(opts)
end
end

def insert_page_connection_hash!(output,replacement)
output.gsub!(replacement,page_connection_hash)
end

# Returns a hash of the page connections and stores them safely in the
# session for an ajax call
def page_connection_hash
return @page_connection_hash if @page_connection_hash
conns = self.paragraph.page_connections || {}
output_hsh = {}
conns.each do |key,val|
output_hsh[key] = page_connection_hash_helper(val)
end
hash_hash = DomainModel.hash_hash(output_hsh)
session[:page_connection_hash] ||= {}
session[:page_connection_hash][paragraph.id.to_s + "_" + hash_hash] = output_hsh

@page_connection_hash = hash_hash
end

def set_page_connection_hash(conns) #:nodoc:
output_hash = {}
conns.each do |key,val|
output_hash[key] = set_page_connection_hash_helper(val)
end
self.paragraph.page_connections = output_hash
end

def page_connection_hash_helper(val) #:nodoc:
if val.is_a?(Array)
val.map { |sval| page_connection_hash_helper(sval) }
elsif val.kind_of?(Hash)
output = {}
val.each { |key,sval| output[key] = page_connection_hash_helper(sval) }
output
elsif val.kind_of?(DomainModel)
{ :domain_model_hash => true, :cls => val.class.to_s, :id => val.id }
elsif val.kind_of?(HashModel)
{ :hash_model_hash => true, :cls => val.class.to_s, :attr => val.to_hash }
else
val
end
end


def set_page_connection_hash_helper(val) # :nodoc:
if val.is_a?(Hash)
if val[:domain_model_hash]
val[:cls].constantize.find(val[:id])
elsif val[:hash_model_hash]
val[:cls].constantize.new(val[:attr])
else
output = {}
val.each { |key,sval| output[key] = set_page_connection_hash_helper(sval) }
output
end
elsif val.is_a?(Array)
val.map { |sval| set_page_connection_hash_helper(sval) }
else
val
end
end


# Includes the specified css file when the page is rendered
# uses the standard rails stylesheet_link_tag syntax
Expand Down
2 changes: 2 additions & 0 deletions app/models/domain_model.rb
Expand Up @@ -306,8 +306,10 @@ def self.generate_hash
# by turning the hash into an array, sorting the keys
# and hashing the resultant array - allows Hash's with the same
# keys and values to generate consistent Hash's
# and will sort upto two hashes deep
def self.hash_hash(hsh)
arr = hsh.to_a.sort { |a,b| a[0].to_s<=>b[0].to_s }
arr.map! { |elm| elm[1].is_a?(Hash) ? [elm[0],elm[1].to_a.sort { |a,b| a[0].to_s<=>b[0].to_s } ] : elm }
Digest::SHA1.hexdigest(arr.to_s)[0..63]
end

Expand Down
8 changes: 7 additions & 1 deletion lib/site_node_engine.rb
Expand Up @@ -202,6 +202,11 @@ def compile_paragraph(site_node,revision,paragraph,opts={})
return output
else
rnd = cls.new(myself.user_class,self,paragraph,site_node,revision,opts)

if opts[:ajax] && params[:page_connection_hash]
pch = (session[:page_connection_hash] || {})[paragraph.id.to_s + "_" + params[:page_connection_hash]]
rnd.set_page_connection_hash(pch) if pch
end
rnd.capture_data = true if opts[:capture]
if paragraph.site_feature_id && !opts[:edit]
# If we're not in the editor, include the feature css
Expand Down Expand Up @@ -372,7 +377,8 @@ def render_output(page,output_obj)
if para.is_a?(String)
output += webiva_post_process_paragraph(para)
else
output+= "<div class='paragraph' >#{webiva_post_process_paragraph(render_paragraph page, output_obj.revision, para)}</div>"
para_id = para.is_a?(ParagraphRenderer::ParagraphOutput) ? "id='cmspara_#{para.rnd.paragraph.id}'" : ""
output+= "<div class='paragraph' #{para_id}>#{webiva_post_process_paragraph(render_paragraph page, output_obj.revision, para)}</div>"
end
end
end
Expand Down
18 changes: 12 additions & 6 deletions spec/spec_helper.rb
Expand Up @@ -377,15 +377,21 @@ def renderer_post(rnd,args = {})

end

class ViewExampleGroup < FunctionalExampleGroup
class ViewExampleGroup < FunctionalExampleGroup
def build_feature(feature_class,code=nil)
if code
site_feature = mock_model(SiteFeature,:body => code,:body_html => code,:feature_type => :any,:options => {} )
paragraph = mock_model(PageParagraph,:site_feature => site_feature, :content_publication => nil)
else
paragraph = mock_model(PageParagraph,:site_feature => nil, :content_publication => nil)
end
renderer = mock_model(ParagraphRenderer,:get_handler_info => [],:protect_against_forgery? => false)
paragraph = mock_model(PageParagraph,:site_feature => site_feature, :content_publication => nil,:page_revision => PageRevision.new)
else
paragraph = mock_model(PageParagraph,:site_feature => nil, :content_publication => nil,:page_revision => PageRevision.new)
end
renderer = mock_model(ParagraphRenderer,
:get_handler_info => [],
:protect_against_forgery? => false,
:require_js => nil,
:paragraph_action_url => '/paragraph',
:paragraph => paragraph)

feature_class.classify.constantize.new(paragraph,renderer)
end
end
Expand Down
Expand Up @@ -42,7 +42,10 @@ def comments_page_comments_feature(data)

paragraph_id = data[:paragraph_id] ? data[:paragraph_id] : paragraph.id

c.form_for_tag('add_comment',"comment_#{paragraph_id}") { |t| data[:comment] }
c.ajax_form_for_tag('add_comment',"comment_#{paragraph_id}") do |t|
{ :object => data[:comment] ,
:page_connection_hash => data[:cached_connection_hash] }
end
c.form_error_tag('add_comment:errors')
c.field_tag('add_comment:email')
c.field_tag('add_comment:website')
Expand Down
Expand Up @@ -4,7 +4,7 @@ class Feedback::CommentsRenderer < ParagraphRenderer

features '/feedback/comments_feature'

paragraph :comments
paragraph :comments, :ajax => true
paragraph :pingback_auto_discovery

def comments
Expand All @@ -30,44 +30,51 @@ def comments
display_string << (myself.missing_name? ? '_missing_name' : '_have_name')

result = renderer_cache(Comment, display_string, :skip => true || request.post? || @options.captcha) do |cache|
@cached_connection_hash = cache[:cached_connection_hash] = DomainModel.generate_hash
@comment = Comment.new
param_str = 'comment_' + paragraph.id.to_s
if request.post? && params[param_str]
if myself.id || @options.allowed_to_post == 'all'
@comment = Comment.new(:target_type => content_link[0],
:target_id => content_link[1],
:posted_ip => request.remote_ip,
:comment => params[param_str][:comment],
:name => params[param_str][:name],
:end_user_id => myself.id)
if myself.id || @options.allowed_to_post == 'all'
@comment = Comment.new(:target_type => content_link[0],
:target_id => content_link[1],
:posted_ip => request.remote_ip,
:comment => params[param_str][:comment],
:name => params[param_str][:name],
:end_user_id => myself.id)

@captcha.validate_object(@comment, :skip => ! @options.captcha)
if @comment.save
target_cls = content_link[0].constantize
if(target_cls && target_cls.respond_to?("comment_posted"))
target_cls.comment_posted(content_link[1])
end

if paragraph.update_action_count > 0
atr = @comment.attributes.slice('name','posted_ip','posted_at','comment')
atr['target'] = @comment.target.title if @comment.target && @comment.target.respond_to?(:title)
paragraph.run_triggered_actions(atr,'action',myself)
end
@captcha.validate_object(@comment, :skip => ! @options.captcha)
if @comment.save
target_cls = content_link[0].constantize
if(target_cls && target_cls.respond_to?("comment_posted"))
target_cls.comment_posted(content_link[1])
end

# Make sure we know if we posted after redirect
flash[:posted_comment] = true if @comment.id

redirect_paragraph :page
return
end
end
if paragraph.update_action_count > 0
atr = @comment.attributes.slice('name','posted_ip','posted_at','comment')
atr['target'] = @comment.target.title if @comment.target && @comment.target.respond_to?(:title)
paragraph.run_triggered_actions(atr,'action',myself)
end

# Make sure we know if we posted after redirect
if ajax?
flash.now[:posted_comment] = true if @comment.id
@comment = Comment.new
else
redirect_paragraph :page
flash[:posted_comment] = true if @comment.id
return
end
end
end
end

@comments = Comment.with_rating(@options.show).for_target(content_link[0],content_link[1]).order_by_posted(@options.order.to_s).find(:all)
@posted_comment = flash[:posted_comment]
cache[:output] = comments_page_comments_feature
end

insert_page_connection_hash!(result.output,result.cached_connection_hash)

render_paragraph :text => result.output
end

Expand Down

0 comments on commit 5d1e39b

Please sign in to comment.