aq1018-dm-is-slug 0.9.9

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.
@@ -0,0 +1 @@
1
+
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Aaron Qian
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.
@@ -0,0 +1,12 @@
1
+ History.txt
2
+ LICENSE
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ TODO
7
+ lib/dm-is-slug.rb
8
+ lib/dm-is-slug/is/slug.rb
9
+ lib/dm-is-slug/is/version.rb
10
+ spec/integration/slug_spec.rb
11
+ spec/spec.opts
12
+ spec/spec_helper.rb
@@ -0,0 +1,56 @@
1
+ = dm-is-slug
2
+
3
+ DataMapper plugin for creating and slugs(permalinks).
4
+
5
+ == Installation
6
+
7
+ NOTE: You no longer need to download dm-more source code in order to install
8
+ this.
9
+
10
+ All you need to do is:
11
+
12
+ $ sudo rake install
13
+
14
+ Remember to require it in your app's init.rb
15
+
16
+ dependency 'dm-is-slug'
17
+
18
+ == Getting started
19
+
20
+ Lets say we have a post-class, and we want to generate permalinks or slugs for all posts.
21
+
22
+ class Post
23
+ include DataMapper::Resource
24
+
25
+ property :id, Serial
26
+ property :title, String
27
+ property :content, String
28
+
29
+ # here we define that it should have a slug that uses title as the permalink
30
+ # it will generate an extra slug property of String type, with the same size as title
31
+ is :slug, :source => :title
32
+ end
33
+
34
+ Let's Say we need to define a permalink based on a method instead of a property.
35
+
36
+ class User
37
+ include DataMapper::Resource
38
+
39
+ property :id, Serial
40
+ property :email, String
41
+ property :password, String
42
+
43
+ # we only want to strip out the domain name
44
+ # and use only the email account name as the permalink
45
+ def slug_for_email
46
+ email.split("@").first
47
+ end
48
+
49
+ # here we define that it should have a slug that uses title as the permalink
50
+ # it will generate an extra slug property of String type, with the same size as title
51
+ is :slug, :source => :slug_for_email, :size => 255
52
+ end
53
+
54
+ You can now find objects by slug like this:
55
+
56
+ post = Post.first(:slug => "your_slug")
@@ -0,0 +1,54 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require 'spec/rake/spectask'
6
+ require 'pathname'
7
+
8
+ ROOT = Pathname(__FILE__).dirname.expand_path
9
+ require ROOT + 'lib/dm-is-slug/is/version'
10
+
11
+ AUTHOR = "Aaron Qian, Nik Radford"
12
+ EMAIL = "aaron [a] ekohe [d] com; nik [a] terminaldischarge [d] net"
13
+ GEM_NAME = "dm-is-slug"
14
+ GEM_VERSION = DataMapper::Is::Slug::VERSION
15
+ GEM_DEPENDENCIES = [["dm-core", "~>0.9"]]
16
+ GEM_CLEAN = ["log", "pkg"]
17
+ GEM_EXTRAS = { :has_rdoc => false }
18
+
19
+ PROJECT_NAME = "dm-is-slug"
20
+ PROJECT_URL = "http://github.com/aq1018/dm-is-slug"
21
+ PROJECT_DESCRIPTION = PROJECT_SUMMARY = "DataMapper plugin that generates unique slugs"
22
+
23
+ require 'tasks/hoe'
24
+
25
+ task :default => [ :spec ]
26
+
27
+ WIN32 = (RUBY_PLATFORM =~ /win32|mingw|cygwin/) rescue nil
28
+ SUDO = WIN32 ? '' : ('sudo' unless ENV['SUDOLESS'])
29
+
30
+ desc "Install #{GEM_NAME} #{GEM_VERSION}"
31
+ task :install => [ :package ] do
32
+ sh "#{SUDO} gem install --local pkg/#{GEM_NAME}-#{GEM_VERSION} --no-update-sources", :verbose => false
33
+ end
34
+
35
+ desc "Uninstall #{GEM_NAME} #{GEM_VERSION} (default ruby)"
36
+ task :uninstall => [ :clobber ] do
37
+ sh "#{SUDO} gem uninstall #{GEM_NAME} -v#{GEM_VERSION} -I -x", :verbose => false
38
+ end
39
+
40
+ desc 'Run specifications'
41
+ Spec::Rake::SpecTask.new(:spec) do |t|
42
+ t.spec_opts << '--options' << 'spec/spec.opts' if File.exists?('spec/spec.opts')
43
+ t.spec_files = Pathname.glob(Pathname.new(__FILE__).dirname + 'spec/**/*_spec.rb')
44
+
45
+ begin
46
+ t.rcov = ENV.has_key?('NO_RCOV') ? ENV['NO_RCOV'] != 'true' : true
47
+ t.rcov_opts << '--exclude' << 'spec'
48
+ t.rcov_opts << '--text-summary'
49
+ t.rcov_opts << '--sort' << 'coverage' << '--sort-reverse'
50
+ rescue Exception
51
+ puts 'rcov is not installed. Please install before continuing'
52
+ exit
53
+ end
54
+ end
data/TODO ADDED
@@ -0,0 +1,4 @@
1
+ TODO
2
+ ====
3
+
4
+ Docs??
@@ -0,0 +1,36 @@
1
+ # Needed to import datamapper and other gems
2
+ require 'rubygems'
3
+ require 'pathname'
4
+ require 'iconv'
5
+
6
+ # Add all external dependencies for the plugin here
7
+ gem 'dm-core', '~>0.9.9'
8
+ require 'dm-core'
9
+
10
+ require Pathname(__FILE__).dirname.expand_path / 'dm-is-slug' / 'is' / 'version.rb'
11
+
12
+ # Require plugin-files
13
+ require Pathname(__FILE__).dirname.expand_path / 'dm-is-slug' / 'is' / 'slug.rb'
14
+
15
+ # Include the plugin in Resource
16
+ module DataMapper
17
+ module Resource
18
+ module ClassMethods
19
+ include DataMapper::Is::Slug
20
+ end # module ClassMethods
21
+ end # module Resource
22
+ end # module DataMapper
23
+
24
+ # Include DataMapper::Model#get and DataMapper::Collection#get override
25
+ # So we do user.posts.get("my-shinny-new-post")
26
+
27
+ module DataMapper
28
+ module Model
29
+ include DataMapper::Is::Slug::AliasMethods
30
+ end
31
+
32
+ class Collection
33
+ include DataMapper::Is::Slug::AliasMethods
34
+ end
35
+ end
36
+
@@ -0,0 +1,164 @@
1
+ module DataMapper
2
+ module Is
3
+ module Slug
4
+ DEFAULT_SLUG_SIZE = 50
5
+
6
+ # @param [String] str A string to escape for use as a slug
7
+ # @return [String] an URL-safe string
8
+ def self.escape(str)
9
+ s = Iconv.conv('ascii//translit//IGNORE', 'utf-8', str)
10
+ s.gsub!(/\W+/, ' ')
11
+ s.strip!
12
+ s.downcase!
13
+ s.gsub!(/\ +/, '-')
14
+ s
15
+ end
16
+
17
+ ##
18
+ # Methods that should be included in DataMapper::Model.
19
+ # Normally this should just be your generator, so that the namespace
20
+ # does not get cluttered. ClassMethods and InstanceMethods gets added
21
+ # in the specific resources when you fire is :slug
22
+ ##
23
+
24
+ # Defines a +slug+ property on your model with the same size as your
25
+ # source property. This property is Unicode escaped, and treated so as
26
+ # to be fit for use in URLs.
27
+ #
28
+ # ==== Example
29
+ # Suppose your source attribute was the following string: "Hot deals on
30
+ # Boxing Day". This string would be escaped to "hot-deals-on-boxing-day".
31
+ #
32
+ # Non-ASCII characters are attempted to be converted to their nearest
33
+ # approximate.
34
+ #
35
+ # ==== Parameters
36
+ # +permanent_slug+::
37
+ # Permanent slugs are not changed even if the source property has
38
+ # +source+::
39
+ # The property on the model to use as the source of the generated slug
40
+ # +size+::
41
+ # The length of the +slug+ property
42
+ #
43
+ # @param [Hash] provide options in a Hash. See *Parameters* for details
44
+ def is_slug(options)
45
+ extend DataMapper::Is::Slug::ClassMethods
46
+ include DataMapper::Is::Slug::InstanceMethods
47
+
48
+ # merge in default options
49
+ options = { :permanent_slug => true }.merge(options)
50
+
51
+ # must at least specify a source property to generate the slug
52
+ # raise 'You must specify a :source to generate slug' unless options.include?(:source)
53
+ raise 'You must specify a :source to generate slug' unless options[:source]
54
+
55
+ # make sure the source property exsists
56
+ source_property = properties.detect do |p|
57
+ p.name == options[:source].to_sym && p.type == String
58
+ end
59
+
60
+ # Find the string length so that slug can adapt size dynamically
61
+ # depending on the source property, or use the default slug size.
62
+ options[:size] ||= source_property &&
63
+ source_property.size ||
64
+ DataMapper::Is::Slug::DEFAULT_SLUG_SIZE
65
+
66
+ # save as class variable for later...
67
+ @slug_options = options
68
+
69
+ unless slug_property
70
+ property :slug, String, :size => options[:size], :unique => true
71
+ end
72
+
73
+ before :save, :generate_slug
74
+ end
75
+
76
+ module ClassMethods
77
+ attr_reader :slug_options
78
+
79
+ def permanent_slug?
80
+ slug_options[:permanent_slug]
81
+ end
82
+
83
+ def slug_source
84
+ slug_options[:source].to_sym
85
+ end
86
+
87
+ def slug_source_property
88
+ detect_slug_property_by_name(slug_source)
89
+ end
90
+
91
+ def slug_property
92
+ detect_slug_property_by_name(:slug)
93
+ end
94
+
95
+ private
96
+
97
+ def detect_slug_property_by_name(name)
98
+ properties.detect do |p|
99
+ p.name == name && p.type == String
100
+ end
101
+ end
102
+ end # ClassMethods
103
+
104
+ module InstanceMethods
105
+ def to_param
106
+ [slug]
107
+ end
108
+
109
+ def permanent_slug?
110
+ self.class.permanent_slug?
111
+ end
112
+
113
+ def slug_source
114
+ self.class.slug_source
115
+ end
116
+
117
+ def slug_source_property
118
+ self.class.slug_source_property
119
+ end
120
+
121
+ def slug_property
122
+ self.class.slug_property
123
+ end
124
+
125
+ def generate_slug
126
+ source = self.send(slug_source)
127
+
128
+ raise ':source is invalid!' unless slug_source_property || self.respond_to?(slug_source)
129
+
130
+ return if permanent_slug? && self.slug || source.nil?
131
+
132
+ # we turn the source into a slug here
133
+ self.slug = DataMapper::Is::Slug.escape(source)
134
+
135
+ self.slug = "#{self.slug}-2" if self.class.first(:slug => self.slug)
136
+
137
+ while self.class.first(:slug => self.slug) != nil
138
+ i = self.slug[-1..-1].to_i + 1
139
+ self.slug = self.slug[0..-2] + i.to_s
140
+ end
141
+ end
142
+ end # InstanceMethods
143
+
144
+ module AliasMethods
145
+ # override the old get method so that it looks for slugs first
146
+ # and call the old get if slug is not found
147
+ def get_with_slug(*key)
148
+ if respond_to?(:slug_options) && slug_options && key[0].to_s.to_i.to_s != key[0].to_s
149
+ first(:slug => key[0])
150
+ else
151
+ get_without_slug(*key)
152
+ end
153
+ end
154
+
155
+ ##
156
+ # fired when your plugin gets included into Resource
157
+ def self.included(base)
158
+ base.send :alias_method, :get_without_slug, :get
159
+ base.send :alias_method, :get, :get_with_slug
160
+ end
161
+ end
162
+ end # Slug
163
+ end # Is
164
+ end # DataMapper
@@ -0,0 +1,7 @@
1
+ module DataMapper
2
+ module Is
3
+ module Slug
4
+ VERSION = "0.9.9"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,182 @@
1
+ require 'pathname'
2
+ require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
3
+
4
+ if HAS_SQLITE3 || HAS_MYSQL || HAS_POSTGRES
5
+ describe 'DataMapper::Is::Slug' do
6
+
7
+ class User
8
+ include DataMapper::Resource
9
+
10
+ property :id, Serial
11
+ property :email, String
12
+ has n, :posts
13
+ has n, :todos
14
+
15
+ def slug_for_email
16
+ email.split("@").first
17
+ end
18
+
19
+ is :slug, :source => :slug_for_email, :size => 80, :permanent_slug => false
20
+ end
21
+
22
+ class Post
23
+ include DataMapper::Resource
24
+
25
+ property :id, Serial
26
+ property :title, String, :size => 2000
27
+ property :content, Text
28
+
29
+ belongs_to :user
30
+
31
+ is :slug, :source => :title
32
+ end
33
+
34
+ class Todo
35
+ include DataMapper::Resource
36
+ property :id, Serial
37
+ property :title, String
38
+
39
+ belongs_to :user
40
+ end
41
+
42
+ before :all do
43
+ User.auto_migrate!(:default)
44
+ Post.auto_migrate!(:default)
45
+ Todo.auto_migrate!(:default)
46
+
47
+ @u1 = User.create(:email => "john@ekohe.com")
48
+ @p1 = Post.create(:user => @u1, :title => "My first shinny blog post")
49
+ @p2 = Post.create(:user => @u1, :title => "My second shinny blog post")
50
+ @p3 = Post.create(:user => @u1, :title => "My third shinny blog post")
51
+
52
+ @u2 = User.create(:email => "john@someotherplace.com")
53
+ @p4 = Post.create(:user => @u2, :title => "My first Shinny blog post")
54
+ @p5 = Post.create(:user => @u2, :title => "i heart merb and dm")
55
+ @p6 = Post.create(:user => @u2, :title => "another productive day!!")
56
+ @p7 = Post.create(:user => @u2, :title => "another productive day!!")
57
+ @p8 = Post.create(:user => @u2, :title => "another productive day!!")
58
+ @p9 = Post.create(:user => @u2, :title => "another productive day!!")
59
+ @p10 = Post.create(:user => @u2, :title => "another productive day!!")
60
+ @p11 = Post.create(:user => @u2, :title => "another productive day!!")
61
+ @p12 = Post.create(:user => @u2, :title => "another productive day!!")
62
+ @p13 = Post.create(:user => @u2, :title => "another productive day!!")
63
+ @p14 = Post.create(:user => @u2, :title => "another productive day!!")
64
+ @p15 = Post.create(:user => @u2, :title => "another productive day!!")
65
+ @p16 = Post.create(:user => @u2, :title => "another productive day!!")
66
+ @p17 = Post.create(:user => @u2, :title => "A fancy café")
67
+ end
68
+
69
+ it "should generate slugs" do
70
+ User.all.each do |u|
71
+ u.slug.should_not be_nil
72
+ end
73
+
74
+ Post.all.each do |p|
75
+ p.slug.should_not be_nil
76
+ end
77
+ end
78
+
79
+ it "should generate unique slugs" do
80
+ @u1.slug.should_not == @u2.slug
81
+ @p1.slug.should_not == @p4.slug
82
+ end
83
+
84
+ it "should generate correct slug for user" do
85
+ @u1.slug.should == "john"
86
+ @u2.slug.should == "john-2"
87
+ end
88
+
89
+ it "should generate correct slug for post" do
90
+ @p1.slug.should == "my-first-shinny-blog-post"
91
+ @p2.slug.should == "my-second-shinny-blog-post"
92
+ @p3.slug.should == "my-third-shinny-blog-post"
93
+ @p4.slug.should == "my-first-shinny-blog-post-2"
94
+ @p5.slug.should == "i-heart-merb-and-dm"
95
+ @p6.slug.should == "another-productive-day"
96
+ @p7.slug.should == "another-productive-day-2"
97
+ @p8.slug.should == "another-productive-day-3"
98
+ @p9.slug.should == "another-productive-day-4"
99
+ @p10.slug.should == "another-productive-day-5"
100
+ @p11.slug.should == "another-productive-day-6"
101
+ @p12.slug.should == "another-productive-day-7"
102
+ @p13.slug.should == "another-productive-day-8"
103
+ @p14.slug.should == "another-productive-day-9"
104
+ @p15.slug.should == "another-productive-day-10"
105
+ @p16.slug.should == "another-productive-day-11"
106
+ end
107
+
108
+ it "should update slug if :permanent_slug => :false is specified" do
109
+ user = User.create(:email => "a_person@ekohe.com")
110
+ user.slug.should == "a_person"
111
+
112
+ user.should_not be_permanent_slug
113
+
114
+ user.email = "changed@ekohe.com"
115
+ user.should be_dirty
116
+ user.save.should be_true
117
+ user.slug.should == "changed"
118
+ user.destroy
119
+ end
120
+
121
+ it "should not update slug if :permanent_slug => :true or not specified" do
122
+ post = Post.create(:user => @u1, :title => "hello world!")
123
+ post.slug.should == "hello-world"
124
+ post.should be_permanent_slug
125
+ post.title = "hello universe!"
126
+ post.should be_dirty
127
+ post.save.should be_true
128
+ post.slug.should == "hello-world"
129
+ post.destroy
130
+ end
131
+
132
+ it "should have the right size for properties" do
133
+ user_slug_property = User.properties.detect{|p| p.name == :slug && p.type == String}
134
+ user_slug_property.should_not be_nil
135
+ user_slug_property.size.should == 80
136
+
137
+ Post.properties.detect{|p| p.name == :title && p.type == String}.size.should == 2000
138
+ post_slug_property = Post.properties.detect{|p| p.name == :slug && p.type == String}
139
+ post_slug_property.should_not be_nil
140
+ post_slug_property.size.should == 2000
141
+ end
142
+
143
+ it "should find model using get method with slug" do
144
+ u = User.get("john")
145
+ u.should_not be_nil
146
+ u.should == @u1
147
+
148
+ Post.get("my-first-shinny-blog-post").should == @p1
149
+ @u1.posts.get("my-first-shinny-blog-post").should == @p1
150
+ end
151
+
152
+ it "should output slug with to_param method" do
153
+ @u1.to_param.should == ["john"]
154
+ @p1.to_param.should == ["my-first-shinny-blog-post"]
155
+ end
156
+
157
+ it "should find model using get method using id" do
158
+ u = User.get(@u1.id)
159
+ u.should_not be_nil
160
+ u.should == @u1
161
+
162
+ Post.get("my-first-shinny-blog-post").should == @p1
163
+ @u1.posts.get("my-first-shinny-blog-post").should == @p1
164
+ end
165
+
166
+ it "should find model using get method using id with non-slug models" do
167
+ todo = Todo.create(:user => @u1, :title => "blabla")
168
+ todo.should_not be_nil
169
+
170
+ Todo.get(todo.id).should == todo
171
+ @u1.todos.get(todo.id).should == todo
172
+ end
173
+
174
+ it 'should strip unicode characters from the slug' do
175
+ @p17.slug.should == 'a-fancy-caf-e'
176
+ end
177
+
178
+ it 'should have slug_property on instance' do
179
+ @p1.slug_property.should == @p1.class.properties.detect{|p| p.name == :slug}
180
+ end
181
+ end
182
+ end
@@ -0,0 +1,2 @@
1
+ --format specdoc
2
+ --colour
@@ -0,0 +1,28 @@
1
+ require 'rubygems'
2
+ gem 'rspec', '~>1.1.3'
3
+ require 'spec'
4
+ require 'pathname'
5
+ require Pathname(__FILE__).dirname.expand_path.parent + 'lib/dm-is-slug'
6
+
7
+ def load_driver(name, default_uri)
8
+ return false if ENV['ADAPTER'] != name.to_s
9
+
10
+ lib = "do_#{name}"
11
+
12
+ begin
13
+ gem lib, '~>0.9.7'
14
+ require lib
15
+ DataMapper.setup(name, ENV["#{name.to_s.upcase}_SPEC_URI"] || default_uri)
16
+ DataMapper::Repository.adapters[:default] = DataMapper::Repository.adapters[name]
17
+ true
18
+ rescue Gem::LoadError => e
19
+ warn "Could not load #{lib}: #{e}"
20
+ false
21
+ end
22
+ end
23
+
24
+ ENV['ADAPTER'] ||= 'sqlite3'
25
+
26
+ HAS_SQLITE3 = load_driver(:sqlite3, 'sqlite3::memory:')
27
+ HAS_MYSQL = load_driver(:mysql, 'mysql://localhost/dm_core_test')
28
+ HAS_POSTGRES = load_driver(:postgres, 'postgres://postgres@localhost/dm_core_test')
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: aq1018-dm-is-slug
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.9
5
+ platform: ruby
6
+ authors:
7
+ - Aaron Qian, Nik Radford
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-01-12 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: dm-core
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: "0.9"
23
+ version:
24
+ - !ruby/object:Gem::Dependency
25
+ name: hoe
26
+ version_requirement:
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: 1.8.2
32
+ version:
33
+ description: DataMapper plugin that generates unique permalinks / slugs
34
+ email:
35
+ - aaron [a] ekohe [d] com; nik [a] terminaldischarge [d] net
36
+ executables: []
37
+
38
+ extensions: []
39
+
40
+ extra_rdoc_files:
41
+ - History.txt
42
+ - Manifest.txt
43
+ - README.txt
44
+ files:
45
+ - History.txt
46
+ - LICENSE
47
+ - Manifest.txt
48
+ - README.txt
49
+ - Rakefile
50
+ - TODO
51
+ - lib/dm-is-slug.rb
52
+ - lib/dm-is-slug/is/slug.rb
53
+ - lib/dm-is-slug/is/version.rb
54
+ - spec/integration/slug_spec.rb
55
+ - spec/spec.opts
56
+ - spec/spec_helper.rb
57
+ has_rdoc: false
58
+ homepage: http://github.com/aq1018/dm-is-slug
59
+ post_install_message:
60
+ rdoc_options:
61
+ - --main
62
+ - README.txt
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: "0"
70
+ version:
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: "0"
76
+ version:
77
+ requirements: []
78
+
79
+ rubyforge_project: dm-is-slug
80
+ rubygems_version: 1.2.0
81
+ signing_key:
82
+ specification_version: 2
83
+ summary: DataMapper plugin that generates unique permalinks / slugs
84
+ test_files: []
85
+