norman-friendly_id 2.0.3 → 2.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +5 -0
- data/Manifest.txt +5 -0
- data/README.rdoc +34 -5
- data/Rakefile +8 -0
- data/friendly_id.gemspec +4 -4
- data/lib/friendly_id/sluggable_class_methods.rb +1 -1
- data/lib/friendly_id/sluggable_instance_methods.rb +10 -6
- data/lib/friendly_id/version.rb +1 -1
- data/lib/friendly_id.rb +8 -4
- data/test/custom_slug_normalizer_test.rb +35 -0
- data/test/models/book.rb +2 -0
- data/test/models/novel.rb +3 -0
- data/test/models/thing.rb +6 -0
- data/test/schema.rb +7 -3
- data/test/sti_test.rb +48 -0
- data/test/test_helper.rb +1 -0
- metadata +9 -2
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
@@ -20,13 +20,18 @@ lib/friendly_id/sluggable_instance_methods.rb
|
|
20
20
|
lib/friendly_id/version.rb
|
21
21
|
lib/tasks/friendly_id.rake
|
22
22
|
lib/tasks/friendly_id.rb
|
23
|
+
test/custom_slug_normalizer_test.rb
|
24
|
+
test/models/book.rb
|
23
25
|
test/models/country.rb
|
26
|
+
test/models/novel.rb
|
24
27
|
test/models/person.rb
|
25
28
|
test/models/post.rb
|
29
|
+
test/models/thing.rb
|
26
30
|
test/models/user.rb
|
27
31
|
test/non_slugged_test.rb
|
28
32
|
test/schema.rb
|
29
33
|
test/scoped_model_test.rb
|
30
34
|
test/slug_test.rb
|
31
35
|
test/slugged_model_test.rb
|
36
|
+
test/sti_test.rb
|
32
37
|
test/test_helper.rb
|
data/README.rdoc
CHANGED
@@ -136,9 +136,13 @@ Here's how to do it:
|
|
136
136
|
|
137
137
|
class Restaurant < ActiveRecord::Base
|
138
138
|
belongs_to :city
|
139
|
-
has_friendly_id :name, :use_slug => true, :reserved => ["
|
139
|
+
has_friendly_id :name, :use_slug => true, :reserved => ["my", "values"]
|
140
140
|
end
|
141
141
|
|
142
|
+
As of FriendlyId version 2.0.2, "new" and "index" are reseved by default. When
|
143
|
+
you attempt to store a reserved value, FriendlyId raises a
|
144
|
+
FriendlyId::SlugGenerationError.
|
145
|
+
|
142
146
|
|
143
147
|
=== Scoped Slugs
|
144
148
|
|
@@ -208,6 +212,33 @@ that uses a non-Roman writing system, your feedback would be most welcome.
|
|
208
212
|
@post.friendly_id # "友好编号在中国"
|
209
213
|
@post2 = Post.create(:title => "友好编号在中国")
|
210
214
|
@post2.friendly_id # "友好编号在中国--2"
|
215
|
+
|
216
|
+
=== Custom Slug Generation
|
217
|
+
|
218
|
+
While FriendlyId's slug generation options work for most people, you may need
|
219
|
+
something else. As of version 2.0.4 you can pass in your own custom slug
|
220
|
+
generation block:
|
221
|
+
|
222
|
+
require 'stringex'
|
223
|
+
class Post < ActiveRecord::Base
|
224
|
+
has_friendly_id :title, :use_slug => true do |text|
|
225
|
+
# User stringex to generate the friendly_id rather than the baked-in methods
|
226
|
+
text.to_url
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
...
|
231
|
+
|
232
|
+
@post = Post.create(:title => "tell your readers 你好")
|
233
|
+
@post.friendly_id # "tell-your-readers-ni-hao"
|
234
|
+
|
235
|
+
FriendlyId will still respect your settings for max length and reserved words,
|
236
|
+
but will use your block rather than the baked-in methods to normalize the
|
237
|
+
friendly_id text.
|
238
|
+
|
239
|
+
(As an aside, the stringex[http://github.com/rsl/stringex/tree/master] library
|
240
|
+
provides some very cool slugging functionality and is a great option for
|
241
|
+
apps using FriendlyId in either English or Chinese. Definitely check it out.)
|
211
242
|
|
212
243
|
== Getting it
|
213
244
|
|
@@ -228,7 +259,7 @@ which FriendlyId depends on:
|
|
228
259
|
|
229
260
|
== Setting it up
|
230
261
|
|
231
|
-
FriendlyId currently works with Rails 2.0.0
|
262
|
+
FriendlyId currently works with Rails 2.0.0 - 2.3.0. Here's how to set it up.
|
232
263
|
|
233
264
|
1) Install the Gem:
|
234
265
|
|
@@ -267,7 +298,7 @@ rake:friendly_id:remove_old_slugs MODEL=MyModelName DAYS=60
|
|
267
298
|
|
268
299
|
== Upgrading from an older version
|
269
300
|
|
270
|
-
If you installed an older version of FriendlyId and want to upgrade to 2.0,
|
301
|
+
If you installed an older version of FriendlyId and want to upgrade to 2.0.x,
|
271
302
|
follow these steps:
|
272
303
|
|
273
304
|
==== Install the friendly_id Gem:
|
@@ -297,8 +328,6 @@ Add this to the bottom of environment.rb:
|
|
297
328
|
./script generate friendly_id_20_upgrade
|
298
329
|
rake db:migrate
|
299
330
|
|
300
|
-
That's it!
|
301
|
-
|
302
331
|
== Hacking FriendlyId:
|
303
332
|
|
304
333
|
FriendlyId is {hosted on Github}[git://github.com/norman/friendly_id.git], and
|
data/Rakefile
CHANGED
@@ -42,3 +42,11 @@ def run_coverage(files)
|
|
42
42
|
puts cmd
|
43
43
|
sh cmd
|
44
44
|
end
|
45
|
+
|
46
|
+
desc 'Publish RDoc to RubyForge.'
|
47
|
+
task :publish_docs => [:clean, :docs] do
|
48
|
+
host = "compay@rubyforge.org"
|
49
|
+
remote_dir = "/var/www/gforge-projects/friendly-id"
|
50
|
+
local_dir = 'doc'
|
51
|
+
sh %{rsync -av --delete #{local_dir}/ #{host}:#{remote_dir}}
|
52
|
+
end
|
data/friendly_id.gemspec
CHANGED
@@ -2,15 +2,15 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{friendly_id}
|
5
|
-
s.version = "2.0.
|
5
|
+
s.version = "2.0.4"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Norman Clarke", "Adrian Mugnolo", "Emilio Tagua"]
|
9
|
-
s.date = %q{2009-02-
|
9
|
+
s.date = %q{2009-02-12}
|
10
10
|
s.description = %q{A comprehensive slugging and pretty-URL plugin for ActiveRecord.}
|
11
11
|
s.email = ["norman@randomba.org", "adrian@randomba.org", "miloops@gmail.com"]
|
12
12
|
s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.rdoc"]
|
13
|
-
s.files = ["History.txt", "MIT-LICENSE", "Manifest.txt", "README.rdoc", "Rakefile", "config/website.yml", "friendly_id.gemspec", "generators/friendly_id/friendly_id_generator.rb", "generators/friendly_id/templates/create_slugs.rb", "generators/friendly_id_20_upgrade/friendly_id_20_upgrade_generator.rb", "generators/friendly_id_20_upgrade/templates/upgrade_friendly_id_to_20.rb", "init.rb", "lib/friendly_id.rb", "lib/friendly_id/helpers.rb", "lib/friendly_id/non_sluggable_class_methods.rb", "lib/friendly_id/non_sluggable_instance_methods.rb", "lib/friendly_id/slug.rb", "lib/friendly_id/sluggable_class_methods.rb", "lib/friendly_id/sluggable_instance_methods.rb", "lib/friendly_id/version.rb", "lib/tasks/friendly_id.rake", "lib/tasks/friendly_id.rb", "test/models/country.rb", "test/models/person.rb", "test/models/post.rb", "test/models/user.rb", "test/non_slugged_test.rb", "test/schema.rb", "test/scoped_model_test.rb", "test/slug_test.rb", "test/slugged_model_test.rb", "test/test_helper.rb"]
|
13
|
+
s.files = ["History.txt", "MIT-LICENSE", "Manifest.txt", "README.rdoc", "Rakefile", "config/website.yml", "friendly_id.gemspec", "generators/friendly_id/friendly_id_generator.rb", "generators/friendly_id/templates/create_slugs.rb", "generators/friendly_id_20_upgrade/friendly_id_20_upgrade_generator.rb", "generators/friendly_id_20_upgrade/templates/upgrade_friendly_id_to_20.rb", "init.rb", "lib/friendly_id.rb", "lib/friendly_id/helpers.rb", "lib/friendly_id/non_sluggable_class_methods.rb", "lib/friendly_id/non_sluggable_instance_methods.rb", "lib/friendly_id/slug.rb", "lib/friendly_id/sluggable_class_methods.rb", "lib/friendly_id/sluggable_instance_methods.rb", "lib/friendly_id/version.rb", "lib/tasks/friendly_id.rake", "lib/tasks/friendly_id.rb", "test/custom_slug_normalizer_test.rb", "test/models/book.rb", "test/models/country.rb", "test/models/novel.rb", "test/models/person.rb", "test/models/post.rb", "test/models/thing.rb", "test/models/user.rb", "test/non_slugged_test.rb", "test/schema.rb", "test/scoped_model_test.rb", "test/slug_test.rb", "test/slugged_model_test.rb", "test/sti_test.rb", "test/test_helper.rb"]
|
14
14
|
s.has_rdoc = true
|
15
15
|
s.homepage = %q{http://friendly-id.rubyforge.org/}
|
16
16
|
s.rdoc_options = ["--main", "README.rdoc"]
|
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.rubyforge_project = %q{friendly-id}
|
19
19
|
s.rubygems_version = %q{1.3.1}
|
20
20
|
s.summary = %q{A comprehensive slugging and pretty-URL plugin for ActiveRecord.}
|
21
|
-
s.test_files = ["test/non_slugged_test.rb", "test/scoped_model_test.rb", "test/slug_test.rb", "test/slugged_model_test.rb"]
|
21
|
+
s.test_files = ["test/custom_slug_normalizer_test.rb", "test/non_slugged_test.rb", "test/scoped_model_test.rb", "test/slug_test.rb", "test/slugged_model_test.rb", "test/sti_test.rb"]
|
22
22
|
|
23
23
|
if s.respond_to? :specification_version then
|
24
24
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
@@ -56,13 +56,17 @@ module FriendlyId::SluggableInstanceMethods
|
|
56
56
|
# Get the processed string used as the basis of the friendly id.
|
57
57
|
def slug_text
|
58
58
|
base = send friendly_id_options[:column]
|
59
|
-
if self.
|
60
|
-
base =
|
61
|
-
|
62
|
-
|
63
|
-
|
59
|
+
if self.slug_normalizer_block
|
60
|
+
base = self.slug_normalizer_block.call(base)
|
61
|
+
else
|
62
|
+
if self.friendly_id_options[:strip_diacritics]
|
63
|
+
base = Slug::strip_diacritics(base)
|
64
|
+
end
|
65
|
+
if self.friendly_id_options[:strip_non_ascii]
|
66
|
+
base = Slug::strip_non_ascii(base)
|
67
|
+
end
|
68
|
+
base = Slug::normalize(base)
|
64
69
|
end
|
65
|
-
base = Slug::normalize(base)
|
66
70
|
|
67
71
|
if base.length > friendly_id_options[:max_length]
|
68
72
|
base = base[0...friendly_id_options[:max_length]]
|
data/lib/friendly_id/version.rb
CHANGED
data/lib/friendly_id.rb
CHANGED
@@ -14,7 +14,7 @@ module FriendlyId
|
|
14
14
|
:strip_diacritics => false,
|
15
15
|
:strip_non_ascii => false,
|
16
16
|
:use_slug => false }.freeze
|
17
|
-
|
17
|
+
|
18
18
|
# Valid keys for has_friendly_id options.
|
19
19
|
VALID_FRIENDLY_ID_KEYS = [
|
20
20
|
:max_length,
|
@@ -24,7 +24,7 @@ module FriendlyId
|
|
24
24
|
:strip_diacritics,
|
25
25
|
:strip_non_ascii,
|
26
26
|
:use_slug ].freeze
|
27
|
-
|
27
|
+
|
28
28
|
# This error is raised when it's not possible to generate a unique slug.
|
29
29
|
class SlugGenerationError < StandardError ; end
|
30
30
|
|
@@ -42,11 +42,12 @@ module FriendlyId
|
|
42
42
|
# * <tt>:strip_non_ascii</tt> - Defaults to false. If true, it will all non-ascii ([^a-z0-9]) characters.
|
43
43
|
# * <tt>:reserved</tt> - Array of words that are reserved and can't be used as friendly_id's. For sluggable models, if such a word is used, it will be treated the same as if that slug was already taken (numeric extension will be appended). Defaults to ["new", "index"].
|
44
44
|
# * <tt>:reserved_message</tt> - The validation message that will be shown when a reserved word is used as a frindly_id. Defaults to '"%s" is reserved'.
|
45
|
-
def has_friendly_id(column, options = {})
|
45
|
+
def has_friendly_id(column, options = {}, &block)
|
46
46
|
options.assert_valid_keys VALID_FRIENDLY_ID_KEYS
|
47
47
|
options = DEFAULT_FRIENDLY_ID_OPTIONS.merge(options).merge(:column => column)
|
48
48
|
write_inheritable_attribute :friendly_id_options, options
|
49
49
|
class_inheritable_accessor :friendly_id_options
|
50
|
+
class_inheritable_reader :slug_normalizer_block
|
50
51
|
|
51
52
|
if options[:use_slug]
|
52
53
|
has_many :slugs, :order => 'id DESC', :as => :sluggable, :dependent => :destroy
|
@@ -55,6 +56,9 @@ module FriendlyId
|
|
55
56
|
extend SluggableClassMethods
|
56
57
|
include SluggableInstanceMethods
|
57
58
|
before_save :set_slug
|
59
|
+
if block_given?
|
60
|
+
write_inheritable_attribute :slug_normalizer_block, block
|
61
|
+
end
|
58
62
|
else
|
59
63
|
require 'friendly_id/non_sluggable_class_methods'
|
60
64
|
require 'friendly_id/non_sluggable_instance_methods'
|
@@ -63,7 +67,7 @@ module FriendlyId
|
|
63
67
|
validate_on_create :validate_friendly_id
|
64
68
|
end
|
65
69
|
end
|
66
|
-
|
70
|
+
|
67
71
|
end
|
68
72
|
|
69
73
|
class << self
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + '/test_helper'
|
4
|
+
|
5
|
+
class CustomSlugNormalizerTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "A slugged model using a custom slug generator" do
|
8
|
+
|
9
|
+
setup do
|
10
|
+
Thing.friendly_id_options = FriendlyId::DEFAULT_FRIENDLY_ID_OPTIONS.merge(:column => :name, :use_slug => true)
|
11
|
+
Thing.delete_all
|
12
|
+
Slug.delete_all
|
13
|
+
end
|
14
|
+
|
15
|
+
should "invoke the block code" do
|
16
|
+
@thing = Thing.create!(:name => "test")
|
17
|
+
assert_equal "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", @thing.friendly_id
|
18
|
+
end
|
19
|
+
|
20
|
+
should "respect the max_length option" do
|
21
|
+
Thing.friendly_id_options = Thing.friendly_id_options.merge(:max_length => 10)
|
22
|
+
@thing = Thing.create!(:name => "test")
|
23
|
+
assert_equal "a94a8fe5cc", @thing.friendly_id
|
24
|
+
end
|
25
|
+
|
26
|
+
should "respect the reserved option" do
|
27
|
+
Thing.friendly_id_options = Thing.friendly_id_options.merge(:reserved => ["a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"])
|
28
|
+
assert_raises FriendlyId::SlugGenerationError do
|
29
|
+
Thing.create!(:name => "test")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
data/test/models/book.rb
ADDED
data/test/schema.rb
CHANGED
@@ -1,10 +1,14 @@
|
|
1
1
|
ActiveRecord::Schema.define(:version => 1) do
|
2
|
-
|
2
|
+
|
3
3
|
create_table "books", :force => true do |t|
|
4
4
|
t.column "title", "string"
|
5
5
|
t.column "type", "text"
|
6
6
|
end
|
7
7
|
|
8
|
+
create_table "things", :force => true do |t|
|
9
|
+
t.column "name", "string"
|
10
|
+
end
|
11
|
+
|
8
12
|
create_table "posts", :force => true do |t|
|
9
13
|
t.column "title", "string"
|
10
14
|
t.column "content", "text"
|
@@ -18,12 +22,12 @@ ActiveRecord::Schema.define(:version => 1) do
|
|
18
22
|
t.column "created_at", "datetime"
|
19
23
|
t.column "updated_at", "datetime"
|
20
24
|
end
|
21
|
-
|
25
|
+
|
22
26
|
create_table "people", :force => true do |t|
|
23
27
|
t.column "name", "string"
|
24
28
|
t.column "country_id", "integer"
|
25
29
|
end
|
26
|
-
|
30
|
+
|
27
31
|
create_table "countries", :force => true do |t|
|
28
32
|
t.column "name", "string"
|
29
33
|
end
|
data/test/sti_test.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + '/test_helper'
|
4
|
+
|
5
|
+
class SluggedModelTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "A slugged model using single table inheritance" do
|
8
|
+
|
9
|
+
setup do
|
10
|
+
Novel.friendly_id_options = FriendlyId::DEFAULT_FRIENDLY_ID_OPTIONS.merge(:column => :title, :use_slug => true)
|
11
|
+
Novel.delete_all
|
12
|
+
Slug.delete_all
|
13
|
+
@novel = Novel.new :title => "Test novel"
|
14
|
+
@novel.save!
|
15
|
+
end
|
16
|
+
|
17
|
+
should "have a slug" do
|
18
|
+
assert_not_nil @novel.slug
|
19
|
+
end
|
20
|
+
|
21
|
+
context "found by its friendly id" do
|
22
|
+
|
23
|
+
setup do
|
24
|
+
@novel = Novel.find(@novel.friendly_id)
|
25
|
+
end
|
26
|
+
|
27
|
+
should "not indicate that it has a better id" do
|
28
|
+
assert !@novel.has_better_id?
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
context "found by its numeric id" do
|
35
|
+
|
36
|
+
setup do
|
37
|
+
@novel = Novel.find(@novel.id)
|
38
|
+
end
|
39
|
+
|
40
|
+
should "indicate that it has a better id" do
|
41
|
+
assert @novel.has_better_id?
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: norman-friendly_id
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Norman Clarke
|
@@ -11,7 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2009-02-
|
14
|
+
date: 2009-02-12 00:00:00 -08:00
|
15
15
|
default_executable:
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
@@ -104,15 +104,20 @@ files:
|
|
104
104
|
- lib/friendly_id/version.rb
|
105
105
|
- lib/tasks/friendly_id.rake
|
106
106
|
- lib/tasks/friendly_id.rb
|
107
|
+
- test/custom_slug_normalizer_test.rb
|
108
|
+
- test/models/book.rb
|
107
109
|
- test/models/country.rb
|
110
|
+
- test/models/novel.rb
|
108
111
|
- test/models/person.rb
|
109
112
|
- test/models/post.rb
|
113
|
+
- test/models/thing.rb
|
110
114
|
- test/models/user.rb
|
111
115
|
- test/non_slugged_test.rb
|
112
116
|
- test/schema.rb
|
113
117
|
- test/scoped_model_test.rb
|
114
118
|
- test/slug_test.rb
|
115
119
|
- test/slugged_model_test.rb
|
120
|
+
- test/sti_test.rb
|
116
121
|
- test/test_helper.rb
|
117
122
|
has_rdoc: true
|
118
123
|
homepage: http://friendly-id.rubyforge.org/
|
@@ -142,7 +147,9 @@ signing_key:
|
|
142
147
|
specification_version: 2
|
143
148
|
summary: A comprehensive slugging and pretty-URL plugin for ActiveRecord.
|
144
149
|
test_files:
|
150
|
+
- test/custom_slug_normalizer_test.rb
|
145
151
|
- test/non_slugged_test.rb
|
146
152
|
- test/scoped_model_test.rb
|
147
153
|
- test/slug_test.rb
|
148
154
|
- test/slugged_model_test.rb
|
155
|
+
- test/sti_test.rb
|