simple_slugs 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,3 @@
1
+ module SimpleSlugs
2
+ VERSION = "0.0.1"
3
+ 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
+