dm-is-sluggable 0.9.10
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.textile +22 -0
- data/Rakefile +56 -0
- data/TODO +1 -0
- data/dm-is-sluggable.gemspec +23 -0
- data/lib/dm-is-sluggable.rb +18 -0
- data/lib/dm-is-sluggable/is/sluggable.rb +41 -0
- data/lib/dm-is-sluggable/is/version.rb +9 -0
- data/lib/dm-is-sluggable/string.rb +33 -0
- data/spec/dm-is-sluggable/sluggable_spec.rb +31 -0
- data/spec/dm-is-sluggable/string_spec.rb +27 -0
- data/spec/spec.opts +5 -0
- data/spec/spec_helper.rb +12 -0
- metadata +75 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Jakub Stastny aka Botanicus
|
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.textile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
h1. About
|
2
|
+
|
3
|
+
This is plugin for easy creating unique slugs from other properties.
|
4
|
+
|
5
|
+
|
6
|
+
h1. Initialization
|
7
|
+
|
8
|
+
You need to have DataMapper model with property slug. To set slug just use before create hook with set_slug model method. This method takes the slug as parameter. Use String#to_slug to get this parameter if you need.
|
9
|
+
|
10
|
+
<pre>
|
11
|
+
class Post
|
12
|
+
include DataMapper::Resource
|
13
|
+
is :sluggable
|
14
|
+
property :title, String
|
15
|
+
property :slug, String, :key => true
|
16
|
+
before :create do
|
17
|
+
set_slug(self.title.to_slug)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
</pre>
|
21
|
+
|
22
|
+
So what exactly set_slug does? It look for given slug, if not found than save it, let say as "foo-bar". If found, than increase number of iteraction and tries it again with "foo-bar-2".
|
data/Rakefile
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'rake/gempackagetask'
|
5
|
+
require 'lib/dm-is-sluggable/is/version'
|
6
|
+
|
7
|
+
GEM_NAME = "dm-is-sluggable"
|
8
|
+
AUTHOR = "Jakub Stastny aka Botanicus"
|
9
|
+
EMAIL = "knava.bestvinensis@gmail.com"
|
10
|
+
HOMEPAGE = "http://101Ideas.cz/"
|
11
|
+
SUMMARY = "Creates unique slug from property. For DataMapper ORM."
|
12
|
+
GEM_VERSION = DataMapper::Is::Sluggable::VERSION
|
13
|
+
|
14
|
+
spec = Gem::Specification.new do |s|
|
15
|
+
s.name = GEM_NAME
|
16
|
+
s.version = GEM_VERSION
|
17
|
+
s.platform = Gem::Platform::RUBY
|
18
|
+
s.has_rdoc = true
|
19
|
+
s.extra_rdoc_files = ["README.textile", "LICENSE"]
|
20
|
+
s.summary = SUMMARY
|
21
|
+
s.description = s.summary
|
22
|
+
s.author = AUTHOR
|
23
|
+
s.email = EMAIL
|
24
|
+
s.homepage = HOMEPAGE
|
25
|
+
s.require_path = 'lib'
|
26
|
+
s.files = %w(LICENSE README.textile Rakefile) + Dir.glob("{lib,spec,app,public,stubs}/**/*")
|
27
|
+
end
|
28
|
+
|
29
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
30
|
+
pkg.gem_spec = spec
|
31
|
+
end
|
32
|
+
|
33
|
+
desc "Create a gemspec file"
|
34
|
+
task :gemspec do
|
35
|
+
File.open("#{GEM_NAME}.gemspec", "w") do |file|
|
36
|
+
file.puts spec.to_ruby
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def sudo_gem(cmd)
|
41
|
+
sh "#{SUDO} #{RUBY} -S gem #{cmd}", :verbose => false
|
42
|
+
end
|
43
|
+
|
44
|
+
desc "Install #{GEM_NAME} #{GEM_VERSION}"
|
45
|
+
task :install => [ :package ] do
|
46
|
+
sudo_gem "install --local pkg/#{GEM_NAME}-#{GEM_VERSION} --no-update-sources"
|
47
|
+
end
|
48
|
+
|
49
|
+
desc "Uninstall #{GEM_NAME} #{GEM_VERSION}"
|
50
|
+
task :uninstall => [ :clobber ] do
|
51
|
+
sudo_gem "uninstall #{GEM_NAME} -v#{GEM_VERSION} -Ix"
|
52
|
+
end
|
53
|
+
|
54
|
+
require 'spec/rake/spectask'
|
55
|
+
desc 'Default: run spec examples'
|
56
|
+
task :default => 'spec'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
begin
|
2
|
+
require "rubygems/specification"
|
3
|
+
rescue SecurityError
|
4
|
+
# http://gems.github.com
|
5
|
+
end
|
6
|
+
|
7
|
+
VERSION = "0.9.10"
|
8
|
+
SPECIFICATION = ::Gem::Specification.new do |s|
|
9
|
+
s.name = "dm-is-sluggable"
|
10
|
+
# s.version = Rango::VERSION
|
11
|
+
s.version = VERSION
|
12
|
+
s.authors = ["Jakub Šťastný aka Botanicus"]
|
13
|
+
s.homepage = "http://github.com/botanicus/dm-is-sluggable"
|
14
|
+
s.summary = "This is plugin for easy creating unique slugs from other properties."
|
15
|
+
# s.description = "" # TODO: long description
|
16
|
+
s.cert_chain = nil
|
17
|
+
s.email = ["knava.bestvinensis", "gmail.com"].join("@")
|
18
|
+
s.files = Dir.glob("**/*") - Dir.glob("pkg/*")
|
19
|
+
s.add_dependency "dm-core"
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
# s.required_ruby_version = ::Gem::Requirement.new(">= 1.9.1")
|
22
|
+
# s.rubyforge_project = "rango"
|
23
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
|
5
|
+
# Add all external dependencies for the plugin here
|
6
|
+
gem 'dm-core'
|
7
|
+
require 'dm-core'
|
8
|
+
|
9
|
+
# Require plugin-files
|
10
|
+
require Pathname(__FILE__).dirname.expand_path / 'dm-is-sluggable' / 'is' / 'sluggable.rb'
|
11
|
+
require Pathname(__FILE__).dirname.expand_path / 'dm-is-sluggable' / 'string'
|
12
|
+
|
13
|
+
# Include the plugin in Resource
|
14
|
+
module DataMapper
|
15
|
+
module Model
|
16
|
+
include DataMapper::Is::Sluggable
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module DataMapper
|
4
|
+
module Is
|
5
|
+
module Sluggable
|
6
|
+
##
|
7
|
+
# fired when your plugin gets included into Resource
|
8
|
+
#
|
9
|
+
def self.included(base)
|
10
|
+
end
|
11
|
+
|
12
|
+
##
|
13
|
+
# Methods that should be included in DataMapper::Model.
|
14
|
+
# Normally this should just be your generator, so that the namespace
|
15
|
+
# does not get cluttered. ClassMethods and InstanceMethods gets added
|
16
|
+
# in the specific resources when you fire is :example
|
17
|
+
##
|
18
|
+
|
19
|
+
def is_sluggable(options = Hash.new)
|
20
|
+
# Add class-methods
|
21
|
+
extend DataMapper::Is::Sluggable::ClassMethods
|
22
|
+
# Add instance-methods
|
23
|
+
include DataMapper::Is::Sluggable::InstanceMethods
|
24
|
+
end
|
25
|
+
|
26
|
+
module ClassMethods
|
27
|
+
end
|
28
|
+
|
29
|
+
module InstanceMethods
|
30
|
+
def set_slug(slug, iteraction = 1)
|
31
|
+
raise ArgumentError if slug.nil?
|
32
|
+
new_slug = "#{slug}#{"-#{iteraction}" unless iteraction == 1}"
|
33
|
+
self.attribute_set(:slug, new_slug)
|
34
|
+
if self.class.first(:slug => self.slug)
|
35
|
+
self.set_slug(slug, iteraction.to_i + 1)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
class String
|
4
|
+
# Important: it do not work with self.tr("á", "a") in Ruby 1.8
|
5
|
+
def unicode_chars
|
6
|
+
{ "á" => "a", "č" => "c", "ď" => "d",
|
7
|
+
"ě" => "e", "é" => "e", "í" => "i",
|
8
|
+
"ň" => "n", "ó" => "o", "ř" => "r",
|
9
|
+
"š" => "s", "ť" => "t", "ú" => "u",
|
10
|
+
"ů" => "u", "ý" => "y", "ž" => "z",
|
11
|
+
"Á" => "A", "Č" => "C", "Ď" => "D",
|
12
|
+
"Ě" => "E", "É" => "E", "Í" => "I",
|
13
|
+
"Ň" => "N", "Ó" => "O", "Ř" => "R",
|
14
|
+
"Š" => "S", "Ť" => "T", "Ú" => "U",
|
15
|
+
"Ů" => "U", "Ý" => "Y", "Ž" => "Z" }
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_ascii
|
19
|
+
string = self.dup
|
20
|
+
self.unicode_chars.each do |unicode, ascii|
|
21
|
+
string.gsub!(/#{unicode}/u, ascii)
|
22
|
+
end
|
23
|
+
return string
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_slug
|
27
|
+
string = self.to_ascii.strip.downcase
|
28
|
+
string.gsub!(/[ \t]+/, "-") # replace blank chars by "-"
|
29
|
+
string.gsub!(/-*(.+)-*/, '\1') # no "-" at begin or end
|
30
|
+
string.delete!(%q{!@#$%^&*(){}[];:"'\|<>,./?]`~±})
|
31
|
+
return string
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require File.join(File.dirname(__FILE__), '..', "spec_helper")
|
4
|
+
require "dm-is-sluggable"
|
5
|
+
|
6
|
+
class Post
|
7
|
+
include DataMapper::Resource
|
8
|
+
is :sluggable
|
9
|
+
property :title, String
|
10
|
+
property :slug, String, :key => true
|
11
|
+
before :create do
|
12
|
+
set_slug(self.title.to_slug)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe DataMapper::Is::Sluggable do
|
17
|
+
before do
|
18
|
+
@post = Post.create(:title => "Hello Bloody World")
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#set_slug" do
|
22
|
+
it "should create slug" do
|
23
|
+
@post.slug.should eql("hello-bloody-world")
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should create unique slug" do
|
27
|
+
second = Post.create(:title => "Hello Bloody World")
|
28
|
+
second.slug.should eql("hello-bloody-world-2")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require File.join(File.dirname(__FILE__), '..', "spec_helper")
|
4
|
+
|
5
|
+
describe "String#to_ascii" do
|
6
|
+
it "should remove diacritics" do
|
7
|
+
"Žádná česká znaménka".to_ascii.should eql("Zadna ceska znamenka")
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "String#to_slug" do
|
12
|
+
it "should remove diacritics" do
|
13
|
+
"česká".to_slug.should eql("ceska")
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should downcase slug" do
|
17
|
+
"BIG".to_slug.should eql("big")
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should remove nonwords chars" do
|
21
|
+
"%^@$".to_slug.should eql("")
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should works" do
|
25
|
+
" Samolepka X2 (černá). ".to_slug.should eql("samolepka-x2-cerna")
|
26
|
+
end
|
27
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dm-is-sluggable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.10
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- "Jakub \xC5\xA0\xC5\xA5astn\xC3\xBD aka Botanicus"
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain:
|
11
|
+
date: 2009-11-26 00:00:00 +00:00
|
12
|
+
default_executable:
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: dm-core
|
16
|
+
type: :runtime
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: "0"
|
23
|
+
version:
|
24
|
+
description:
|
25
|
+
email: knava.bestvinensis@gmail.com
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files: []
|
31
|
+
|
32
|
+
files:
|
33
|
+
- dm-is-sluggable.gemspec
|
34
|
+
- lib/dm-is-sluggable/is/sluggable.rb
|
35
|
+
- lib/dm-is-sluggable/is/version.rb
|
36
|
+
- lib/dm-is-sluggable/string.rb
|
37
|
+
- lib/dm-is-sluggable.rb
|
38
|
+
- LICENSE
|
39
|
+
- Rakefile
|
40
|
+
- README.textile
|
41
|
+
- spec/dm-is-sluggable/sluggable_spec.rb
|
42
|
+
- spec/dm-is-sluggable/string_spec.rb
|
43
|
+
- spec/spec.opts
|
44
|
+
- spec/spec_helper.rb
|
45
|
+
- TODO
|
46
|
+
has_rdoc: true
|
47
|
+
homepage: http://github.com/botanicus/dm-is-sluggable
|
48
|
+
licenses: []
|
49
|
+
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options: []
|
52
|
+
|
53
|
+
require_paths:
|
54
|
+
- lib
|
55
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: "0"
|
60
|
+
version:
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: "0"
|
66
|
+
version:
|
67
|
+
requirements: []
|
68
|
+
|
69
|
+
rubyforge_project:
|
70
|
+
rubygems_version: 1.3.5
|
71
|
+
signing_key:
|
72
|
+
specification_version: 3
|
73
|
+
summary: This is plugin for easy creating unique slugs from other properties.
|
74
|
+
test_files: []
|
75
|
+
|