permalink 1.3.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/.travis.yml +8 -0
- data/README.md +20 -30
- data/Rakefile +9 -4
- data/lib/permalink.rb +32 -1
- data/lib/permalink/active_record.rb +29 -16
- data/lib/permalink/normalizations/contraction.rb +9 -0
- data/lib/permalink/normalizations/downcase.rb +9 -0
- data/lib/permalink/normalizations/leading_trailing_dashes.rb +9 -0
- data/lib/permalink/normalizations/multiple_dashes.rb +9 -0
- data/lib/permalink/normalizations/non_alphanumeric.rb +10 -0
- data/lib/permalink/normalizations/transliteration.rb +12 -0
- data/lib/permalink/version.rb +2 -2
- data/permalink.gemspec +6 -6
- data/test/permalink/active_record_test.rb +172 -0
- data/test/permalink/normalizations_test.rb +36 -0
- data/{spec/permalink/string_spec.rb → test/permalink/permalink_test.rb} +4 -5
- data/{spec → test}/support/post.rb +0 -0
- data/{spec → test}/support/schema.rb +0 -0
- data/{spec → test}/support/user.rb +0 -0
- data/{spec/spec_helper.rb → test/test_helper.rb} +4 -0
- metadata +31 -39
- data/.rspec +0 -1
- data/Gemfile.lock +0 -77
- data/lib/permalink/string_ext.rb +0 -12
- data/spec/permalink/active_record_spec.rb +0 -148
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f06ab000bf6cd401528119d1204c00ab69bef315
|
4
|
+
data.tar.gz: a5849ef5070c956a7e75c43107beebec5313a631
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 669627b51b923cc660c53f0022eeef03b516364beef51f4358366b1df99872a52518255d33699351cae1cd1acd79e120846469b894298b6c63a25e7f8fe49f02
|
7
|
+
data.tar.gz: e15ce00042b5d16d54e4ede403ccb27452f7a6f0e5892d935a38acfc71a2b03d86a42cd02ddf65877e39eb5a72f0f47a143e277974f7dac1ac53de7b1c1e7465
|
data/.gitignore
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
pkg
|
1
|
+
pkg
|
2
|
+
*.lock
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
# Permalink
|
2
2
|
|
3
|
-
|
3
|
+
[![Code Climate](https://codeclimate.com/github/fnando/permalink.png)](https://codeclimate.com/github/fnando/permalink)
|
4
|
+
[![Build Status](https://travis-ci.org/fnando/permalink.svg)](https://travis-ci.org/fnando/permalink)
|
5
|
+
[![Gem](https://img.shields.io/gem/v/permalink.svg)](https://rubygems.org/permalink)
|
6
|
+
[![Gem](https://img.shields.io/gem/dt/permalink.svg)](https://rubygems.org/permalink)
|
7
|
+
|
8
|
+
## Installation
|
4
9
|
|
5
10
|
gem install permalink
|
6
11
|
|
@@ -18,12 +23,11 @@ You can specify the permalink field:
|
|
18
23
|
|
19
24
|
```ruby
|
20
25
|
class page < ActiveRecord::Base
|
21
|
-
permalink :title, :
|
26
|
+
permalink :title, to: "title_permalink"
|
22
27
|
end
|
23
28
|
```
|
24
29
|
|
25
|
-
If you don't want to use `permalink`, you can call `
|
26
|
-
manage the permalink process by yourself.
|
30
|
+
If you don't want to use `permalink`, you can call `Permalink.generate("some text")` string method and manage the permalink process by yourself.
|
27
31
|
|
28
32
|
Permalinks are not unique by default. `permalink` overrides `to_param` as following:
|
29
33
|
|
@@ -37,7 +41,7 @@ You can define the `to_param` format:
|
|
37
41
|
|
38
42
|
```ruby
|
39
43
|
class Page < ActiveRecord::Base
|
40
|
-
permalink :title, :
|
44
|
+
permalink :title, to_param: %w(id permalink page)
|
41
45
|
end
|
42
46
|
```
|
43
47
|
|
@@ -47,7 +51,7 @@ If you want to generate unique permalink, use the `:unique` option:
|
|
47
51
|
|
48
52
|
```ruby
|
49
53
|
class Page < ActiveRecord::Base
|
50
|
-
permalink :title, :
|
54
|
+
permalink :title, unique: true, to_param: "permalink"
|
51
55
|
end
|
52
56
|
```
|
53
57
|
|
@@ -56,7 +60,7 @@ The permalink can be tied to a given scope. Let's say you want to have unique pe
|
|
56
60
|
```ruby
|
57
61
|
class Page < ActiveRecord::Base
|
58
62
|
belongs_to :user
|
59
|
-
permalink :title, :
|
63
|
+
permalink :title, unique: true, scope: "user_id"
|
60
64
|
end
|
61
65
|
|
62
66
|
user = User.first
|
@@ -71,36 +75,22 @@ another_page.permalink #=> hello
|
|
71
75
|
|
72
76
|
The permalink is generated using `ActiveSupport::Multibyte::Chars` class; this means that characters will properly replaced from `áéíó` to `aeio`, for instance.
|
73
77
|
|
74
|
-
The permalink is created when `before_validation` callback is evaluated. This plugin also tries
|
75
|
-
to generate a permalink when `before_save` callback is evaluated and the instance has no permalink set.
|
78
|
+
The permalink is created when `before_validation` callback is evaluated. This plugin also tries to generate a permalink when `before_save` callback is evaluated and the instance has no permalink set.
|
76
79
|
|
77
80
|
You can force the permalink generation by setting the `:force` option.
|
78
81
|
|
79
82
|
```ruby
|
80
83
|
class Page < ActiveRecord::Base
|
81
|
-
permalink :title, :
|
84
|
+
permalink :title, force: true
|
82
85
|
end
|
83
86
|
```
|
84
87
|
|
85
88
|
## License
|
86
89
|
|
87
|
-
Copyright (c) 2011 Nando Vieira, released under the MIT license
|
88
|
-
|
89
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
permit persons to whom the Software is furnished to do so, subject to
|
95
|
-
the following conditions:
|
96
|
-
|
97
|
-
The above copyright notice and this permission notice shall be
|
98
|
-
included in all copies or substantial portions of the Software.
|
99
|
-
|
100
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
101
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
102
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
103
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
104
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
105
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
106
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
90
|
+
Copyright (c) 2011-2015 Nando Vieira, released under the MIT license
|
91
|
+
|
92
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
93
|
+
|
94
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
95
|
+
|
96
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
CHANGED
@@ -1,5 +1,10 @@
|
|
1
|
-
require "bundler"
|
2
|
-
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rake/testtask"
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
Rake::TestTask.new(:test) do |t|
|
5
|
+
t.libs << "test"
|
6
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
7
|
+
t.warning = false
|
8
|
+
end
|
9
|
+
|
10
|
+
task default: :test
|
data/lib/permalink.rb
CHANGED
@@ -1,5 +1,36 @@
|
|
1
1
|
require "active_record"
|
2
|
-
require "permalink/string_ext"
|
3
2
|
require "permalink/active_record"
|
3
|
+
require "permalink/normalizations/contraction"
|
4
|
+
require "permalink/normalizations/downcase"
|
5
|
+
require "permalink/normalizations/leading_trailing_dashes"
|
6
|
+
require "permalink/normalizations/multiple_dashes"
|
7
|
+
require "permalink/normalizations/non_alphanumeric"
|
8
|
+
require "permalink/normalizations/transliteration"
|
9
|
+
|
10
|
+
module Permalink
|
11
|
+
DEFAULT_NORMALIZATIONS = [
|
12
|
+
Normalizations::Transliteration,
|
13
|
+
Normalizations::Downcase,
|
14
|
+
Normalizations::Contraction,
|
15
|
+
Normalizations::NonAlphanumeric,
|
16
|
+
Normalizations::MultipleDashes,
|
17
|
+
Normalizations::LeadingTrailingDashes
|
18
|
+
]
|
19
|
+
|
20
|
+
DEFAULT_OPTIONS = {
|
21
|
+
normalizations: DEFAULT_NORMALIZATIONS,
|
22
|
+
separator: "-"
|
23
|
+
}
|
24
|
+
|
25
|
+
def self.generate(input, options = DEFAULT_OPTIONS)
|
26
|
+
options = DEFAULT_OPTIONS.merge(options)
|
27
|
+
|
28
|
+
options[:normalizations].each do |normalization|
|
29
|
+
input = normalization.call(input, options)
|
30
|
+
end
|
31
|
+
|
32
|
+
input
|
33
|
+
end
|
34
|
+
end
|
4
35
|
|
5
36
|
ActiveRecord::Base.send(:include, Permalink::ActiveRecord)
|
@@ -3,22 +3,26 @@ module Permalink
|
|
3
3
|
def self.included(base)
|
4
4
|
base.extend(ClassMethods)
|
5
5
|
base.extend(Permalink::ActiveRecord::ClassMethods)
|
6
|
-
|
6
|
+
base.cattr_accessor :permalink_options
|
7
7
|
end
|
8
8
|
|
9
9
|
module ClassMethods
|
10
10
|
# permalink :title
|
11
|
-
# permalink :title, :
|
12
|
-
# permalink :title, :
|
13
|
-
# permalink :title, :
|
11
|
+
# permalink :title, to: :custom_permalink_field
|
12
|
+
# permalink :title, to: :permalink, to_param: [:id, :permalink]
|
13
|
+
# permalink :title, unique: true
|
14
|
+
# permalink :title, separator: "_"
|
15
|
+
# permalink :title, normalizations: array_of_normalizations
|
14
16
|
def permalink(from_column, options = {})
|
15
17
|
include InstanceMethods
|
16
18
|
|
17
|
-
options.reverse_merge
|
19
|
+
options = options.reverse_merge({
|
18
20
|
to_param: [:id, :permalink],
|
19
21
|
to: :permalink,
|
20
22
|
unique: false,
|
21
|
-
force: false
|
23
|
+
force: false,
|
24
|
+
separator: "-",
|
25
|
+
normalizations: Permalink::DEFAULT_NORMALIZATIONS
|
22
26
|
})
|
23
27
|
|
24
28
|
self.permalink_options = {
|
@@ -27,7 +31,9 @@ module Permalink
|
|
27
31
|
to_param: [options[:to_param]].flatten,
|
28
32
|
unique: options[:unique],
|
29
33
|
force: options[:force],
|
30
|
-
scope: options[:scope]
|
34
|
+
scope: options[:scope],
|
35
|
+
separator: options[:separator],
|
36
|
+
normalizations: options[:normalizations]
|
31
37
|
}
|
32
38
|
|
33
39
|
before_validation :create_permalink
|
@@ -37,11 +43,11 @@ module Permalink
|
|
37
43
|
|
38
44
|
module InstanceMethods
|
39
45
|
def to_param
|
40
|
-
to_param_option =
|
46
|
+
to_param_option = permalink_options[:to_param]
|
41
47
|
|
42
48
|
to_param_option.compact.map {|name|
|
43
49
|
respond_to?(name) ? public_send(name).to_s : name.to_s
|
44
|
-
}.reject(&:blank?).join(
|
50
|
+
}.reject(&:blank?).join(permalink_options[:separator])
|
45
51
|
end
|
46
52
|
|
47
53
|
private
|
@@ -50,11 +56,11 @@ module Permalink
|
|
50
56
|
unique_permalink = permalink
|
51
57
|
scope = build_scope_for_permalink
|
52
58
|
|
53
|
-
if
|
59
|
+
if permalink_options[:unique]
|
54
60
|
suffix = 2
|
55
61
|
|
56
62
|
while scope.where(to_permalink_name => unique_permalink).first
|
57
|
-
unique_permalink =
|
63
|
+
unique_permalink = [permalink, suffix].join(permalink_options[:separator])
|
58
64
|
suffix += 1
|
59
65
|
end
|
60
66
|
end
|
@@ -63,18 +69,18 @@ module Permalink
|
|
63
69
|
end
|
64
70
|
|
65
71
|
def build_scope_for_permalink
|
66
|
-
search_scope =
|
72
|
+
search_scope = permalink_options[:scope]
|
67
73
|
scope = self.class.unscoped
|
68
74
|
scope = scope.where(search_scope => public_send(search_scope)) if search_scope
|
69
75
|
scope
|
70
76
|
end
|
71
77
|
|
72
78
|
def from_permalink_name
|
73
|
-
|
79
|
+
permalink_options[:from_column_name]
|
74
80
|
end
|
75
81
|
|
76
82
|
def to_permalink_name
|
77
|
-
|
83
|
+
permalink_options[:to_column_name]
|
78
84
|
end
|
79
85
|
|
80
86
|
def from_permalink_value
|
@@ -87,15 +93,22 @@ module Permalink
|
|
87
93
|
|
88
94
|
def update_permalink?
|
89
95
|
changes[from_permalink_name] &&
|
90
|
-
(
|
96
|
+
(permalink_options[:force] || to_permalink_value.blank?)
|
91
97
|
end
|
92
98
|
|
93
99
|
def create_permalink
|
94
100
|
write_attribute(
|
95
101
|
to_permalink_name,
|
96
|
-
next_available_permalink(from_permalink_value.to_s
|
102
|
+
next_available_permalink(Permalink.generate(from_permalink_value.to_s, permalink_generator_options))
|
97
103
|
) if update_permalink?
|
98
104
|
end
|
105
|
+
|
106
|
+
def permalink_generator_options
|
107
|
+
{
|
108
|
+
separator: permalink_options[:separator],
|
109
|
+
normalizations: permalink_options[:normalizations]
|
110
|
+
}
|
111
|
+
end
|
99
112
|
end
|
100
113
|
end
|
101
114
|
end
|
data/lib/permalink/version.rb
CHANGED
data/permalink.gemspec
CHANGED
@@ -7,17 +7,17 @@ Gem::Specification.new do |s|
|
|
7
7
|
s.authors = ["Nando Vieira"]
|
8
8
|
s.email = ["fnando.vieira@gmail.com"]
|
9
9
|
s.homepage = "http://rubygems.org/gems/permalink"
|
10
|
-
s.summary = "Generate permalink attributes on ActiveRecord"
|
10
|
+
s.summary = "Generate permalink attributes on ActiveModel/ActiveRecord"
|
11
11
|
s.description = s.summary
|
12
|
+
s.license = "MIT"
|
12
13
|
|
13
14
|
s.files = `git ls-files`.split("\n")
|
14
15
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
15
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map{
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map {|f| File.basename(f) }
|
16
17
|
s.require_paths = ["lib"]
|
17
18
|
|
18
|
-
s.
|
19
|
-
s.add_development_dependency "sqlite3
|
20
|
-
s.add_development_dependency "
|
21
|
-
s.add_development_dependency "pry-meta"
|
19
|
+
s.add_dependency "activerecord"
|
20
|
+
s.add_development_dependency "sqlite3"
|
21
|
+
s.add_development_dependency "minitest-utils"
|
22
22
|
s.add_development_dependency "rake"
|
23
23
|
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class ActiveRecordTest < Minitest::Test
|
4
|
+
let(:model) { Post }
|
5
|
+
|
6
|
+
setup do
|
7
|
+
model.delete_all
|
8
|
+
model.permalink :title
|
9
|
+
end
|
10
|
+
|
11
|
+
test "responds to options" do
|
12
|
+
assert model.respond_to?(:permalink_options)
|
13
|
+
end
|
14
|
+
|
15
|
+
test "uses default options" do
|
16
|
+
model.permalink :title
|
17
|
+
record = model.create(title: "Some nice post")
|
18
|
+
assert_equal "some-nice-post", record.permalink
|
19
|
+
end
|
20
|
+
|
21
|
+
test "uses custom attribute" do
|
22
|
+
model.permalink :title, to: :slug
|
23
|
+
record = model.create(title: "Some nice post")
|
24
|
+
assert_equal "some-nice-post", record.slug
|
25
|
+
end
|
26
|
+
|
27
|
+
test "sets permalink before_save" do
|
28
|
+
record = model.new(title: "Some nice post")
|
29
|
+
assert_nil record.permalink
|
30
|
+
record.valid?
|
31
|
+
assert_equal "some-nice-post", record.permalink
|
32
|
+
end
|
33
|
+
|
34
|
+
test "creates unique permalinks" do
|
35
|
+
model.permalink :title, unique: true
|
36
|
+
|
37
|
+
record = model.create(title: "Some nice post")
|
38
|
+
assert_equal "some-nice-post", record.permalink
|
39
|
+
|
40
|
+
record = model.create(title: "Some nice post")
|
41
|
+
assert_equal "some-nice-post-2", record.permalink
|
42
|
+
|
43
|
+
record = model.create(title: "Some nice post")
|
44
|
+
assert_equal "some-nice-post-3", record.permalink
|
45
|
+
end
|
46
|
+
|
47
|
+
test "creates unique permalinks with custom separator" do
|
48
|
+
model.permalink :title, unique: true, separator: "_"
|
49
|
+
|
50
|
+
record = model.create(title: "Some nice post")
|
51
|
+
assert_equal "some_nice_post", record.permalink
|
52
|
+
|
53
|
+
record = model.create(title: "Some nice post")
|
54
|
+
assert_equal "some_nice_post_2", record.permalink
|
55
|
+
end
|
56
|
+
|
57
|
+
test "creates unique permalinks based on scope" do
|
58
|
+
model.permalink :title, unique: true, scope: :user_id
|
59
|
+
|
60
|
+
user = User.create!
|
61
|
+
another_user = User.create!
|
62
|
+
|
63
|
+
# Create posts for user
|
64
|
+
record = model.create(title: "Some nice post", user: user)
|
65
|
+
assert_equal "some-nice-post", record.permalink
|
66
|
+
|
67
|
+
record = model.create(title: "Some nice post", user: user)
|
68
|
+
assert_equal "some-nice-post-2", record.permalink
|
69
|
+
|
70
|
+
# Create posts for another user
|
71
|
+
record = model.create(title: "Some nice post", user: another_user)
|
72
|
+
assert_equal "some-nice-post", record.permalink
|
73
|
+
|
74
|
+
record = model.create(title: "Some nice post", user: another_user)
|
75
|
+
assert_equal "some-nice-post-2", record.permalink
|
76
|
+
end
|
77
|
+
|
78
|
+
test "returns param for unique permalink" do
|
79
|
+
model.permalink :title, to_param: :permalink, unique: true
|
80
|
+
|
81
|
+
record = model.create(title: "Ruby")
|
82
|
+
assert_equal "ruby", record.to_param
|
83
|
+
|
84
|
+
record = model.create(title: "Ruby")
|
85
|
+
assert_equal "ruby-2", record.to_param
|
86
|
+
end
|
87
|
+
|
88
|
+
test "overrides to_param with custom fields" do
|
89
|
+
model.permalink :title, to: :slug, to_param: [:slug, :id, "page"]
|
90
|
+
|
91
|
+
record = model.create(title: "Some nice post")
|
92
|
+
assert_equal "some-nice-post-#{record.id}-page", record.to_param
|
93
|
+
end
|
94
|
+
|
95
|
+
test "ignores blank attributes from to_param" do
|
96
|
+
model.permalink :title, to_param: [:id, " ", nil, "\t", :permalink]
|
97
|
+
|
98
|
+
record = model.create(title: "Some nice post")
|
99
|
+
assert_equal "#{record.id}-some-nice-post", record.to_param
|
100
|
+
end
|
101
|
+
|
102
|
+
test "sets permalink if permalink is blank" do
|
103
|
+
record = model.create(title: "Some nice post", permalink: " ")
|
104
|
+
assert_equal "some-nice-post", record.permalink
|
105
|
+
end
|
106
|
+
|
107
|
+
test "keeps defined permalink" do
|
108
|
+
record = model.create(title: "Some nice post", permalink: "awesome-post")
|
109
|
+
assert_equal "awesome-post", record.permalink
|
110
|
+
end
|
111
|
+
|
112
|
+
test "creates unique permalinks for number-ended titles" do
|
113
|
+
model.permalink :title, unique: true
|
114
|
+
|
115
|
+
record = model.create(title: "Rails 3")
|
116
|
+
assert_equal "rails-3", record.permalink
|
117
|
+
|
118
|
+
record = model.create(title: "Rails 3")
|
119
|
+
assert_equal "rails-3-2", record.permalink
|
120
|
+
end
|
121
|
+
|
122
|
+
test "forces permalink" do
|
123
|
+
model.permalink :title, force: true
|
124
|
+
|
125
|
+
record = model.create(title: "Some nice post")
|
126
|
+
record.update_attributes title: "Awesome post"
|
127
|
+
|
128
|
+
assert_equal "awesome-post", record.permalink
|
129
|
+
end
|
130
|
+
|
131
|
+
test "forces permalink and keep unique" do
|
132
|
+
model.permalink :title, force: true, unique: true
|
133
|
+
|
134
|
+
record = model.create(title: "Some nice post")
|
135
|
+
|
136
|
+
record.update_attributes title: "Awesome post"
|
137
|
+
assert_equal "awesome-post", record.permalink
|
138
|
+
|
139
|
+
record = model.create(title: "Awesome post")
|
140
|
+
assert_equal "awesome-post-2", record.permalink
|
141
|
+
end
|
142
|
+
|
143
|
+
test "keeps same permalink when another field changes" do
|
144
|
+
model.permalink :title, force: true, unique: true
|
145
|
+
|
146
|
+
record = model.create(title: "Some nice post")
|
147
|
+
record.update_attributes description: "some description"
|
148
|
+
|
149
|
+
assert_equal "some-nice-post", record.permalink
|
150
|
+
end
|
151
|
+
|
152
|
+
test "overrides to_param method" do
|
153
|
+
model.permalink :title
|
154
|
+
|
155
|
+
record = model.create(title: "Some nice post")
|
156
|
+
assert_equal "#{record.id}-some-nice-post", record.to_param
|
157
|
+
end
|
158
|
+
|
159
|
+
test "uses custom separator" do
|
160
|
+
model.permalink :title, separator: "_"
|
161
|
+
record = model.create(title: "Some nice post")
|
162
|
+
|
163
|
+
assert_equal "#{record.id}_some_nice_post", record.to_param
|
164
|
+
end
|
165
|
+
|
166
|
+
test "uses custom normalization" do
|
167
|
+
model.permalink :title, normalizations: [->(input, options) { input.to_s.reverse }]
|
168
|
+
record = model.create(title: "Some nice post")
|
169
|
+
|
170
|
+
assert_equal "Some nice post".reverse, record.permalink
|
171
|
+
end
|
172
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class NormalizationsTest < Minitest::Test
|
4
|
+
test "applies contraction replacement" do
|
5
|
+
assert_equal "its", Permalink::Normalizations::Contraction.call("it's")
|
6
|
+
assert_equal "aint", Permalink::Normalizations::Contraction.call("ain’t")
|
7
|
+
end
|
8
|
+
|
9
|
+
test "applies transliteration" do
|
10
|
+
assert_equal "aeiou", Permalink::Normalizations::Transliteration.call("áéíóú")
|
11
|
+
end
|
12
|
+
|
13
|
+
test "applies downcasing" do
|
14
|
+
assert_equal "test", Permalink::Normalizations::Downcase.call("TEST")
|
15
|
+
end
|
16
|
+
|
17
|
+
test "applies lead/trailing dashes replacement" do
|
18
|
+
assert_equal "test", Permalink::Normalizations::LeadingTrailingDashes.call("-test-")
|
19
|
+
end
|
20
|
+
|
21
|
+
test "applies multiple dashes replacement" do
|
22
|
+
assert_equal "nice-permalink", Permalink::Normalizations::MultipleDashes.call("nice----permalink")
|
23
|
+
end
|
24
|
+
|
25
|
+
test "applies multiple dashes replacement with custom separator" do
|
26
|
+
assert_equal "nice_permalink", Permalink::Normalizations::MultipleDashes.call("nice----permalink", separator: "_")
|
27
|
+
end
|
28
|
+
|
29
|
+
test "applies non-alphanumeric replacement" do
|
30
|
+
assert_equal "nice-permalink-", Permalink::Normalizations::NonAlphanumeric.call("nice-permalink!")
|
31
|
+
end
|
32
|
+
|
33
|
+
test "applies non-alphanumeric replacement with custom separator" do
|
34
|
+
assert_equal "nice_permalink_", Permalink::Normalizations::NonAlphanumeric.call("nice-permalink!", separator: "_")
|
35
|
+
end
|
36
|
+
end
|
@@ -1,7 +1,6 @@
|
|
1
|
-
|
2
|
-
require "spec_helper"
|
1
|
+
require "test_helper"
|
3
2
|
|
4
|
-
|
3
|
+
class PermalinkTest < Minitest::Test
|
5
4
|
{
|
6
5
|
'This IS a Tripped out title!!.!1 (well/ not really)' => 'this-is-a-tripped-out-title-1-well-not-really',
|
7
6
|
'////// meph1sto r0x ! \\\\\\' => 'meph1sto-r0x',
|
@@ -14,8 +13,8 @@ describe "String#to_permalink" do
|
|
14
13
|
"can't do it" => "cant-do-it",
|
15
14
|
"i'm a dog" => "im-a-dog"
|
16
15
|
}.each do |from, to|
|
17
|
-
|
18
|
-
|
16
|
+
test "creates permalink for #{from}" do
|
17
|
+
assert_equal to, Permalink.generate(from)
|
19
18
|
end
|
20
19
|
end
|
21
20
|
end
|
File without changes
|
File without changes
|
File without changes
|
@@ -1,9 +1,13 @@
|
|
1
1
|
require "bundler/setup"
|
2
2
|
require "permalink"
|
3
3
|
|
4
|
+
require "minitest/utils"
|
5
|
+
require "minitest/autorun"
|
6
|
+
|
4
7
|
ActiveRecord::Base
|
5
8
|
.establish_connection(adapter: "sqlite3", database: ":memory:")
|
6
9
|
|
7
10
|
load("support/schema.rb")
|
8
11
|
require "support/user"
|
9
12
|
require "support/post"
|
13
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: permalink
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nando Vieira
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-03-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -17,21 +17,7 @@ dependencies:
|
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
|
-
type: :
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: sqlite3-ruby
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :development
|
20
|
+
type: :runtime
|
35
21
|
prerelease: false
|
36
22
|
version_requirements: !ruby/object:Gem::Requirement
|
37
23
|
requirements:
|
@@ -39,7 +25,7 @@ dependencies:
|
|
39
25
|
- !ruby/object:Gem::Version
|
40
26
|
version: '0'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
28
|
+
name: sqlite3
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
44
30
|
requirements:
|
45
31
|
- - ">="
|
@@ -53,7 +39,7 @@ dependencies:
|
|
53
39
|
- !ruby/object:Gem::Version
|
54
40
|
version: '0'
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
42
|
+
name: minitest-utils
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
58
44
|
requirements:
|
59
45
|
- - ">="
|
@@ -80,7 +66,7 @@ dependencies:
|
|
80
66
|
- - ">="
|
81
67
|
- !ruby/object:Gem::Version
|
82
68
|
version: '0'
|
83
|
-
description: Generate permalink attributes on ActiveRecord
|
69
|
+
description: Generate permalink attributes on ActiveModel/ActiveRecord
|
84
70
|
email:
|
85
71
|
- fnando.vieira@gmail.com
|
86
72
|
executables: []
|
@@ -88,24 +74,30 @@ extensions: []
|
|
88
74
|
extra_rdoc_files: []
|
89
75
|
files:
|
90
76
|
- ".gitignore"
|
91
|
-
- ".
|
77
|
+
- ".travis.yml"
|
92
78
|
- Gemfile
|
93
|
-
- Gemfile.lock
|
94
79
|
- README.md
|
95
80
|
- Rakefile
|
96
81
|
- lib/permalink.rb
|
97
82
|
- lib/permalink/active_record.rb
|
98
|
-
- lib/permalink/
|
83
|
+
- lib/permalink/normalizations/contraction.rb
|
84
|
+
- lib/permalink/normalizations/downcase.rb
|
85
|
+
- lib/permalink/normalizations/leading_trailing_dashes.rb
|
86
|
+
- lib/permalink/normalizations/multiple_dashes.rb
|
87
|
+
- lib/permalink/normalizations/non_alphanumeric.rb
|
88
|
+
- lib/permalink/normalizations/transliteration.rb
|
99
89
|
- lib/permalink/version.rb
|
100
90
|
- permalink.gemspec
|
101
|
-
-
|
102
|
-
-
|
103
|
-
-
|
104
|
-
-
|
105
|
-
-
|
106
|
-
-
|
91
|
+
- test/permalink/active_record_test.rb
|
92
|
+
- test/permalink/normalizations_test.rb
|
93
|
+
- test/permalink/permalink_test.rb
|
94
|
+
- test/support/post.rb
|
95
|
+
- test/support/schema.rb
|
96
|
+
- test/support/user.rb
|
97
|
+
- test/test_helper.rb
|
107
98
|
homepage: http://rubygems.org/gems/permalink
|
108
|
-
licenses:
|
99
|
+
licenses:
|
100
|
+
- MIT
|
109
101
|
metadata: {}
|
110
102
|
post_install_message:
|
111
103
|
rdoc_options: []
|
@@ -123,15 +115,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
115
|
version: '0'
|
124
116
|
requirements: []
|
125
117
|
rubyforge_project:
|
126
|
-
rubygems_version: 2.
|
118
|
+
rubygems_version: 2.5.1
|
127
119
|
signing_key:
|
128
120
|
specification_version: 4
|
129
|
-
summary: Generate permalink attributes on ActiveRecord
|
121
|
+
summary: Generate permalink attributes on ActiveModel/ActiveRecord
|
130
122
|
test_files:
|
131
|
-
-
|
132
|
-
-
|
133
|
-
-
|
134
|
-
-
|
135
|
-
-
|
136
|
-
-
|
137
|
-
|
123
|
+
- test/permalink/active_record_test.rb
|
124
|
+
- test/permalink/normalizations_test.rb
|
125
|
+
- test/permalink/permalink_test.rb
|
126
|
+
- test/support/post.rb
|
127
|
+
- test/support/schema.rb
|
128
|
+
- test/support/user.rb
|
129
|
+
- test/test_helper.rb
|
data/.rspec
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
--colour
|
data/Gemfile.lock
DELETED
@@ -1,77 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
permalink (1.3.0)
|
5
|
-
|
6
|
-
GEM
|
7
|
-
remote: https://rubygems.org/
|
8
|
-
specs:
|
9
|
-
activemodel (4.1.1)
|
10
|
-
activesupport (= 4.1.1)
|
11
|
-
builder (~> 3.1)
|
12
|
-
activerecord (4.1.1)
|
13
|
-
activemodel (= 4.1.1)
|
14
|
-
activesupport (= 4.1.1)
|
15
|
-
arel (~> 5.0.0)
|
16
|
-
activesupport (4.1.1)
|
17
|
-
i18n (~> 0.6, >= 0.6.9)
|
18
|
-
json (~> 1.7, >= 1.7.7)
|
19
|
-
minitest (~> 5.1)
|
20
|
-
thread_safe (~> 0.1)
|
21
|
-
tzinfo (~> 1.1)
|
22
|
-
arel (5.0.1.20140414130214)
|
23
|
-
awesome_print (1.2.0)
|
24
|
-
builder (3.2.2)
|
25
|
-
byebug (2.7.0)
|
26
|
-
columnize (~> 0.3)
|
27
|
-
debugger-linecache (~> 1.2)
|
28
|
-
coderay (1.1.0)
|
29
|
-
columnize (0.8.9)
|
30
|
-
debugger-linecache (1.2.0)
|
31
|
-
diff-lcs (1.2.5)
|
32
|
-
i18n (0.6.9)
|
33
|
-
json (1.8.1)
|
34
|
-
method_source (0.8.2)
|
35
|
-
minitest (5.3.4)
|
36
|
-
pry (0.9.12.6)
|
37
|
-
coderay (~> 1.0)
|
38
|
-
method_source (~> 0.8)
|
39
|
-
slop (~> 3.4)
|
40
|
-
pry-byebug (1.3.2)
|
41
|
-
byebug (~> 2.7)
|
42
|
-
pry (~> 0.9.12)
|
43
|
-
pry-meta (0.0.8)
|
44
|
-
awesome_print
|
45
|
-
pry
|
46
|
-
pry-byebug
|
47
|
-
pry-remote
|
48
|
-
pry-remote (0.1.8)
|
49
|
-
pry (~> 0.9)
|
50
|
-
slop (~> 3.0)
|
51
|
-
rake (10.3.2)
|
52
|
-
rspec (2.14.1)
|
53
|
-
rspec-core (~> 2.14.0)
|
54
|
-
rspec-expectations (~> 2.14.0)
|
55
|
-
rspec-mocks (~> 2.14.0)
|
56
|
-
rspec-core (2.14.8)
|
57
|
-
rspec-expectations (2.14.5)
|
58
|
-
diff-lcs (>= 1.1.3, < 2.0)
|
59
|
-
rspec-mocks (2.14.6)
|
60
|
-
slop (3.5.0)
|
61
|
-
sqlite3 (1.3.9)
|
62
|
-
sqlite3-ruby (1.3.3)
|
63
|
-
sqlite3 (>= 1.3.3)
|
64
|
-
thread_safe (0.3.3)
|
65
|
-
tzinfo (1.1.0)
|
66
|
-
thread_safe (~> 0.1)
|
67
|
-
|
68
|
-
PLATFORMS
|
69
|
-
ruby
|
70
|
-
|
71
|
-
DEPENDENCIES
|
72
|
-
activerecord
|
73
|
-
permalink!
|
74
|
-
pry-meta
|
75
|
-
rake
|
76
|
-
rspec
|
77
|
-
sqlite3-ruby
|
data/lib/permalink/string_ext.rb
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
class String
|
2
|
-
def to_permalink
|
3
|
-
str = ActiveSupport::Multibyte::Chars.new(self)
|
4
|
-
str = str.normalize(:kd).gsub(/[^\x00-\x7F]/,'').to_s
|
5
|
-
str.gsub!(/'/, "")
|
6
|
-
str.gsub!(/[^-\w\d]+/sim, "-")
|
7
|
-
str.gsub!(/-+/sm, "-")
|
8
|
-
str.gsub!(/^-?(.*?)-?$/, '\1')
|
9
|
-
str.downcase!
|
10
|
-
str
|
11
|
-
end
|
12
|
-
end
|
@@ -1,148 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Permalink::ActiveRecord do
|
4
|
-
let(:model) { Post }
|
5
|
-
|
6
|
-
before do
|
7
|
-
model.delete_all
|
8
|
-
model.permalink :title
|
9
|
-
end
|
10
|
-
|
11
|
-
it "responds to options" do
|
12
|
-
expect(model).to respond_to(:permalink_options)
|
13
|
-
end
|
14
|
-
|
15
|
-
it "uses default options" do
|
16
|
-
model.permalink :title
|
17
|
-
record = model.create(:title => "Some nice post")
|
18
|
-
expect(record.permalink).to eq("some-nice-post")
|
19
|
-
end
|
20
|
-
|
21
|
-
it "uses custom attribute" do
|
22
|
-
model.permalink :title, :to => :slug
|
23
|
-
record = model.create(:title => "Some nice post")
|
24
|
-
expect(record.slug).to eq("some-nice-post")
|
25
|
-
end
|
26
|
-
|
27
|
-
it "sets permalink before_save" do
|
28
|
-
record = model.new(:title => "Some nice post")
|
29
|
-
expect(record.permalink).to be_nil
|
30
|
-
record.valid?
|
31
|
-
expect(record.permalink).to eq("some-nice-post")
|
32
|
-
end
|
33
|
-
|
34
|
-
it "creates unique permalinks" do
|
35
|
-
model.permalink :title, :unique => true
|
36
|
-
|
37
|
-
record = model.create(:title => "Some nice post")
|
38
|
-
expect(record.permalink).to eq("some-nice-post")
|
39
|
-
|
40
|
-
record = model.create(:title => "Some nice post")
|
41
|
-
expect(record.permalink).to eq("some-nice-post-2")
|
42
|
-
|
43
|
-
record = model.create(:title => "Some nice post")
|
44
|
-
expect(record.permalink).to eq("some-nice-post-3")
|
45
|
-
end
|
46
|
-
|
47
|
-
it "creates unique permalinks based on scope" do
|
48
|
-
model.permalink :title, :unique => true, :scope => :user_id
|
49
|
-
|
50
|
-
user = User.create!
|
51
|
-
another_user = User.create!
|
52
|
-
|
53
|
-
# Create posts for user
|
54
|
-
record = model.create(:title => "Some nice post", :user => user)
|
55
|
-
expect(record.permalink).to eq("some-nice-post")
|
56
|
-
|
57
|
-
record = model.create(:title => "Some nice post", :user => user)
|
58
|
-
expect(record.permalink).to eq("some-nice-post-2")
|
59
|
-
|
60
|
-
# Create posts for another user
|
61
|
-
record = model.create(:title => "Some nice post", :user => another_user)
|
62
|
-
expect(record.permalink).to eq("some-nice-post")
|
63
|
-
|
64
|
-
record = model.create(:title => "Some nice post", :user => another_user)
|
65
|
-
expect(record.permalink).to eq("some-nice-post-2")
|
66
|
-
end
|
67
|
-
|
68
|
-
it "returns param for unique permalink" do
|
69
|
-
model.permalink :title, :to_param => :permalink, :unique => true
|
70
|
-
|
71
|
-
record = model.create(:title => "Ruby")
|
72
|
-
expect(record.to_param).to eq("ruby")
|
73
|
-
|
74
|
-
record = model.create(:title => "Ruby")
|
75
|
-
expect(record.to_param).to eq("ruby-2")
|
76
|
-
end
|
77
|
-
|
78
|
-
it "overrides to_param with custom fields" do
|
79
|
-
model.permalink :title, :to => :slug, :to_param => [:slug, :id, "page"]
|
80
|
-
|
81
|
-
record = model.create(:title => "Some nice post")
|
82
|
-
expect(record.to_param).to eq("some-nice-post-#{record.id}-page")
|
83
|
-
end
|
84
|
-
|
85
|
-
it "ignores blank attributes from to_param" do
|
86
|
-
model.permalink :title, :to_param => [:id, " ", nil, "\t", :permalink]
|
87
|
-
|
88
|
-
record = model.create(:title => "Some nice post")
|
89
|
-
expect(record.to_param).to eq("#{record.id}-some-nice-post")
|
90
|
-
end
|
91
|
-
|
92
|
-
it "sets permalink if permalink is blank" do
|
93
|
-
record = model.create(:title => "Some nice post", :permalink => " ")
|
94
|
-
expect(record.permalink).to eq("some-nice-post")
|
95
|
-
end
|
96
|
-
|
97
|
-
it "keeps defined permalink" do
|
98
|
-
record = model.create(:title => "Some nice post", :permalink => "awesome-post")
|
99
|
-
expect(record.permalink).to eq("awesome-post")
|
100
|
-
end
|
101
|
-
|
102
|
-
it "creates unique permalinks for number-ended titles" do
|
103
|
-
model.permalink :title, :unique => true
|
104
|
-
|
105
|
-
record = model.create(:title => "Rails 3")
|
106
|
-
expect(record.permalink).to eq("rails-3")
|
107
|
-
|
108
|
-
record = model.create(:title => "Rails 3")
|
109
|
-
expect(record.permalink).to eq("rails-3-2")
|
110
|
-
end
|
111
|
-
|
112
|
-
it "forces permalink" do
|
113
|
-
model.permalink :title, :force => true
|
114
|
-
|
115
|
-
record = model.create(:title => "Some nice post")
|
116
|
-
record.update_attributes :title => "Awesome post"
|
117
|
-
|
118
|
-
expect(record.permalink).to eq("awesome-post")
|
119
|
-
end
|
120
|
-
|
121
|
-
it "forces permalink and keep unique" do
|
122
|
-
model.permalink :title, :force => true, :unique => true
|
123
|
-
|
124
|
-
record = model.create(:title => "Some nice post")
|
125
|
-
|
126
|
-
record.update_attributes :title => "Awesome post"
|
127
|
-
expect(record.permalink).to eq("awesome-post")
|
128
|
-
|
129
|
-
record = model.create(:title => "Awesome post")
|
130
|
-
expect(record.permalink).to eq("awesome-post-2")
|
131
|
-
end
|
132
|
-
|
133
|
-
it "keeps same permalink when another field changes" do
|
134
|
-
model.permalink :title, :force => true, :unique => true
|
135
|
-
|
136
|
-
record = model.create(:title => "Some nice post")
|
137
|
-
record.update_attributes :description => "some description"
|
138
|
-
|
139
|
-
expect(record.permalink).to eq("some-nice-post")
|
140
|
-
end
|
141
|
-
|
142
|
-
it "overrides to_param method" do
|
143
|
-
model.permalink :title
|
144
|
-
|
145
|
-
record = model.create(:title => "Some nice post")
|
146
|
-
expect(record.to_param).to eql("#{record.id}-some-nice-post")
|
147
|
-
end
|
148
|
-
end
|