slugger 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/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in slugger.gemspec
4
+ gemspec
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Seth Faxon
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,43 @@
1
+ = Slugger
2
+
3
+ Slugger is yet another slug generator. It makes pretty urls for Active Record models. It jumps through some hoops to make sure every slug is unique.
4
+
5
+ == Installation
6
+
7
+ It's a gem. Either run `gem install slugger` at the command line, or add `gem 'slugger'` to your Gemfile.
8
+
9
+ == Usage
10
+
11
+ has_slug :source_column, [options]
12
+
13
+ The default source column is title.
14
+
15
+ :source_column can also be an array, for example, if you wanted to create slugs for an Author model on first and last name:
16
+
17
+ has_slug [:first_name, :last_name]
18
+
19
+ == Options
20
+
21
+ Say you have an Episode model that belongs to TVSeries. Every episode will have a pilot, but you don't want the unique validation to build silly looking urls:
22
+
23
+ class Episode << ActiveRecord::Base
24
+ belongs_to :series
25
+
26
+ has_slug :title, :scope => :series_id
27
+ end
28
+
29
+
30
+ == Example
31
+
32
+ create_table "collection" do |t|
33
+ t.string "title"
34
+ t.string "slug"
35
+ end
36
+
37
+ class Project < ActiveRecord::Base
38
+ has_slug
39
+ end
40
+
41
+ Collection.create(:title => 'Quick foxes jumping')
42
+ Collection.first.slug => 'quick-foxes-jumping'
43
+
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
4
+
5
+ task :default => :spec
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,3 @@
1
+ module Slugger
2
+ VERSION = File.read(File.dirname(__FILE__) + "/../../VERSION").chomp
3
+ end
data/lib/slugger.rb ADDED
@@ -0,0 +1,81 @@
1
+ require 'slugger/version'
2
+ require 'active_record'
3
+ require 'iconv'
4
+
5
+ module Slugger
6
+ def self.included(base)
7
+ base.extend(ClassMethods)
8
+ end
9
+ module ClassMethods
10
+ def acts_as_sluggable(title_column=nil,sluger_options={})
11
+ class_inheritable_accessor :sluger_options
12
+ sluger_options[:title_column] ||= title_column || 'title'
13
+ # sluger_options[:title_column] ||= 'title'
14
+ sluger_options[:slug_column] ||= 'slug'
15
+ sluger_options[:as_param] ||= true
16
+ sluger_options[:substitution_char] ||= '-'
17
+ self.sluger_options = sluger_options
18
+
19
+ # if columns_hash[sluger_options[:title_column].to_s].nil?
20
+ #
21
+ # raise ArgumentError, "#{self.name} is missing source column"
22
+ # end
23
+ raise ArgumentError, "#{self.name} is missing required slug column" if columns_hash[sluger_options[:slug_column]].nil?
24
+
25
+ before_validation :create_slug, :on => :create
26
+
27
+ validates sluger_options[:slug_column].to_sym, :presence => true
28
+ if sluger_options[:scope]
29
+ validates sluger_options[:slug_column].to_sym, :uniqueness => {:scope => sluger_options[:scope]}
30
+ else
31
+ validates sluger_options[:slug_column].to_sym, :uniqueness => true
32
+ end
33
+
34
+ send :define_method, :column_to_slug, lambda { self.send(sluger_options[:title_column]) }
35
+
36
+ class << self
37
+ def find(*args)
38
+ if self.sluger_options[:as_param] && args.first.is_a?(String)
39
+ find_by_slug(args)
40
+ else
41
+ super(*args)
42
+ end
43
+ end
44
+ end
45
+
46
+ include InstanceMethods
47
+ end
48
+ end
49
+ module InstanceMethods
50
+
51
+ def to_param
52
+ sluger_options[:as_param] ? self.slug : self.id
53
+ end
54
+
55
+ protected
56
+
57
+ def permalize
58
+ return if !self.send("#{self.sluggable_conf[:slug_column]}").blank?
59
+ s = Iconv.iconv('ascii//ignore//translit', 'utf-8', self.send("#{self.sluggable_conf[:title_column]}")).to_s
60
+ s.gsub!(/\'/, '') # remove '
61
+ s.gsub!(/\W+/, ' ') # all non-word chars to spaces
62
+ s.strip! # ohh la la
63
+ s.downcase! #
64
+ s.gsub!(/\ +/, '-') # spaces to dashes, preferred separator char everywhere
65
+ self.send("#{self.sluggable_conf[:slug_column]}=", s)
66
+ end
67
+ def strip_title
68
+ self.send("#{self.sluggable_conf[:title_column]}").strip!
69
+ end
70
+
71
+ def create_slug
72
+ self.slug ||= clean("#{column_to_slug}")
73
+ end
74
+
75
+ def clean(string)
76
+ string.downcase.gsub(/[^\w\s\d\_\-]/,'').gsub(/\s\s+/,' ').gsub(/[^\w\d]/, sluger_options[:substitution_char])
77
+ end
78
+ end
79
+ end
80
+
81
+ ActiveRecord::Base.send(:include, Slugger)
data/slugger.gemspec ADDED
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "slugger/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "slugger"
7
+ s.version = Slugger::VERSION
8
+ s.authors = ["Seth Faxon"]
9
+ s.email = ["seth.faxon@gmail.com"]
10
+ s.homepage = "https://github.com/sfaxon/slugger"
11
+ s.summary = %q{Slugger is yet another slug generator.}
12
+ s.description = %q{Slugger is yet another slug generator.}
13
+
14
+ s.rubyforge_project = "slugger"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.extra_rdoc_files = [
22
+ "MIT-LICENSE",
23
+ "README.rdoc"
24
+ ]
25
+
26
+ # specify any dependencies here; for example:
27
+ s.add_dependency "activerecord", ">= 3.0.0"
28
+ s.add_development_dependency "rspec", ">= 2.0.0"
29
+ s.add_development_dependency "sqlite3", "~> 1.3.0"
30
+ # s.add_runtime_dependency "rest-client"
31
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+
3
+ describe Post do
4
+ it "should set slug on create" do
5
+ p = Post.create(:title => "hello world")
6
+ p.slug.should == "hello-world"
7
+ end
8
+ end
data/spec/schema.rb ADDED
@@ -0,0 +1,44 @@
1
+ require 'active_record'
2
+ require 'sqlite3'
3
+
4
+ ActiveRecord::Base.establish_connection(
5
+ :adapter => defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby' ? 'jdbcsqlite3' : 'sqlite3',
6
+ :database => File.join(File.dirname(__FILE__), 'test.db')
7
+ )
8
+
9
+ class CreateSchema < ActiveRecord::Migration
10
+ def self.up
11
+ create_table :posts, :force => true do |t|
12
+ t.string :title
13
+ t.string :slug
14
+ t.timestamps
15
+ end
16
+
17
+ create_table :users, :force => true do |t|
18
+ t.string :first_name
19
+ t.string :last_name
20
+ t.string :slug
21
+ t.timestamps
22
+ end
23
+ end
24
+ end
25
+
26
+ CreateSchema.suppress_messages do
27
+ CreateSchema.migrate(:up)
28
+ end
29
+
30
+ class Post < ActiveRecord::Base
31
+ acts_as_sluggable
32
+ end
33
+
34
+ class User < ActiveRecord::Base
35
+ acts_as_sluggable [:first_name, :last_name]
36
+
37
+ def name
38
+ [first_name, last_name].compact.join(' ')
39
+ end
40
+
41
+ def name=(names)
42
+ self[:first_name], self[:last_name] = names.split(' ', 2)
43
+ end
44
+ end
@@ -0,0 +1,18 @@
1
+ # Requires supporting ruby files with custom matchers and macros, etc,
2
+ # in spec/support/ and its subdirectories.
3
+ require 'slugger'
4
+ require 'schema'
5
+
6
+ Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|f| require f}
7
+
8
+
9
+ RSpec.configure do |config|
10
+ # == Mock Framework
11
+ #
12
+ # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
13
+ #
14
+ # config.mock_with :mocha
15
+ # config.mock_with :flexmock
16
+ # config.mock_with :rr
17
+ config.mock_with :rspec
18
+ end
data/tasks/spec.rake ADDED
@@ -0,0 +1,34 @@
1
+ ENV['BUNDLE_GEMFILE'] = File.dirname(__FILE__) + '/../Gemfile'
2
+
3
+ require 'rake'
4
+ require 'rake/testtask'
5
+ require 'rspec'
6
+ require 'rspec/core/rake_task'
7
+
8
+ desc "Run the test suite"
9
+ task :spec => ['spec:setup', 'spec:slugger_lib', 'spec:cleanup']
10
+
11
+ namespace :spec do
12
+ desc "Setup the test environment"
13
+ task :setup do
14
+ end
15
+
16
+ desc "Cleanup the test environment"
17
+ task :cleanup do
18
+ File.delete(File.expand_path(File.dirname(__FILE__) + '/../spec/test.db'))
19
+ end
20
+
21
+ desc "Test slugger"
22
+ RSpec::Core::RakeTask.new(:slugger_lib) do |task|
23
+ slugger_root = File.expand_path(File.dirname(__FILE__) + '/..')
24
+ task.pattern = slugger_root + '/spec/lib/**/*_spec.rb'
25
+ end
26
+
27
+ desc "Run the coverage report"
28
+ RSpec::Core::RakeTask.new(:rcov) do |task|
29
+ slugger_root = File.expand_path(File.dirname(__FILE__) + '/..')
30
+ task.pattern = slugger_root + '/spec/lib/**/*_spec.rb'
31
+ task.rcov=true
32
+ task.rcov_opts = %w{--rails --exclude osx\/objc,gems\/,spec\/,features\/}
33
+ end
34
+ end
metadata ADDED
@@ -0,0 +1,128 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: slugger
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
+ - Seth Faxon
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-08-23 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: activerecord
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 7
29
+ segments:
30
+ - 3
31
+ - 0
32
+ - 0
33
+ version: 3.0.0
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ hash: 15
45
+ segments:
46
+ - 2
47
+ - 0
48
+ - 0
49
+ version: 2.0.0
50
+ type: :development
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
53
+ name: sqlite3
54
+ prerelease: false
55
+ requirement: &id003 !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ~>
59
+ - !ruby/object:Gem::Version
60
+ hash: 27
61
+ segments:
62
+ - 1
63
+ - 3
64
+ - 0
65
+ version: 1.3.0
66
+ type: :development
67
+ version_requirements: *id003
68
+ description: Slugger is yet another slug generator.
69
+ email:
70
+ - seth.faxon@gmail.com
71
+ executables: []
72
+
73
+ extensions: []
74
+
75
+ extra_rdoc_files:
76
+ - MIT-LICENSE
77
+ - README.rdoc
78
+ files:
79
+ - .gitignore
80
+ - Gemfile
81
+ - MIT-LICENSE
82
+ - README.rdoc
83
+ - Rakefile
84
+ - VERSION
85
+ - lib/slugger.rb
86
+ - lib/slugger/version.rb
87
+ - slugger.gemspec
88
+ - spec/lib/slugger_spec.rb
89
+ - spec/schema.rb
90
+ - spec/spec_helper.rb
91
+ - tasks/spec.rake
92
+ homepage: https://github.com/sfaxon/slugger
93
+ licenses: []
94
+
95
+ post_install_message:
96
+ rdoc_options: []
97
+
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ hash: 3
106
+ segments:
107
+ - 0
108
+ version: "0"
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ none: false
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ hash: 3
115
+ segments:
116
+ - 0
117
+ version: "0"
118
+ requirements: []
119
+
120
+ rubyforge_project: slugger
121
+ rubygems_version: 1.8.8
122
+ signing_key:
123
+ specification_version: 3
124
+ summary: Slugger is yet another slug generator.
125
+ test_files:
126
+ - spec/lib/slugger_spec.rb
127
+ - spec/schema.rb
128
+ - spec/spec_helper.rb