Skip to content

Instantly share code, notes, and snippets.

@nimms
Created September 26, 2010 07:24
Show Gist options
  • Save nimms/597689 to your computer and use it in GitHub Desktop.
Save nimms/597689 to your computer and use it in GitHub Desktop.
require 'rubygems'
require 'hpricot'
require 'fileutils'
class RendererController < ApplicationController
before_filter :login_required, :only => %w[render_page_as_html save_changes_to_site]
before_filter :load_paths, :only => %w[index load_page_from_disk save_changes_to_site]
layout "renderer"
def index
#it should redirect to a 404 if a page is not found
show_404 and return unless @page
html_output = ""
options = {}
options[:edit] = true if session[:edit_status] == "on"
options[:drafts] = true if session[:drafts] == "on"
options[:toolbar] = true if logged_in?
if !logged_in?
path = @doc_path + @page.path + ".html"
html_output = load_page_from_disk(path)
end
if html_output.blank?
html_output = render_page_as_html(@page, options)
end
send_data(html_output, :type => "text/html", :disposition => "inline")
#rescue Exception => exception
# show_404 and return
end
def save_changes_to_site
@active_site.pages.each do |page|
save_page_to_disk(page)
end
respond_to do |wants|
wants.html { redirect_to "/" }
end
end
def load_page_from_disk(path)
html = ""
if File.file?(path)
html = File.read(path)
end
html
end
def create_menu(pages, page_name, options = { })
if options[:submenu] == true
menu = "\n<ul>\n"
else
menu = "\n<ul class='menu'>\n"
end
pages.each_with_index do |page, i|
page = pages[i]
class_string = ""
menu << "\t<li"
#set the class of the list to current if it is selected or is the parent of the
#selected page
if page.name == page_name || page.children_for_menu.detect{ |p| p.name == page_name}
class_string << "current "
end
class_string << "first " if page.parent.nil? && (i == 0)
class_string << " last" if page.parent.nil? && (i == (pages.length - 1))
menu << " class='#{class_string}'" unless class_string.blank?
menu << "><a href='#{page.path(@active_site)}'>#{page.menu_title}</a>"
if !(page.children.empty?)
menu << create_menu(page.children_for_menu, page_name, {:submenu => true})
end
menu << "</li>\n"
end
menu << "</ul>"
end
protected
def load_paths
begin
#
page_name = params[:page]
#it should load the page
if !@subdomain.blank? && page_name.blank?
page_name = @subdomain
end
if page_name.blank?
@page = @active_site.get_home_page
if @page.nil?
@page = Page.find(:first, :conditions => ["site_id = ?", @active_site.id])
end
else
@page = @active_site.pages.find_by_name(page_name)
end
#catch all rule just incase none of the others pick up a page
if !@page
@page = @active_site.pages.find(:first)
@is_subdomain = false
end
@doc_path = RAILS_ROOT + "/public/static/" + @active_site.url
rescue => err
logger.error { err }
show_404
end
end
def render_specials_list(site)
if site
specials = site.specials
if specials
list = "<ul>"
specials.each do |special|
list << <<-EOS
<li>
<a href="#{special.url}">#{special.description}</a>
</li>
EOS
end
list << "</ul>"
list
end
end
end
def show_404
render( :file => "#{RAILS_ROOT}/public/404.html",
:status => "404 Not Found" )
end
def render_page_as_html(page, options={})
if page.blank? || page.site.blank? || page.theme.blank?
return ""
end
site = page.site
# it "should check if there is a page layout for the page and load it other wise it should load the site specific page layout"
begin
page_layout = page.theme.page_layout.blank? ? Hpricot(site.theme.page_layout.html) : Hpricot(page.theme.page_layout.html)
rescue
show_404
end
#convenience accessor methods for the html structure
head = page_layout.search("//head")
body = page_layout.search("//body")
# it should insert a menu
page_layout.search("div.menu").each do |menu_div|
menu_div.inner_html = create_menu(site.get_top_level_pages_for_menu, page.name)
end
#it should insert the page title
(head/"title").inner_html = page.title
#it should insert meta tags
head.append(page.meta_tags.inject("") do |value, tag|
value << <<-EOS
<meta name="#{tag.name}" content="#{tag.content}" />
EOS
end)
# it should load the elements for this page - it loads all at once for so it doesn't make too many db calls
# it should look through the page layout and insert the elements into the editable divs
(page_layout/".editable").each do |edit_div|
element = page.elements.find_by_html_id(edit_div.attributes['id'])
if element
if options[:drafts]
logger.debug { "================ loading drafts ================" }
draft = element.load_from_draft
content = draft.blank? ? element.content : draft[:content]
elsif options[:save]
logger.debug { "================ saving drafts =================" }
element.save_from_draft if element
content = element.content if element
else
content = element.content rescue nil
end
edit_div.inner_html(content) if content
end
end
#it should look through the page layout and insert images
(page_layout/".banner, .image").each do |image_container|
element = page.elements.find_by_html_id(image_container.attributes['id'])
unless element.nil?
if options[:drafts]
draft = element.load_from_draft
element.image = Imagemage.find(draft[:image_id]) if draft && !draft[:image].blank?
elsif options[:save]
element.save_from_draft unless element.blank?
end
image_container.inner_html="<img src=#{element.image.public_filename}/>" unless element.image.nil?
end
end
#it should insert the contact form html
(page_layout/".newsletter-form").each do |contact_form|
contact_form.inner_html = Contact.signup_form_html
end
(page_layout/".contactus-form").each do |contact_form|
contact_form.inner_html = Contact.contact_us_form_html
end
#it should insert the style sheets
css_links = ""
if !page.theme.style_sheets.blank?
page.theme.style_sheets.each do |style_sheet|
css_links << <<-EOS
<link rel="stylesheet" href="/style_sheets/#{style_sheet.id}/styles.css" type="text/css" media="screen" title="no title" charset="utf-8">
EOS
end
end
head.prepend(css_links)
#it should insert javascripts for page
if !page.theme.javascripts.blank?
page.theme.javascripts.each do |javascript|
head.append("<script src='/javascripts/#{javascript.id}.js' type='text/javascript'></script>")
end
end
#it should load the specials for this site and insert it as a list
page_layout.search(".specials").each do |specials_container|
specials_container.inner_html = render_specials_list(site)
end
if options[:save]
head.append(<<-EOS
<!-- Saved as html on #{Time.now} -->
EOS
)
end
if logged_in? && options[:toolbar]
head.append(<<-EOS
<link rel="stylesheet" href="/stylesheets/toolbar.css" type="text/css" media="screen" title="no title" charset="utf-8">
EOS
)
body.prepend(<<-EOS
<div class='toolbar-spacer'>
&nbsp;
</div>
EOS
)
body.prepend(<<-EOS
<div class='toolbar'>
<p><span class='left'>
<a href='/admin'>control panel</a>
<a href="/renderer/save_changes_to_site">save changes to live site</a>
<a href="/toggle/edits">turn page editing #{options[:edit] ? "off" : "on"}</a>
<a href="/toggle/drafts">viewing drafts is #{options[:drafts] ? "on" : "off"}</a>
</span>
<span class='right'>Logged in as #{current_user.name} (<a href='/logout'>log out?</a>)</span><br style='clear:both'/>
</p>
</div>
EOS
)
end
#it should check if the edit functionality is turned on and insert the edit javascripts
if options[:edit]
js_links = <<-EOS
<link rel="stylesheet" href="/stylesheets/edit.css" type="text/css" media="screen" title="no title" charset="utf-8">
<link rel="stylesheet" href="/stylesheets/modalbox.css" type="text/css" media="screen" title="no title" charset="utf-8">
EOS
head.append(js_links)
#if editing is turned on, it should insert the edit links for content
page_layout.search(".editable").each do |edit|
content_srch_link = <<-EOS
<span style="float:left" class="utils edit-box">
<a id='#{edit.attributes['id']}_content_link' class='edit edit-link'
href='/elements/element_form?html_id=#{edit.attributes['id']}&page=#{page.name}'>edit content</a>
</span>
EOS
edit.inner_html= content_srch_link + edit.inner_html
end
#if editing is turned on, it should insert edit links for images
page_layout.search(".image, .banner").each do |image_span|
image_srch_link = <<-EOS
<span style="float:left" class='edit-box utils'>
<a id='#{image_span.attributes['id']}_img_link' class='edit-link edit' href='/images/lightbox_search?html_id=#{image_span.attributes['id']}&page=#{page.name}'>edit image</a>
</span>
EOS
image_span.inner_html = image_srch_link + image_span.inner_html
end
#if editing is turned on, it should insert the edit links for specials
page_layout.search(".specials").each do |specials_container|
specials_edit_link = <<-EOS
<span style="float:left" class='utils edit-box'>
<a id='#{specials_container.attributes['id']}_specials_link' class='edit edit-link' href='/admin/sites/#{site.id}/specials/'>edits specials</a>
</span>
EOS
specials_container.inner_html = specials_edit_link + specials_container.inner_html
end
end
@html_output = page_layout.to_html
end
private
def save_page_to_disk(page)
session[:edit_status] = "off"
filepath = @doc_path + page.path + ".html"
html = render_page_as_html(page, {:save => true, :toolbar => false, :drafts => false})
FileUtils.mkdir_p(@doc_path + (page.parent.nil? ? "" : "/#{page.parent.name}"))
File.open(filepath, "w") do |file|
file.puts(html)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment