rdavila_friendly_id 2.2.6
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +189 -0
- data/LICENSE +19 -0
- data/README.rdoc +384 -0
- data/Rakefile +35 -0
- data/extras/README.txt +3 -0
- data/extras/template-gem.rb +26 -0
- data/extras/template-plugin.rb +28 -0
- data/generators/friendly_id/friendly_id_generator.rb +28 -0
- data/generators/friendly_id/templates/create_slugs.rb +18 -0
- data/generators/friendly_id_20_upgrade/friendly_id_20_upgrade_generator.rb +12 -0
- data/generators/friendly_id_20_upgrade/templates/upgrade_friendly_id_to_20.rb +19 -0
- data/init.rb +1 -0
- data/lib/friendly_id.rb +83 -0
- data/lib/friendly_id/helpers.rb +12 -0
- data/lib/friendly_id/non_sluggable_class_methods.rb +34 -0
- data/lib/friendly_id/non_sluggable_instance_methods.rb +45 -0
- data/lib/friendly_id/slug.rb +98 -0
- data/lib/friendly_id/sluggable_class_methods.rb +113 -0
- data/lib/friendly_id/sluggable_instance_methods.rb +161 -0
- data/lib/friendly_id/tasks.rb +92 -0
- data/lib/friendly_id/version.rb +8 -0
- data/lib/tasks/friendly_id.rake +40 -0
- data/lib/tasks/friendly_id.rb +1 -0
- data/test/cached_slug_test.rb +109 -0
- data/test/custom_slug_normalizer_test.rb +36 -0
- data/test/non_slugged_test.rb +99 -0
- data/test/scoped_model_test.rb +64 -0
- data/test/slug_test.rb +105 -0
- data/test/slugged_model_test.rb +348 -0
- data/test/sti_test.rb +49 -0
- data/test/support/database.yml.postgres +6 -0
- data/test/support/database.yml.sqlite3 +2 -0
- data/test/support/models.rb +45 -0
- data/test/tasks_test.rb +105 -0
- data/test/test_helper.rb +104 -0
- metadata +144 -0
data/History.txt
ADDED
@@ -0,0 +1,189 @@
|
|
1
|
+
== 2.2.6 2009-12-10
|
2
|
+
|
3
|
+
* 2 major fixes
|
4
|
+
* Made cached_slug automagic configuration occur outside of has_friendly_id. This was causing problems
|
5
|
+
in code where the class is loaded before ActiveRecord has established its connection.
|
6
|
+
* Fixes for scope feature with Postgres (Ben Woosley)
|
7
|
+
|
8
|
+
* 2 minor enhancements
|
9
|
+
* Migrated away from Hoe/Newgem for gem management.
|
10
|
+
* Made tests database-agnostic (Ben Woosley)
|
11
|
+
|
12
|
+
== 2.2.5 2009-11-30
|
13
|
+
|
14
|
+
* 1 minor fix
|
15
|
+
* Fixed typo which in config options (Steven Noble).
|
16
|
+
|
17
|
+
== 2.2.4 2009-11-12
|
18
|
+
|
19
|
+
* 1 minor fix
|
20
|
+
* Fixed typo in post-install message.
|
21
|
+
|
22
|
+
== 2.2.3 2009-11-12
|
23
|
+
|
24
|
+
* 4 minor enhancements:
|
25
|
+
* Fixed some issues with gem load order under 1.8.x (closes GH Issue #20)
|
26
|
+
* Made sure friendly_id generator makes a lib/tasks directory (Josh Nichols)
|
27
|
+
* Finders now accept instances of ActiveRecord::Base, matching AR's behavior (Josh Nichols)
|
28
|
+
* SlugGenerationError now raise when a blank value is passed to strip_diacritics
|
29
|
+
|
30
|
+
== 2.2.2 2009-10-26
|
31
|
+
|
32
|
+
* 1 minor enhancement:
|
33
|
+
* Fixed Rake tasks creating duplicate slugs and not properly clearing cached slugs (closes GH issues #14 and #15)
|
34
|
+
|
35
|
+
== 2.2.1 2009-10-23
|
36
|
+
|
37
|
+
* 2 minor enhancements:
|
38
|
+
* slug cache now properly caches the slug sequence (closes GH issue #10)
|
39
|
+
* attr_protected is now only invoked on the cached_slug column if attr_accessible has not already been invoked. (closes GH issue #11)
|
40
|
+
|
41
|
+
== 2.2.0 2009-10-19
|
42
|
+
|
43
|
+
* 1 major enhancement:
|
44
|
+
* Added slug caching, offers huge performance boost (Bruno Michel)
|
45
|
+
|
46
|
+
* 2 minor enhancements:
|
47
|
+
* Handle Unicode string length correctly (Mikhail Shirkov)
|
48
|
+
* Remove alias_method_chain in favor of super (Diego Carrion)
|
49
|
+
|
50
|
+
== 2.1.4 2009-09-01
|
51
|
+
|
52
|
+
* 3 minor enhancements:
|
53
|
+
* Fixed upgrade generator not installing rake tasks (Harry Love)
|
54
|
+
* Fixed handling of very large id's (Nathan Phelps)
|
55
|
+
* Fixed long index name on migration (Rob Ingram)
|
56
|
+
|
57
|
+
== 2.1.3 2009-06-03
|
58
|
+
|
59
|
+
* 1 minor enhancement:
|
60
|
+
* Always call #to_s on slug_text to allow objects such as DateTimes to be used for the friendly_id text. (reported by Jon Ng)
|
61
|
+
|
62
|
+
== 2.1.2 2009-05-21
|
63
|
+
|
64
|
+
* 2 minor enhancements:
|
65
|
+
* Non-slugged models now validate the friendly_id on save as well as create (Joe Van Dyk).
|
66
|
+
* Replaced Shoulda with Contest.
|
67
|
+
|
68
|
+
== 2.1.1 2009-03-25
|
69
|
+
|
70
|
+
* 2 minor enhancements:
|
71
|
+
* Fixed bug with find_some; if a record has old slugs, find_some will no longer return
|
72
|
+
multiple copies of that record when finding by numerical ID. (Steve Luscher)
|
73
|
+
* Fixed bug with find_some: you can now find_some with an array of numerical IDs without
|
74
|
+
an error being thrown. (Steve Luscher)
|
75
|
+
|
76
|
+
== 2.1.0 2009-03-25
|
77
|
+
|
78
|
+
* 2 major enhancements:
|
79
|
+
* Ruby 1.9 compatibility.
|
80
|
+
* Removed dependency on ancient Unicode gem.
|
81
|
+
|
82
|
+
== 2.0.4 2009-02-12
|
83
|
+
|
84
|
+
* 1 major enhancment:
|
85
|
+
* You can now pass in your own custom slug generation blocks while setting up friendly_id.
|
86
|
+
|
87
|
+
== 2.0.3 2009-02-11
|
88
|
+
|
89
|
+
* 1 minor enhancment:
|
90
|
+
* Fixed to_param returning an empty string for non-slugged models with a null friendly_id.
|
91
|
+
|
92
|
+
== 2.0.2 2009-02-09
|
93
|
+
|
94
|
+
* 2 major enhancements:
|
95
|
+
* Made FriendlyId depend only on ActiveRecord. It should now be possible to
|
96
|
+
use FriendlyId with Camping or any other codebase that uses AR.
|
97
|
+
* Overhauled creaky testing setup and switched to Shoulda.
|
98
|
+
|
99
|
+
* 1 minor enhancment:
|
100
|
+
* Made reserved words work for non-slugged models.
|
101
|
+
|
102
|
+
== 2.0.1 2009-01-19
|
103
|
+
|
104
|
+
* 1 minor enhancements:
|
105
|
+
* Fix infinite redirect bug when using .has_better_id? in your controllers (Sean Abrahams)
|
106
|
+
|
107
|
+
|
108
|
+
== 2.0.0 2009-01-03
|
109
|
+
|
110
|
+
* 5 major enhancements:
|
111
|
+
* Support for scoped slugs (Norman Clarke)
|
112
|
+
* Support for UTF-8 friendly_ids (Norman Clarke)
|
113
|
+
* Can now be installed via Ruby Gems, or as a Rails plugin (Norman Clarke)
|
114
|
+
* Improved handling of non-unique slugs (Norman Clarke and Adrian Mugnolo)
|
115
|
+
* 2 minor enhancements:
|
116
|
+
* Shoulda macro (Josh Nichols)
|
117
|
+
* Various small bugfixes, cleanups and refactorings
|
118
|
+
|
119
|
+
== 2008-12-01
|
120
|
+
|
121
|
+
* Fixed bug that may return invalid records having similar id/names and using MySQL. (Emilio Tagua)
|
122
|
+
* Fixed slug generation to increment only numeric extension without modifying the name on duplicated slugs. (Emilio Tagua)
|
123
|
+
|
124
|
+
== 2008-10-31
|
125
|
+
|
126
|
+
* Fixed compatibility with Rails 2.0.x. (Norman Clarke)
|
127
|
+
* friendly_id::make_slugs update records in chunks of 1000 to avoid running out of memory with large datasets. (Tim Kadom)
|
128
|
+
* Fixed logic error with slug name collisions. Thanks to Tim Kadom for reporting this bug.
|
129
|
+
|
130
|
+
== 2008-10-22
|
131
|
+
|
132
|
+
* Reverted use of UTF8Handler - was causing errors for some people (Bence Nagy)
|
133
|
+
* Corrected find in case if a friendly_id begins with number (Bence Nagy)
|
134
|
+
* Added ability to reserve words from slugs (Adam Cigánek)
|
135
|
+
|
136
|
+
== 2008-10-09
|
137
|
+
|
138
|
+
* Moved "require"" for iconv to init.rb (Florian Aßmann)
|
139
|
+
* Removed "require" for Unicode, use Rails' handler instead (Florian Aßmann)
|
140
|
+
* Replaced some magic numbers with constants (Florian Aßmann)
|
141
|
+
* Don't overwrite find, alias_method_chain find_one and find_some instead (Florian Aßmann)
|
142
|
+
* Slugs behave more like ids now (Florian Aßmann)
|
143
|
+
* Can find by mixture of ids and slugs (Florian Aßmann)
|
144
|
+
* Reformatted code and comments (Florian Aßmann)
|
145
|
+
* Added support for Edge Rails' Inflector::parameterize (Norman Clarke)
|
146
|
+
|
147
|
+
== 2008-08-25
|
148
|
+
|
149
|
+
* Moved strip_diacritics into Slug for easier reuse/better organization.
|
150
|
+
* Put class methods inside class << self block. (Norman Clarke)
|
151
|
+
|
152
|
+
* Small change to allow friendly_id to work better with STI. (David Ramalho)
|
153
|
+
|
154
|
+
== 2008-07-14
|
155
|
+
|
156
|
+
* Improved slug generation for friendly id's with apostrophes. (Alistair Holt)
|
157
|
+
* Added support for namespaced models in Rakefile. (David Ramalho)
|
158
|
+
|
159
|
+
== 2008-06-23
|
160
|
+
|
161
|
+
* Cached most recent slug to improve performance (Emilio Tagua).
|
162
|
+
|
163
|
+
== 2008-06-10
|
164
|
+
|
165
|
+
* Added ability to find friendly_ids by array (Emilio Tagua)
|
166
|
+
|
167
|
+
== 2008-05-15
|
168
|
+
|
169
|
+
* Made friendly_id raise an error if slug method returns a blank value.
|
170
|
+
|
171
|
+
== 2008-05-12
|
172
|
+
|
173
|
+
* Added experimental Github gemspec.
|
174
|
+
|
175
|
+
== 2008-04-18
|
176
|
+
|
177
|
+
* Improved slug name collision avoidance.
|
178
|
+
|
179
|
+
== 2008-03-13
|
180
|
+
|
181
|
+
* Added :dependent => :destroy to slug relation, as suggested by Emilio Tagua.
|
182
|
+
* Fixed error when renaming a slugged item back to a previously used name.
|
183
|
+
* Incorporated documentation changes suggested by Jesse Crouch and Chris Nolan.
|
184
|
+
|
185
|
+
== 2008-02-07
|
186
|
+
|
187
|
+
* Applied patches from blog commenter "suntzu" to fix problem with model values were being overwritten.
|
188
|
+
* Applied patch from Dan Blue to make friendly_id no longer ignore options on ActiveRecordBase#find.
|
189
|
+
* Added call to options.assert_valid_keys in has_friendly_id. Thanks to W. Andrew Loe III for pointing out that this was missing.
|
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2008 Norman Clarke, Adrian Mugnolo and Emilio Tagua.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,384 @@
|
|
1
|
+
= FriendlyId
|
2
|
+
|
3
|
+
FriendlyId is the "Swiss Army bulldozer" of slugging and permalink plugins for
|
4
|
+
Ruby on Rails. It allows you to create pretty URL's and work with
|
5
|
+
human-friendly strings as if they were numeric ids for ActiveRecord models.
|
6
|
+
|
7
|
+
Using FriendlyId, it's easy to make your application use URL's like:
|
8
|
+
|
9
|
+
http://example.com/states/washington
|
10
|
+
|
11
|
+
instead of:
|
12
|
+
|
13
|
+
http://example.com/states/4323454
|
14
|
+
|
15
|
+
You can always read the latest version of this document at the {friendly_id page on
|
16
|
+
rdoc.info}[http://rdoc.info/projects/norman/friendly_id].
|
17
|
+
|
18
|
+
=== Why?
|
19
|
+
|
20
|
+
* Text-based id's look better
|
21
|
+
* They make URL's easier to remember.
|
22
|
+
* They give no hint about the number of records in your database.
|
23
|
+
* They are better for search engine optimization.
|
24
|
+
|
25
|
+
=== But...
|
26
|
+
|
27
|
+
* They can change, breaking your URL's and your SEO.
|
28
|
+
* It can be tricky to ensure they're always unique.
|
29
|
+
* They can become a pain to manage in large Rails applications.
|
30
|
+
* They can conflict with your application's namespace.
|
31
|
+
|
32
|
+
FriendlyId tries to offer you the all the advantages, and avoid or soften the
|
33
|
+
potential impact of the disadvantages.
|
34
|
+
|
35
|
+
== Typical Uses
|
36
|
+
|
37
|
+
=== User names ("non-slugged" models)
|
38
|
+
|
39
|
+
Usually users have unique user names stored in a column with a unique
|
40
|
+
constraint or index. In this case, all you need to do is add this to your
|
41
|
+
model:
|
42
|
+
|
43
|
+
has_friendly_id :login
|
44
|
+
|
45
|
+
and you can then write code like this:
|
46
|
+
|
47
|
+
@member = Member.find("joe") # the old Member.find(1) still works, too.
|
48
|
+
@member.to_param # returns "joe"
|
49
|
+
redirect_to @member # The URL would be /members/joe
|
50
|
+
|
51
|
+
=== Blog posts ("slugged" models)
|
52
|
+
|
53
|
+
Blog posts generally have titles which are distinctive but not necessarily
|
54
|
+
unique. In this and similar cases, FriendlyId provides a Slug model separate
|
55
|
+
from your Post model. The Slug model handles duplicate friendly_ids, as well
|
56
|
+
as versioning.
|
57
|
+
|
58
|
+
Your model code would look something like this:
|
59
|
+
|
60
|
+
has_friendly_id :title, :use_slug => true
|
61
|
+
|
62
|
+
and you can then write code like this:
|
63
|
+
|
64
|
+
@post = Post.find("new-version-released") # Post.find(1) still works, too
|
65
|
+
@post.to_param # returns "new-version-released"
|
66
|
+
redirect_to @post # The URL would be /posts/new-version-released
|
67
|
+
|
68
|
+
Now in your controllers, if you want to prevent people from accessing your
|
69
|
+
models by numeric id, you can detect whether they were found by the
|
70
|
+
friendly_id:
|
71
|
+
|
72
|
+
@post = Post.find(params[:id])
|
73
|
+
raise "some error" if !@post.found_using_friendly_id?
|
74
|
+
|
75
|
+
or, you can 301 redirect if the model was found by the numeric id if you don't
|
76
|
+
care about numeric access, but want the SEO value of the friendly_id:
|
77
|
+
|
78
|
+
@post = Post.find(params[:id])
|
79
|
+
redirect_to @post, :status => 301 if @post.has_better_id?
|
80
|
+
|
81
|
+
The "has_better_id?" method returns true if the model was found with the
|
82
|
+
numeric id, or with an outdated slug.
|
83
|
+
|
84
|
+
== Extra Features
|
85
|
+
|
86
|
+
=== Slug Versioning
|
87
|
+
|
88
|
+
FriendlyId will record changes to slugs so that you can tell when the model is
|
89
|
+
found with an older slug, or by the numeric id. This can be useful if you want
|
90
|
+
to do a 301 redirect to your updated URL.
|
91
|
+
|
92
|
+
class PostsController < ApplicationController
|
93
|
+
|
94
|
+
before_filter ensure_current_post_url, :only => :show
|
95
|
+
|
96
|
+
...
|
97
|
+
|
98
|
+
def ensure_current_post_url
|
99
|
+
redirect_to @post, :status => :moved_permanently if @post.has_better_id?
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
This is particularly useful when implementing FrindlyId on an existing
|
105
|
+
website that already has many URL's with the old numeric id listed on search
|
106
|
+
engines. When the search engine spiders crawl your site, they will
|
107
|
+
eventually pick up the new, more SEO-friendly URL's.
|
108
|
+
|
109
|
+
=== Non-unique Slug Names
|
110
|
+
|
111
|
+
FriendlyId will append a arbitrary number to the end of the id to keep it
|
112
|
+
unique if necessary:
|
113
|
+
|
114
|
+
/posts/new-version-released
|
115
|
+
/posts/new-version-released--2
|
116
|
+
/posts/new-version-released--3
|
117
|
+
...
|
118
|
+
etc.
|
119
|
+
|
120
|
+
Note that the number is preceeded by two dashes to distinguish it from the
|
121
|
+
rest of the slug. This is important to enable having slugs like:
|
122
|
+
|
123
|
+
/cars/peugeot-206
|
124
|
+
/cars/peugeot-206--2
|
125
|
+
|
126
|
+
=== Reserved Names
|
127
|
+
|
128
|
+
You can mark off some strings as reserved so that, for example, you don't end
|
129
|
+
up with this problem:
|
130
|
+
|
131
|
+
/users/joe-schmoe # A user chose "joe schmoe" as his user name - no worries.
|
132
|
+
/users/new # A user chose "new" as his user name, and now no one can sign up.
|
133
|
+
|
134
|
+
Here's how to do it:
|
135
|
+
|
136
|
+
class Restaurant < ActiveRecord::Base
|
137
|
+
belongs_to :city
|
138
|
+
has_friendly_id :name, :use_slug => true, :reserved => ["my", "values"]
|
139
|
+
end
|
140
|
+
|
141
|
+
As of FriendlyId version 2.0.2, "new" and "index" are reseved by default. When
|
142
|
+
you attempt to store a reserved value, FriendlyId raises a
|
143
|
+
FriendlyId::SlugGenerationError.
|
144
|
+
|
145
|
+
=== Cached slugs
|
146
|
+
|
147
|
+
Checking the slugs table all the time has an impact on performance, so as of
|
148
|
+
2.3.0, FriendlyId offers slug caching.
|
149
|
+
|
150
|
+
This feature can improve the performance of some views by about 25%, and reduce
|
151
|
+
memory consumption by about 40% as compared to the same view without cached
|
152
|
+
slugs. The biggest improvement will be for "index" type views with many links
|
153
|
+
that depend on slugs to generate the URL.
|
154
|
+
|
155
|
+
==== Automagic setup:
|
156
|
+
|
157
|
+
To enable slug caching, simply add a column named "cached_slug" to your model.
|
158
|
+
FriendlyId will automagically use this column if it detects it:
|
159
|
+
|
160
|
+
class AddCachedSlugToUsers < ActiveRecord::Migration
|
161
|
+
def self.up
|
162
|
+
add_column :users, :cached_slug, :string
|
163
|
+
end
|
164
|
+
|
165
|
+
def self.down
|
166
|
+
remove_column :users, :cached_slug
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
Then, redo the slugs:
|
171
|
+
|
172
|
+
rake friendly_id:redo_slugs MODEL=User
|
173
|
+
|
174
|
+
This feature exists largely to improve the performance of URL
|
175
|
+
generation, the part of Rails where FriendlyId has the biggest
|
176
|
+
performance impact. FriendlyId never queries against this column, so
|
177
|
+
it's not necessary to add an index on it unless your application does.
|
178
|
+
|
179
|
+
Two warnings when using this feature:
|
180
|
+
|
181
|
+
*DO NOT* forget to redo the slugs, or else this feature will not work!
|
182
|
+
|
183
|
+
Also, this feature uses +attr_protected+ to protect the cached_slug
|
184
|
+
column, unless you have already invoked +attr_accessible+. So if you
|
185
|
+
wish to use +attr_accessible+, you must invoke it BEFORE you invoke
|
186
|
+
+has_friendly_id+ in your class.
|
187
|
+
|
188
|
+
==== Using a custom column name:
|
189
|
+
|
190
|
+
You can also use a different name for the column if you choose, via the
|
191
|
+
:cache_column config option:
|
192
|
+
|
193
|
+
class User < ActiveRecord::Base
|
194
|
+
has_friendly_id :name, :use_slug => true, :cache_column => 'my_cached_slug'
|
195
|
+
end
|
196
|
+
|
197
|
+
=== Scoped Slugs
|
198
|
+
|
199
|
+
FriendlyId can generate unique slugs within a given scope. For example:
|
200
|
+
|
201
|
+
class Restaurant < ActiveRecord::Base
|
202
|
+
belongs_to :city
|
203
|
+
has_friendly_id :name, :use_slug => true, :scope => :city
|
204
|
+
end
|
205
|
+
|
206
|
+
class City < ActiveRecord::Base
|
207
|
+
has_many :restaurants
|
208
|
+
has_friendly_id :name, :use_slug => true
|
209
|
+
end
|
210
|
+
|
211
|
+
http://example.org/cities/seattle/restaurants/joes-diner
|
212
|
+
http://example.org/cities/chicago/restaurants/joes-diner
|
213
|
+
|
214
|
+
Restaurant.find("joes-diner", :scope => "seattle") # returns 1 record
|
215
|
+
Restaurant.find("joes-diner", :scope => "chicago") # returns 1 record
|
216
|
+
Restaurant.find("joes-diner") # returns both records
|
217
|
+
|
218
|
+
|
219
|
+
The value for the :scope key in your model can be a custom method you define,
|
220
|
+
or the name of a relation. If it's the name of a relation, then the scope's
|
221
|
+
text value will be the result of calling <code>to_param</code> on the related
|
222
|
+
model record. In the example above, the city model also uses FriendlyId and so
|
223
|
+
its <code>to_param</code> method returns its friendly_id: chicago or seattle.
|
224
|
+
|
225
|
+
This feature is new in FriendlyId 2 and should be considered of experimental
|
226
|
+
quality. Please don't use this for code that needs to run on the Space
|
227
|
+
Shuttle.
|
228
|
+
|
229
|
+
=== Text Normalization
|
230
|
+
|
231
|
+
FriendlyId's slugging can strip diacritics from Western European characters,
|
232
|
+
so that you can have ASCII-only URL's; for example, conveting "ñøîéçü" to
|
233
|
+
"noiecu."
|
234
|
+
|
235
|
+
has_friendly_id :title, :use_slug => true, :strip_diacritics => true
|
236
|
+
|
237
|
+
If you are not using slugs, you'll have to do this manually for whatever value
|
238
|
+
you're using as the friendly_id.
|
239
|
+
|
240
|
+
=== Diacritic-sensitive normalization
|
241
|
+
|
242
|
+
FriendlyId can also normalize slug text while preserving accented characters, if
|
243
|
+
you prefer to leave them in your URL's:
|
244
|
+
|
245
|
+
has_friendly_id :title, :use_slug => true
|
246
|
+
...
|
247
|
+
@post = Post.create(:title => "¡Feliz Año!")
|
248
|
+
@post.friendly_id # "feliz-año"
|
249
|
+
|
250
|
+
=== Unicode URL's
|
251
|
+
|
252
|
+
FriendlyId can generate slugs in any language that can be written with
|
253
|
+
Unicode. It does its best to strip away punctuation regardless of the language
|
254
|
+
being used. Since the authors only speak English, Spanish, Portuguese and
|
255
|
+
German, this has not been extensively tested with anything like Chinese,
|
256
|
+
Russian, Greek, etc, but it "should work." If you're a speaker of a language
|
257
|
+
that uses a non-Roman writing system, your feedback would be most welcome.
|
258
|
+
|
259
|
+
has_friendly_id :title, :use_slug => true
|
260
|
+
...
|
261
|
+
@post = Post.create(:title => "友好编号在中国")
|
262
|
+
@post.friendly_id # "友好编号在中国"
|
263
|
+
@post2 = Post.create(:title => "友好编号在中国")
|
264
|
+
@post2.friendly_id # "友好编号在中国--2"
|
265
|
+
|
266
|
+
=== Custom Slug Generation
|
267
|
+
|
268
|
+
While FriendlyId's slug generation options work for most people, you may need
|
269
|
+
something else. As of version 2.0.4 you can pass in your own custom slug
|
270
|
+
generation block:
|
271
|
+
|
272
|
+
class Post < ActiveRecord::Base
|
273
|
+
has_friendly_id :title, :use_slug => true do |text|
|
274
|
+
MySlugGeneratorClass::my_slug_method(text)
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
FriendlyId will still respect your settings for max length and reserved words,
|
279
|
+
but will use your block rather than the baked-in methods to normalize the
|
280
|
+
friendly_id text.
|
281
|
+
|
282
|
+
== Getting it
|
283
|
+
|
284
|
+
FriendlyId is best installed as a Ruby Gem:
|
285
|
+
|
286
|
+
gem install friendly_id
|
287
|
+
|
288
|
+
Alternatively, you can install it as a Rails plugin, though this is
|
289
|
+
discouraged:
|
290
|
+
|
291
|
+
./script/plugin install git://github.com/norman/friendly_id.git
|
292
|
+
|
293
|
+
== Setting it up
|
294
|
+
|
295
|
+
The current release works with Rails 2.2 and above, and is compatible with
|
296
|
+
Ruby 1.8 and 1.9.
|
297
|
+
|
298
|
+
1) Install the Gem:
|
299
|
+
|
300
|
+
sudo gem install friendly_id
|
301
|
+
cd my_app
|
302
|
+
script/generate friendly_id
|
303
|
+
rake db:migrate
|
304
|
+
|
305
|
+
2) Add the gem to config/environment.rb:
|
306
|
+
|
307
|
+
config.gem "friendly_id"
|
308
|
+
|
309
|
+
3) Add some code to your models:
|
310
|
+
|
311
|
+
class Post < ActiveRecord::Base
|
312
|
+
has_friendly_id :title, :use_slug => true
|
313
|
+
end
|
314
|
+
|
315
|
+
4) If you are using slugs, you can use a Rake task to generate slugs for your
|
316
|
+
existing records:
|
317
|
+
|
318
|
+
rake friendly_id:make_slugs MODEL=MyModelName
|
319
|
+
|
320
|
+
If you eventually want to expire old slugs every so often, or perhaps every
|
321
|
+
day via cron, you can do:
|
322
|
+
|
323
|
+
rake friendly_id:remove_old_slugs
|
324
|
+
|
325
|
+
The default is to remove dead slugs older than 45 days, but is configurable:
|
326
|
+
|
327
|
+
rake friendly_id:remove_old_slugs MODEL=MyModelName DAYS=60
|
328
|
+
|
329
|
+
== Installing an older version
|
330
|
+
|
331
|
+
You can download older versions of FriendlyId from Github that work with Rails <
|
332
|
+
2.2. These versions are, however, no longer maintained or supported.
|
333
|
+
|
334
|
+
== Hacking FriendlyId:
|
335
|
+
|
336
|
+
FriendlyId is {hosted on Github}[git://github.com/norman/friendly_id.git], and
|
337
|
+
we love pull requests. :-)
|
338
|
+
|
339
|
+
== Bugs:
|
340
|
+
|
341
|
+
Please report them on the {Github issue tracker}[http://github.com/norman/friendly_id/issues]
|
342
|
+
for this project.
|
343
|
+
|
344
|
+
If you have a bug to report, please include the following information:
|
345
|
+
|
346
|
+
* Stack trace and error message.
|
347
|
+
* Version information for FriendlyId, Rails and Ruby.
|
348
|
+
* Any snippets of relevant model, view or controller code that shows how your are using FriendlyId.
|
349
|
+
|
350
|
+
If you are able to, it helps even more if you can fork FriendlyId on Github, and
|
351
|
+
add a test that reproduces the error you are experiencing.
|
352
|
+
|
353
|
+
== Credits:
|
354
|
+
|
355
|
+
FriendlyId was created by {Norman Clarke}[mailto:norman@njclarke.com],
|
356
|
+
{Adrian Mugnolo}[mailto:adrian@mugnolo.com], and {Emilio Tagua}[mailto:miloops@gmail.com].
|
357
|
+
|
358
|
+
We are grateful for many contributions from the Ruby and Rails community, in
|
359
|
+
particular from the following people:
|
360
|
+
|
361
|
+
* Adam Cigánek
|
362
|
+
* Alistair Holt
|
363
|
+
* Andrew Loe III
|
364
|
+
* Ben Woosley
|
365
|
+
* Bence Nagy
|
366
|
+
* Bruno Michel
|
367
|
+
* Chris Nolan
|
368
|
+
* David Ramalho
|
369
|
+
* Diego Carrion
|
370
|
+
* Florian Aßmann
|
371
|
+
* Harry Love
|
372
|
+
* Jesse Crouch
|
373
|
+
* Joe Van Dyk
|
374
|
+
* Josh Nichols
|
375
|
+
* Mikhail Shirkov
|
376
|
+
* Nathan Phelps
|
377
|
+
* Rob Ingram
|
378
|
+
* Sean Abrahams
|
379
|
+
* Steve Luscher
|
380
|
+
* Steven Noble
|
381
|
+
* Tim Kadom
|
382
|
+
|
383
|
+
Copyright (c) 2008 Norman Clarke, Adrian Mugnolo and Emilio Tagua, released
|
384
|
+
under the MIT license.
|