Sha256: ff66b01b57dda1fa84667ed01d9f11dbb9044b3c801e465fe28ee9013abe0c1e

Contents?: true

Size: 1.96 KB

Versions: 1

Compression:

Stored size: 1.96 KB

Contents

module WulffeldSlug
  module SlugInclude
    def self.included(base)
      base.class_eval do
        if self.slug_config[:mongo]
          field :slug
        end
          
        validates_presence_of :slug

        before_validation :on => :create do
          cb_make_slug
        end
      end
    end
    
    def to_param
      slug
    end
    
    # Can override this.
    def slug_unique?(slug)
      !self.class.where(:slug => slug).first
    end

    def cb_make_slug
      return unless slug.blank?

      a = [*send(slug_config[:fields])].reject {|f| f.blank? }.map {|f| f.is_a?(String) ? f : send(f) }.flatten
      return if a.blank?

      self.slug = to_unique_slug(a.join('-'))
    end

    def to_unique_slug(s, n=nil)
      str_part = prepare_string(s)

      loop do
        slug = [str_part, n].compact.join('-')
        return slug if slug_unique?(slug)

        # First loop we do some optimistic searching.
        if n.nil?
          b = 512
          last_b = nil
          loop do
            slug = [str_part, b].join('-')
            if slug_unique?(slug) || b < 1
              last_b = b
              break if b < 1
            else
              n = last_b
              break
            end
            
            b /= 2
          end
        end
        n ||= 0
        n += 1
      end
    end

    # Use dashes.
    # http://www.mattcutts.com/blog/dashes-vs-underscores/
    def prepare_string(s)
      s.strip!

      # Blow away apostrophes
      s.gsub! /['`]/,""

      orig = s

      # @ --> at, and & --> and
      s.gsub! /\s*@\s*/, " at "
      s.gsub! /\s*&\s*/, " and "

      s = s.to_slug.transliterate.to_s
      s.strip!
      # Convert spaces to dashes.
      s.gsub!(/[^a-zA-Z0-9]+/i, '-')
      words = s.split('-').reject {|w| w.blank? }
      s = words.each { |word| word.sub!(/^[a-z]/) {|m| slug_config[:capitalize] ? m.tr('a-z', 'A-Z') : m} }.join('-')

      new_slug = s.blank? ? orig : s
      new_slug = new_slug[0..239]
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
wulffeld_slug-0.0.6 lib/wulffeld_slug/slug_include.rb