i76-has_slug 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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