diff --git a/lib/meta_tags/meta_tags_collection.rb b/lib/meta_tags/meta_tags_collection.rb index c63923f8..999b3594 100644 --- a/lib/meta_tags/meta_tags_collection.rb +++ b/lib/meta_tags/meta_tags_collection.rb @@ -82,17 +82,12 @@ def delete(*names) # @return [String] page title. # def extract_full_title - title = extract_title || [] - separator = extract_separator + site_title = extract(:site) || '' + title = extract_title || [] + separator = extract_separator + reverse = extract(:reverse) === true - site_title = extract(:site).presence - title.unshift(site_title) if site_title - title = TextNormalizer.normalize_title(title) - - title.reverse! if extract(:reverse) === true - title = TextNormalizer.safe_join(title, separator) - - title + TextNormalizer.normalize_title(site_title, title, separator, reverse) end # Extracts page title as an array of segments without site title and separators. diff --git a/lib/meta_tags/renderer.rb b/lib/meta_tags/renderer.rb index e6922243..7f279b0f 100644 --- a/lib/meta_tags/renderer.rb +++ b/lib/meta_tags/renderer.rb @@ -199,8 +199,8 @@ def process_array(tags, property, content, options = {}) # Recursive method to process a hash with meta tags # # @param [Array] tags a buffer object to store tag in. - # @param [String, Symbol] property a Hash or a String to render as meta tag. - # @param [String, Symbol] content text content or a symbol reference to + # @param [String, Symbol] name a Hash or a String to render as meta tag. + # @param [String, Symbol] value text content or a symbol reference to # top-level meta tag. # def render_tag(tags, name, value, options = {}) diff --git a/lib/meta_tags/text_normalizer.rb b/lib/meta_tags/text_normalizer.rb index 382a465d..ae303ff2 100644 --- a/lib/meta_tags/text_normalizer.rb +++ b/lib/meta_tags/text_normalizer.rb @@ -3,11 +3,26 @@ module MetaTags module TextNormalizer # Normalize title value. # + # @param [String] site_title site title. # @param [String, Array] title title string. + # @param [String] separator a string to join title parts with. + # @param [true,false] reverse whether title should be reversed. # @return [Array] array of title parts with tags removed. # - def self.normalize_title(title) - Array(title).flatten.map(&method(:strip_tags)) + def self.normalize_title(site_title, title, separator, reverse = false) + title = Array(title).flatten.map(&method(:strip_tags)) + title.reject!(&:blank?) + site_title = strip_tags(site_title) + separator = strip_tags(separator) + + if MetaTags.config.title_limit + limit = MetaTags.config.title_limit - site_title.length - separator.length + title = truncate_array(title, limit, separator) + end + + title.unshift(site_title) if site_title.present? + title.reverse! if reverse + safe_join(title, separator) end # Normalize description value. @@ -18,7 +33,8 @@ def self.normalize_title(title) # def self.normalize_description(description) return '' if description.blank? - helpers.truncate(cleanup_string(description), :length => 200) + description = cleanup_string(description) + truncate(description, MetaTags.config.description_limit) end # Normalize keywords value. @@ -28,7 +44,11 @@ def self.normalize_description(description) # def self.normalize_keywords(keywords) return '' if keywords.blank? - cleanup_strings(keywords).join(', ').downcase + keywords = cleanup_strings(keywords).each(&:downcase!) + separator = strip_tags MetaTags.config.keywords_separator + + keywords = truncate_array(keywords, MetaTags.config.keywords_limit, separator) + safe_join(keywords, separator) end # Easy way to get access to Rails helpers. @@ -45,7 +65,7 @@ def self.helpers # @return [String] string with no HTML tags. # def self.strip_tags(string) - helpers.strip_tags(string) + ERB::Util.html_escape helpers.strip_tags(string) end # This method returns a html safe string similar to what Array#join @@ -76,8 +96,47 @@ def self.cleanup_string(string) # @param [Array] strings input strings. # @return [Array] clean strings. # @see cleanup_string + # def self.cleanup_strings(strings) Array(strings).flatten.map(&method(:cleanup_string)) end + + # Truncates a string to a specific limit. + # + # @param [String] string input strings. + # @param [Integer,nil] limit characters number to truncate to. + # @param [String] natural_separator natural separator to truncate at. + # @return [String] truncated string. + # + def self.truncate(string, limit = nil, natural_separator = ' ') + string = helpers.truncate(string, :length => limit, :separator => natural_separator, :omission => '') if limit + string + end + + # Truncates a string to a specific limit. + # + # @param [Array] string_array input strings. + # @param [Integer,nil] limit characters number to truncate to. + # @param [String] separator separator that will be used to join array later. + # @param [String] natural_separator natural separator to truncate at. + # @return [String] truncated string. + # + def self.truncate_array(string_array, limit = nil, separator = '', natural_separator = ' ') + return string_array if limit.nil? || limit == 0 + length = 0 + result = [] + string_array.each do |string| + limit_left = limit - length - separator.length + if string.length > limit_left + result << truncate(string, limit_left, natural_separator) + break + end + length += (result.any? ? separator.length : 0) + string.length + result << string + # No more strings will fit + break if length + separator.length >= limit + end + result + end end end diff --git a/spec/view_helper/description_spec.rb b/spec/view_helper/description_spec.rb index b0473e3c..8a52a8b0 100644 --- a/spec/view_helper/description_spec.rb +++ b/spec/view_helper/description_spec.rb @@ -49,7 +49,7 @@ it 'should truncate correctly' do subject.display_meta_tags(:site => 'someSite', :description => "Lorem ipsum dolor sit amet, consectetuer sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.").tap do |meta| - expect(meta).to include('') + expect(meta).to include('') end end end