acts_as_permalink 0.6.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/{README.markdown → README.md} +8 -0
- data/lib/acts_as_permalink.rb +30 -68
- data/lib/acts_as_permalink/version.rb +1 -1
- data/lib/config.rb +18 -0
- data/lib/string.rb +14 -0
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a688f2777a3102e366b6caa9c9b4a820dcbe1dbd
|
4
|
+
data.tar.gz: aa13d167b062e6aa5d68c81e717fe2be53dc7b33
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5dfcbb6895a593a348402b31cfae60bc08df806b55285110c9b239434ea16aac07297ce20c5592365a7ad009544c1e5c6ac53c7e1e29026160cebca9943ad385
|
7
|
+
data.tar.gz: 214c634039408be7bbb7b1751a7f894f1358687f69f32c96593526461db0e1b8feae1bd624110ad93d358ad8e8e22b74a86fadfb64db14f63365db843de86585
|
@@ -21,6 +21,12 @@ Or stand alone:
|
|
21
21
|
$ gem install acts_as_permalink
|
22
22
|
```
|
23
23
|
|
24
|
+
## Requirements
|
25
|
+
|
26
|
+
* Ruby 2.0 or higher
|
27
|
+
* Rails 4.0 or higher
|
28
|
+
|
29
|
+
|
24
30
|
## Usage
|
25
31
|
|
26
32
|
This gem works with ActiveRecord, and by convention looks for a `title` method and a `permalink` string field on the model:
|
@@ -68,6 +74,8 @@ $ bundle exec rspec
|
|
68
74
|
|
69
75
|
## Changelog
|
70
76
|
|
77
|
+
* 1.0.0 -- Internal refactor. Require Rails 4.0 or above and Ruby 2.0 or above. Full release, only took 6 years!
|
78
|
+
|
71
79
|
* 0.6.0 -- Switch default replacement character to a dash, but allow the `underscore: true` property to go back to the old format
|
72
80
|
|
73
81
|
* 0.5.0 -- Fix bugs in `max_length` property which would sometimes allow the permalink to be longer than the value
|
data/lib/acts_as_permalink.rb
CHANGED
@@ -1,69 +1,47 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
module Permalink #:nodoc:
|
1
|
+
require "string"
|
2
|
+
require "config"
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
module Acts
|
5
|
+
module Permalink
|
6
|
+
extend ActiveSupport::Concern
|
8
7
|
|
9
|
-
|
8
|
+
class_methods do
|
10
9
|
def acts_as_permalink(options={})
|
11
|
-
|
12
|
-
self.
|
13
|
-
|
14
|
-
# Read and scrub the option for the column or function which will generate the permalink
|
15
|
-
self.base_class.instance_variable_set('@permalink_source', (options[:from].try(:to_sym) || :title))
|
16
|
-
|
17
|
-
# Set the underscore character
|
18
|
-
self.base_class.instance_variable_set('@permalink_underscore', options[:underscore])
|
10
|
+
cattr_accessor :acts_as_permalink_config
|
11
|
+
self.acts_as_permalink_config = Acts::Permalink::Config.new(options)
|
19
12
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
if Rails.version >= "3"
|
26
|
-
before_validation :update_permalink, on: :create
|
27
|
-
else
|
28
|
-
before_validation_on_create :update_permalink
|
29
|
-
end
|
13
|
+
before_validation :update_permalink, on: :create
|
14
|
+
validates_uniqueness_of self.acts_as_permalink_config.to
|
15
|
+
attr_readonly self.acts_as_permalink_config.to
|
16
|
+
end
|
17
|
+
end
|
30
18
|
|
31
|
-
|
32
|
-
|
19
|
+
included do
|
20
|
+
def to_param
|
21
|
+
self.public_send(self.class.base_class.acts_as_permalink_config.to)
|
22
|
+
end
|
33
23
|
|
34
|
-
|
35
|
-
|
24
|
+
def update_permalink
|
25
|
+
self.public_send("#{ self.class.base_class.acts_as_permalink_config.to }=", build_permalink)
|
26
|
+
true
|
36
27
|
end
|
37
28
|
|
38
|
-
|
39
|
-
|
40
|
-
column_name = obj.class.base_class.instance_variable_get('@permalink_column_name')
|
41
|
-
text = obj.send(obj.class.base_class.instance_variable_get('@permalink_source'))
|
42
|
-
max_length = obj.class.base_class.instance_variable_get('@permalink_length')
|
43
|
-
separator = obj.class.base_class.instance_variable_get('@permalink_underscore') ? "_" : "-"
|
29
|
+
def build_permalink
|
30
|
+
config = self.class.base_class.acts_as_permalink_config
|
44
31
|
|
45
|
-
|
46
|
-
if text.blank?
|
47
|
-
|
48
|
-
|
49
|
-
# If it is not blank, scrub
|
50
|
-
else
|
51
|
-
text = text.downcase.strip # make the string lowercase and scrub white space on either side
|
52
|
-
text = text.gsub(/[^a-z0-9\w]/, separator) # make any character that is not nupermic or alphabetic into a special character
|
53
|
-
text = text.squeeze(separator) # removes any consecutive duplicates of the special character
|
54
|
-
text = text[0...max_length] # trim to length
|
55
|
-
text = text.sub(Regexp.new("^#{ separator }+"), "") # remove leading special characters
|
56
|
-
text = text.sub(Regexp.new("#{ separator }+$"), "") # remove trailing special characters
|
57
|
-
end
|
32
|
+
text = self.public_send(config.from)
|
33
|
+
text = [self.class.base_class.to_s, rand(10000)].join(config.separator) if text.blank?
|
34
|
+
text = text.to_permalink(separator: config.separator, max_length: config.max_length)
|
58
35
|
|
59
36
|
# Attempt to find the object by the permalink, and if so there is a collision and we need to de-collision it
|
60
|
-
if
|
37
|
+
if self.class.base_class.where(config.to => text).first
|
61
38
|
candidate_text = nil
|
62
39
|
|
40
|
+
# This will fail if you have a million records with the same name
|
63
41
|
(1..999999).each do |num|
|
64
|
-
suffix = "#{ separator }#{ num }"
|
65
|
-
candidate_text = [text[0...(max_length - suffix.length)], suffix].join("")
|
66
|
-
break unless
|
42
|
+
suffix = "#{ config.separator }#{ num }"
|
43
|
+
candidate_text = [text[0...(config.max_length - suffix.length)], suffix].join("")
|
44
|
+
break unless self.class.base_class.where(config.to => candidate_text).first
|
67
45
|
end
|
68
46
|
|
69
47
|
text = candidate_text
|
@@ -73,22 +51,6 @@ module Acts #:nodoc:
|
|
73
51
|
end
|
74
52
|
end
|
75
53
|
|
76
|
-
module SingletonMethods
|
77
|
-
end
|
78
|
-
|
79
|
-
module InstanceMethods
|
80
|
-
|
81
|
-
# Override this method so that find searches by permalink and not by id
|
82
|
-
def to_param
|
83
|
-
self.send(self.class.base_class.instance_variable_get('@permalink_column_name'))
|
84
|
-
end
|
85
|
-
|
86
|
-
# Generate the permalink and assign it directly via callback
|
87
|
-
def update_permalink
|
88
|
-
self.send("#{ self.class.base_class.instance_variable_get('@permalink_column_name') }=", self.class.base_class.generate_permalink_for(self))
|
89
|
-
true
|
90
|
-
end
|
91
|
-
end
|
92
54
|
end
|
93
55
|
end
|
94
56
|
|
data/lib/config.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Acts
|
2
|
+
module Permalink
|
3
|
+
class Config
|
4
|
+
attr_reader :to, :from, :separator, :max_length
|
5
|
+
|
6
|
+
def initialize(options={})
|
7
|
+
@config = options.with_indifferent_access
|
8
|
+
|
9
|
+
@to = @config[:to].try(:to_sym) || :permalink
|
10
|
+
@from = @config[:from].try(:to_sym) || :title
|
11
|
+
@separator = @config[:underscore] ? "_" : "-"
|
12
|
+
|
13
|
+
@max_length = @config[:max_length].to_i rescue 0
|
14
|
+
@max_length = 60 unless @max_length > 0
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/string.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
class String
|
2
|
+
def to_permalink(max_length: nil, separator: "-")
|
3
|
+
text = self.dup
|
4
|
+
|
5
|
+
text = text.downcase.strip # make the string lowercase and scrub white space on either side
|
6
|
+
text = text.gsub(/[^a-z0-9]/, separator) # make any character that is not nupermic or alphabetic into a special character
|
7
|
+
text = text.squeeze(separator) # removes any consecutive duplicates of the special character
|
8
|
+
text = text.sub(Regexp.new("^#{ separator }+"), "") # remove leading special characters
|
9
|
+
text = text.sub(Regexp.new("#{ separator }+$"), "") # remove trailing special characters
|
10
|
+
text = text[0...max_length] if max_length # trim to length
|
11
|
+
|
12
|
+
text
|
13
|
+
end
|
14
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_permalink
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin McPhillips
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-10-
|
11
|
+
date: 2015-10-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '4.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '4.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rspec
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -75,10 +75,12 @@ extensions: []
|
|
75
75
|
extra_rdoc_files: []
|
76
76
|
files:
|
77
77
|
- MIT-LICENSE
|
78
|
-
- README.
|
78
|
+
- README.md
|
79
79
|
- Rakefile
|
80
80
|
- lib/acts_as_permalink.rb
|
81
81
|
- lib/acts_as_permalink/version.rb
|
82
|
+
- lib/config.rb
|
83
|
+
- lib/string.rb
|
82
84
|
homepage: http://github.com/kmcphillips/acts_as_permalink
|
83
85
|
licenses: []
|
84
86
|
metadata: {}
|