wulffeld_slug 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/README ADDED
File without changes
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "wulffeld_slug"
8
+ gem.summary = "Slug generation."
9
+ gem.description = ""
10
+ gem.email = "martin@wulffeld.org"
11
+ gem.homepage = "http://www.wulffeld.org/"
12
+ gem.authors = ["Martin Moen Wulffeld"]
13
+ end
14
+ Jeweler::GemcutterTasks.new
15
+ rescue LoadError
16
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
17
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,16 @@
1
+ module WulffeldMisc
2
+ module Slug
3
+ def has_slug(fields, options = {})
4
+ class_attribute :slug_config
5
+ self.slug_config = options.merge(:fields => fields)
6
+
7
+ include WulffeldMisc::SlugInclude
8
+ end
9
+ end
10
+ end
11
+
12
+ module ActiveRecord
13
+ class Base
14
+ extend WulffeldMisc::Slug
15
+ end
16
+ end
@@ -0,0 +1,138 @@
1
+ module WulffeldMisc
2
+ module SlugInclude
3
+ def self.included(base)
4
+ base.class_eval do
5
+ if self.slug_config[:mongo]
6
+ field :slug
7
+ end
8
+
9
+ validates_presence_of :slug
10
+
11
+ before_validation :on => :create do
12
+ cb_make_slug
13
+ end
14
+ end
15
+ end
16
+
17
+ def to_param
18
+ slug
19
+ end
20
+
21
+ # Can override this.
22
+ def slug_unique?(slug)
23
+ !self.class.where(:slug => slug).first
24
+ end
25
+
26
+ def cb_make_slug
27
+ a = [*send(slug_config[:fields])].compact.map {|f| f.is_a?(String) ? f : send(f) }.flatten
28
+ return if a.blank?
29
+ self.slug = to_unique_slug(a.join('-')) if slug.blank?
30
+ end
31
+
32
+ def to_unique_slug(s, n=nil)
33
+ loop do
34
+ slug = to_slug([s,n].compact.join('-'))
35
+ return slug if slug_unique?(slug)
36
+
37
+ # First loop we do some optimistic searching.
38
+ if n.nil?
39
+ b = 512
40
+ last_b = nil
41
+ loop do
42
+ slug = to_slug([s, b].compact.join('-'))
43
+ if slug_unique?(slug) || b < 1
44
+ last_b = b
45
+ break if b < 1
46
+ else
47
+ n = last_b
48
+ break
49
+ end
50
+
51
+ b /= 2
52
+ end
53
+ end
54
+ n ||= 0
55
+ n += 1
56
+ end
57
+ end
58
+
59
+ # Use dashes.
60
+ # http://www.mattcutts.com/blog/dashes-vs-underscores/
61
+ def to_slug(s)
62
+ s.strip!
63
+
64
+ # Blow away apostrophes
65
+ s.gsub! /['`]/,""
66
+
67
+ orig = s
68
+
69
+ # @ --> at, and & --> and
70
+ s.gsub! /\s*@\s*/, " at "
71
+ s.gsub! /\s*&\s*/, " and "
72
+
73
+ [
74
+ [/[+]/, 'plus'],
75
+ [/[ÀÁÂÃÅĀĂĄǍ]/, 'A'],
76
+ [/[āăąàáâãǎ]/, 'a'],
77
+ [/[ĆĈĊČÇ]/, 'C'],
78
+ [/[ćĉċčç]/, 'c'],
79
+ [/[ĎĐ]/, 'D'],
80
+ [/[ďđ]/, 'd'],
81
+ [/[ĒĔĖĘĚÈÉÊË]/, 'E'],
82
+ [/[èéêëēĕėęě]/, 'e'],
83
+ [/[ĜĞĠĢǤǦǴ]/, 'G'],
84
+ [/[ĝğġģǥǧ]/, 'g'],
85
+ [/[Ĥ]/, 'H'],
86
+ [/[ĥĦħ]/, 'h'],
87
+ [/[ĨĪĬĮİǏÌÍÎÏ]/, 'I'],
88
+ [/[ĩīĭįıǐìíîï]/, 'i'],
89
+ [/[Ĵ]/, 'J'],
90
+ [/[ĵ]/, 'j'],
91
+ [/[ĶǨК]/, 'K'],
92
+ [/[ķĸǩ]/, 'k'],
93
+ [/[ĹĻĽĿŁ]/, 'L'],
94
+ [/[ĺļľŀł]/, 'l'],
95
+ [/[ŃŅŇŊÑǸП]/, 'N'],
96
+ [/[ńņňʼnŋñǹ]/, 'n'],
97
+ [/[ŌŎŐǑÒÓÔÕÖ]/, 'O'],
98
+ [/[ōŏőǒðòóôõ]/, 'o'],
99
+ [/[ŔŖŘ]/, 'R'],
100
+ [/[ŕŗř]/, 'r'],
101
+ [/[ŚŜŞŠ]/, 'S'],
102
+ [/[śŝşš]/, 's'],
103
+ [/[ŢŤŦ]/, 'T'],
104
+ [/[ţťŧ]/, 't'],
105
+ [/[ŨŪŬŮŰŲÙÚÛÜ]/, 'U'],
106
+ [/[ũūŭůűųùúûü]/, 'u'],
107
+ [/[Ŵ]/, 'W'],
108
+ [/[ŵ]/, 'w'],
109
+ [/[ŶŸÝ]/, 'Y'],
110
+ [/[ýÿŷ]/, 'y'],
111
+ [/[ŹŻŽ]/, 'Z'],
112
+ [/[źżž]/, 'z'],
113
+ [/[ǓǕǗǙǛ]/, 'U'],
114
+ [/[ǔǖǘǚǜ]/, 'u'],
115
+ [/[ǢÆǼ]/, 'AE'],
116
+ [/[ǣäæǽ]/, 'ae'],
117
+ [/[ØǾ]/, 'OE'],
118
+ [/[øǿö]/, 'oe'],
119
+ [/[ÄÅ]/, 'AA'],
120
+ [/[å]/, 'aa'],
121
+ [/[ǪǬ]/, 'O'],
122
+ [/[ǫǭ]/, 'o'],
123
+ [/[^a-zA-Z0-9]+/i, '-']
124
+ ].each do |regex, ch|
125
+ s.gsub! regex, ch
126
+ end
127
+
128
+ s.strip!
129
+ s = s.split('-').each { |word| word.sub!(/^[a-z]/) {|m| m.tr('a-z', 'A-Z')} }.join('-')
130
+ new_slug = s.blank? ? orig : s
131
+ if new_slug.length > 200
132
+ new_slug = new_slug[0..199]
133
+ else
134
+ new_slug
135
+ end
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,2 @@
1
+ require 'wulffeld_slug/slug'
2
+ require 'wulffeld_slug/slug_include'
@@ -0,0 +1,41 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{wulffeld_slug}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Martin Moen Wulffeld"]
12
+ s.date = %q{2011-04-23}
13
+ s.description = %q{}
14
+ s.email = %q{martin@wulffeld.org}
15
+ s.extra_rdoc_files = [
16
+ "README"
17
+ ]
18
+ s.files = [
19
+ "README",
20
+ "Rakefile",
21
+ "VERSION",
22
+ "lib/wulffeld_slug.rb",
23
+ "lib/wulffeld_slug/slug.rb",
24
+ "lib/wulffeld_slug/slug_include.rb",
25
+ "wulffeld_slug.gemspec"
26
+ ]
27
+ s.homepage = %q{http://www.wulffeld.org/}
28
+ s.require_paths = ["lib"]
29
+ s.rubygems_version = %q{1.5.0}
30
+ s.summary = %q{Slug generation.}
31
+
32
+ if s.respond_to? :specification_version then
33
+ s.specification_version = 3
34
+
35
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
36
+ else
37
+ end
38
+ else
39
+ end
40
+ end
41
+
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wulffeld_slug
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Martin Moen Wulffeld
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-04-23 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: ""
23
+ email: martin@wulffeld.org
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files:
29
+ - README
30
+ files:
31
+ - README
32
+ - Rakefile
33
+ - VERSION
34
+ - lib/wulffeld_slug.rb
35
+ - lib/wulffeld_slug/slug.rb
36
+ - lib/wulffeld_slug/slug_include.rb
37
+ - wulffeld_slug.gemspec
38
+ has_rdoc: true
39
+ homepage: http://www.wulffeld.org/
40
+ licenses: []
41
+
42
+ post_install_message:
43
+ rdoc_options: []
44
+
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ hash: 3
53
+ segments:
54
+ - 0
55
+ version: "0"
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 3
62
+ segments:
63
+ - 0
64
+ version: "0"
65
+ requirements: []
66
+
67
+ rubyforge_project:
68
+ rubygems_version: 1.5.0
69
+ signing_key:
70
+ specification_version: 3
71
+ summary: Slug generation.
72
+ test_files: []
73
+