refinerycms-blog 2.1.0 → 3.0.1

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.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +9 -23
  3. data/Gemfile +15 -7
  4. data/Rakefile +0 -1
  5. data/app/assets/javascripts/refinery/blog/backend.js +18 -59
  6. data/app/assets/stylesheets/refinery/blog/backend.css.scss +4 -55
  7. data/app/assets/stylesheets/refinery/blog/frontend.css.scss +2 -2
  8. data/app/controllers/refinery/blog/admin/categories_controller.rb +6 -0
  9. data/app/controllers/refinery/blog/admin/posts_controller.rb +25 -3
  10. data/app/controllers/refinery/blog/blog_controller.rb +31 -5
  11. data/app/controllers/refinery/blog/categories_controller.rb +10 -3
  12. data/app/controllers/refinery/blog/posts_controller.rb +16 -6
  13. data/app/helpers/refinery/blog/controller_helper.rb +1 -22
  14. data/app/models/refinery/blog/categorization.rb +0 -1
  15. data/app/models/refinery/blog/category.rb +3 -6
  16. data/app/models/refinery/blog/comment.rb +15 -17
  17. data/app/models/refinery/blog/post.rb +44 -43
  18. data/app/views/refinery/blog/admin/_submenu.html.erb +1 -3
  19. data/app/views/refinery/blog/admin/categories/_category.html.erb +14 -5
  20. data/app/views/refinery/blog/admin/posts/_form.html.erb +13 -6
  21. data/app/views/refinery/blog/admin/posts/_form_part.html.erb +1 -1
  22. data/app/views/refinery/blog/admin/posts/_post.html.erb +12 -5
  23. data/app/views/refinery/blog/admin/posts/_teaser_part.html.erb +1 -1
  24. data/app/views/refinery/blog/posts/index.html.erb +2 -2
  25. data/app/views/refinery/blog/shared/_categories.html.erb +3 -3
  26. data/app/views/refinery/shared/admin/_autocomplete.html.erb +45 -0
  27. data/bin/rails +5 -0
  28. data/bin/refinerycms +62 -0
  29. data/changelog.md +4 -1
  30. data/config/locales/cs.yml +2 -2
  31. data/config/locales/en.yml +3 -0
  32. data/config/locales/fr.yml +6 -4
  33. data/config/locales/nb.yml +154 -14
  34. data/config/locales/nl.yml +21 -0
  35. data/config/locales/pl.yml +2 -2
  36. data/config/locales/ru.yml +25 -14
  37. data/config/locales/zh-CN.yml +32 -1
  38. data/config/locales/zh-TW.yml +160 -0
  39. data/config/routes.rb +6 -3
  40. data/db/migrate/20110803223522_create_blog_structure.rb +4 -4
  41. data/db/migrate/20120531113632_delete_cached_slugs.rb +2 -2
  42. data/db/migrate/20140622132537_add_missing_unique_indices.acts_as_taggable_on_engine.rb +20 -0
  43. data/db/migrate/20140622132538_add_taggings_counter_cache_to_tags.acts_as_taggable_on_engine.rb +15 -0
  44. data/db/seeds.rb +4 -4
  45. data/lib/refinery/blog.rb +1 -1
  46. data/lib/refinery/blog/configuration.rb +1 -1
  47. data/lib/refinery/blog/engine.rb +8 -3
  48. data/readme.md +21 -6
  49. data/refinerycms-blog.gemspec +9 -7
  50. data/script/rails +1 -3
  51. data/spec/controllers/refinery/blog/admin/comments_controller_spec.rb +23 -19
  52. data/spec/controllers/refinery/blog/admin/posts_controller_spec.rb +35 -0
  53. data/spec/controllers/refinery/blog/posts_controller_spec.rb +3 -3
  54. data/spec/factories/blog_posts.rb +1 -1
  55. data/spec/factories/user.rb +27 -0
  56. data/spec/features/refinery/blog/admin/categories_spec.rb +106 -104
  57. data/spec/features/refinery/blog/admin/comments_spec.rb +18 -18
  58. data/spec/features/refinery/blog/admin/menu_spec.rb +14 -8
  59. data/spec/features/refinery/blog/admin/posts_spec.rb +99 -86
  60. data/spec/features/refinery/blog/categories_spec.rb +20 -18
  61. data/spec/features/refinery/blog/posts_spec.rb +128 -124
  62. data/spec/helpers/refinery/blog/posts_helper_spec.rb +13 -13
  63. data/spec/lib/refinery/blog/engine_spec.rb +1 -11
  64. data/spec/models/refinery/blog/category_spec.rb +10 -10
  65. data/spec/models/refinery/blog/comment_spec.rb +3 -3
  66. data/spec/models/refinery/blog/post_spec.rb +59 -33
  67. data/spec/spec_helper.rb +2 -3
  68. metadata +75 -50
  69. data/app/assets/images/refinery/blog/icons/add.png +0 -0
  70. data/app/assets/images/refinery/blog/icons/cog.png +0 -0
  71. data/app/assets/images/refinery/blog/icons/comment.png +0 -0
  72. data/app/assets/images/refinery/blog/icons/comment_cross.png +0 -0
  73. data/app/assets/images/refinery/blog/icons/comment_tick.png +0 -0
  74. data/app/assets/images/refinery/blog/icons/comments.png +0 -0
  75. data/app/assets/images/refinery/blog/icons/down.gif +0 -0
  76. data/app/assets/images/refinery/blog/icons/folder.png +0 -0
  77. data/app/assets/images/refinery/blog/icons/folder_add.png +0 -0
  78. data/app/assets/images/refinery/blog/icons/folder_edit.png +0 -0
  79. data/app/assets/images/refinery/blog/icons/page.png +0 -0
  80. data/app/assets/images/refinery/blog/icons/page_add.png +0 -0
  81. data/app/assets/images/refinery/blog/icons/page_copy.png +0 -0
  82. data/app/assets/images/refinery/blog/icons/up.gif +0 -0
  83. data/spec/helpers/refinery/blog/controller_helper_spec.rb +0 -27
  84. data/todo.md +0 -5
@@ -2,28 +2,7 @@ module Refinery
2
2
  module Blog
3
3
  module ControllerHelper
4
4
 
5
- protected
6
-
7
- def find_blog_post
8
- unless (@post = Refinery::Blog::Post.with_globalize.find(params[:id])).try(:live?)
9
- if refinery_user? and current_refinery_user.authorized_plugins.include?("refinerycms_blog")
10
- @post = Refinery::Blog::Post.find(params[:id])
11
- else
12
- error_404
13
- end
14
- end
15
- end
16
-
17
- def find_all_blog_posts
18
- @posts = Refinery::Blog::Post.live.includes(:comments, :categories).with_globalize.page(params[:page])
19
- end
20
-
21
- def find_tags
22
- @tags = Refinery::Blog::Post.live.tag_counts_on(:tags)
23
- end
24
- def find_all_blog_categories
25
- @categories = Refinery::Blog::Category.translated
26
- end
5
+
27
6
  end
28
7
  end
29
8
  end
@@ -6,7 +6,6 @@ module Refinery
6
6
  belongs_to :blog_post, :class_name => 'Refinery::Blog::Post', :foreign_key => :blog_post_id
7
7
  belongs_to :blog_category, :class_name => 'Refinery::Blog::Category', :foreign_key => :blog_category_id
8
8
 
9
- attr_accessible :blog_category_id, :blog_post_id
10
9
  end
11
10
  end
12
11
  end
@@ -1,10 +1,10 @@
1
1
  module Refinery
2
2
  module Blog
3
3
  class Category < ActiveRecord::Base
4
+ extend FriendlyId
4
5
 
5
6
  translates :title, :slug
6
7
 
7
- extend FriendlyId
8
8
  friendly_id :title, :use => [:slugged, :globalize]
9
9
 
10
10
  has_many :categorizations, :dependent => :destroy, :foreign_key => :blog_category_id
@@ -12,11 +12,8 @@ module Refinery
12
12
 
13
13
  validates :title, :presence => true, :uniqueness => true
14
14
 
15
- attr_accessible :title
16
- attr_accessor :locale
17
-
18
- class Translation
19
- attr_accessible :locale
15
+ def self.by_title(title)
16
+ joins(:translations).find_by(title: title)
20
17
  end
21
18
 
22
19
  def self.translated
@@ -1,31 +1,29 @@
1
+ require 'filters_spam'
2
+
1
3
  module Refinery
2
4
  module Blog
3
5
  class Comment < ActiveRecord::Base
4
6
 
5
- attr_accessible :name, :email, :message
6
-
7
- filters_spam :author_field => :name,
8
- :email_field => :email,
9
- :message_field => :body
7
+ filters_spam author_field: :name, email_field: :email, message_field: :body
10
8
 
11
- belongs_to :post, :foreign_key => 'blog_post_id'
9
+ belongs_to :post, foreign_key: 'blog_post_id'
12
10
 
13
11
  alias_attribute :message, :body
14
12
 
15
- validates :name, :message, :presence => true
16
- validates :email, :format => { :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i }
13
+ validates :name, :message, presence: true
14
+ validates :email, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i }
17
15
 
18
16
  class << self
19
17
  def unmoderated
20
- where(:state => nil)
18
+ where(state: nil)
21
19
  end
22
20
 
23
21
  def approved
24
- where(:state => 'approved')
22
+ where(state: 'approved')
25
23
  end
26
24
 
27
25
  def rejected
28
- where(:state => 'rejected')
26
+ where(state: 'rejected')
29
27
  end
30
28
  end
31
29
 
@@ -55,7 +53,7 @@ module Refinery
55
53
  currently = Refinery::Setting.find_or_set(:comments_allowed, true, {
56
54
  :scoping => 'blog'
57
55
  })
58
- Refinery::Setting.set(:comments_allowed, {:value => !currently, :scoping => 'blog'})
56
+ Refinery::Setting.set(:comments_allowed, {value: !currently, scoping: 'blog'})
59
57
  end
60
58
 
61
59
  before_create do |comment|
@@ -68,16 +66,16 @@ module Refinery
68
66
  class << self
69
67
  def enabled?
70
68
  Refinery::Setting.find_or_set(:comment_moderation, true, {
71
- :scoping => 'blog',
72
- :restricted => false
69
+ scoping: 'blog',
70
+ restricted: false
73
71
  })
74
72
  end
75
73
 
76
74
  def toggle!
77
75
  new_value = {
78
- :value => !Blog::Comment::Moderation.enabled?,
79
- :scoping => 'blog',
80
- :restricted => false
76
+ value: !Blog::Comment::Moderation.enabled?,
77
+ scoping: 'blog',
78
+ restricted: false
81
79
  }
82
80
  Refinery::Setting.set(:comment_moderation, new_value)
83
81
  end
@@ -4,51 +4,50 @@ require 'seo_meta'
4
4
  module Refinery
5
5
  module Blog
6
6
  class Post < ActiveRecord::Base
7
+ extend FriendlyId
7
8
 
8
9
  translates :title, :body, :custom_url, :custom_teaser, :slug, :include => :seo_meta
9
10
 
10
- extend FriendlyId
11
11
  friendly_id :friendly_id_source, :use => [:slugged, :globalize]
12
12
 
13
- is_seo_meta if self.table_exists?
14
-
15
- default_scope :order => 'published_at DESC'
16
-
17
- belongs_to :author, :class_name => Refinery::Blog.user_class.to_s, :foreign_key => :user_id, :readonly => true
13
+ is_seo_meta
18
14
 
19
- has_many :comments, :dependent => :destroy, :foreign_key => :blog_post_id
20
15
  acts_as_taggable
21
16
 
17
+ belongs_to :author, proc { readonly(true) }, :class_name => Refinery::Blog.user_class.to_s, :foreign_key => :user_id
18
+ has_many :comments, :dependent => :destroy, :foreign_key => :blog_post_id
22
19
  has_many :categorizations, :dependent => :destroy, :foreign_key => :blog_post_id
23
20
  has_many :categories, :through => :categorizations, :source => :blog_category
24
21
 
25
22
  validates :title, :presence => true, :uniqueness => true
26
23
  validates :body, :presence => true
27
- validates :published_at, :author, :presence => true
28
-
24
+ validates :published_at, :presence => true
25
+ validates :author, :presence => true, if: :author_required?
29
26
  validates :source_url, :url => { :if => 'Refinery::Blog.validate_source_url',
30
27
  :update => true,
31
28
  :allow_nil => true,
32
29
  :allow_blank => true,
33
30
  :verify => [:resolve_redirects]}
34
31
 
35
- attr_accessible :title, :body, :custom_teaser, :tag_list, :draft, :published_at, :custom_url, :author
36
- attr_accessible :browser_title, :meta_description, :user_id, :category_ids
37
- attr_accessible :source_url, :source_url_title
38
- attr_accessor :locale
39
-
32
+ class Translation
33
+ is_seo_meta
34
+ end
35
+
36
+ # Override this to disable required authors
37
+ def author_required?
38
+ true
39
+ end
40
40
 
41
- class Translation
42
- is_seo_meta
43
- attr_accessible :browser_title, :meta_description, :locale
44
- end
41
+ # If custom_url or title changes tell friendly_id to regenerate slug when
42
+ # saving record
43
+ def should_generate_new_friendly_id?
44
+ custom_url_changed? || title_changed?
45
+ end
45
46
 
46
- # Delegate SEO Attributes to globalize3 translation
47
+ # Delegate SEO Attributes to globalize translation
47
48
  seo_fields = ::SeoMeta.attributes.keys.map{|a| [a, :"#{a}="]}.flatten
48
49
  delegate(*(seo_fields << {:to => :translation}))
49
50
 
50
- before_save { |m| m.translation.save }
51
-
52
51
  self.per_page = Refinery::Blog.posts_per_page
53
52
 
54
53
  def next
@@ -60,7 +59,7 @@ module Refinery
60
59
  end
61
60
 
62
61
  def live?
63
- !draft and published_at <= Time.now
62
+ !draft && published_at <= Time.now
64
63
  end
65
64
 
66
65
  def friendly_id_source
@@ -79,56 +78,58 @@ module Refinery
79
78
  end
80
79
  end
81
80
  # A join implies readonly which we don't really want.
82
- joins(:translations).where(globalized_conditions).where(conditions).readonly(false)
81
+ where(conditions).joins(:translations).where(globalized_conditions)
82
+ .readonly(false)
83
83
  end
84
84
 
85
- def find_by_slug_or_id(slug_or_id)
86
- if slug_or_id.friendly_id?
87
- find_by_slug(slug_or_id)
88
- else
89
- find(slug_or_id)
90
- end
85
+ def by_month(date)
86
+ newest_first.where(:published_at => date.beginning_of_month..date.end_of_month)
91
87
  end
92
88
 
93
- def by_month(date)
94
- where(:published_at => date.beginning_of_month..date.end_of_month)
89
+ def by_year(date)
90
+ newest_first.where(:published_at => date.beginning_of_year..date.end_of_year).with_globalize
95
91
  end
96
92
 
97
- def by_archive(date)
98
- Refinery.deprecate("Refinery::Blog::Post.by_archive(date)", {:replacement => "Refinery::Blog::Post.by_month(date)", :when => 2.2 })
99
- by_month(date)
93
+ def by_title(title)
94
+ joins(:translations).find_by(:title => title)
100
95
  end
101
96
 
102
- def by_year(date)
103
- where(:published_at => date.beginning_of_year..date.end_of_year).with_globalize
97
+ def newest_first
98
+ order("published_at DESC")
104
99
  end
105
100
 
106
101
  def published_dates_older_than(date)
107
- published_before(date).select(:published_at).map(&:published_at)
102
+ newest_first.published_before(date).select(:published_at).map(&:published_at)
108
103
  end
109
104
 
110
105
  def recent(count)
111
- live.limit(count)
106
+ newest_first.live.limit(count)
112
107
  end
113
108
 
114
109
  def popular(count)
115
- unscoped.order("access_count DESC").limit(count).with_globalize
110
+ order("access_count DESC").limit(count).with_globalize
116
111
  end
117
112
 
118
113
  def previous(item)
119
- published_before(item.published_at).first
114
+ newest_first.published_before(item.published_at).first
120
115
  end
121
116
 
122
117
  def uncategorized
123
- live.includes(:categories).where(Refinery::Blog::Categorization.table_name => { :blog_category_id => nil })
118
+ newest_first.live.includes(:categories).where(
119
+ Refinery::Blog::Categorization.table_name => { :blog_category_id => nil }
120
+ )
124
121
  end
125
122
 
126
123
  def next(current_record)
127
- where(["published_at > ? and draft = ?", current_record.published_at, false]).reorder('published_at ASC').with_globalize.first
124
+ where(arel_table[:published_at].gt(current_record.published_at))
125
+ .where(:draft => false)
126
+ .order('published_at ASC').with_globalize.first
128
127
  end
129
128
 
130
129
  def published_before(date=Time.now)
131
- where("published_at < ? and draft = ?", date, false).with_globalize
130
+ where(arel_table[:published_at].lt(date))
131
+ .where(:draft => false)
132
+ .with_globalize
132
133
  end
133
134
  alias_method :live, :published_before
134
135
 
@@ -1,8 +1,6 @@
1
1
  <nav id='actions' class='multilist'>
2
2
  <ul class='search_list'>
3
- <li class='not_a_link'>
4
- <%= render "/refinery/admin/search", :url => request.path %>
5
- </li>
3
+ <li class='not_a_link'><%= render "/refinery/admin/search", :url => request.path -%></li>
6
4
  </ul>
7
5
 
8
6
  <ul class='collapsible_menu'>
@@ -2,12 +2,21 @@
2
2
  <span class='title'>
3
3
  <%= category.title.presence || category.translations.detect {|t| t.title.present?}.title %>
4
4
  <span class="preview">
5
- <% category.translations.each do |translation| %>
6
- <% if translation.title.present? %>
7
- <%= link_to refinery_icon_tag("flags/#{translation.locale}.png", :size => '16x11'),
8
- refinery.edit_blog_admin_category_path(category, :switch_locale => translation.locale),
9
- :class => 'locale' %>
5
+ <% if Refinery::I18n.frontend_locales.many? %>
6
+ <span class='locales'>
7
+ <% category.translations.sort_by{ |t| Refinery::I18n.frontend_locales.index(t.locale)}.each do |translation| %>
8
+ <% if translation.title.present? %>
9
+ <%= link_to refinery.edit_blog_admin_category_path(category,
10
+ :switch_locale => translation.locale),
11
+ :class => 'locale',
12
+ :title => translation.locale.upcase do %>
13
+ <div class="<%=translation.locale %> locale_marker">
14
+ <%= locale_text_icon(translation.locale.upcase) %>
15
+ </div>
16
+ <% end %>
17
+ <% end %>
10
18
  <% end %>
19
+ </span>
11
20
  <% end %>
12
21
  </span>
13
22
  </span>
@@ -40,14 +40,14 @@
40
40
  </div>
41
41
  </div>
42
42
 
43
- <%= render '/refinery/admin/form_advanced_options_menu', :f => f %>
44
-
45
43
  <div class='field'>
46
44
  <%= f.label :tag_list, t('refinery.blog.shared.tags.title') -%>
47
- <%= f.text_field :tag_list, :class => 'larger' -%>
45
+ <%= f.text_field :tag_list, value: @post.tag_list.to_s, :class => 'larger' -%>
48
46
  </div>
49
47
 
50
- <div id='more_options' style="display:none;">
48
+ <%= render '/refinery/admin/form_advanced_options_menu', :f => f %>
49
+
50
+ <div id='more_options'>
51
51
  <div class="hemisquare">
52
52
  <h3><%= t('title', :scope => 'refinery.blog.admin.submenu.categories') %></h3>
53
53
  <ul class='blog_categories'>
@@ -106,11 +106,18 @@
106
106
  <%= render "/refinery/admin/form_actions",
107
107
  :f => f,
108
108
  :continue_editing => true,
109
- :delete_title => t('delete', :scope => 'refinery.blog.admin.posts.post') %>
109
+ :delete_title => t('delete', :scope => 'refinery.blog.admin.posts.post'),
110
+ :before_delete_button => (link_to(t('delete_translation', :scope => 'refinery.blog.admin.posts.post'),
111
+ refinery.delete_translation_blog_admin_post_path(@post, :locale_to_delete => Globalize.locale),
112
+ :method => :post,
113
+ :data => {
114
+ :confirm => t('delete_translation_confirmation', :scope => 'refinery.blog.admin.posts.post')
115
+ },
116
+ :class => "button confirm-delete") if Refinery::I18n.frontend_locales.many? && @post.translations.size > 1) %>
110
117
  <% end -%>
111
118
 
112
119
  <% content_for :stylesheets, stylesheet_link_tag('refinery/blog/backend') %>
113
120
  <% content_for :javascripts, javascript_include_tag('refinery/blog/backend') %>
114
121
  <%= render 'refinery/shared/admin/autocomplete',
115
- :dom_id => '#blog_post_tag_list',
122
+ :dom_id => '#post_tag_list',
116
123
  :url => refinery.tags_blog_admin_posts_url %>
@@ -1,3 +1,3 @@
1
1
  <div class='page_part' id='page_part_body'>
2
- <%= f.text_area :body, :rows => 20, :class => 'wymeditor widest' -%>
2
+ <%= f.text_area :body, :rows => 20, :class => 'visual_editor widest' -%>
3
3
  </div>
@@ -2,12 +2,19 @@
2
2
  <span class='title'>
3
3
  <%= post.title.presence || post.translations.detect {|t| t.title.present?}.title %>
4
4
  <span class="preview">
5
- <% post.translations.each do |translation| %>
6
- <% if translation.title.present? %>
7
- <%= link_to refinery_icon_tag("flags/#{translation.locale}.png", :size => '16x11'),
8
- refinery.edit_blog_admin_post_path(post, :switch_locale => translation.locale),
9
- :class => 'locale' %>
5
+ <% if Refinery::I18n.frontend_locales.many? %>
6
+ <span class='locales'>
7
+ <% post.translations.sort_by{ |t| Refinery::I18n.frontend_locales.index(t.locale)}.each do |translation| %>
8
+ <% if translation.title.present? %>
9
+ <%= link_to refinery.edit_blog_admin_post_path(post, :switch_locale => translation.locale), :class => 'locale', title: translation.locale.upcase do %>
10
+
11
+ <div class="<%=translation.locale %> locale_marker">
12
+ <%= locale_text_icon(translation.locale.upcase) %>
13
+ </div>
14
+ <% end %>
15
+ <% end %>
10
16
  <% end %>
17
+ </span>
11
18
  <% end %>
12
19
 
13
20
  <%= post.published_at.try(:strftime, '%b %d, %Y') || 'draft' %>
@@ -1,5 +1,5 @@
1
1
  <div class='page_part' id='page_part_teaser'>
2
- <%= f.text_area :custom_teaser, :rows => 20, :class => 'wymeditor widest' -%>
2
+ <%= f.text_area :custom_teaser, :rows => 20, :class => 'visual_editor widest' -%>
3
3
  <p>
4
4
  <span class='clearfix label_inline_with_link'>
5
5
  <%= link_to t('copy_body', :scope => 'refinery.blog.admin.posts.form'), "#",
@@ -1,5 +1,5 @@
1
1
  <% content_for :body do %>
2
- <%= raw @page.content_for(Refinery::Pages.default_parts.first.to_sym) if Refinery::Pages.default_parts.any? %>
2
+ <%= raw @page.content_for(Refinery::Pages.default_parts.first[:slug].to_sym) if Refinery::Pages.default_parts.any? %>
3
3
 
4
4
  <% if @posts.any? %>
5
5
  <section id="blog_posts">
@@ -12,7 +12,7 @@
12
12
  <% end %>
13
13
 
14
14
  <% content_for :side_body_prepend do -%>
15
- <%= raw @page.content_for(Refinery::Pages.default_parts.second.to_sym) %>
15
+ <%= raw @page.content_for(Refinery::Pages.default_parts.second[:slug].to_sym) %>
16
16
  <% end if Refinery::Pages.default_parts.many? -%>
17
17
  <%= render '/refinery/blog/shared/body_content_right' %>
18
18
 
@@ -1,10 +1,10 @@
1
1
  <% if @categories.any? %>
2
2
  <h2><%= t('.title') %></h2>
3
- <ul id='categories'>
3
+ <ul id="categories">
4
4
  <% @categories.each do |category| %>
5
- <li<%= " class='selected'" if @category.present? and @category.id == category.id %>>
5
+ <li<%== ' class="selected"' if @category.present? && @category.id == category.id %>>
6
6
  <%= link_to "#{category.title} (#{category.post_count})", refinery.blog_category_path(category) %>
7
7
  </li>
8
8
  <% end %>
9
9
  </ul>
10
- <% end %>
10
+ <% end %>
@@ -1 +1,46 @@
1
1
  <% content_for :stylesheets, stylesheet_link_tag("refinery/blog/ui-lightness/jquery-ui-1.8.13.custom") %>
2
+ <% content_for :javascripts do %>
3
+ <script>
4
+ function split(val) {
5
+ return val.split(/,\s*/);
6
+ }
7
+ function extractLast(term) {
8
+ return split(term).pop();
9
+ }
10
+ $(document).ready(function(){
11
+ $('<%= dom_id %>').bind("keydown", function(event) {
12
+ if (event.keyCode === $.ui.keyCode.TAB && $(this).data("autocomplete").menu.active) {
13
+ event.preventDefault()
14
+ }
15
+ }).autocomplete({
16
+ source: function(request, response) {
17
+ $.getJSON("<%= url %>", {
18
+ term: extractLast(request.term)
19
+ }, response);
20
+ },
21
+ search: function() {
22
+ // custom minLength
23
+ var term = extractLast(this.value);
24
+ if (term.length < 2) {
25
+ return false;
26
+ }
27
+ },
28
+ focus: function() {
29
+ // prevent value inserted on focus
30
+ return false;
31
+ },
32
+ select: function(event, ui) {
33
+ var terms = split(this.value);
34
+ // remove the current input
35
+ terms.pop();
36
+ // add the selected item
37
+ terms.push(ui.item.value);
38
+ // add placeholder to get the comma-and-space at the end
39
+ terms.push("");
40
+ this.value = terms.join(", ");
41
+ return false;
42
+ }
43
+ });
44
+ })
45
+ </script>
46
+ <% end %>