i76-has_slug 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -14,10 +14,10 @@ module HasSlug
14
14
  module ClassMethods
15
15
 
16
16
  # Valid options for the has_slug method
17
- VALID_HAS_SLUG_OPTIONS = [:scope, :slug_column].freeze
17
+ VALID_HAS_SLUG_OPTIONS = [:scope, :slug_column, :preserve].freeze
18
18
 
19
19
  # Default options for the has_slug method
20
- DEFAULT_HAS_SLUG_OPTIONS = { :scope => nil, :slug_column => 'slug' }.freeze
20
+ DEFAULT_HAS_SLUG_OPTIONS = { :scope => nil, :slug_column => 'slug', :preserve => '' }.freeze
21
21
 
22
22
  # Set up an ActiveRecord model to use a slug.
23
23
  #
@@ -15,7 +15,7 @@ module HasSlug::NotSluggableInstanceMethods
15
15
 
16
16
  def slug
17
17
  id = self.send(self.class.primary_key)
18
- slug = self.sluggable.to_slug
18
+ slug = self.sluggable.to_slug(:preserve => has_slug_options[:preserve])
19
19
 
20
20
  "#{id}-#{slug}"
21
21
  end
@@ -1,37 +1,37 @@
1
1
  class String
2
2
  # convert strings to slugs that are lowercase an only contain alphanumeric
3
3
  # characters, dashes and sometimes dots
4
- def to_slug
4
+ def to_slug(options = {})
5
5
  slug = self
6
6
 
7
+ preserve = options.delete(:preserve).to_s.split
8
+ acceptable = preserve + ["-", "_"]
9
+
7
10
  # Transliterate
8
11
  slug = Unicode.normalize_KD(slug).gsub(/[^\x00-\x7F]/n,'')
9
12
 
10
13
  # Convert to lowercase
11
14
  slug.downcase!
12
15
 
13
- # Change seperators (like spaces) to dashes
14
- slug.gsub!(/[+_',\/|;; ]/, '-')
16
+ # Change all characters that are not to be preserved to dashes
17
+ slug.gsub!(Regexp.new("[^a-z0-9#{Regexp.escape(preserve.join)}]"), '-')
15
18
 
16
- # Dot's should be saved only when they have letter or number on both sides
17
- # (this preserves file extensions)
18
- slug.gsub!(/[^\w\d]\.+/, '-')
19
- slug.gsub!(/\.+[^\w\d]/, '-')
20
-
21
- # Replace everything that is not letter, number, dash or dot with a dash
22
- slug.gsub!(/[^\w\d.-]/, '-')
23
-
24
- # Strip dots from begining and end
25
- slug.gsub!(/^\.+/, '')
26
- slug.gsub!(/\.+$/, '')
19
+ # Preservable chars should be saved only when they have letter or number on
20
+ # both sides (this preserves file extensions in case of :preserve => '.')
21
+ preserve.each do |char|
22
+ slug.gsub!(Regexp.new("([^a-z0-9])#{Regexp.escape(char)}+"), '\\1-')
23
+ slug.gsub!(Regexp.new("#{Regexp.escape(char)}+([^a-z0-9])"), '-\\1')
24
+ slug.gsub!(Regexp.new("^#{Regexp.escape(char)}+"), '')
25
+ slug.gsub!(Regexp.new("#{Regexp.escape(char)}+$"), '')
26
+ end
27
27
 
28
28
  # Strip dashes from begining and end
29
29
  slug.gsub!(/^-(.+)+/, '\1')
30
30
  slug.gsub!(/(.+)-+$/, '\1')
31
31
 
32
- # Change multiple succesive dashes to single dashe.
32
+ # Change multiple succesive dashes to single dash.
33
33
  slug.gsub!(/-+/, '-')
34
34
 
35
35
  slug
36
36
  end
37
- end
37
+ end
@@ -40,12 +40,12 @@ module HasSlug::SluggableInstanceMethods
40
40
  private
41
41
 
42
42
  def set_slug
43
- self.slug = self.sluggable.to_slug
43
+ self.slug = self.sluggable.to_slug(:preserve => has_slug_options[:preserve])
44
44
 
45
45
  while existing = self.class.find_one_with_same_slug(self)
46
46
  index ||= 2
47
47
 
48
- self.slug = "#{self.sluggable.to_slug}_#{index}"
48
+ self.slug = "#{self.sluggable.to_slug(:preserve => has_slug_options[:preserve])}_#{index}"
49
49
 
50
50
  index += 1
51
51
  end
@@ -1,6 +1,7 @@
1
1
  class Restaurant < ActiveRecord::Base
2
2
  has_slug :name,
3
- :scope => :city
3
+ :scope => :city,
4
+ :preserve => '.'
4
5
 
5
6
  belongs_to :city
6
7
 
@@ -9,13 +9,15 @@ HAS_SLUG_ROOT = File.dirname(__FILE__) + "/.."
9
9
  $:.unshift("#{HAS_SLUG_ROOT}/lib")
10
10
 
11
11
  ActiveRecord::Base.establish_connection(:adapter => "sqlite3",
12
- :dbfile => ":memory:")
12
+ :dbfile => "#{HAS_SLUG_ROOT}/test/test.db")
13
13
  require 'has_slug'
14
14
  require "#{HAS_SLUG_ROOT}/test/schema.rb"
15
15
 
16
16
  Dir["#{HAS_SLUG_ROOT}/test/models/*"].each { |f| require f }
17
17
  Dir["#{HAS_SLUG_ROOT}/test/factories/*"].each { |f| require f }
18
18
 
19
+ [City, Restaurant, Kitchen].each { |c| c.reset_column_information }
20
+
19
21
  class Test::Unit::TestCase
20
22
  def reset_database!
21
23
  City.destroy_all
@@ -80,6 +80,16 @@ class HasSlugTest < Test::Unit::TestCase
80
80
  end
81
81
  end
82
82
 
83
+ context 'and characters to preserve' do
84
+ setup do
85
+ @restaurant_2_0 = Factory(:restaurant, :name => 'Restaurant 2.0')
86
+ end
87
+
88
+ should 'preserve the .' do
89
+ assert_equal 'restaurant-2.0', @restaurant_2_0.slug
90
+ end
91
+ end
92
+
83
93
  context 'and a scope' do
84
94
  setup do
85
95
  @da_marco = Factory(:restaurant, :name => 'Da Marco',
@@ -95,7 +105,8 @@ class HasSlugTest < Test::Unit::TestCase
95
105
 
96
106
  should 'not create duplicate slugs' do
97
107
  @da_marco_2 = Factory(:restaurant, :name => 'Da Marco',
98
- :city => @new_york)
108
+ :city => @new_york)
109
+
99
110
  assert_not_equal @da_marco_2.slug, @da_marco.slug
100
111
 
101
112
  @da_marco_2.update_attributes(:city => @san_fransisco)
@@ -20,12 +20,18 @@ class SlugTest < Test::Unit::TestCase
20
20
  assert_equal 'internationalization', "Iñtërnâtiônàlizâtiôn".to_slug
21
21
  end
22
22
 
23
- should 'preserve dots that have numbers or letters on both sides' do
24
- assert_equal 'filename.1', "filename.1".to_slug
25
- assert_equal 'filename.txt', "filename.txt".to_slug
23
+ should 'preserve specified characters if they have numbers or letters on both sides' do
24
+ assert_equal 'filename-1', "filename.1".to_slug
25
+ assert_equal 'filename.1', "filename.1".to_slug(:preserve => '.')
26
+
27
+ assert_equal 'filename-txt', "filename.txt".to_slug
28
+ assert_equal 'filename.txt', "filename.txt".to_slug(:preserve => '.')
26
29
 
27
30
  assert_equal 'a-sentence', "A sentence.".to_slug
31
+ assert_equal 'a-sentence', "A sentence.".to_slug(:preserve => '.')
32
+
28
33
  assert_equal 'a-sentence-a-new-sentence', "A sentence. A new sentence.".to_slug
34
+ assert_equal 'a-sentence-a-new-sentence', "A sentence. A new sentence.".to_slug(:preserve => '.')
29
35
  end
30
36
 
31
37
  should 'not have trailing dashes' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: i76-has_slug
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom-Eric Gerritsen
@@ -14,6 +14,7 @@ default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: unicode
17
+ type: :runtime
17
18
  version_requirement:
18
19
  version_requirements: !ruby/object:Gem::Requirement
19
20
  requirements:
@@ -43,6 +44,7 @@ files:
43
44
  - tasks/has_slug_tasks.rake
44
45
  has_rdoc: true
45
46
  homepage: http://www.i76.nl/
47
+ licenses:
46
48
  post_install_message:
47
49
  rdoc_options:
48
50
  - --main
@@ -64,7 +66,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
64
66
  requirements: []
65
67
 
66
68
  rubyforge_project:
67
- rubygems_version: 1.2.0
69
+ rubygems_version: 1.3.5
68
70
  signing_key:
69
71
  specification_version: 2
70
72
  summary: A slugging plugin for Ruby on Rails