supertag 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +191 -0
  7. data/Rakefile +6 -0
  8. data/lib/generators/supertag/migration_generator.rb +24 -0
  9. data/lib/generators/supertag/templates/migrations/create_hashtaggings_migration.rb +11 -0
  10. data/lib/generators/supertag/templates/migrations/create_hashtags_migration.rb +10 -0
  11. data/lib/generators/supertag/templates/migrations/create_moneytaggings_migration.rb +11 -0
  12. data/lib/generators/supertag/templates/migrations/create_moneytags_migration.rb +10 -0
  13. data/lib/generators/supertag/templates/migrations/create_usertaggings_migration.rb +11 -0
  14. data/lib/generators/supertag/templates/migrations/create_usertags_migration.rb +10 -0
  15. data/lib/generators/supertag/templates/views/hashtags_controller.rb +10 -0
  16. data/lib/generators/supertag/templates/views/hashtags_index.html.erb +6 -0
  17. data/lib/generators/supertag/templates/views/hashtags_show.html.erb +8 -0
  18. data/lib/generators/supertag/templates/views/moneytags_controller.rb +10 -0
  19. data/lib/generators/supertag/templates/views/moneytags_index.html.erb +6 -0
  20. data/lib/generators/supertag/templates/views/moneytags_show.html.erb +8 -0
  21. data/lib/generators/supertag/templates/views/tags_helper.rb +36 -0
  22. data/lib/generators/supertag/templates/views/usertags_controller.rb +10 -0
  23. data/lib/generators/supertag/templates/views/usertags_index.html.erb +6 -0
  24. data/lib/generators/supertag/templates/views/usertags_show.html.erb +8 -0
  25. data/lib/generators/supertag/views_generator.rb +28 -0
  26. data/lib/supertag.rb +12 -0
  27. data/lib/supertag/hashtag.rb +63 -0
  28. data/lib/supertag/hashtaggable.rb +45 -0
  29. data/lib/supertag/hashtagging.rb +8 -0
  30. data/lib/supertag/moneytag.rb +63 -0
  31. data/lib/supertag/moneytaggable.rb +45 -0
  32. data/lib/supertag/moneytagging.rb +8 -0
  33. data/lib/supertag/usertag.rb +64 -0
  34. data/lib/supertag/usertaggable.rb +45 -0
  35. data/lib/supertag/usertagging.rb +8 -0
  36. data/lib/supertag/version.rb +3 -0
  37. data/spec/dummy/README.rdoc +261 -0
  38. data/spec/dummy/Rakefile +7 -0
  39. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  40. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  41. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  42. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  43. data/spec/dummy/app/mailers/.gitkeep +0 -0
  44. data/spec/dummy/app/models/.gitkeep +0 -0
  45. data/spec/dummy/app/models/picture.rb +4 -0
  46. data/spec/dummy/app/models/post.rb +3 -0
  47. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  48. data/spec/dummy/config.ru +4 -0
  49. data/spec/dummy/config/application.rb +56 -0
  50. data/spec/dummy/config/boot.rb +10 -0
  51. data/spec/dummy/config/database.yml +25 -0
  52. data/spec/dummy/config/environment.rb +5 -0
  53. data/spec/dummy/config/environments/development.rb +37 -0
  54. data/spec/dummy/config/environments/production.rb +67 -0
  55. data/spec/dummy/config/environments/test.rb +37 -0
  56. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  57. data/spec/dummy/config/initializers/inflections.rb +15 -0
  58. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  59. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  60. data/spec/dummy/config/initializers/session_store.rb +8 -0
  61. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  62. data/spec/dummy/config/locales/en.yml +5 -0
  63. data/spec/dummy/config/routes.rb +2 -0
  64. data/spec/dummy/db/migrate/20130919041824_create_posts.rb +9 -0
  65. data/spec/dummy/db/migrate/20130919041825_create_pictures.rb +9 -0
  66. data/spec/dummy/db/migrate/20131004085836_create_simple_usertag_usertags.rb +9 -0
  67. data/spec/dummy/db/migrate/20131004085907_create_simple_usertag_usertaggings.rb +10 -0
  68. data/spec/dummy/db/schema.rb +43 -0
  69. data/spec/dummy/lib/assets/.gitkeep +0 -0
  70. data/spec/dummy/log/.gitkeep +0 -0
  71. data/spec/dummy/public/404.html +26 -0
  72. data/spec/dummy/public/422.html +26 -0
  73. data/spec/dummy/public/500.html +25 -0
  74. data/spec/dummy/public/favicon.ico +0 -0
  75. data/spec/dummy/script/rails +6 -0
  76. data/spec/simple_usertag_spec.rb +138 -0
  77. data/spec/spec_helper.rb +13 -0
  78. data/supertag.gemspec +28 -0
  79. metadata +232 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8c795e9e93b046fe42eb0ab82c12e209619b7fde
4
+ data.tar.gz: f29d8f753739100fe8462806f69491b66c033931
5
+ SHA512:
6
+ metadata.gz: dcc50fa0b6731aca9dc7cb0bdba8d9ba2e5103f7458c6e2e622a8ad0386b7aa16e2476f93b6ab264206b5bf0da0bfbcf9ca1af2154e8d88988f3b3a57205c1cf
7
+ data.tar.gz: 6f5fcc47d7c5f6c41720c8fe387f10d0249b09b15bafeb9fb6b7065e76e1b3418452973a0e9e53d11eb78b73c9eb318bed60245331d969c61fd54fdad5a9c820
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ **/*.log
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+ _Notes.txt
20
+ *.sqlite3
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in simple_hashtag.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Taylor Mitchell
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,191 @@
1
+ # Supertag
2
+
3
+
4
+ This gem is for tagging users using the "@", tagging things using the "#", tagging whatever else with "$" and in the future allowing extentions of the tags with "%". It will search your code and create a page with those attributes.
5
+
6
+ Thank you Raphael Campardou for use of your gem(simple_hashtag)
7
+ This is a work in progress, right now. It allows for the use of "$", "#", "@", and "%". The "%" is a future work in progress for allowing an attribute. For example: @somealias%private would create a private message. For now use it if you wish, but that one is not complete as of now. If you would like to contribute, by all means fork and let me know! Or collaborate with me as well so we can improve this. Any questions/comments/additions you would like to see/subtractions you think I should do/or just to tell me that you think this is awesome(or sucks) can be done through github/scy0846 or the email address in the gemfile.
8
+
9
+ It's simple, and like all things simple, it can create a nice effect, quickly.
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+ ```ruby
15
+ gem 'supertag'
16
+ ```
17
+
18
+ And execute:
19
+ ```shell
20
+ $ bundle
21
+ ```
22
+
23
+ Then you have to generate the migration files:
24
+ ```shell
25
+ $ rails g supertag:migration
26
+ ```
27
+
28
+ This will create two migration files, one for the `tags` table and one for the `tagging` table.
29
+ You will need to run `rake db:migrate` to actually create the tables.
30
+
31
+ __Optionnally__, you can create views,
32
+ if only to guide you through your own implementation:
33
+ ```shell
34
+ $ rails g supertag:views
35
+ ```
36
+
37
+ **you may need a partial file in your fiew of _posts(or whatever content your using)**
38
+
39
+ This will create a __basic controller__, a __short index view__ and a __small helper__.
40
+ It assume your views follow the convention of having a directory named after your model's plural, and a partial named after your model's name.
41
+ ```
42
+ app
43
+ |-- views
44
+ | |-- posts
45
+ | | |-- _post.html.erb
46
+ ```
47
+
48
+
49
+ ## Usage
50
+
51
+ Just add `include Supertag::Taggable` in your model.
52
+
53
+ _Simple Hasthag_ will parse the `body` attribute by default:
54
+
55
+ ```ruby
56
+ class Post < ActiveRecord::Base
57
+ include Supertag::Taggable
58
+ end
59
+ ```
60
+
61
+
62
+ If you need to parse another attribute instead,
63
+ add `taggable_attribute` followed by the name of your attribute, i.e.:
64
+ ```ruby
65
+ class Picture < ActiveRecord::Base
66
+ include Supertag::Taggable
67
+ taggable_attribute :caption
68
+ end
69
+ ```
70
+
71
+ From here on, if your text contains a tag, say _@RubyRocks_,
72
+ _Supertag_ will find it, store it in a table and retreive it and its associated object if asked.
73
+ ---------------------------------------------------------------------------------------
74
+ Helpers are also available to create a link when displaying the text.
75
+ To use the helper, if you are new to rails you would place in your view page
76
+
77
+ <%= linkify_tags(taggable_content) %>
78
+
79
+ when you use this helper it will read the content find the hashtags and spew all of your content back on the page with links on the taggables. If you have your content tag above it and the helper tag below that realize you will repeat your content. Hopefully this will save you some time.
80
+ ----------------------------------------------------------------------------------------
81
+ ### Controller and Views
82
+ If you don't want to bother looking at the generated controller and views, here is a quick peek.
83
+ In a Controller, display all tags, or search for a Tag and its associated records:
84
+ ```ruby
85
+ class TagsController < ApplicationController
86
+ def index
87
+ @tags = Supertag::Tag.all
88
+ end
89
+
90
+ def show
91
+ @tag = Supertag::Tag.find_by_name(params[:tag])
92
+ @tagged = @tag.taggables if @tag
93
+ end
94
+ end
95
+ ```
96
+
97
+ The views could resemble something like this:
98
+
99
+ Index:
100
+ ```erb
101
+ <h1>Tags</h1>
102
+ <ul>
103
+ <% @tags.each do |tag| %>
104
+ <li><%= link_to tag.name, tag_path(tag.name) %></li>
105
+ <% end -%>
106
+ </ul>
107
+ ```
108
+
109
+ Show:
110
+ ```erb
111
+ <h1><%= params[:tag] %></h1>
112
+ <% if @tagged %>
113
+ <% @tagged.each do |tagged| %>
114
+ <% view = tagged.class.to_s.underscore.pluralize %>
115
+ <% partial = tagged.class.to_s.underscore %>
116
+ <%= render "#{view}/#{partial}", {partial.to_sym => tagged} %>
117
+ <% end -%>
118
+ <% else -%>
119
+ <p>There is no match for the <em><%= params[:tag] %></em> tag.</p>
120
+ <% end -%>
121
+ ```
122
+ In the gem it is actually extracted in a helper.
123
+
124
+
125
+ ### Routes
126
+
127
+ If you use the provided controller and views, the generator will add two routes to your app:
128
+ ```ruby
129
+ get 'tags/', to: 'tags#index', as: :tags
130
+ get 'tags/:tag', to: 'tags#show', as: :tag
131
+ ```
132
+
133
+ The helper generating the link relies on it.
134
+
135
+
136
+
137
+ ### Spring Cleaning
138
+ There is a class method `Supertag::Tag#clean_orphans` to remove unused tags from the DB.
139
+ It is currently not hooked, for two reasons:
140
+ - It is not optimised at all, DB-wise.
141
+ - Destructive method should be called explicitly.
142
+
143
+ Knowing all this, you can hook it after each change, or automate it with a Cron job, or even spring-clean manually once in a while.
144
+
145
+ Improvements for this method are listed in the Todo section below.
146
+
147
+
148
+ ## Gotchas
149
+ ### Association Query
150
+ The association between a Tag and your models is a polymorphic many-to-many.
151
+
152
+ The object returned by the query is an array, not an Arel query, so you can't chain (i.e.: to specify the order), and should do it by hand:
153
+
154
+ ```ruby
155
+ tag = Supertag.find_by_name("RubyRocks")
156
+ posts_and_picts = tag.taggables
157
+ posts_and_picts.sort_by! { |p| p.created_at }
158
+ ```
159
+
160
+ ### find_by
161
+
162
+ To preserve coherence, Tags are stored downcased.
163
+ To ensure coherence, they are also searched downcased.
164
+ Internally, the model overrides `find_by_name` to perform the downcase query.
165
+ Should you search Tags manually you should use the `Supertag::Tag#find_by_name` method, instead of `Supertag::Tag.find_by(name: 'RubyRocks')`
166
+
167
+
168
+ ## ToDo
169
+
170
+ _Supertag_ is in its very early stage and would need a lot of love to reach 1.0.0.
171
+ Among the many improvement areas:
172
+
173
+ - Code for only allowing a user to be tagged and not create a completely new user.
174
+ - Code for replying to a feed using @
175
+ - Update clean orphans code to find rogue users
176
+ - Code for attributes and only allowing certain attributes
177
+
178
+ ## Contributing
179
+
180
+ All contributions are welcome.
181
+ I might not develop new features (unless a project does require it),
182
+ but I will definitely merge any interesting feature or bug fix quickly.
183
+
184
+ You know the drill:
185
+
186
+ 1. Fork it
187
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
188
+ 3. Add passing tests
189
+ 4. Commit your changes (`git commit -am 'Add some feature'`)
190
+ 5. Push to the branch (`git push origin my-new-feature`)
191
+ 6. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,24 @@
1
+ require 'rails/generators/active_record'
2
+
3
+ module Supertag
4
+ module Generators
5
+ class MigrationGenerator < Rails::Generators::Base
6
+ include Rails::Generators::Migration
7
+
8
+ source_root File.expand_path('../templates', __FILE__)
9
+
10
+ def self.next_migration_number(path)
11
+ ActiveRecord::Generators::Base.next_migration_number(path)
12
+ end
13
+
14
+ def generate_migration
15
+ migration_template "migrations/create_hashtags_migration.rb", "db/migrate/create_supertag_hashtags.rb"
16
+ migration_template "migrations/create_hashtaggings_migration.rb", "db/migrate/create_supertag_hashtaggings.rb"
17
+ migration_template "migrations/create_usertags_migration.rb", "db/migrate/create_supertag_usertags.rb"
18
+ migration_template "migrations/create_usertaggings_migration.rb", "db/migrate/create_supertag_usertaggings.rb"
19
+ migration_template "migrations/create_moneytags_migration.rb", "db/migrate/create_supertag_moneytags.rb"
20
+ migration_template "migrations/create_moneytaggings_migration.rb", "db/migrate/create_supertag_moneytaggings.rb"
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,11 @@
1
+ # This migration comes from supertag
2
+ class CreateSupertagHashtaggings < ActiveRecord::Migration
3
+ def change
4
+ create_table :supertag_hashtaggings do |t|
5
+ t.references :hashtag, :index => true
6
+ t.references :hashtaggable, :polymorphic => true
7
+ end
8
+ add_index :supertag_hashtaggings, ["hashtaggable_id", "hashtaggable_type"],
9
+ :name => 'index_hashtaggings_hashtaggable_id_hashtaggable_type'
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ # This migration comes from supertag
2
+ class CreateSupertagHashtags < ActiveRecord::Migration
3
+ def change
4
+ create_table :supertag_hashtags do |t|
5
+ t.string :name, :index => true
6
+
7
+ t.timestamps
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ # This migration comes from supertag
2
+ class CreateSupertagMoneytaggings < ActiveRecord::Migration
3
+ def change
4
+ create_table :supertag_moneytaggings do |t|
5
+ t.references :moneytag, :index => true
6
+ t.references :moneytaggable, :polymorphic => true
7
+ end
8
+ add_index :supertag_moneytaggings, ["moneytaggable_id", "moneytaggable_type"],
9
+ :name => 'index_moneytaggings_moneytaggable_id_moneytaggable_type'
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ # This migration comes from supertag
2
+ class CreateSupertagMoneytags < ActiveRecord::Migration
3
+ def change
4
+ create_table :supertag_moneytags do |t|
5
+ t.string :name, :index => true
6
+
7
+ t.timestamps
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ # This migration comes from supertag
2
+ class CreateSupertagUsertaggings < ActiveRecord::Migration
3
+ def change
4
+ create_table :supertag_usertaggings do |t|
5
+ t.references :usertag, :index => true
6
+ t.references :usertaggable, :polymorphic => true
7
+ end
8
+ add_index :supertag_usertaggings, ["usertaggable_id", "usertaggable_type"],
9
+ :name => 'index_usertaggings_usertaggable_id_usertaggable_type'
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ # This migration comes from supertag
2
+ class CreateSupertagUsertags < ActiveRecord::Migration
3
+ def change
4
+ create_table :supertag_usertags do |t|
5
+ t.string :name, :index => true
6
+
7
+ t.timestamps
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ class HashtagsController < ApplicationController
2
+ def index
3
+ @hashtags = Supertag::Hashtag.all
4
+ end
5
+
6
+ def show
7
+ @hashtag = Supertag::Hashtag.find_by_name(params[:hashtag])
8
+ @hashtagged = @hashtag.hashtaggables if @hashtag
9
+ end
10
+ end
@@ -0,0 +1,6 @@
1
+ <h1>Hashtags</h1>
2
+ <ul>
3
+ <% @hashtags.each do |hashtag| %>
4
+ <li><%= link_to hashtag.name, hashtag_path(hashtag.name) %></li>
5
+ <% end -%>
6
+ </ul>
@@ -0,0 +1,8 @@
1
+ <h1><%= params[:hashtag] %></h1>
2
+ <% if @hashtagged %>
3
+ <% @hashtagged.each do |hashtagged| %>
4
+ <%= render_hashtaggable hashtagged %>
5
+ <% end -%>
6
+ <% else -%>
7
+ <p>There is no match for the <em><%= params[:hashtag] %></em> hashtag.</p>
8
+ <% end -%>
@@ -0,0 +1,10 @@
1
+ class MoneytagsController < ApplicationController
2
+ def index
3
+ @moneytags = Supertag::Moneytag.all
4
+ end
5
+
6
+ def show
7
+ @moneytag = Supertag::Moneytag.find_by_name(params[:moneytag])
8
+ @moneytagged = @moneytag.moneytaggables if @moneytag
9
+ end
10
+ end
@@ -0,0 +1,6 @@
1
+ <h1>Moneytags</h1>
2
+ <ul>
3
+ <% @moneytags.each do |moneytag| %>
4
+ <li><%= link_to moneytag.name, moneytag_path(moneytag.name) %></li>
5
+ <% end -%>
6
+ </ul>
@@ -0,0 +1,8 @@
1
+ <h1><%= params[:moneytag] %></h1>
2
+ <% if @moneytagged %>
3
+ <% @moneytagged.each do |moneytagged| %>
4
+ <%= render_moneytaggable moneytagged %>
5
+ <% end -%>
6
+ <% else -%>
7
+ <p>There is no match for the <em><%= params[:moneytag] %></em> moneytag.</p>
8
+ <% end -%>
@@ -0,0 +1,36 @@
1
+ module TagsHelper
2
+ REGEXS = [[Supertag::Usertag::USERTAG_REGEX, :usertag_path],
3
+ [Supertag::Hashtag::HASHTAG_REGEX, :hashtag_path],
4
+ [Supertag::Moneytag::MONEYTAG_REGEX, :moneytag_path]]
5
+
6
+ def linkify_tags(taggable_content)
7
+ text = taggable_content.to_s
8
+
9
+ REGEXS.each do |regex, path|
10
+ text = text.gsub(regex) {link_to($&, send(path, $2), class: 'tag')}
11
+ end
12
+
13
+ text.html_safe
14
+ end
15
+
16
+ def render_hashtaggable(hashtaggable)
17
+ klass = hashtaggable.class.to_s.underscore
18
+ view_dirname = klass.pluralize
19
+ partial = klass
20
+ render "#{view_dirname}/#{partial}", {klass.to_sym => hashtaggable}
21
+ end
22
+
23
+ def render_usertaggable(usertaggable)
24
+ klass = usertaggable.class.to_s.underscore
25
+ view_dirname = klass.pluralize
26
+ partial = klass
27
+ render "#{view_dirname}/#{partial}", {klass.to_sym => usertaggable}
28
+ end
29
+
30
+ def render_moneytaggable(moneytaggable)
31
+ klass = moneytaggable.class.to_s.underscore
32
+ view_dirname = klass.pluralize
33
+ partial = klass
34
+ render "#{view_dirname}/#{partial}", {klass.to_sym => moneytaggable}
35
+ end
36
+ end