gastropod 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2013 James Cook
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,60 @@
1
+ # gastropod
2
+
3
+ Simple library for generating slugs
4
+
5
+ ![gastropod](http://i.imgur.com/5UhkBfI.jpg)
6
+
7
+ ## Install
8
+
9
+ 1. Update your Gemfile: `gem 'gastropod'`
10
+ 2. Add a 'slug' column to your table.
11
+ 3. Extend gastropod in your model
12
+ 4. Call `assign_generated_slug` to generate a slug
13
+
14
+ ## ActiveRecord Example
15
+
16
+ class Product < ActiveRecord::Base
17
+ extend Gastropod
18
+ include Gastropod::ActiveRecord::Validations # Roll your own for other ORMs
19
+
20
+ # Method to generate a slug against
21
+ slug :name
22
+ end
23
+
24
+ ## Sequel Example
25
+
26
+ DB = Sequel.connect('sqlite://db/sequel.db')
27
+
28
+ DB.create_table? :fruits do
29
+ primary_key :id
30
+ String :name
31
+ String :slug
32
+ end
33
+
34
+ class Fruit < Sequel::Model
35
+ extend Gastropod
36
+
37
+ slug :name
38
+
39
+ def before_save
40
+ assign_generated_slug
41
+ end
42
+ end
43
+
44
+ ## Customisation
45
+
46
+ If you aren't using ActiveRecord, you will likely want to override the class method 'slug_finder'
47
+
48
+ ## Contributing
49
+
50
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
51
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
52
+ * Fork the project.
53
+ * Start a feature/bugfix branch.
54
+ * Commit and push until you are happy with your contribution.
55
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
56
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
57
+
58
+ ## Copyright
59
+
60
+ Copyright (c) 2013 James Cook & Patrick Reagan (Viget). See MIT_LICENSE for further details.
data/gastropod.gemspec ADDED
@@ -0,0 +1,19 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+
3
+ require "gastropod/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "gastropod"
7
+ s.version = Gastropod::VERSION
8
+ s.authors = ["James Cook", "Patrick Reagan"]
9
+ s.email = ["james.cook@viget.com"]
10
+ s.homepage = "https://github.com/vigetlabs/gastropod"
11
+ s.summary = s.description = "Simple library for generating slugs"
12
+
13
+ s.files = Dir["lib/**/*"] + %w(MIT-LICENSE README.md gastropod.gemspec)
14
+ s.test_files = Dir["spec/**/*"]
15
+
16
+ s.add_development_dependency "activerecord", "~> 3.1"
17
+ s.add_development_dependency "sqlite3"
18
+ s.add_development_dependency 'rspec'
19
+ end
data/lib/gastropod.rb ADDED
@@ -0,0 +1,56 @@
1
+ require "gastropod/active_record/validations" if Object.const_defined? "ActiveRecord"
2
+
3
+ module Gastropod
4
+ def self.extended(base)
5
+ base.send(:instance_variable_set, "@slug_source_attribute", "name")
6
+ base.send(:include, InstanceMethods)
7
+ end
8
+
9
+ def slug(attribute)
10
+ instance_variable_set("@slug_source_attribute", attribute)
11
+ end
12
+
13
+ def slug_source_attribute
14
+ @slug_source_attribute
15
+ end
16
+
17
+ def slug_finder
18
+ instance_variable_defined?("@slug_finder") ? @slug_finder : default_slug_finder
19
+ end
20
+
21
+ def default_slug_finder
22
+ lambda {|value| where(:slug => value) }
23
+ end
24
+
25
+ module InstanceMethods
26
+
27
+ def assign_generated_slug
28
+ self.slug = next_available_slug if generate_slug?
29
+ end
30
+
31
+ private
32
+
33
+ def slug_source
34
+ send self.class.slug_source_attribute
35
+ end
36
+
37
+ def slug_from_source
38
+ slug_source.to_s.downcase.gsub(/[^a-zA-Z0-9\-_]+/, '-')
39
+ end
40
+
41
+ def generate_slug?
42
+ slug_source.present? && slug.blank?
43
+ end
44
+
45
+ def next_available_slug
46
+ possible_slug = slug_from_source
47
+
48
+ index = 2
49
+ while self.class.slug_finder.call(possible_slug).any?
50
+ possible_slug = slug_from_source + "-#{index}"
51
+ index+= 1
52
+ end
53
+ possible_slug
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,13 @@
1
+ module Gastropod
2
+ module ActiveRecord
3
+ module Validations
4
+ def self.included(base)
5
+ base.validates :slug, :uniqueness => true
6
+ base.validates :slug, :format => { :with => /^[a-z0-9-]+$/, :allow_blank => true }
7
+ base.validates :slug, :presence => true
8
+
9
+ base.before_validation :assign_generated_slug, :if => :generate_slug?
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ module Gastropod
2
+ VERSION = "0.1.0"
3
+ end
Binary file
Binary file
data/spec/db/sequel.db ADDED
Binary file
@@ -0,0 +1,8 @@
1
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => "spec/db/activerecord.db")
2
+
3
+ class Product < ActiveRecord::Base
4
+ extend Gastropod
5
+ include Gastropod::ActiveRecord::Validations
6
+
7
+ slug :name
8
+ end
@@ -0,0 +1,19 @@
1
+ require "spec_helper"
2
+ require "fixtures/product"
3
+
4
+ Product.connection.execute "DROP TABLE IF EXISTS products;"
5
+ Product.connection.execute "CREATE TABLE products (id INTEGER PRIMARY KEY , name VARCHAR(255), slug VARCHAR(255));"
6
+
7
+ describe Gastropod do
8
+ it "can create a slug" do
9
+ product = Product.create!(:name => "HELLO WORLD")
10
+ product.slug.should == "hello-world"
11
+ end
12
+
13
+ it "can handle creating a unique slug" do
14
+ product1 = Product.create!(:name => "jimmy boy")
15
+ product2 = Product.create!(:name => "jimmy boy")
16
+
17
+ product2.slug.should == "jimmy-boy-2"
18
+ end
19
+ end
@@ -0,0 +1,2 @@
1
+ require "active_record"
2
+ require "gastropod"
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gastropod
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - James Cook
9
+ - Patrick Reagan
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2013-03-22 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activerecord
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: '3.1'
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ version: '3.1'
31
+ - !ruby/object:Gem::Dependency
32
+ name: sqlite3
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ type: :development
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ description: Simple library for generating slugs
64
+ email:
65
+ - james.cook@viget.com
66
+ executables: []
67
+ extensions: []
68
+ extra_rdoc_files: []
69
+ files:
70
+ - lib/gastropod/active_record/validations.rb
71
+ - lib/gastropod/version.rb
72
+ - lib/gastropod.rb
73
+ - MIT-LICENSE
74
+ - README.md
75
+ - gastropod.gemspec
76
+ - spec/db/activerecord.db
77
+ - spec/db/fixtures.sqlite3
78
+ - spec/db/sequel.db
79
+ - spec/fixtures/product.rb
80
+ - spec/lib/gastropod_spec.rb
81
+ - spec/spec_helper.rb
82
+ homepage: https://github.com/vigetlabs/gastropod
83
+ licenses: []
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ! '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ requirements: []
101
+ rubyforge_project:
102
+ rubygems_version: 1.8.23
103
+ signing_key:
104
+ specification_version: 3
105
+ summary: Simple library for generating slugs
106
+ test_files:
107
+ - spec/db/activerecord.db
108
+ - spec/db/fixtures.sqlite3
109
+ - spec/db/sequel.db
110
+ - spec/fixtures/product.rb
111
+ - spec/lib/gastropod_spec.rb
112
+ - spec/spec_helper.rb