radiant-tags-extension 1.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (200) hide show
  1. data/HELP.md +50 -0
  2. data/HELP_admin.md +30 -0
  3. data/README +38 -0
  4. data/Rakefile +25 -0
  5. data/app/models/meta_tag.rb +53 -0
  6. data/app/models/radius_tags.rb +328 -0
  7. data/app/models/tag_search_page.rb +87 -0
  8. data/app/models/tagging.rb +10 -0
  9. data/app/views/admin/help/_using_tags.html.haml +4 -0
  10. data/app/views/admin/pages/_tag_field.html.haml +8 -0
  11. data/db/migrate/001_add_tag_support.rb +20 -0
  12. data/lib/tagging_methods.rb +128 -0
  13. data/lib/tasks/tags_extension_tasks.rake +32 -0
  14. data/public/stylesheets/tags.css +11 -0
  15. data/tags_extension.rb +57 -0
  16. data/test/fixtures/meta_tags.yml +12 -0
  17. data/test/fixtures/page_parts.yml +17 -0
  18. data/test/fixtures/pages.yml +43 -0
  19. data/test/fixtures/taggings.yml +20 -0
  20. data/test/functional/tag_search_page_test.rb +44 -0
  21. data/test/functional/tags_extension_test.rb +19 -0
  22. data/test/helpers/render_test_helper.rb +60 -0
  23. data/test/test_helper.rb +20 -0
  24. data/test/unit/page_taggability_test.rb +20 -0
  25. data/vendor/plugins/has_many_polymorphs/.gitignore +1 -0
  26. data/vendor/plugins/has_many_polymorphs/CHANGELOG +86 -0
  27. data/vendor/plugins/has_many_polymorphs/LICENSE +184 -0
  28. data/vendor/plugins/has_many_polymorphs/Manifest +173 -0
  29. data/vendor/plugins/has_many_polymorphs/README +205 -0
  30. data/vendor/plugins/has_many_polymorphs/Rakefile +28 -0
  31. data/vendor/plugins/has_many_polymorphs/TODO +2 -0
  32. data/vendor/plugins/has_many_polymorphs/examples/hmph.rb +69 -0
  33. data/vendor/plugins/has_many_polymorphs/generators/tagging/tagging_generator.rb +97 -0
  34. data/vendor/plugins/has_many_polymorphs/generators/tagging/templates/migration.rb +28 -0
  35. data/vendor/plugins/has_many_polymorphs/generators/tagging/templates/tag.rb +39 -0
  36. data/vendor/plugins/has_many_polymorphs/generators/tagging/templates/tag_test.rb +15 -0
  37. data/vendor/plugins/has_many_polymorphs/generators/tagging/templates/tagging.rb +16 -0
  38. data/vendor/plugins/has_many_polymorphs/generators/tagging/templates/tagging_extensions.rb +203 -0
  39. data/vendor/plugins/has_many_polymorphs/generators/tagging/templates/tagging_test.rb +85 -0
  40. data/vendor/plugins/has_many_polymorphs/generators/tagging/templates/taggings.yml +23 -0
  41. data/vendor/plugins/has_many_polymorphs/generators/tagging/templates/tags.yml +7 -0
  42. data/vendor/plugins/has_many_polymorphs/init.rb +2 -0
  43. data/vendor/plugins/has_many_polymorphs/lib/has_many_polymorphs/association.rb +160 -0
  44. data/vendor/plugins/has_many_polymorphs/lib/has_many_polymorphs/autoload.rb +69 -0
  45. data/vendor/plugins/has_many_polymorphs/lib/has_many_polymorphs/base.rb +60 -0
  46. data/vendor/plugins/has_many_polymorphs/lib/has_many_polymorphs/class_methods.rb +600 -0
  47. data/vendor/plugins/has_many_polymorphs/lib/has_many_polymorphs/configuration.rb +19 -0
  48. data/vendor/plugins/has_many_polymorphs/lib/has_many_polymorphs/debugging_tools.rb +103 -0
  49. data/vendor/plugins/has_many_polymorphs/lib/has_many_polymorphs/rake_task_redefine_task.rb +35 -0
  50. data/vendor/plugins/has_many_polymorphs/lib/has_many_polymorphs/reflection.rb +58 -0
  51. data/vendor/plugins/has_many_polymorphs/lib/has_many_polymorphs/support_methods.rb +88 -0
  52. data/vendor/plugins/has_many_polymorphs/lib/has_many_polymorphs.rb +27 -0
  53. data/vendor/plugins/has_many_polymorphs/test/fixtures/bow_wows.yml +10 -0
  54. data/vendor/plugins/has_many_polymorphs/test/fixtures/cats.yml +18 -0
  55. data/vendor/plugins/has_many_polymorphs/test/fixtures/eaters_foodstuffs.yml +0 -0
  56. data/vendor/plugins/has_many_polymorphs/test/fixtures/fish.yml +12 -0
  57. data/vendor/plugins/has_many_polymorphs/test/fixtures/frogs.yml +5 -0
  58. data/vendor/plugins/has_many_polymorphs/test/fixtures/keep_your_enemies_close.yml +0 -0
  59. data/vendor/plugins/has_many_polymorphs/test/fixtures/little_whale_pupils.yml +0 -0
  60. data/vendor/plugins/has_many_polymorphs/test/fixtures/people.yml +7 -0
  61. data/vendor/plugins/has_many_polymorphs/test/fixtures/petfoods.yml +11 -0
  62. data/vendor/plugins/has_many_polymorphs/test/fixtures/whales.yml +5 -0
  63. data/vendor/plugins/has_many_polymorphs/test/fixtures/wild_boars.yml +10 -0
  64. data/vendor/plugins/has_many_polymorphs/test/generator/tagging_generator_test.rb +42 -0
  65. data/vendor/plugins/has_many_polymorphs/test/integration/app/README +182 -0
  66. data/vendor/plugins/has_many_polymorphs/test/integration/app/Rakefile +19 -0
  67. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/controllers/application.rb +7 -0
  68. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/controllers/bones_controller.rb +5 -0
  69. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/helpers/addresses_helper.rb +2 -0
  70. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/helpers/application_helper.rb +3 -0
  71. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/helpers/bones_helper.rb +2 -0
  72. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/helpers/sellers_helper.rb +28 -0
  73. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/helpers/states_helper.rb +2 -0
  74. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/helpers/users_helper.rb +2 -0
  75. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/models/bone.rb +2 -0
  76. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/models/double_sti_parent.rb +2 -0
  77. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/models/double_sti_parent_relationship.rb +2 -0
  78. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/models/organic_substance.rb +2 -0
  79. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/models/single_sti_parent.rb +4 -0
  80. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/models/single_sti_parent_relationship.rb +4 -0
  81. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/models/stick.rb +2 -0
  82. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/models/stone.rb +2 -0
  83. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/addresses/edit.html.erb +12 -0
  84. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/addresses/index.html.erb +18 -0
  85. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/addresses/new.html.erb +11 -0
  86. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/addresses/show.html.erb +3 -0
  87. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/bones/index.rhtml +5 -0
  88. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/layouts/addresses.html.erb +17 -0
  89. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/layouts/sellers.html.erb +17 -0
  90. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/layouts/states.html.erb +17 -0
  91. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/layouts/users.html.erb +17 -0
  92. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/sellers/edit.html.erb +12 -0
  93. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/sellers/index.html.erb +20 -0
  94. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/sellers/new.html.erb +11 -0
  95. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/sellers/show.html.erb +3 -0
  96. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/states/edit.html.erb +12 -0
  97. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/states/index.html.erb +19 -0
  98. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/states/new.html.erb +11 -0
  99. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/states/show.html.erb +3 -0
  100. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/users/edit.html.erb +12 -0
  101. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/users/index.html.erb +22 -0
  102. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/users/new.html.erb +11 -0
  103. data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/users/show.html.erb +3 -0
  104. data/vendor/plugins/has_many_polymorphs/test/integration/app/config/boot.rb +110 -0
  105. data/vendor/plugins/has_many_polymorphs/test/integration/app/config/database.yml +17 -0
  106. data/vendor/plugins/has_many_polymorphs/test/integration/app/config/environment.rb +19 -0
  107. data/vendor/plugins/has_many_polymorphs/test/integration/app/config/environment.rb.canonical +19 -0
  108. data/vendor/plugins/has_many_polymorphs/test/integration/app/config/environments/development.rb +9 -0
  109. data/vendor/plugins/has_many_polymorphs/test/integration/app/config/environments/production.rb +18 -0
  110. data/vendor/plugins/has_many_polymorphs/test/integration/app/config/environments/test.rb +19 -0
  111. data/vendor/plugins/has_many_polymorphs/test/integration/app/config/locomotive.yml +6 -0
  112. data/vendor/plugins/has_many_polymorphs/test/integration/app/config/routes.rb +33 -0
  113. data/vendor/plugins/has_many_polymorphs/test/integration/app/config/ultrasphinx/default.base +56 -0
  114. data/vendor/plugins/has_many_polymorphs/test/integration/app/config/ultrasphinx/development.conf.canonical +155 -0
  115. data/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/001_create_sticks.rb +11 -0
  116. data/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/002_create_stones.rb +11 -0
  117. data/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/003_create_organic_substances.rb +11 -0
  118. data/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/004_create_bones.rb +8 -0
  119. data/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/005_create_single_sti_parents.rb +11 -0
  120. data/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/006_create_double_sti_parents.rb +11 -0
  121. data/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/007_create_single_sti_parent_relationships.rb +13 -0
  122. data/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/008_create_double_sti_parent_relationships.rb +14 -0
  123. data/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/009_create_library_model.rb +11 -0
  124. data/vendor/plugins/has_many_polymorphs/test/integration/app/doc/README_FOR_APP +2 -0
  125. data/vendor/plugins/has_many_polymorphs/test/integration/app/generators/commenting_generator_test.rb +83 -0
  126. data/vendor/plugins/has_many_polymorphs/test/integration/app/lib/library_model.rb +2 -0
  127. data/vendor/plugins/has_many_polymorphs/test/integration/app/public/.htaccess +40 -0
  128. data/vendor/plugins/has_many_polymorphs/test/integration/app/public/404.html +30 -0
  129. data/vendor/plugins/has_many_polymorphs/test/integration/app/public/500.html +30 -0
  130. data/vendor/plugins/has_many_polymorphs/test/integration/app/public/dispatch.cgi +10 -0
  131. data/vendor/plugins/has_many_polymorphs/test/integration/app/public/dispatch.fcgi +24 -0
  132. data/vendor/plugins/has_many_polymorphs/test/integration/app/public/dispatch.rb +10 -0
  133. data/vendor/plugins/has_many_polymorphs/test/integration/app/public/favicon.ico +0 -0
  134. data/vendor/plugins/has_many_polymorphs/test/integration/app/public/images/rails.png +0 -0
  135. data/vendor/plugins/has_many_polymorphs/test/integration/app/public/index.html +277 -0
  136. data/vendor/plugins/has_many_polymorphs/test/integration/app/public/javascripts/application.js +2 -0
  137. data/vendor/plugins/has_many_polymorphs/test/integration/app/public/javascripts/controls.js +833 -0
  138. data/vendor/plugins/has_many_polymorphs/test/integration/app/public/javascripts/dragdrop.js +942 -0
  139. data/vendor/plugins/has_many_polymorphs/test/integration/app/public/javascripts/effects.js +1088 -0
  140. data/vendor/plugins/has_many_polymorphs/test/integration/app/public/javascripts/prototype.js +2515 -0
  141. data/vendor/plugins/has_many_polymorphs/test/integration/app/public/robots.txt +1 -0
  142. data/vendor/plugins/has_many_polymorphs/test/integration/app/public/stylesheets/scaffold.css +74 -0
  143. data/vendor/plugins/has_many_polymorphs/test/integration/app/script/about +3 -0
  144. data/vendor/plugins/has_many_polymorphs/test/integration/app/script/breakpointer +3 -0
  145. data/vendor/plugins/has_many_polymorphs/test/integration/app/script/console +3 -0
  146. data/vendor/plugins/has_many_polymorphs/test/integration/app/script/destroy +3 -0
  147. data/vendor/plugins/has_many_polymorphs/test/integration/app/script/generate +3 -0
  148. data/vendor/plugins/has_many_polymorphs/test/integration/app/script/performance/benchmarker +3 -0
  149. data/vendor/plugins/has_many_polymorphs/test/integration/app/script/performance/profiler +3 -0
  150. data/vendor/plugins/has_many_polymorphs/test/integration/app/script/plugin +3 -0
  151. data/vendor/plugins/has_many_polymorphs/test/integration/app/script/process/inspector +3 -0
  152. data/vendor/plugins/has_many_polymorphs/test/integration/app/script/process/reaper +3 -0
  153. data/vendor/plugins/has_many_polymorphs/test/integration/app/script/process/spawner +3 -0
  154. data/vendor/plugins/has_many_polymorphs/test/integration/app/script/runner +3 -0
  155. data/vendor/plugins/has_many_polymorphs/test/integration/app/script/server +3 -0
  156. data/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/double_sti_parent_relationships.yml +7 -0
  157. data/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/double_sti_parents.yml +7 -0
  158. data/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/organic_substances.yml +5 -0
  159. data/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/single_sti_parent_relationships.yml +7 -0
  160. data/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/single_sti_parents.yml +7 -0
  161. data/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/sticks.yml +7 -0
  162. data/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/stones.yml +7 -0
  163. data/vendor/plugins/has_many_polymorphs/test/integration/app/test/functional/addresses_controller_test.rb +57 -0
  164. data/vendor/plugins/has_many_polymorphs/test/integration/app/test/functional/bones_controller_test.rb +8 -0
  165. data/vendor/plugins/has_many_polymorphs/test/integration/app/test/functional/sellers_controller_test.rb +57 -0
  166. data/vendor/plugins/has_many_polymorphs/test/integration/app/test/functional/states_controller_test.rb +57 -0
  167. data/vendor/plugins/has_many_polymorphs/test/integration/app/test/functional/users_controller_test.rb +57 -0
  168. data/vendor/plugins/has_many_polymorphs/test/integration/app/test/test_helper.rb +8 -0
  169. data/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/bone_test.rb +8 -0
  170. data/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/double_sti_parent_relationship_test.rb +8 -0
  171. data/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/double_sti_parent_test.rb +8 -0
  172. data/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/organic_substance_test.rb +8 -0
  173. data/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/single_sti_parent_relationship_test.rb +8 -0
  174. data/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/single_sti_parent_test.rb +8 -0
  175. data/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/stick_test.rb +8 -0
  176. data/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/stone_test.rb +8 -0
  177. data/vendor/plugins/has_many_polymorphs/test/integration/server_test.rb +43 -0
  178. data/vendor/plugins/has_many_polymorphs/test/models/aquatic/fish.rb +5 -0
  179. data/vendor/plugins/has_many_polymorphs/test/models/aquatic/pupils_whale.rb +7 -0
  180. data/vendor/plugins/has_many_polymorphs/test/models/aquatic/whale.rb +15 -0
  181. data/vendor/plugins/has_many_polymorphs/test/models/beautiful_fight_relationship.rb +26 -0
  182. data/vendor/plugins/has_many_polymorphs/test/models/canine.rb +9 -0
  183. data/vendor/plugins/has_many_polymorphs/test/models/cat.rb +5 -0
  184. data/vendor/plugins/has_many_polymorphs/test/models/dog.rb +18 -0
  185. data/vendor/plugins/has_many_polymorphs/test/models/eaters_foodstuff.rb +8 -0
  186. data/vendor/plugins/has_many_polymorphs/test/models/frog.rb +4 -0
  187. data/vendor/plugins/has_many_polymorphs/test/models/kitten.rb +3 -0
  188. data/vendor/plugins/has_many_polymorphs/test/models/parentship.rb +4 -0
  189. data/vendor/plugins/has_many_polymorphs/test/models/person.rb +9 -0
  190. data/vendor/plugins/has_many_polymorphs/test/models/petfood.rb +39 -0
  191. data/vendor/plugins/has_many_polymorphs/test/models/tabby.rb +2 -0
  192. data/vendor/plugins/has_many_polymorphs/test/models/wild_boar.rb +3 -0
  193. data/vendor/plugins/has_many_polymorphs/test/modules/extension_module.rb +9 -0
  194. data/vendor/plugins/has_many_polymorphs/test/modules/other_extension_module.rb +9 -0
  195. data/vendor/plugins/has_many_polymorphs/test/patches/symlinked_plugins_1.2.6.diff +46 -0
  196. data/vendor/plugins/has_many_polymorphs/test/schema.rb +87 -0
  197. data/vendor/plugins/has_many_polymorphs/test/setup.rb +14 -0
  198. data/vendor/plugins/has_many_polymorphs/test/test_helper.rb +52 -0
  199. data/vendor/plugins/has_many_polymorphs/test/unit/has_many_polymorphs_test.rb +713 -0
  200. metadata +421 -0
@@ -0,0 +1,128 @@
1
+ TaggingMethods = Proc.new do
2
+
3
+ def valid_with_tags?
4
+ return (self.errors.empty? && valid_without_tags?)
5
+ end
6
+ alias_method_chain :valid?, :tags
7
+
8
+ def tag_with tags
9
+ self.save if self.new_record?
10
+ # just skip the whole method if the tags string hasn't changed
11
+ return if tags == tag_list
12
+ # do we need to delete any tags?
13
+ tags_to_delete = tag_list.split(MetaTag::DELIMITER) - tags.split(MetaTag::DELIMITER)
14
+ tags_to_delete.select{|t| meta_tags.delete(MetaTag.find_by_name(t))}
15
+
16
+ tags.split(MetaTag::DELIMITER).each do |tag|
17
+ begin
18
+ tag = MetaTag.find_or_initialize_by_name(tag.strip.squeeze(" "))
19
+ meta_tags << tag unless meta_tags.include?(tag)
20
+ rescue ActiveRecord::RecordInvalid => e
21
+ errors.add_to_base("Tags can not contain special characters")
22
+ rescue ActiveRecord::StatementInvalid => e
23
+ # With SQLite3 - a duplicate tagging will result in the following message:
24
+ # SQLite3::SQLException: SQL logic error or missing database: INSERT INTO taggings ("meta_tag_id", "taggable_type", "taggable_id") VALUES(11, 'Page', 74)
25
+ # raise unless e.to_s =~ /duplicate/i
26
+ end
27
+ end
28
+ end
29
+
30
+ alias :meta_tags= :tag_with
31
+
32
+ def tag_list
33
+ meta_tags.map(&:name).join(MetaTag::DELIMITER)
34
+ end
35
+
36
+ #
37
+ # Find all the objects tagged with the supplied list of tags
38
+ #
39
+ # Usage : Model.tagged_with("ruby")
40
+ # Model.tagged_with("hello", "world")
41
+ # Model.tagged_with("hello", "world", :limit => 10)
42
+ #
43
+ def self.tagged_with(*tag_list)
44
+ options = tag_list.extract_options!
45
+ tag_list = parse_tags(tag_list)
46
+
47
+ scope = scope(:find)
48
+ options[:select] ||= "#{table_name}.*"
49
+ options[:from] ||= "#{table_name}, meta_tags, taggings"
50
+
51
+ sql = "SELECT #{(scope && scope[:select]) || options[:select]} "
52
+ sql << "FROM #{(scope && scope[:from]) || options[:from]} "
53
+
54
+ add_joins!(sql, options[:joins], scope)
55
+
56
+ sql << "WHERE #{table_name}.#{primary_key} = taggings.taggable_id "
57
+ sql << "AND taggings.taggable_type = '#{ActiveRecord::Base.send(:class_name_of_active_record_descendant, self).to_s}' "
58
+ sql << "AND taggings.meta_tag_id = meta_tags.id "
59
+ sql << "AND pages.site_id = #{current_site.id} " if self.respond_to?(:current_site)
60
+
61
+ tag_list_condition = tag_list.map {|name| "\"#{name.strip.squeeze(' ')}\""}.join(", ")
62
+
63
+ sql << "AND (meta_tags.name IN (#{sanitize_sql(tag_list_condition)})) "
64
+ sql << "AND #{sanitize_sql(options[:conditions])} " if options[:conditions]
65
+
66
+ columns = column_names.map do |column|
67
+ "#{table_name}.#{column}"
68
+ end.join(", ")
69
+
70
+ sql << "GROUP BY #{columns} "
71
+ sql << "HAVING COUNT(taggings.meta_tag_id) = #{tag_list.size}"
72
+
73
+ add_order!(sql, options[:order], scope)
74
+ add_limit!(sql, options, scope)
75
+ add_lock!(sql, options, scope)
76
+
77
+
78
+ find_by_sql(sql)
79
+ end
80
+
81
+ def self.tagged_with_any(*tag_list)
82
+ options = tag_list.extract_options!
83
+ tag_list = parse_tags(tag_list)
84
+
85
+ scope = scope(:find)
86
+ options[:select] ||= "#{table_name}.*"
87
+ options[:from] ||= "#{table_name}, meta_tags, taggings"
88
+
89
+ sql = "SELECT #{(scope && scope[:select]) || options[:select]} "
90
+ sql << "FROM #{(scope && scope[:from]) || options[:from]} "
91
+
92
+ add_joins!(sql, options[:joins], scope)
93
+
94
+ sql << "WHERE #{table_name}.#{primary_key} = taggings.taggable_id "
95
+ sql << "AND taggings.taggable_type = '#{ActiveRecord::Base.send(:class_name_of_active_record_descendant, self).to_s}' "
96
+ sql << "AND taggings.meta_tag_id = meta_tags.id "
97
+ sql << "AND pages.site_id = #{current_site.id} " if self.respond_to?(:current_site)
98
+
99
+ sql << "AND ("
100
+ sql << tag_list.inject([]) do |arr,name|
101
+ arr << sanitize_sql(["meta_tags.name = ?", name.strip.squeeze(' ')])
102
+ end.join(" OR ")
103
+ sql << ") "
104
+
105
+
106
+ sql << "AND #{sanitize_sql(options[:conditions])} " if options[:conditions]
107
+
108
+ columns = column_names.map do |column|
109
+ "#{table_name}.#{column}"
110
+ end.join(", ")
111
+
112
+ sql << "GROUP BY #{columns} "
113
+
114
+ add_order!(sql, options[:order], scope)
115
+ add_limit!(sql, options, scope)
116
+ add_lock!(sql, options, scope)
117
+
118
+ find_by_sql(sql)
119
+ end
120
+
121
+ def self.parse_tags(tags)
122
+ return [] if tags.blank?
123
+ tags = Array(tags).first
124
+ tags = tags.respond_to?(:flatten) ? tags.flatten : tags.split(MetaTag::DELIMITER)
125
+ tags.map { |tag| tag.strip.squeeze(" ") }.flatten.compact.uniq
126
+ end
127
+
128
+ end
@@ -0,0 +1,32 @@
1
+ namespace :radiant do
2
+ namespace :extensions do
3
+ namespace :tags do
4
+
5
+ desc "Runs the migration and update tasks of the Tags extension"
6
+ task :install => [:environment, :migrate, :update]
7
+
8
+ desc "Runs the migration of the Tags extension"
9
+ task :migrate => :environment do
10
+ require 'radiant/extension_migrator'
11
+ if ENV["VERSION"]
12
+ TagsExtension.migrator.migrate(ENV["VERSION"].to_i)
13
+ else
14
+ TagsExtension.migrator.migrate
15
+ end
16
+ end
17
+
18
+ desc "Copy needed files to public dir"
19
+ task :update => :environment do
20
+ is_svn_or_dir = proc {|path| path =~ /\.svn/ || File.directory?(path) }
21
+ Dir[TagsExtension.root + "/public/**/*"].reject(&is_svn_or_dir).each do |file|
22
+ path = file.sub(TagsExtension.root, '')
23
+ directory = File.dirname(path)
24
+ puts "Copying #{path}..."
25
+ mkdir_p RAILS_ROOT + directory
26
+ cp file, RAILS_ROOT + path
27
+ end
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,11 @@
1
+ ol.tag_cloud { list-style: none; }
2
+ .tag_cloud li { display: inline; }
3
+ /* hide the extra context from CSS-enabled browsers, but not screenreaders */
4
+ .tag_cloud span { position: absolute; left: 0px; top: -500px; width: 1px; height: 1px; overflow: hidden; }
5
+
6
+ .tag_cloud .size1 { font-size: 1em; }
7
+ .tag_cloud .size2 { font-size: 1.3em; }
8
+ .tag_cloud .size3 { font-size: 1.6em; }
9
+ .tag_cloud .size4 { font-size: 1.9em; }
10
+ .tag_cloud .size5 { font-size: 2.2em; }
11
+ .tag_cloud .size6 { font-size: 2.5em; }
data/tags_extension.rb ADDED
@@ -0,0 +1,57 @@
1
+ require_dependency 'application_controller'
2
+ require File.dirname(__FILE__)+'/lib/tagging_methods'
3
+ require 'radiant-tags-extension'
4
+
5
+ class TagsExtension < Radiant::Extension
6
+ version RadiantTagsExtension::VERSION
7
+ description "This extension enhances the page model with tagging capabilities, tagging as in \"2.0\" and tagclouds."
8
+ url "http://gorilla-webdesign.be"
9
+
10
+ DEFAULT_RESULTS_URL = '/search/by-tag'
11
+
12
+ define_routes do |map|
13
+ if Radiant::Config['tags.results_page_url'].blank?
14
+ Radiant::Config['tags.results_page_url'] = TagsExtension::DEFAULT_RESULTS_URL if Radiant::Config['tags.results_page_url'].blank?
15
+ end
16
+ begin
17
+ if defined?(SiteLanguage) && SiteLanguage.count > 0
18
+ include Globalize
19
+ SiteLanguage.codes.each do |code|
20
+ langname = Locale.new(code).language.code
21
+ map.connect "#{langname}#{Radiant::Config['tags.results_page_url']}/:tag", :controller => 'site', :action => 'show_page', :url => Radiant::Config['tags.results_page_url'], :language => code
22
+ end
23
+ else if defined?(VhostExtension)
24
+ map.connect "#{Radiant::Config['tags.results_page_url']}/:tag", :controller => 'site', :action => 'show_page', :url => Radiant::Config['tags.results_page_url']
25
+ end
26
+ map.connect "#{Radiant::Config['tags.results_page_url']}/:tag", :controller => 'site', :action => 'show_page', :url => Radiant::Config['tags.results_page_url']
27
+ end
28
+ rescue
29
+ # dirty hack; need to get trough here to allow migrations to run..
30
+ end
31
+ end
32
+
33
+ def activate
34
+ raise "The Shards extension is required and must be loaded first!" unless defined?(admin.page)
35
+ if Radiant::Config.table_exists?
36
+ Radiant::Config['tags.results_page_url'] = TagsExtension::DEFAULT_RESULTS_URL unless Radiant::Config['tags.results_page_url']
37
+ Radiant::Config['tags.complex_strings'] = 'false' unless Radiant::Config['tags.complex_strings']
38
+ end
39
+ TagSearchPage
40
+ Page.send :include, RadiusTags
41
+ begin
42
+ MetaTag
43
+ rescue
44
+ # dirty hack; need to get trough here to allow migrations to run..
45
+ end
46
+ Page.module_eval &TaggingMethods
47
+ admin.page.edit.add :extended_metadata, 'tag_field'
48
+
49
+ # HELP
50
+ if admin.respond_to?(:help)
51
+ admin.help.index.add :page_details, 'using_tags', :after => 'breadcrumbs'
52
+ end
53
+ end
54
+
55
+ def deactivate
56
+ end
57
+ end
@@ -0,0 +1,12 @@
1
+ lorem:
2
+ id: 1
3
+ name: lorem
4
+ ipsum:
5
+ id: 2
6
+ name: ipsum
7
+ dolor:
8
+ id: 3
9
+ name: dolor
10
+ sit:
11
+ id: 4
12
+ name: sit
@@ -0,0 +1,17 @@
1
+ display_tags_part:
2
+ id: 1
3
+ page_id: 5
4
+ name: body
5
+ content:
6
+ <h1>Results for <r:search:query /></h1>
7
+ <r:search:empty>
8
+ <h2>No pages tagged with "<r:search:query/>".</h2>
9
+ </r:search:empty>
10
+ <r:search:results>
11
+ <h2>These pages are tagged with "<r:search:query/>".</h2>
12
+ <ul>
13
+ <r:search:results:each order="desc" by="published_at">
14
+ <li><r:link/> door <r:author/> op <r:date/></li>
15
+ </r:search:results:each>
16
+ </ul>
17
+ </r:search:results>
@@ -0,0 +1,43 @@
1
+ # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2
+ homepage:
3
+ id: 1
4
+ title: Ruby Home Page
5
+ breadcrumb: Home
6
+ slug: /
7
+ status_id: 100
8
+ parent_id:
9
+ published_at: 2006-01-30 08:41:07
10
+ documentation:
11
+ id: 2
12
+ title: Documentation
13
+ breadcrumb: Documentation
14
+ slug: documentation
15
+ status_id: 100
16
+ parent_id: 1
17
+ published_at: 2006-01-31 08:41:07
18
+ books:
19
+ id: 3
20
+ title: Books
21
+ breadcrumb: Books
22
+ slug: books
23
+ status_id: 100
24
+ parent_id: 2
25
+ published_at: 2006-01-30 08:41:07
26
+ textile:
27
+ id: 4
28
+ title: Textile
29
+ breadcrumb: Textile
30
+ slug: textile
31
+ status_id: 100
32
+ parent_id: 1
33
+ published_at: 2006-01-30 08:41:07
34
+
35
+ tags_page:
36
+ id: 5
37
+ title: Tags Page
38
+ breadcrumb: tags
39
+ slug: tags
40
+ status_id: 100
41
+ parent_id: 1
42
+ class_name: TagSearchPage
43
+ published_at: 2006-01-30 08:41:07
@@ -0,0 +1,20 @@
1
+ 1:
2
+ meta_tag_id: 1
3
+ taggable_id: 1
4
+ taggable_type: Page
5
+ 2:
6
+ meta_tag_id: 2
7
+ taggable_id: 1
8
+ taggable_type: Page
9
+ 3:
10
+ meta_tag_id: 3
11
+ taggable_id: 1
12
+ taggable_type: Page
13
+ 4:
14
+ meta_tag_id: 1
15
+ taggable_id: 2
16
+ taggable_type: Page
17
+ 5:
18
+ meta_tag_id: 2
19
+ taggable_id: 2
20
+ taggable_type: Page
@@ -0,0 +1,44 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class TagSearchPageTest < Test::Unit::TestCase
4
+
5
+ fixtures :pages, :meta_tags, :taggings, :page_parts
6
+
7
+ def setup
8
+ @page = pages(:tags_page)
9
+ @page.request = ActionController::TestRequest.new
10
+ @page.response = ActionController::TestResponse.new
11
+ end
12
+
13
+ def test_title_gets_set_ok
14
+ @page.request.request_parameters = {:tag => "foo"}
15
+ @page.render
16
+ assert_equal "Tagged with foo", @page.title
17
+ end
18
+
19
+ def test_no_title_means_no_title_change
20
+ @page.render
21
+ assert_equal "Tags Page", @page.title
22
+ end
23
+
24
+ def test_page_should_show_posts_tagged_with_tag
25
+ @page.request.request_parameters = {:tag => "lorem"}
26
+ output = @page.render
27
+ assert_match /These pages are tagged with "lorem"/, output
28
+ assert_match /Ruby Home Page/, output
29
+ assert_match /Documentation/, output
30
+ end
31
+
32
+ def test_resulting_pages_should_be_sorted
33
+ @page.request.request_parameters = {:tag => "lorem"}
34
+ output = @page.render
35
+ assert_match /Documentation.*Ruby Home Page/, output
36
+ end
37
+
38
+ def test_unknown_tag_should_say_so
39
+ @page.request.request_parameters = {:tag => "foobarbar"}
40
+ output = @page.render
41
+ assert_match /No pages tagged with "foobarbar"/, output
42
+ end
43
+
44
+ end
@@ -0,0 +1,19 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class TagsExtensionTest < Test::Unit::TestCase
4
+
5
+ fixtures :pages, :meta_tags, :taggings
6
+ test_helper :render
7
+
8
+ def setup
9
+ @page = pages(:documentation)
10
+ end
11
+
12
+ def test_cloud_tag
13
+ assert_renders "<ol class=\"tag_cloud\"><li class=\"size2\"><span>1 page is tagged with </span><a href=\"?q=dolor\" class=\"tag\">dolor</a></li><li class=\"size3\"><span>2 pages are tagged with </span><a href=\"?q=ipsum\" class=\"tag\">ipsum</a></li><li class=\"size3\"><span>2 pages are tagged with </span><a href=\"?q=lorem\" class=\"tag\">lorem</a></li></ol>", "<r:tag_cloud />"
14
+ end
15
+
16
+ def test_tag_list
17
+ assert_renders "<a href=\"?q=ipsum\" class=\"tag\">ipsum</a>, <a href=\"?q=lorem\" class=\"tag\">lorem</a>", "<r:tag_list />"
18
+ end
19
+ end
@@ -0,0 +1,60 @@
1
+ module RenderTestHelper
2
+
3
+ def assert_renders(expected, input, url = nil, host = nil)
4
+ output = get_render_output(input, url, host)
5
+ message = "<#{expected.inspect}> expected but was <#{output.inspect}>"
6
+ assert_block(message) { expected == output }
7
+ end
8
+
9
+ def assert_render_match(regexp, input, url = nil)
10
+ regexp = Regexp.new(regexp) if regexp.kind_of? String
11
+ output = get_render_output(input, url)
12
+ message = "<#{output.inspect}> expected to be =~ <#{regexp.inspect}>"
13
+ assert_block(message) { output =~ regexp }
14
+ end
15
+
16
+ def assert_render_error(expected_error_message, input, url = nil)
17
+ output = get_render_output(input, url)
18
+ message = "expected error message <#{expected_error_message.inspect}> expected but none was thrown"
19
+ assert_block(message) { false }
20
+ rescue => e
21
+ message = "expected error message <#{expected_error_message.inspect}> but was <#{e.message.inspect}>"
22
+ assert_block(message) { expected_error_message === e.message }
23
+ end
24
+
25
+ def assert_headers(expected_headers, url = nil)
26
+ setup_page(url)
27
+ headers = @page.headers
28
+ message = "<#{expected_headers.inspect}> expected but was <#{headers.inspect}>"
29
+ assert_block(message) { expected_headers == headers }
30
+ end
31
+
32
+ def assert_page_renders(page_name, expected, message = nil)
33
+ page = pages(page_name)
34
+ output = page.render
35
+ message = "<#{expected.inspect}> expected, but was <#{output.inspect}>"
36
+ assert_block(message) { expected == output }
37
+ end
38
+
39
+ def assert_snippet_renders(snippet_name, expected, message = nil)
40
+ snippet = snippets(snippet_name)
41
+ output = @page.render_snippet(snippet)
42
+ message = "<#{expected.inspect}> expected, but was <#{output.inspect}>"
43
+ assert_block(message) { expected == output }
44
+ end
45
+
46
+ private
47
+
48
+ def get_render_output(input, url, host = nil)
49
+ setup_page(url, host)
50
+ @page.send(:parse, input)
51
+ end
52
+
53
+ def setup_page(url = nil, host = nil)
54
+ @page.request = ActionController::TestRequest.new
55
+ @page.request.request_uri = (url || @page.url)
56
+ @page.request.host = host || "testhost.tld"
57
+ @page.response = ActionController::TestResponse.new
58
+ end
59
+
60
+ end
@@ -0,0 +1,20 @@
1
+ require 'test/unit'
2
+ # Load the the environment
3
+ unless defined? RADIANT_ROOT
4
+ ENV["RAILS_ENV"] = "test"
5
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../")}/config/environment"
6
+ end
7
+ require "#{RADIANT_ROOT}/test/test_helper"
8
+
9
+ class Test::Unit::TestCase
10
+
11
+ # Include a helper to make testing Radius tags easier
12
+ test_helper :render
13
+
14
+ # Add the fixture directory to the fixture path
15
+ self.fixture_path << File.dirname(__FILE__) + "/fixtures"
16
+
17
+ fixtures :users, :pages
18
+ # Add more helper methods to be used by all extension tests here...
19
+
20
+ end
@@ -0,0 +1,20 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class PageTaggabilityTest < Test::Unit::TestCase
4
+ def setup
5
+ @page = Page.find 1
6
+ end
7
+
8
+ def test_page_should_be_taggable
9
+ assert true, @page.respond_to?("tag_with")
10
+ assert_difference MetaTag, :count, 2 do
11
+ @page.tag_with 'lorem ipsum'
12
+ end
13
+ end
14
+
15
+ def assert_difference(object, method = nil, difference = 1)
16
+ initial_value = object.send(method)
17
+ yield
18
+ assert_equal initial_value + difference, object.send(method), "#{object}##{method}"
19
+ end
20
+ end
@@ -0,0 +1 @@
1
+ test/integration/app/log
@@ -0,0 +1,86 @@
1
+ v2.2. Various fixes.
2
+
3
+ v2.13. Merge various fixes for Rails 2.2.2.
4
+
5
+ v2.12. Improvements to the test suite; bugfixes for STI children (rsl). Remove fancy dependency system in favor of using Dispatcher::to_prepare every time.
6
+
7
+ v2.11. Rails 1.2.6 tagging generator compatibility; change test suite to use included integration app.
8
+
9
+ v2.10. Add :parent_conditions option; bugfix for nullified conditions; bugfix for self-referential tagging generator; allow setting of has_many_polymorphs_options hash in Configuration's after_initialize if you need to adjust the autoload behavior; clear error message on missing or improperly namespaced models; fix .build on double-sided relationships; add :namespace key for easier set up of Camping apps or other unusual class structures.
10
+
11
+ v2.9. Gem version renumbering; my apologies if this messes anyone up.
12
+
13
+ v2.8. RDoc documentation; repository relocation; Rakefile cleanup; remove deprecated plugin-specific class caching.
14
+
15
+ v2.7.5. Various bugfixes; Postgres problems may remain on edge.
16
+
17
+ v2.7.3. Use new :source and :source_type options in 1.2.3 (David Lemstra); fix pluralization bug; add some tests; experimental tagging generator.
18
+
19
+ v2.7.2. Deprecate has_many_polymorphs_cache_classes= option because it doesn't really work. Use config.cache_classes= instead to cache all reloadable items.
20
+
21
+ v2.7.1. Dispatcher.to_prepare didn't fire in the console; now using a config.after_initialize wrapper instead.
22
+
23
+ v2.7. Dependency injection framework elimates having to care about load order.
24
+
25
+ v2.6. Make the logger act sane for the gem version.
26
+
27
+ v2.5.2. Allow :skip_duplicates on double relationships.
28
+
29
+ v2.5.1. Renamed :ignore_duplicates to :skip_duplicates to better express its non-passive behavior; made sure not to load target set on push unless necessary.
30
+
31
+ v2.5. Activerecord compatibility branch becomes trunk: extra options now supported for double polymorphism; conditions nulled-out and propogated to child relationships; more tests; new :ignore_duplicates option on macro can be set to false if you want << to push duplicate associations.
32
+
33
+ v2.4.1. Code split into multiple files; tests added for pluralization check; Rails 1.1.6 no longer supported.
34
+
35
+ v2.4. Unlimited mixed class association extensions for both single and double targets and joins.
36
+
37
+ v2.3. Gem version
38
+
39
+ v2.2. API change; prefix on methods is now singular when using :rename_individual_collections.
40
+
41
+ v2.1. Add configuration option to cache polymorphic classes in development mode.
42
+
43
+ v2.0. Collection methods (push, delete, clear) now on individual collections.
44
+
45
+ v1.9.2. Disjoint collection sides bugfix, don't raise on new records.
46
+
47
+ v1.9.1. Double classify bugfix.
48
+
49
+ v1.9. Large changes to properly support double polymorphism.
50
+
51
+ v1.8.2. Bugfix to make sure the type gets checked on doubly polymorphic parents.
52
+
53
+ v1.8.1. Bugfix for sqlite3 child attribute retrieval.
54
+
55
+ v1.8. Bugfix for instantiating attributes of namespaced models.
56
+
57
+ v1.7.1. Bugfix for double polymorphic relationships.
58
+
59
+ v1.7. Double polymorphic relationships (includes new API method).
60
+
61
+ v1.6. Namespaced model support.
62
+
63
+ v1.5. Bugfix for Postgres and Mysql under 1.1.6; refactored tests (hildofur); properly handles legacy table names set with set_table_name().
64
+
65
+ v1.4. STI support added (use the child class names, not the base class).
66
+
67
+ v1.3. Bug regarding table names with underscores in SQL query fixed.
68
+
69
+ v1.2. License change, again.
70
+
71
+ v1.1. File_column bug fixed.
72
+
73
+ v1.0. Tests written; after_find and after_initialize now correctly called.
74
+
75
+ v0.5. SQL performance enhancements added.
76
+
77
+ v0.4. Rewrote singletons as full-fledged proxy class so that marshalling works (e.g. in the session).
78
+
79
+ v0.3. Caching added.
80
+
81
+ v0.2. Fixed dependency reloading problem in development mode.
82
+
83
+ v0.1. License change.
84
+
85
+ v0. Added :dependent support on the join table; no changelog before this version.
86
+