From f5fd3dec7a015f3974f388927bf8637a5ce7f0fd Mon Sep 17 00:00:00 2001 From: Christophe Vilayphiou Date: Thu, 22 Mar 2012 01:51:16 +0800 Subject: [PATCH] Trying nokogiri --- Gemfile | 1 + Gemfile.lock | 4 + app/controllers/application_controller.rb | 2 +- app/controllers/pages_controller.rb | 2 + app/helpers/application_helper.rb | 47 ++++++++++ app/models/design/layout.rb | 8 +- app/models/meta.rb | 4 + app/views/layouts/page_layout.html.erb | 17 ++++ lib/parsers/parser_front_end.rb | 105 ++++++++++++++-------- lib/parsers/parser_layout.rb | 57 +++++------- 10 files changed, 172 insertions(+), 75 deletions(-) create mode 100644 app/views/layouts/page_layout.html.erb diff --git a/Gemfile b/Gemfile index 024f3449..d1afdb8c 100644 --- a/Gemfile +++ b/Gemfile @@ -16,6 +16,7 @@ gem 'kaminari', :git => 'git://github.com/amatsuda/kaminari.git' gem 'mini_magick' gem 'mongoid' gem "mongo_session_store-rails3" +gem 'nokogiri' gem 'radius' gem 'rake' gem 'ruby-debug19' diff --git a/Gemfile.lock b/Gemfile.lock index 1df648c4..71742974 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -41,6 +41,7 @@ GEM archive-tar-minitar (0.5.2) arel (2.2.3) bcrypt-ruby (3.0.1) + bcrypt-ruby (3.0.1-x86-mingw32) brakeman (1.5.1) activesupport erubis (~> 2.6) @@ -115,6 +116,8 @@ GEM mongo (~> 1.3) tzinfo (~> 0.3.22) multi_json (1.1.0) + nokogiri (1.5.2) + nokogiri (1.5.2-x86-mingw32) orm_adapter (0.0.6) pdf-writer (1.1.8) color (>= 1.4.0) @@ -252,6 +255,7 @@ DEPENDENCIES mini_magick mongo_session_store-rails3 mongoid + nokogiri radius rails (>= 3.1.0, < 3.2.0) rake diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 4b433777..fb82774e 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -47,7 +47,7 @@ class ApplicationController < ActionController::Base # Render the page def render_page(id = nil) if @item - render :text => parse_page(@item, id) + render :text => process_page(@item, id), :layout => 'page_layout' else render :text => '404 Not Found' end diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb index 8ea35391..4860ea2e 100644 --- a/app/controllers/pages_controller.rb +++ b/app/controllers/pages_controller.rb @@ -1,5 +1,7 @@ class PagesController < ApplicationController + include ApplicationHelper + before_filter :get_item, :only => [:index_from_link, :show_from_link] def index diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 50510e3c..9c03de3d 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -107,4 +107,51 @@ module ApplicationHelper end end + + def process_page(page, id) + parse_page_noko(page, id) + end + + def page_metas(page) + metas = '' + @site.page_metas.each do |meta| + name, content = meta.get_name_content + metas << "\n" + end rescue nil + return metas + end + + def page_title(page) + "#{page.title ? page.title[I18n.locale] : page.i18n_variable[I18n.locale]}\n" + end + + def page_stylesheets(page) + stylesheets = '' + stylesheets << "\n" + stylesheets << "\n" + stylesheets << "\n" + stylesheets << "\n" if page.design.reset_css + stylesheets << "\n" if page.design.default_css + theme = page.design.themes.detect{ |d| d.id == page.theme_id } + stylesheets << "\n" if theme + stylesheets + end + + def page_javascripts(page) + javascripts = '' + javascripts << "\n" + javascripts << "\n" + javascripts << "\n" + javascripts << "\n" + javascripts << "\n" + javascripts << "\n" + javascripts << "\n" + javascripts << "\n" + javascripts << "\n" + page.design.javascripts.each do |js| + # javascripts << "" + end + javascripts + end + end diff --git a/app/models/design/layout.rb b/app/models/design/layout.rb index e13498f3..bf48415c 100644 --- a/app/models/design/layout.rb +++ b/app/models/design/layout.rb @@ -2,6 +2,8 @@ class Layout < DesignFile include ParserLayout attr_reader :content + + field :body embeds_one :menu embedded_in :design @@ -17,8 +19,10 @@ class Layout < DesignFile Layout.count > 0 end - def parse_layout - parse_layout_contents(self) + def parse_layout + html = Nokogiri::HTML(self.file.read) + self.body = html.at_css("body").inner_html + parse_body(self) end end diff --git a/app/models/meta.rb b/app/models/meta.rb index 411a4f0c..dbeac167 100644 --- a/app/models/meta.rb +++ b/app/models/meta.rb @@ -7,5 +7,9 @@ class Meta field :value, :default => nil has_one :i18n_variable, :as => :language_value, :autosave => true, :dependent => :destroy + + def get_name_content + [self.key, self.value ? self.value : self.i18n_variable[I18n.locale]] + end end diff --git a/app/views/layouts/page_layout.html.erb b/app/views/layouts/page_layout.html.erb new file mode 100644 index 00000000..8fb884b0 --- /dev/null +++ b/app/views/layouts/page_layout.html.erb @@ -0,0 +1,17 @@ + + + + + <%= page_title(@item).html_safe %> + <%= page_metas(@item).html_safe %> + <%= @metas %> + + <%= page_stylesheets(@item).html_safe %> + <%= page_javascripts(@item).html_safe %> + + + <%= yield %> + + diff --git a/lib/parsers/parser_front_end.rb b/lib/parsers/parser_front_end.rb index 4b5a523f..8ea3840a 100644 --- a/lib/parsers/parser_front_end.rb +++ b/lib/parsers/parser_front_end.rb @@ -63,22 +63,6 @@ module ParserFrontEnd res << '>' end end - c.define_tag 'javascripts' do |tag| - res = '' - res << "" - res << "" - res << "" - res << "" - res << "" - res << "" - res << "" - res << "" - res << "" - page.design.javascripts.each do |js| - # res << "" - end - res - end c.define_tag 'language_bar' do @site.in_use_locales.map{ |locale| lang = I18nVariable.first(:conditions => {:key => locale})[locale] @@ -101,38 +85,87 @@ module ParserFrontEnd menu = page.design.layout.menu menu_level(home, 0, menu) end - c.define_tag 'meta' do |tag| - res = '' - #res << "" - end - c.define_tag 'stylesheets' do |tag| - res = '' - res << "" - res << "" - res << "" - res << "" if page.design.reset_css - res << " " if page.design.default_css - theme = page.design.themes.detect{ |d| d.id == page.theme_id } - res << "" if theme - res - end - c.define_tag 'title' do |tag| - "#{page.title ? page.title[I18n.locale] : page.i18n_variable[I18n.locale]}" - end end end def parse_page(page, id = nil) if page._type == 'Page' - layout_content = page.design.layout.content.force_encoding('UTF-8') rescue '' context = parser_context(page, {}, id) parser = Radius::Parser.new(context, :tag_prefix => 'r') - parser.parse(parser.parse(layout_content)) + parser.parse(parser.parse(page.design.layout.body)) end end def self.included(base) base.send :helper_method, :parse_page if base.respond_to? :helper_method end + + + + require 'nokogiri' + + def parse_page_noko(page, id = nil) + body = Nokogiri::HTML(page.design.layout.body, nil, 'UTF-8') + + # page_contents + body.css('.page_content').each do |content| + ret = '' + if (content["main"] == "true" && !page.module_app.nil?) + ret << "
" + else + part = page.page_parts.detect{ |p| p.name.to_s == content['name'].to_s } rescue nil + case part.kind + when 'text' + ret << part.i18n_variable[I18n.locale] rescue '' + when 'module_widget' + if part[:category] + ret << "
" + else + ret << "
" + end + when 'public_r_tag' + ret << "" + else + '' + end + end + scope = "<#{content.name}" + content.attributes.each_pair do |key, value| + scope << " #{key}='#{value}'" + end + scope << ">#{ret}" + fragment = Nokogiri::HTML::DocumentFragment.new(body, scope) + content.swap(fragment) + end + + # page_menu + page_menu = body.css('.page_menu').first + home = get_homepage + menu = page.design.layout.menu + fragment = Nokogiri::HTML::DocumentFragment.new(body, menu_level(home, 0, menu)) + page_menu.swap(fragment) + + # page_image + body.css('.page_image').each do |page_image| + # image = page.custom_images.detect{|image| image.name.eql?(tag.attr['name']) } + # image = page.design.custom_images.detect{|image| image.name.eql?(tag.attr['name']) } unless image + image = page.design.images.detect{|image| image.name.eql?(page_image['name']) } unless image + if image + res = "' + end + fragment = Nokogiri::HTML::DocumentFragment.new(body, res) + page_image.swap(fragment) + end + + body.to_html + end end diff --git a/lib/parsers/parser_layout.rb b/lib/parsers/parser_layout.rb index 063078df..01d681ef 100644 --- a/lib/parsers/parser_layout.rb +++ b/lib/parsers/parser_layout.rb @@ -1,44 +1,27 @@ module ParserLayout - require 'radius' - include ParserCommon + require 'nokogiri' - def parse_layout_contents(layout) - content = layout.content.force_encoding('UTF-8') - context = parser_layout_contents(layout) - parser = Radius::Parser.new(context, :tag_prefix => 'r') - parser.parse(content) - end - - def parser_layout_contents(layout) - Radius::Context.new do |c| - c.define_tag 'ad_banner' do |tag| - end - c.define_tag 'content' do |tag| - layout.layout_parts.new(:name => tag.attr['name']) - end - c.define_tag 'image' do |tag| - image = layout.design.images.detect{ |i| i.file_identifier.eql?(parse_html_image(tag.expand)) } - image.update_attributes(:name => tag.attr['name'], :html_id => tag.attr['id'], :html_class => tag.attr['class']) if image - end - c.define_tag 'javascripts' do |tag| - end - c.define_tag 'menu' do |tag| - layout.build_menu(:levels => 0, :values => {}) unless layout.menu - layout.menu.levels = i = tag.attr['level'].to_i - layout.menu.values.merge!({'home' => tag.attr['home']}) if i == 1 - layout.menu.values.merge!({"id_#{i}" => tag.attr['id'], "class_#{i}" => tag.attr['class'], "li_class_#{i}" => tag.attr['li_class'], "li_incremental_#{i}" => tag.attr['li_incremental']}) - tag.expand - end - c.define_tag 'meta' do |tag| - end - c.define_tag 'stylesheets' do |tag| - end - c.define_tag 'title' do |tag| - end + def parse_body(layout) + body = Nokogiri::HTML(layout.body) + body.css('.page_content').each do |content| + layout.layout_parts.build(:name => content['name']) end + + body.css('.page_image').each do |image| + image = layout.design.images.detect{ |i| i.file_identifier.eql?(parse_html_image(image.to_html)) } + image.update_attributes(:name => image['name'], :html_id => image['id'], :html_class => image['class']) if image + end + + body.css('.page_menu').each do |menu| + layout.build_menu(:levels => 0, :values => {}) unless layout.menu + layout.menu.levels = i = menu['level'].to_i + layout.menu.values.merge!({'home' => menu['home']}) if i == 1 + layout.menu.values.merge!({"id_#{i}" => menu['id'], "class_#{i}" => menu['class'], "li_class_#{i}" => menu['li_class'], "li_incremental_#{i}" => menu['li_incremental']}) + end + end - + def parse_html_image(html) html.scan(/(?<=\)/){ $1.gsub(' ','').scan(/(?<=src=\")(.*?)(?=\")/){ @@ -46,4 +29,6 @@ module ParserLayout } } end + + end