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.
@@ -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
+