acts_as_permalink 0.6.0 → 1.0.0
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.
- 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: {}
|