<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>test/custom_slug_normalizer_test.rb</filename>
    </added>
    <added>
      <filename>test/models/thing.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,3 +1,8 @@
+== 2.0.4 2009-02-12
+
+* 1 major enhancment:
+  * You can now pass in your own custom slug generation blocks while setting up friendly_id.
+
 == 2.0.3 2009-02-11
 
 * 1 minor enhancment:</diff>
      <filename>History.txt</filename>
    </modified>
    <modified>
      <diff>@@ -20,13 +20,18 @@ 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</diff>
      <filename>Manifest.txt</filename>
    </modified>
    <modified>
      <diff>@@ -136,9 +136,13 @@ Here's how to do it:
 
   class Restaurant &lt; ActiveRecord::Base
     belongs_to :city
-    has_friendly_id :name, :use_slug =&gt; true, :reserved =&gt; [&quot;new&quot;, &quot;index&quot;]
+    has_friendly_id :name, :use_slug =&gt; true, :reserved =&gt; [&quot;my&quot;, &quot;values&quot;]
   end
 
+As of FriendlyId version 2.0.2, &quot;new&quot; and &quot;index&quot; are reseved by default. When
+you attempt to store a reserved value, FriendlyId raises a
+FriendlyId::SlugGenerationError.
+
 
 === Scoped Slugs
 
@@ -208,6 +212,33 @@ that uses a non-Roman writing system, your feedback would be most welcome.
   @post.friendly_id # &quot;&#21451;&#22909;&#32534;&#21495;&#22312;&#20013;&#22269;&quot;
   @post2 = Post.create(:title =&gt; &quot;&#21451;&#22909;&#32534;&#21495;&#22312;&#20013;&#22269;&quot;)
   @post2.friendly_id # &quot;&#21451;&#22909;&#32534;&#21495;&#22312;&#20013;&#22269;--2&quot;
+  
+=== Custom Slug Generation
+
+While FriendlyId's slug generation options work for most people, you may need
+something else. As of version 2.0.4 you can pass in your own custom slug
+generation block:
+
+  require 'stringex'
+  class Post &lt; ActiveRecord::Base
+    has_friendly_id :title, :use_slug =&gt; true do |text|
+      # User stringex to generate the friendly_id rather than the baked-in methods
+      text.to_url
+    end
+  end
+  
+  ...
+  
+  @post = Post.create(:title =&gt; &quot;tell your readers &#20320;&#22909;&quot;)
+  @post.friendly_id # &quot;tell-your-readers-ni-hao&quot;
+
+FriendlyId will still respect your settings for max length and reserved words,
+but will use your block rather than the baked-in methods to normalize the
+friendly_id text.
+
+(As an aside, the stringex[http://github.com/rsl/stringex/tree/master] library
+provides some very cool slugging functionality and is a great option for
+apps using FriendlyId in either English or Chinese. Definitely check it out.)
 
 == Getting it
 
@@ -228,7 +259,7 @@ which FriendlyId depends on:
 
 == Setting it up
 
-FriendlyId currently works with Rails 2.0.0 and higher. Here's how to set it up.
+FriendlyId currently works with Rails 2.0.0 - 2.3.0. Here's how to set it up.
 
 1) Install the Gem:
 
@@ -267,7 +298,7 @@ rake:friendly_id:remove_old_slugs MODEL=MyModelName DAYS=60
 
 == Upgrading from an older version
 
-If you installed an older version of FriendlyId and want to upgrade to 2.0,
+If you installed an older version of FriendlyId and want to upgrade to 2.0.x,
 follow these steps:
 
 ==== Install the friendly_id Gem:
@@ -297,8 +328,6 @@ Add this to the bottom of environment.rb:
   ./script generate friendly_id_20_upgrade
   rake db:migrate
 
-That's it!
-
 == Hacking FriendlyId:
 
 FriendlyId is {hosted on Github}[git://github.com/norman/friendly_id.git], and</diff>
      <filename>README.rdoc</filename>
    </modified>
    <modified>
      <diff>@@ -42,3 +42,11 @@ def run_coverage(files)
   puts cmd
   sh cmd
 end
+
+desc 'Publish RDoc to RubyForge.'
+task :publish_docs =&gt; [:clean, :docs] do
+  host = &quot;compay@rubyforge.org&quot;
+  remote_dir = &quot;/var/www/gforge-projects/friendly-id&quot;
+  local_dir = 'doc'
+  sh %{rsync -av --delete #{local_dir}/ #{host}:#{remote_dir}}
+end
\ No newline at end of file</diff>
      <filename>Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -2,15 +2,15 @@
 
 Gem::Specification.new do |s|
   s.name = %q{friendly_id}
-  s.version = &quot;2.0.3&quot;
+  s.version = &quot;2.0.4&quot;
 
   s.required_rubygems_version = Gem::Requirement.new(&quot;&gt;= 0&quot;) if s.respond_to? :required_rubygems_version=
   s.authors = [&quot;Norman Clarke&quot;, &quot;Adrian Mugnolo&quot;, &quot;Emilio Tagua&quot;]
-  s.date = %q{2009-02-11}
+  s.date = %q{2009-02-12}
   s.description = %q{A comprehensive slugging and pretty-URL plugin for ActiveRecord.}
   s.email = [&quot;norman@randomba.org&quot;, &quot;adrian@randomba.org&quot;, &quot;miloops@gmail.com&quot;]
   s.extra_rdoc_files = [&quot;History.txt&quot;, &quot;Manifest.txt&quot;, &quot;README.rdoc&quot;]
-  s.files = [&quot;History.txt&quot;, &quot;MIT-LICENSE&quot;, &quot;Manifest.txt&quot;, &quot;README.rdoc&quot;, &quot;Rakefile&quot;, &quot;config/website.yml&quot;, &quot;friendly_id.gemspec&quot;, &quot;generators/friendly_id/friendly_id_generator.rb&quot;, &quot;generators/friendly_id/templates/create_slugs.rb&quot;, &quot;generators/friendly_id_20_upgrade/friendly_id_20_upgrade_generator.rb&quot;, &quot;generators/friendly_id_20_upgrade/templates/upgrade_friendly_id_to_20.rb&quot;, &quot;init.rb&quot;, &quot;lib/friendly_id.rb&quot;, &quot;lib/friendly_id/helpers.rb&quot;, &quot;lib/friendly_id/non_sluggable_class_methods.rb&quot;, &quot;lib/friendly_id/non_sluggable_instance_methods.rb&quot;, &quot;lib/friendly_id/slug.rb&quot;, &quot;lib/friendly_id/sluggable_class_methods.rb&quot;, &quot;lib/friendly_id/sluggable_instance_methods.rb&quot;, &quot;lib/friendly_id/version.rb&quot;, &quot;lib/tasks/friendly_id.rake&quot;, &quot;lib/tasks/friendly_id.rb&quot;, &quot;test/models/country.rb&quot;, &quot;test/models/person.rb&quot;, &quot;test/models/post.rb&quot;, &quot;test/models/user.rb&quot;, &quot;test/non_slugged_test.rb&quot;, &quot;test/schema.rb&quot;, &quot;test/scoped_model_test.rb&quot;, &quot;test/slug_test.rb&quot;, &quot;test/slugged_model_test.rb&quot;, &quot;test/test_helper.rb&quot;]
+  s.files = [&quot;History.txt&quot;, &quot;MIT-LICENSE&quot;, &quot;Manifest.txt&quot;, &quot;README.rdoc&quot;, &quot;Rakefile&quot;, &quot;config/website.yml&quot;, &quot;friendly_id.gemspec&quot;, &quot;generators/friendly_id/friendly_id_generator.rb&quot;, &quot;generators/friendly_id/templates/create_slugs.rb&quot;, &quot;generators/friendly_id_20_upgrade/friendly_id_20_upgrade_generator.rb&quot;, &quot;generators/friendly_id_20_upgrade/templates/upgrade_friendly_id_to_20.rb&quot;, &quot;init.rb&quot;, &quot;lib/friendly_id.rb&quot;, &quot;lib/friendly_id/helpers.rb&quot;, &quot;lib/friendly_id/non_sluggable_class_methods.rb&quot;, &quot;lib/friendly_id/non_sluggable_instance_methods.rb&quot;, &quot;lib/friendly_id/slug.rb&quot;, &quot;lib/friendly_id/sluggable_class_methods.rb&quot;, &quot;lib/friendly_id/sluggable_instance_methods.rb&quot;, &quot;lib/friendly_id/version.rb&quot;, &quot;lib/tasks/friendly_id.rake&quot;, &quot;lib/tasks/friendly_id.rb&quot;, &quot;test/custom_slug_normalizer_test.rb&quot;, &quot;test/models/book.rb&quot;, &quot;test/models/country.rb&quot;, &quot;test/models/novel.rb&quot;, &quot;test/models/person.rb&quot;, &quot;test/models/post.rb&quot;, &quot;test/models/thing.rb&quot;, &quot;test/models/user.rb&quot;, &quot;test/non_slugged_test.rb&quot;, &quot;test/schema.rb&quot;, &quot;test/scoped_model_test.rb&quot;, &quot;test/slug_test.rb&quot;, &quot;test/slugged_model_test.rb&quot;, &quot;test/sti_test.rb&quot;, &quot;test/test_helper.rb&quot;]
   s.has_rdoc = true
   s.homepage = %q{http://friendly-id.rubyforge.org/}
   s.rdoc_options = [&quot;--main&quot;, &quot;README.rdoc&quot;]
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
   s.rubyforge_project = %q{friendly-id}
   s.rubygems_version = %q{1.3.1}
   s.summary = %q{A comprehensive slugging and pretty-URL plugin for ActiveRecord.}
-  s.test_files = [&quot;test/non_slugged_test.rb&quot;, &quot;test/scoped_model_test.rb&quot;, &quot;test/slug_test.rb&quot;, &quot;test/slugged_model_test.rb&quot;]
+  s.test_files = [&quot;test/custom_slug_normalizer_test.rb&quot;, &quot;test/non_slugged_test.rb&quot;, &quot;test/scoped_model_test.rb&quot;, &quot;test/slug_test.rb&quot;, &quot;test/slugged_model_test.rb&quot;, &quot;test/sti_test.rb&quot;]
 
   if s.respond_to? :specification_version then
     current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION</diff>
      <filename>friendly_id.gemspec</filename>
    </modified>
    <modified>
      <diff>@@ -14,7 +14,7 @@ module FriendlyId
     :strip_diacritics =&gt; false,
     :strip_non_ascii =&gt; false,
     :use_slug =&gt; false }.freeze
-  
+
   # Valid keys for has_friendly_id options.
   VALID_FRIENDLY_ID_KEYS = [
     :max_length,
@@ -24,7 +24,7 @@ module FriendlyId
     :strip_diacritics,
     :strip_non_ascii,
     :use_slug ].freeze
-    
+
   # This error is raised when it's not possible to generate a unique slug.
   class SlugGenerationError &lt; StandardError ; end
 
@@ -42,11 +42,12 @@ module FriendlyId
     # * &lt;tt&gt;:strip_non_ascii&lt;/tt&gt; - Defaults to false. If true, it will all non-ascii ([^a-z0-9]) characters.
     # * &lt;tt&gt;:reserved&lt;/tt&gt; - 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 [&quot;new&quot;, &quot;index&quot;].
     # * &lt;tt&gt;:reserved_message&lt;/tt&gt; - The validation message that will be shown when a reserved word is used as a frindly_id. Defaults to '&quot;%s&quot; is reserved'.
-    def has_friendly_id(column, options = {})
+    def has_friendly_id(column, options = {}, &amp;block)
       options.assert_valid_keys VALID_FRIENDLY_ID_KEYS
       options = DEFAULT_FRIENDLY_ID_OPTIONS.merge(options).merge(:column =&gt; column)
       write_inheritable_attribute :friendly_id_options, options
       class_inheritable_accessor :friendly_id_options
+      class_inheritable_reader :slug_normalizer_block
 
       if options[:use_slug]
         has_many :slugs, :order =&gt; 'id DESC', :as =&gt; :sluggable, :dependent =&gt; :destroy
@@ -55,6 +56,9 @@ module FriendlyId
         extend SluggableClassMethods
         include SluggableInstanceMethods
         before_save :set_slug
+        if block_given?
+          write_inheritable_attribute :slug_normalizer_block, block
+        end
       else
         require 'friendly_id/non_sluggable_class_methods'
         require 'friendly_id/non_sluggable_instance_methods'
@@ -63,7 +67,7 @@ module FriendlyId
         validate_on_create :validate_friendly_id
       end
     end
-    
+
   end
 
   class &lt;&lt; self</diff>
      <filename>lib/friendly_id.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,7 +1,7 @@
 module FriendlyId::SluggableClassMethods
 
   include FriendlyId::Helpers
-
+  
   def self.extended(base) #:nodoc:#
 
     class &lt;&lt; base</diff>
      <filename>lib/friendly_id/sluggable_class_methods.rb</filename>
    </modified>
    <modified>
      <diff>@@ -56,13 +56,17 @@ module FriendlyId::SluggableInstanceMethods
   # Get the processed string used as the basis of the friendly id.
   def slug_text
     base = send friendly_id_options[:column]
-    if self.friendly_id_options[:strip_diacritics]
-      base = Slug::strip_diacritics(base)
-    end
-    if self.friendly_id_options[:strip_non_ascii]
-      base = Slug::strip_non_ascii(base)
+    if self.slug_normalizer_block
+      base = self.slug_normalizer_block.call(base)
+    else
+      if self.friendly_id_options[:strip_diacritics]
+        base = Slug::strip_diacritics(base)
+      end
+      if self.friendly_id_options[:strip_non_ascii]
+        base = Slug::strip_non_ascii(base)
+      end
+      base = Slug::normalize(base)
     end
-    base = Slug::normalize(base)
     
     if base.length &gt; friendly_id_options[:max_length]
       base = base[0...friendly_id_options[:max_length]]</diff>
      <filename>lib/friendly_id/sluggable_instance_methods.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,7 +2,7 @@ module FriendlyId #:nodoc:
   module Version #:nodoc:
     MAJOR = 2
     MINOR = 0
-    TINY = 3
+    TINY = 4
     STRING = [MAJOR, MINOR, TINY].join('.')
   end
 end
\ No newline at end of file</diff>
      <filename>lib/friendly_id/version.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,10 +1,14 @@
 ActiveRecord::Schema.define(:version =&gt; 1) do
-  
+
   create_table &quot;books&quot;, :force =&gt; true do |t|
     t.column &quot;title&quot;, &quot;string&quot;
     t.column &quot;type&quot;, &quot;text&quot;
   end
 
+  create_table &quot;things&quot;, :force =&gt; true do |t|
+    t.column &quot;name&quot;, &quot;string&quot;
+  end
+
   create_table &quot;posts&quot;, :force =&gt; true do |t|
     t.column &quot;title&quot;, &quot;string&quot;
     t.column &quot;content&quot;, &quot;text&quot;
@@ -18,12 +22,12 @@ ActiveRecord::Schema.define(:version =&gt; 1) do
     t.column &quot;created_at&quot;, &quot;datetime&quot;
     t.column &quot;updated_at&quot;, &quot;datetime&quot;
   end
-  
+
   create_table &quot;people&quot;, :force =&gt; true do |t|
     t.column &quot;name&quot;, &quot;string&quot;
     t.column &quot;country_id&quot;, &quot;integer&quot;
   end
-  
+
   create_table &quot;countries&quot;, :force =&gt; true do |t|
     t.column &quot;name&quot;, &quot;string&quot;
   end</diff>
      <filename>test/schema.rb</filename>
    </modified>
    <modified>
      <diff>@@ -18,6 +18,7 @@ require 'models/user'
 require 'models/country'
 require 'models/book'
 require 'models/novel'
+require 'models/thing'
 
 # Borrowed from ActiveSupport
 def silence_stream(stream)</diff>
      <filename>test/test_helper.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>50a75b9f9eec615c2ad6517f4d928d0ba98b5fcf</id>
    </parent>
  </parents>
  <author>
    <name>Norman Clarke</name>
    <email>norman@randomba.org</email>
  </author>
  <url>http://github.com/norman/friendly_id/commit/650e80fa1d992282b0307333664d89b495cbbbb3</url>
  <id>650e80fa1d992282b0307333664d89b495cbbbb3</id>
  <committed-date>2009-02-12T07:18:09-08:00</committed-date>
  <authored-date>2009-02-12T07:18:09-08:00</authored-date>
  <message>Added ability to use custom slug generation code by passing a block parameter
to has_friendly_id. Resolves Lighthouse ticket #20.</message>
  <tree>a4b5138c1846db36562b115a66e083d58d4b20f6</tree>
  <committer>
    <name>Norman Clarke</name>
    <email>norman@randomba.org</email>
  </committer>
</commit>
