friendly_id4 4.0.0.beta6 → 4.0.0.pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,31 +0,0 @@
1
- # encoding: utf-8
2
- $:.push File.expand_path("../lib", __FILE__)
3
-
4
- require "friendly_id"
5
-
6
- Gem::Specification.new do |s|
7
- s.name = "friendly_id4"
8
- s.version = FriendlyId::VERSION
9
- s.authors = ["Norman Clarke"]
10
- s.email = ["norman@njclarke.com"]
11
- s.homepage = "http://norman.github.com/friendly_id"
12
- s.summary = "A comprehensive slugging and pretty-URL plugin."
13
- s.rubyforge_project = "friendly_id"
14
- s.files = `git ls-files`.split("\n")
15
- s.test_files = `git ls-files -- {test}/*`.split("\n")
16
- s.require_paths = ["lib"]
17
-
18
- s.add_development_dependency "activerecord", "~> 3.0"
19
- s.add_development_dependency "sqlite3", "~> 1.3"
20
- s.add_development_dependency "cutest", "~> 1.1.2"
21
- s.add_development_dependency "ffaker"
22
- s.add_development_dependency "maruku"
23
- s.add_development_dependency "yard"
24
- s.add_development_dependency "mocha"
25
-
26
- s.description = <<-EOM
27
- FriendlyId is the "Swiss Army bulldozer" of slugging and permalink plugins
28
- for Ruby on Rails. It allows you to create pretty URL's and work with
29
- human-friendly strings as if they were numeric ids for ActiveRecord models.
30
- EOM
31
- end
@@ -1,134 +0,0 @@
1
- module FriendlyId
2
- # Class methods that will be added to model classes that extend {FriendlyId}.
3
- module Base
4
-
5
- # Configure FriendlyId's behavior in a model.
6
- #
7
- # class Post < ActiveRecord::Base
8
- # extend FriendlyId
9
- # friendly_id :title, :use => :slugged
10
- # end
11
- #
12
- # When given the optional block, this method will yield the class's instance
13
- # of {FriendlyId::Configuration} to the block before evaluating other
14
- # arguments, so configuration values set in the block may be overwritten by
15
- # the arguments. This order was chosen to allow passing the same proc to
16
- # multiple models, while being able to override the values it sets. Here is
17
- # a contrived example:
18
- #
19
- # $friendly_id_config_proc = Proc.new do |config|
20
- # config.base = :name
21
- # config.use :slugged
22
- # end
23
- #
24
- # class Foo < ActiveRecord::Base
25
- # extend FriendlyId
26
- # friendly_id &$friendly_id_config_proc
27
- # end
28
- #
29
- # class Bar < ActiveRecord::Base
30
- # extend FriendlyId
31
- # friendly_id :title, &$friendly_id_config_proc
32
- # end
33
- #
34
- # However, it's usually better to use {FriendlyId.defaults} for this:
35
- #
36
- # FriendlyId.defaults do |config|
37
- # config.base = :name
38
- # config.use :slugged
39
- # end
40
- #
41
- # class Foo < ActiveRecord::Base
42
- # extend FriendlyId
43
- # end
44
- #
45
- # class Bar < ActiveRecord::Base
46
- # extend FriendlyId
47
- # friendly_id :title
48
- # end
49
- #
50
- # In general you should use the block syntax either because of your personal
51
- # aesthetic preference, or because you need to share some functionality
52
- # between multiple models that can't be well encapsulated by
53
- # {FriendlyId.defaults}.
54
- #
55
- # === Order Method Calls in a Block vs Ordering Options
56
- #
57
- # When calling this method without a block, you may set the hash options in
58
- # any order.
59
- #
60
- # However, when using block-style invocation, be sure to call
61
- # FriendlyId::Configuration's {FriendlyId::Configuration#use use} method
62
- # *prior* to the associated configuration options, because it will include
63
- # modules into your class, and these modules in turn may add required
64
- # configuration options to the +@friendly_id_configuraton+'s class:
65
- #
66
- # class Person < ActiveRecord::Base
67
- # friendly_id do |config|
68
- # # This will work
69
- # config.use :slugged
70
- # config.sequence_separator = ":"
71
- # end
72
- # end
73
- #
74
- # class Person < ActiveRecord::Base
75
- # friendly_id do |config|
76
- # # This will fail
77
- # config.sequence_separator = ":"
78
- # config.use :slugged
79
- # end
80
- # end
81
- #
82
- # @option options [Symbol] :use The name of an addon to use. By default,
83
- # FriendlyId provides {FriendlyId::Slugged :slugged},
84
- # {FriendlyId::History :history}, {FriendlyId::Reserved :reserved}, and
85
- # {FriendlyId::Scoped :scoped}.
86
- #
87
- # @option options [Array] :reserved_words Available when using +:reserved+,
88
- # which is loaded by default. Sets an array of words banned for use as
89
- # the basis of a friendly_id. By default this includes "edit" and "new".
90
- #
91
- # @option options [Symbol] :scope Available when using +:scoped+.
92
- # Sets the relation or column used to scope generated friendly ids. This
93
- # option has no default value.
94
- #
95
- # @option options [Symbol] :sequence_separator Available when using +:slugged+.
96
- # Configures the sequence of characters used to separate a slug from a
97
- # sequence. Defaults to +--+.
98
- #
99
- # @option options [Symbol] :slug_column Available when using +:slugged+.
100
- # Configures the name of the column where FriendlyId will store the slug.
101
- # Defaults to +:slug+.
102
- #
103
- # @option options [Symbol] :slug_sequencer_class Available when using +:slugged+.
104
- # Sets the class used to generate unique slugs. You should not specify this
105
- # unless you're doing some extensive hacking on FriendlyId. Defaults to
106
- # {FriendlyId::SlugSequencer}.
107
- #
108
- # @yield Provides access to the model class's friendly_id_config, which
109
- # allows an alternate configuration syntax, and conditional configuration
110
- # logic.
111
- #
112
- # @yieldparam config The model class's {FriendlyId::Configuration friendly_id_config}.
113
- def friendly_id(base = nil, options = {}, &block)
114
- yield @friendly_id_config if block_given?
115
- @friendly_id_config.use options.delete :use
116
- @friendly_id_config.send :set, base ? options.merge(:base => base) : options
117
- before_save do |record|
118
- record.instance_eval {@current_friendly_id = friendly_id}
119
- end
120
- include Model
121
- end
122
-
123
- # Returns the model class's {FriendlyId::Configuration friendly_id_config}.
124
- # @note In the case of Single Table Inheritance (STI), this method will
125
- # duplicate the parent class's FriendlyId::Configuration instance on first
126
- # access. If you're concerned about thread safety, then be sure to invoke
127
- # {#friendly_id} in your class for each model.
128
- def friendly_id_config
129
- @friendly_id_config or begin
130
- @friendly_id_config = base_class.friendly_id_config.dup
131
- end
132
- end
133
- end
134
- end
@@ -1,78 +0,0 @@
1
- module FriendlyId
2
- # The configuration paramters passed to +friendly_id+ will be stored in
3
- # this object.
4
- class Configuration
5
-
6
- # The base column or method used by FriendlyId as the basis of a friendly id
7
- # or slug.
8
- #
9
- # For models that don't use FriendlyId::Slugged, the base is the column that
10
- # is used as the FriendlyId directly. For models using FriendlyId::Slugged,
11
- # the base is a column or method whose value is used as the basis of the
12
- # slug.
13
- #
14
- # For example, if you have a model representing blog posts and that uses
15
- # slugs, you likely will want to use the "title" attribute as the base, and
16
- # FriendlyId will take care of transforming the human-readable title into
17
- # something suitable for use in a URL.
18
- #
19
- # @param [Symbol] A symbol referencing a column or method in the model. This
20
- # value is usually set by passing it as the first argument to
21
- # {FriendlyId::Base#friendly_id friendly_id}:
22
- #
23
- # @example
24
- # class Book < ActiveRecord::Base
25
- # extend FriendlyId
26
- # friendly_id :name
27
- # end
28
- attr_accessor :base
29
-
30
- # The default configuration options.
31
- attr_reader :defaults
32
-
33
- # The model class that this configuration belongs to.
34
- # @return ActiveRecord::Base
35
- attr_reader :model_class
36
-
37
- def initialize(model_class, values = nil)
38
- @model_class = model_class
39
- @defaults = {}
40
- set values
41
- end
42
-
43
- # Lets you specify the modules to use with FriendlyId.
44
- #
45
- # This method is invoked by {FriendlyId::Base#friendly_id friendly_id} when
46
- # passing the +:use+ option, or when using {FriendlyId::Base#friendly_id
47
- # friendly_id} with a block.
48
- #
49
- # @example
50
- # class Book < ActiveRecord::Base
51
- # extend FriendlyId
52
- # friendly_id :name, :use => :slugged
53
- # end
54
- # @param [#to_s] *modules Arguments should be a symbols or strings that
55
- # correspond with the name of a module inside the FriendlyId namespace. By
56
- # default FriendlyId provides +:slugged+, +:history+ and +:scoped+.
57
- def use(*modules)
58
- modules.to_a.flatten.compact.map do |name|
59
- model_class.send :include, FriendlyId.const_get(name.to_s.classify)
60
- end
61
- end
62
-
63
- # The column that FriendlyId will use to find the record when querying by
64
- # friendly id.
65
- #
66
- # This method is generally only used internally by FriendlyId.
67
- # @return String
68
- def query_field
69
- base.to_s
70
- end
71
-
72
- private
73
-
74
- def set(values)
75
- values and values.each {|name, value| self.send "#{name}=", value}
76
- end
77
- end
78
- end
@@ -1,20 +0,0 @@
1
- module FriendlyId
2
- # These methods will override the finder methods in ActiveRecord::Relation.
3
- module FinderMethods
4
-
5
- protected
6
-
7
- # FriendlyId overrides this method to make it possible to use friendly id's
8
- # identically to numeric ids in finders.
9
- #
10
- # @example
11
- # person = Person.find(123)
12
- # person = Person.find("joe")
13
- #
14
- # @see FriendlyId::ObjectUtils
15
- def find_one(id)
16
- return super if !@klass.respond_to?(:friendly_id) || id.unfriendly_id?
17
- where(@klass.friendly_id_config.query_field => id).first or super
18
- end
19
- end
20
- end
@@ -1,64 +0,0 @@
1
- require "friendly_id/slug"
2
-
3
- module FriendlyId
4
-
5
- =begin
6
- FriendlyId can maintain a history of your record's older slugs, so if your
7
- record's friendly_id changes, your URL's won't break.
8
-
9
- class Post < ActiveRecord::Base
10
- extend FriendlyId
11
- friendly_id :title, :use => :history
12
- end
13
-
14
- class PostsController < ApplicationController
15
-
16
- before_filter :find_post
17
-
18
- ...
19
- def find_post
20
- return unless params[:id]
21
- @post = begin
22
- Post.find params[:id]
23
- rescue ActiveRecord::RecordNotFound
24
- Post.find_by_friendly_id params[:id]
25
- end
26
- # If an old id or a numeric id was used to find the record, then
27
- # the request path will not match the post_path, and we should do
28
- # a 301 redirect that uses the current friendly_id
29
- if request.path != post_path(@post)
30
- return redirect_to @post, :status => :moved_permanently
31
- end
32
- end
33
- end
34
- =end
35
- module History
36
-
37
- # Configures the model instance to use the History add-on.
38
- def self.included(klass)
39
- klass.instance_eval do
40
- raise "FriendlyId::History is incompatibe with FriendlyId::Scoped" if self < Scoped
41
- include Slugged unless self < Slugged
42
- has_many :friendly_id_slugs, :as => :sluggable, :dependent => :destroy
43
- before_save :build_friendly_id_slug, :if => lambda {|r| r.slug_sequencer.slug_changed?}
44
- scope :with_friendly_id, lambda {|id| includes(:friendly_id_slugs).where("friendly_id_slugs.slug = ?", id)}
45
- extend Finder
46
- end
47
- end
48
-
49
- private
50
-
51
- def build_friendly_id_slug
52
- self.friendly_id_slugs.build :slug => friendly_id
53
- end
54
- end
55
-
56
- # Adds a finder that explictly uses slugs from the slug table.
57
- module Finder
58
-
59
- # Search for a record in the slugs table using the specified slug.
60
- def find_by_friendly_id(*args)
61
- with_friendly_id(args.shift).first(*args)
62
- end
63
- end
64
- end
@@ -1,18 +0,0 @@
1
- class CreateFriendlyIdSlugs < ActiveRecord::Migration
2
-
3
- def self.up
4
- create_table :friendly_id_slugs do |t|
5
- t.string :slug, :null => false
6
- t.integer :sluggable_id, :null => false
7
- t.string :sluggable_type, :limit => 40
8
- t.datetime :created_at
9
- end
10
- add_index :friendly_id_slugs, :sluggable_id
11
- add_index :friendly_id_slugs, [:slug, :sluggable_type], :unique => true
12
- add_index :friendly_id_slugs, :sluggable_type
13
- end
14
-
15
- def self.down
16
- drop_table :friendly_id_slugs
17
- end
18
- end
@@ -1,22 +0,0 @@
1
- module FriendlyId
2
- # Instance methods that will be added to all classes using FriendlyId.
3
- module Model
4
-
5
- attr_reader :current_friendly_id
6
-
7
- # Convenience method for accessing the class method of the same name.
8
- def friendly_id_config
9
- self.class.friendly_id_config
10
- end
11
-
12
- # Get the instance's friendly_id.
13
- def friendly_id
14
- send friendly_id_config.query_field
15
- end
16
-
17
- # Either the friendly_id, or the numeric id cast to a string.
18
- def to_param
19
- (friendly_id.present? ? friendly_id : id).to_s
20
- end
21
- end
22
- end
@@ -1,40 +0,0 @@
1
- module FriendlyId
2
- # Utility methods for determining whether any object is a friendly id.
3
- #
4
- # Monkey-patching Object is a somewhat extreme measure not to be taken lightly
5
- # by libraries, but in this case I decided to do it because to me, it feels
6
- # cleaner than adding a module method to {FriendlyId}. I've given the methods
7
- # names that unambigously refer to the library of their origin, which should
8
- # be sufficient to avoid conflicts with other libraries.
9
- module ObjectUtils
10
-
11
- # True is the id is definitely friendly, false if definitely unfriendly,
12
- # else nil.
13
- #
14
- # An object is considired "definitely unfriendly" if its class is or
15
- # inherits from Numeric, Symbol or ActiveRecord::Base.
16
- #
17
- # An object is considered "definitely friendly" if it responds to +to_i+,
18
- # and its value when cast to an integer and then back to a string is
19
- # different from its value when merely cast to a string:
20
- #
21
- # 123.friendly_id? #=> false
22
- # "123".friendly_id? #=> nil
23
- # "abc123".friendly_id? #=> true
24
- def friendly_id?
25
- if [Numeric, Symbol, ActiveRecord::Base].detect {|klass| self.class < klass}
26
- false
27
- elsif respond_to?(:to_i) && to_i.to_s != to_s
28
- true
29
- end
30
- end
31
-
32
- # True if the id is definitely unfriendly, false if definitely friendly,
33
- # else nil.
34
- def unfriendly_id?
35
- val = friendly_id? ; !val unless val.nil?
36
- end
37
- end
38
- end
39
-
40
- Object.send :include, FriendlyId::ObjectUtils
@@ -1,46 +0,0 @@
1
- module FriendlyId
2
-
3
- =begin
4
- This module adds the ability to exlude a list of words from use as
5
- FriendlyId slugs.
6
-
7
- By default, FriendlyId reserves the words "new" and "edit" when this module
8
- is included. You can configure this globally by using {FriendlyId.defaults FriendlyId.defaults}:
9
-
10
- FriendlyId.defaults do |config|
11
- config.use :reserved
12
- # Reserve words for English and Spanish URLs
13
- config.reserved_words = %w(new edit nueva nuevo editar)
14
- end
15
- =end
16
- module Reserved
17
-
18
- # When included, this module adds configuration options to the model class's
19
- # friendly_id_config.
20
- def self.included(model_class)
21
- model_class.class_eval do
22
- friendly_id_config.class.send :include, Reserved::Configuration
23
- friendly_id_config.defaults[:reserved_words] ||= ["new", "edit"]
24
- end
25
- end
26
-
27
- # This module adds the +:reserved_words+ configuration option to
28
- # {FriendlyId::Configuration FriendlyId::Configuration}.
29
- module Configuration
30
- attr_writer :reserved_words
31
-
32
- # Overrides {FriendlyId::Configuration#base} to add a validation to the
33
- # model class.
34
- def base=(base)
35
- super
36
- reserved_words = model_class.friendly_id_config.reserved_words
37
- model_class.validates_exclusion_of base, :in => reserved_words
38
- end
39
-
40
- # An array of words forbidden as slugs.
41
- def reserved_words
42
- @reserved_words ||= @defaults[:reserved_words]
43
- end
44
- end
45
- end
46
- end