Class: Slimmer::Skin
- Inherits:
-
Object
- Object
- Slimmer::Skin
- Defined in:
- lib/slimmer/skin.rb,
lib/slimmer/test.rb
Instance Attribute Summary collapse
-
#asset_host ⇒ Object
Returns the value of attribute asset_host.
-
#logger ⇒ Object
Returns the value of attribute logger.
-
#options ⇒ Object
Returns the value of attribute options.
-
#strict ⇒ Object
Returns the value of attribute strict.
-
#template_cache ⇒ Object
Returns the value of attribute template_cache.
-
#use_cache ⇒ Object
Returns the value of attribute use_cache.
Instance Method Summary collapse
- #admin(body) ⇒ Object
- #context(html, error) ⇒ Object
- #error(template_name, body) ⇒ Object
- #ignorable?(error) ⇒ Boolean
-
#initialize(options = {}) ⇒ Skin
constructor
TODO: Extract the cache to something we can pass in instead of using true/false and an in-memory cache.
- #load_template(name) ⇒ Object
- #parse_html(html, description_for_error_message) ⇒ Object
- #process(processors, body, template) ⇒ Object
- #report_parse_errors_if_strict!(nokogiri_doc, description_for_error_message) ⇒ Object
- #success(source_request, response, body) ⇒ Object
- #template(template_name) ⇒ Object
- #template_url(template_name) ⇒ Object
Constructor Details
#initialize(options = {}) ⇒ Skin
TODO: Extract the cache to something we can pass in instead of using true/false and an in-memory cache.
7 8 9 10 11 12 13 14 |
# File 'lib/slimmer/skin.rb', line 7 def initialize = {} @options = @asset_host = [:asset_host] @template_cache = {} @use_cache = [:use_cache] || false @logger = [:logger] || NullLogger.instance @strict = [:strict] || (%w{development test}.include?(ENV['RACK_ENV'])) end |
Instance Attribute Details
#asset_host ⇒ Object
Returns the value of attribute asset_host.
3 4 5 |
# File 'lib/slimmer/skin.rb', line 3 def asset_host @asset_host end |
#logger ⇒ Object
Returns the value of attribute logger.
3 4 5 |
# File 'lib/slimmer/skin.rb', line 3 def logger @logger end |
#options ⇒ Object
Returns the value of attribute options.
3 4 5 |
# File 'lib/slimmer/skin.rb', line 3 def @options end |
#strict ⇒ Object
Returns the value of attribute strict.
3 4 5 |
# File 'lib/slimmer/skin.rb', line 3 def strict @strict end |
#template_cache ⇒ Object
Returns the value of attribute template_cache.
3 4 5 |
# File 'lib/slimmer/skin.rb', line 3 def template_cache @template_cache end |
#use_cache ⇒ Object
Returns the value of attribute use_cache.
3 4 5 |
# File 'lib/slimmer/skin.rb', line 3 def use_cache @use_cache end |
Instance Method Details
#admin(body) ⇒ Object
112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/slimmer/skin.rb', line 112 def admin(body) processors = [ TitleInserter.new(), TagMover.new(), AdminTitleInserter.new, FooterRemover.new, BodyInserter.new(), BodyClassCopier.new, ] process(processors, body, template('admin')) end |
#context(html, error) ⇒ Object
67 68 69 70 71 72 73 74 75 76 |
# File 'lib/slimmer/skin.rb', line 67 def context(html, error) context_size = 5 lines = [""] + html.split("\n") from = [1, error.line - context_size].max to = [lines.size - 1, error.line + context_size].min context = (from..to).zip(lines[from..to]).map {|lineno, line| "%4d: %s" % [lineno, line] } marker = " " * (error.column - 1) + "-----v" context.insert(context_size, marker) context.join("\n") end |
#error(template_name, body) ⇒ Object
142 143 144 145 146 147 |
# File 'lib/slimmer/skin.rb', line 142 def error(template_name, body) processors = [ TitleInserter.new() ] process(processors, body, template(template_name)) end |
#ignorable?(error) ⇒ Boolean
78 79 80 81 |
# File 'lib/slimmer/skin.rb', line 78 def ignorable?(error) ignorable_codes = [801] ignorable_codes.include?(error.code) || error..match(/Element script embeds close tag/) || error..match(/Unexpected end tag : noscript/) end |
#load_template(name) ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/slimmer/skin.rb', line 24 def load_template(template_name) url = template_url(template_name) source = open(url, "r:UTF-8", :ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE).read if template_name =~ /\.raw/ template = source else template = ERB.new(source).result binding end template rescue OpenURI::HTTPError => e raise TemplateNotFoundException, "Unable to fetch: '#{template_name}' from '#{url}' because #{e}", caller rescue Errno::ECONNREFUSED => e raise CouldNotRetrieveTemplate, "Unable to fetch: '#{template_name}' from '#{url}' because #{e}", caller rescue SocketError => e raise CouldNotRetrieveTemplate, "Unable to fetch: '#{template_name}' from '#{url}' because #{e}", caller end |
#parse_html(html, description_for_error_message) ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/slimmer/skin.rb', line 51 def parse_html(html, ) doc = Nokogiri::HTML.parse(html) if strict errors = doc.errors.select {|e| e.error?}.reject {|e| ignorable?(e)} if errors.size > 0 error = errors.first = "In #{}: '#{error.}' at line #{error.line} col #{error.column} (code #{error.code}).\n" << "Add ?skip_slimmer=1 to the url to show the raw backend request.\n\n" << context(html, error) raise end end doc end |
#process(processors, body, template) ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/slimmer/skin.rb', line 83 def process(processors,body,template) logger.debug "Slimmer: starting skinning process" src = parse_html(body.to_s, "backend response") dest = parse_html(template, "template") start_time = Time.now logger.debug "Slimmer: Start time = #{start_time}" processors.each do |p| processor_start_time = Time.now logger.debug "Slimmer: Processor #{p} started at #{processor_start_time}" begin p.filter(src,dest) rescue GdsApi::TimedOutException raise rescue => e logger.error "Slimmer: Failed while processing #{p}: #{[ e., e.backtrace ].flatten.join("\n")}" end processor_end_time = Time.now process_time = processor_end_time - processor_start_time logger.debug "Slimmer: Processor #{p} ended at #{processor_end_time} (#{process_time}s)" end end_time = Time.now logger.debug "Slimmer: Skinning process completed at #{end_time} (#{end_time - start_time}s)" # this is a horrible fix to Nokogiri removing the closing </noscript> tag required by Google Website Optimizer. # http://www.google.com/support/websiteoptimizer/bin/answer.py?hl=en_us&answer=64418 dest.to_html.sub(/<noscript rel=("|')placeholder("|')>/, "") end |
#report_parse_errors_if_strict!(nokogiri_doc, description_for_error_message) ⇒ Object
47 48 49 |
# File 'lib/slimmer/skin.rb', line 47 def report_parse_errors_if_strict!(nokogiri_doc, ) nokogiri_doc end |
#success(source_request, response, body) ⇒ Object
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/slimmer/skin.rb', line 124 def success(source_request, response, body) processors = [ TitleInserter.new(), TagMover.new(), ConditionalCommentMover.new(), BodyInserter.new([:wrapper_id] || 'wrapper'), BodyClassCopier.new, HeaderContextInserter.new(), SectionInserter.new(), GoogleAnalyticsConfigurator.new(response), SearchPathSetter.new(response), RelatedItemsInserter.new(template('related.raw'), source_request), ] template_name = response.headers[TEMPLATE_HEADER] || 'wrapper' process(processors, body, template(template_name)) end |
#template(template_name) ⇒ Object
16 17 18 19 20 21 22 |
# File 'lib/slimmer/skin.rb', line 16 def template(template_name) if use_cache template_cache[template_name] ||= load_template(template_name) else load_template(template_name) end end |
#template_url(template_name) ⇒ Object
41 42 43 44 45 |
# File 'lib/slimmer/skin.rb', line 41 def template_url(template_name) host = asset_host.dup host += '/' unless host =~ /\/$/ "#{host}templates/#{template_name}.html.erb" end |