simple_slugs 0.0.1
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.
- data/lib/simple_slugs.rb +16 -0
- data/lib/simple_slugs/act_macro.rb +16 -0
- data/lib/simple_slugs/slug.rb +41 -0
- data/lib/simple_slugs/slugger.rb +66 -0
- data/lib/simple_slugs/version.rb +3 -0
- metadata +168 -0
data/lib/simple_slugs.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'active_support/ordered_options'
|
2
|
+
require 'active_support/core_ext/hash/reverse_merge'
|
3
|
+
|
4
|
+
module SimpleSlugs
|
5
|
+
autoload :Slug, 'simple_slugs/slug'
|
6
|
+
autoload :Slugger, 'simple_slugs/slugger'
|
7
|
+
autoload :ActMacro, 'simple_slugs/act_macro'
|
8
|
+
end
|
9
|
+
|
10
|
+
class String
|
11
|
+
def to_slug
|
12
|
+
SimpleSlugs::Slug.new(self)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
ActiveRecord::Base.extend(SimpleSlugs::ActMacro)
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module SimpleSlugs
|
2
|
+
module ActMacro
|
3
|
+
def has_slug(options = {})
|
4
|
+
return if has_slug?
|
5
|
+
|
6
|
+
before_validation lambda { |record| record.slugger.unique_slug!(record) }
|
7
|
+
|
8
|
+
class_inheritable_accessor :slugger
|
9
|
+
self.slugger = Slugger.new(self, options)
|
10
|
+
end
|
11
|
+
|
12
|
+
def has_slug?
|
13
|
+
included_modules.include?(SimpleSlugs)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module SimpleSlugs
|
2
|
+
class Slug < String
|
3
|
+
def initialize(string)
|
4
|
+
super
|
5
|
+
normalize
|
6
|
+
end
|
7
|
+
|
8
|
+
def normalize
|
9
|
+
transliterate
|
10
|
+
spacify
|
11
|
+
strip!
|
12
|
+
downcase!
|
13
|
+
dasherize
|
14
|
+
end
|
15
|
+
|
16
|
+
def transliterate
|
17
|
+
replace(I18n.transliterate(self))
|
18
|
+
end
|
19
|
+
|
20
|
+
def spacify
|
21
|
+
gsub!(/[\W_]/, ' ')
|
22
|
+
end
|
23
|
+
|
24
|
+
def dasherize
|
25
|
+
gsub!(' ', '-')
|
26
|
+
end
|
27
|
+
|
28
|
+
# def normalize(ascii = false)
|
29
|
+
# if ascii
|
30
|
+
# approximate_ascii
|
31
|
+
# to_ascii
|
32
|
+
# end
|
33
|
+
# clean
|
34
|
+
# word_chars
|
35
|
+
# clean
|
36
|
+
# downcase
|
37
|
+
# truncate_bytes(255)
|
38
|
+
# with_dashes
|
39
|
+
# end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module SimpleSlugs
|
2
|
+
class Slugger < ActiveSupport::InheritableOptions
|
3
|
+
DEFAULTS = {
|
4
|
+
:slug_name => :slug,
|
5
|
+
:on_blank => true,
|
6
|
+
:scope => nil,
|
7
|
+
:separator => '-'
|
8
|
+
}
|
9
|
+
|
10
|
+
attr_reader :model
|
11
|
+
|
12
|
+
def initialize(model, options)
|
13
|
+
@model = model
|
14
|
+
super(options.reverse_merge(DEFAULTS))
|
15
|
+
end
|
16
|
+
|
17
|
+
def unique_slug!(record)
|
18
|
+
if record.send(slug_name).blank? || !on_blank
|
19
|
+
source = record.send(self.source)
|
20
|
+
source || raise("can not generate a slug for #{record.inspect} because #{self.source} is #{source.inspect}")
|
21
|
+
record.slug = ensure_unique_slug(record, source.to_slug)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
|
27
|
+
def ensure_unique_slug(record, base)
|
28
|
+
slug, taken, n = base, self.taken_slugs(record, base), 0
|
29
|
+
slug = [base, separator, n += 1].join while taken.include?(slug)
|
30
|
+
slug
|
31
|
+
end
|
32
|
+
|
33
|
+
def taken_slugs(record, slug)
|
34
|
+
scope = translated? ? with_translated_slug(record, slug) : with_slug(record, slug)
|
35
|
+
scope.map(&:slug)
|
36
|
+
end
|
37
|
+
|
38
|
+
def slug_scope(record)
|
39
|
+
scope ? model.where(scope => record.send(scope)) : model.scoped
|
40
|
+
end
|
41
|
+
|
42
|
+
def with_slug(record, slug)
|
43
|
+
condition = model.arel_table[:slug].matches("#{slug}%")
|
44
|
+
slug_scope(record).where(condition)
|
45
|
+
end
|
46
|
+
|
47
|
+
def with_translated_slug(record, slug)
|
48
|
+
condition = model.translation_class.arel_table[:slug].matches("#{slug}%")
|
49
|
+
slug_scope(record) & model.with_translations.where(condition)
|
50
|
+
end
|
51
|
+
|
52
|
+
def source
|
53
|
+
@source ||= self[:source] || %w(name title).detect { |s| column_names.include?(s) }
|
54
|
+
end
|
55
|
+
|
56
|
+
def column_names
|
57
|
+
names = model.column_names
|
58
|
+
names = names + model.translation_class.column_names if model.respond_to?(:translation_class)
|
59
|
+
names
|
60
|
+
end
|
61
|
+
|
62
|
+
def translated?
|
63
|
+
model.translated_attribute_names.include?(:slug) rescue false
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
metadata
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: simple_slugs
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Sven Fuchs
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-08-01 00:00:00 +02:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: active_record
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: active_support
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id002
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: pathname_local
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 3
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
version: "0"
|
61
|
+
type: :development
|
62
|
+
version_requirements: *id003
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: test_declarative
|
65
|
+
prerelease: false
|
66
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
hash: 3
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
version: "0"
|
75
|
+
type: :development
|
76
|
+
version_requirements: *id004
|
77
|
+
- !ruby/object:Gem::Dependency
|
78
|
+
name: database_cleaner
|
79
|
+
prerelease: false
|
80
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
hash: 3
|
86
|
+
segments:
|
87
|
+
- 0
|
88
|
+
version: "0"
|
89
|
+
type: :development
|
90
|
+
version_requirements: *id005
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: i18n
|
93
|
+
prerelease: false
|
94
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
hash: 3
|
100
|
+
segments:
|
101
|
+
- 0
|
102
|
+
version: "0"
|
103
|
+
type: :development
|
104
|
+
version_requirements: *id006
|
105
|
+
- !ruby/object:Gem::Dependency
|
106
|
+
name: globalize3
|
107
|
+
prerelease: false
|
108
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
109
|
+
none: false
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
hash: 3
|
114
|
+
segments:
|
115
|
+
- 0
|
116
|
+
version: "0"
|
117
|
+
type: :development
|
118
|
+
version_requirements: *id007
|
119
|
+
description: Simple slugs for ActiveRecord.
|
120
|
+
email: svenfuchs@artweb-design.de
|
121
|
+
executables: []
|
122
|
+
|
123
|
+
extensions: []
|
124
|
+
|
125
|
+
extra_rdoc_files: []
|
126
|
+
|
127
|
+
files:
|
128
|
+
- lib/simple_slugs.rb
|
129
|
+
- lib/simple_slugs/act_macro.rb
|
130
|
+
- lib/simple_slugs/slug.rb
|
131
|
+
- lib/simple_slugs/slugger.rb
|
132
|
+
- lib/simple_slugs/version.rb
|
133
|
+
has_rdoc: true
|
134
|
+
homepage: http://github.com/svenfuchs/simple_slugs
|
135
|
+
licenses: []
|
136
|
+
|
137
|
+
post_install_message:
|
138
|
+
rdoc_options: []
|
139
|
+
|
140
|
+
require_paths:
|
141
|
+
- lib
|
142
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
143
|
+
none: false
|
144
|
+
requirements:
|
145
|
+
- - ">="
|
146
|
+
- !ruby/object:Gem::Version
|
147
|
+
hash: 3
|
148
|
+
segments:
|
149
|
+
- 0
|
150
|
+
version: "0"
|
151
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
152
|
+
none: false
|
153
|
+
requirements:
|
154
|
+
- - ">="
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
hash: 3
|
157
|
+
segments:
|
158
|
+
- 0
|
159
|
+
version: "0"
|
160
|
+
requirements: []
|
161
|
+
|
162
|
+
rubyforge_project: "[none]"
|
163
|
+
rubygems_version: 1.3.7
|
164
|
+
signing_key:
|
165
|
+
specification_version: 3
|
166
|
+
summary: Simple slugs for ActiveRecord
|
167
|
+
test_files: []
|
168
|
+
|