diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..5bc2a80 --- /dev/null +++ b/Gemfile @@ -0,0 +1,4 @@ +source 'https://rubygems.org' + +# Specify your gem's dependencies in slugtastic.gemspec +gemspec diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..6445f21 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,34 @@ +PATH + remote: . + specs: + slugtastic (0.2.0.alpha) + +GEM + remote: https://rubygems.org/ + specs: + activemodel (3.0.17) + activesupport (= 3.0.17) + builder (~> 2.1.2) + i18n (~> 0.5.0) + activesupport (3.0.17) + builder (2.1.2) + diff-lcs (1.1.3) + i18n (0.5.0) + rspec (2.11.0) + rspec-core (~> 2.11.0) + rspec-expectations (~> 2.11.0) + rspec-mocks (~> 2.11.0) + rspec-core (2.11.1) + rspec-expectations (2.11.2) + diff-lcs (~> 1.1.3) + rspec-mocks (2.11.2) + supermodel (0.1.6) + activemodel (~> 3.0.0) + +PLATFORMS + ruby + +DEPENDENCIES + rspec + slugtastic! + supermodel diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..4e37348 --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2012 Dan Barber + +MIT License + +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: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +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. \ No newline at end of file diff --git a/Manifest b/Manifest deleted file mode 100644 index 6740bae..0000000 --- a/Manifest +++ /dev/null @@ -1,5 +0,0 @@ -Manifest -README.md -Rakefile -lib/slugtastic.rb -slugtastic.gemspec diff --git a/README.md b/README.md index 46d4ecb..2c652b2 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,20 @@ -Slugtastic -========== +# Slugtastic Simple gem for autogenerating permalink style slugs for your ActiveRecord models. -## Install +## Installation -Add this to your Gemfile: +Add this line to your application's Gemfile: - gem "slugtastic" + gem 'slugtastic' -And run `bundle install` +And then execute: + + $ bundle + +Or install it yourself as: + + $ gem install slugtastic ## Usage @@ -19,4 +24,12 @@ Usage is very simple. Just add the following to your model: This will generate a slug string from the title atrribute and store it in the slug attribute unless the slug already contains a string. The slug is generated pre-validation so you can still use `validates_presence_of :slug`. -There are no extra options at present. \ No newline at end of file +There are no extra options at present. + +## Contributing + +1. Fork it +2. Create your feature branch (`git checkout -b my-new-feature`) +3. Commit your changes (`git commit -am 'Added some feature'`) +4. Push to the branch (`git push origin my-new-feature`) +5. Create new Pull Request diff --git a/Rakefile b/Rakefile index 7f649cb..93b3e16 100644 --- a/Rakefile +++ b/Rakefile @@ -1,14 +1,7 @@ -require 'rubygems' -require 'rake' -require 'echoe' +#!/usr/bin/env rake +require "bundler/gem_tasks" +require "rspec/core/rake_task" -Echoe.new('slugtastic', '0.1.2') do |p| - p.description = "A simple slug string generator for ActiveRecord. Will populate a slug attribute from another attribute." - p.url = "http://github.com/danbee/slugtastic" - p.author = "Dan Barber" - p.email = "danbee@gmail.com" - p.ignore_pattern = ["tmp/*", "script/*"] - p.development_dependencies = [] -end +RSpec::Core::RakeTask.new(:spec) -Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext } \ No newline at end of file +task default: :spec diff --git a/lib/slugtastic.rb b/lib/slugtastic.rb index 39245b7..82f2053 100644 --- a/lib/slugtastic.rb +++ b/lib/slugtastic.rb @@ -1,23 +1,8 @@ +require "slugtastic/version" +require "slugtastic/model_additions" + module Slugtastic - def self.included(base) - base.extend ClassMethods - end - - def generate_slug(string) + def self.generate_slug(string) string.downcase.gsub(/ /, '_').gsub(/[^a-z0-9\-_]/, '') unless string.nil? end - - module ClassMethods - - def has_slug(name, options = { :from => :title }) - before_validation do |record| - self[name] = generate_slug(self[options[:from]]) if self[name].nil? or self[name].empty? - end - end - - end end - -class ActiveRecord::Base - include Slugtastic -end \ No newline at end of file diff --git a/lib/slugtastic/model_additions.rb b/lib/slugtastic/model_additions.rb new file mode 100644 index 0000000..2585198 --- /dev/null +++ b/lib/slugtastic/model_additions.rb @@ -0,0 +1,12 @@ +module Slugtastic + module ModelAdditions + + def has_slug name, options = { :from => :title } + before_validation do |record| + return if responds_to?(name) and send(name).present? + send("#{name}=", Slugtastic.generate_slug(send(options[:from]))) + end + end + + end +end diff --git a/lib/slugtastic/version.rb b/lib/slugtastic/version.rb new file mode 100644 index 0000000..15867fd --- /dev/null +++ b/lib/slugtastic/version.rb @@ -0,0 +1,3 @@ +module Slugtastic + VERSION = "0.2.0.alpha" +end diff --git a/slugtastic.gemspec b/slugtastic.gemspec index 7b7b338..4d87e17 100644 --- a/slugtastic.gemspec +++ b/slugtastic.gemspec @@ -1,29 +1,20 @@ # -*- encoding: utf-8 -*- +require File.expand_path('../lib/slugtastic/version', __FILE__) -Gem::Specification.new do |s| - s.name = %q{slugtastic} - s.version = "0.1.2" +Gem::Specification.new do |gem| + gem.authors = ["Dan Barber"] + gem.email = ["danbee@gmail.com"] + gem.description = %q{A simple slug string generator for ActiveRecord. Will populate a slug attribute from another attribute.} + gem.summary = %q{A simple slug string generator for ActiveRecord.} + gem.homepage = "" - s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version= - s.authors = [%q{Dan Barber}] - s.date = %q{2011-10-08} - s.description = %q{A simple slug string generator for ActiveRecord. Will populate a slug attribute from another attribute.} - s.email = %q{danbee@gmail.com} - s.extra_rdoc_files = [%q{README.md}, %q{lib/slugtastic.rb}] - s.files = [%q{Manifest}, %q{README.md}, %q{Rakefile}, %q{lib/slugtastic.rb}, %q{slugtastic.gemspec}] - s.homepage = %q{http://github.com/danbee/slugtastic} - s.rdoc_options = [%q{--line-numbers}, %q{--inline-source}, %q{--title}, %q{Slugtastic}, %q{--main}, %q{README.md}] - s.require_paths = [%q{lib}] - s.rubyforge_project = %q{slugtastic} - s.rubygems_version = %q{1.8.6} - s.summary = %q{A simple slug string generator for ActiveRecord. Will populate a slug attribute from another attribute.} + gem.files = `git ls-files`.split($\) + gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } + gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) + gem.name = "slugtastic" + gem.require_paths = ["lib"] + gem.version = Slugtastic::VERSION - if s.respond_to? :specification_version then - s.specification_version = 3 - - if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then - else - end - else - end + gem.add_development_dependency "rspec" + gem.add_development_dependency "supermodel" end diff --git a/spec/slugtastic/.model_additions_spec.rb.swp b/spec/slugtastic/.model_additions_spec.rb.swp new file mode 100644 index 0000000..9938153 Binary files /dev/null and b/spec/slugtastic/.model_additions_spec.rb.swp differ diff --git a/spec/slugtastic/model_additions_spec.rb b/spec/slugtastic/model_additions_spec.rb new file mode 100644 index 0000000..555bf4c --- /dev/null +++ b/spec/slugtastic/model_additions_spec.rb @@ -0,0 +1,23 @@ +# encoding: utf-8 +require 'spec_helper' + +class Model < SuperModel::Base + include ActiveModel::Validations::Callbacks + extend Slugtastic::ModelAdditions + has_slug :slug, from: :title +end + +describe Slugtastic::ModelAdditions do + it "generates a slug from the title" do + Model.create!(:title => "A Simple Title").slug.should eq "a_simple_title" + end + + it "doesn't regenerate the slug if it already exists" do + model = Model.create!(:title => "A Simple Title") + model.slug.should eq "a_simple_title" + + model.title = "A new title" + model.save + model.slug.should eq "a_simple_title" + end +end diff --git a/spec/slugtastic_spec.rb b/spec/slugtastic_spec.rb new file mode 100644 index 0000000..e90b274 --- /dev/null +++ b/spec/slugtastic_spec.rb @@ -0,0 +1,18 @@ +# encoding: utf-8 +require 'spec_helper' + +describe Slugtastic do + describe ".generate_slug" do + it "generates a slug from a simple string" do + Slugtastic.generate_slug("A simple string.").should eq "a_simple_string" + end + + it "handles strings with hypens in them" do + Slugtastic.generate_slug("A string - with Hyphens").should eq "a_string_-_with_hyphens" + end + + it "handles strings with other characters in them" do + Slugtastic.generate_slug("A string, with /All sorts!").should eq "a_string_with_all_sorts" + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..4618b2a --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,2 @@ +require "slugtastic" +require "supermodel"