adva_blog 0.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 (43) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +22 -0
  5. data/README.md +29 -0
  6. data/Rakefile +2 -0
  7. data/adva_blog.gemspec +17 -0
  8. data/app/controllers/admin/blog/articles_controller.rb +5 -0
  9. data/app/controllers/admin/blog/categories_controller.rb +1 -0
  10. data/app/controllers/admin/blog/contents_controller.rb +5 -0
  11. data/app/controllers/admin/blogs_controller.rb +1 -0
  12. data/app/controllers/blog_articles_controller.rb +23 -0
  13. data/app/helpers/blog_helper.rb +49 -0
  14. data/app/models/blog.rb +34 -0
  15. data/app/views/admin/blog/articles/index.html.erb +40 -0
  16. data/app/views/admin/sections/settings/_blog.html.erb +11 -0
  17. data/app/views/blogs/articles/_article.html.erb +28 -0
  18. data/app/views/blogs/articles/_footer.html.erb +40 -0
  19. data/app/views/blogs/articles/index.atom.builder +21 -0
  20. data/app/views/blogs/articles/index.html.erb +4 -0
  21. data/app/views/blogs/articles/show.html.erb +14 -0
  22. data/config/initializers/base_controller.rb +3 -0
  23. data/config/routes.rb +49 -0
  24. data/lib/adva_blog.rb +10 -0
  25. data/lib/adva_blog/version.rb +3 -0
  26. data/test/contexts.rb +9 -0
  27. data/test/fixtures.rb +50 -0
  28. data/test/functional/blog_articles_controller_test.rb +139 -0
  29. data/test/functional/blog_articles_routes_test.rb +159 -0
  30. data/test/integration/admin/blog_article_test.rb +54 -0
  31. data/test/integration/admin/blog_ping_test.rb +68 -0
  32. data/test/integration/admin/blog_test.rb +43 -0
  33. data/test/integration/blog_article_test.rb +40 -0
  34. data/test/integration/blog_categories_test.rb +55 -0
  35. data/test/integration/blog_comment_test.rb +51 -0
  36. data/test/integration/blog_index_test.rb +104 -0
  37. data/test/test_helper.rb +2 -0
  38. data/test/unit/cells/blog_cell_test.rb +29 -0
  39. data/test/unit/helpers/blog_helper_test.rb +50 -0
  40. data/test/unit/helpers/content_helper_test.rb +19 -0
  41. data/test/unit/models/blog_test.rb +37 -0
  42. data/test/unit/models/counter_test.rb +44 -0
  43. metadata +101 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: eaca04c9824c2a859bd1a6702a393f9d6bd47608
4
+ data.tar.gz: 9b49939cb632912f8a3a7e3718bdd7bc40ab2e2b
5
+ SHA512:
6
+ metadata.gz: 6f1a8bf1af639cc618b2182e1f3e6c55ea5e0b40abe5270d2b3e21e70197eed4b1139858446bdb8ca80c72732d38cc2551ffd89ca69ffece4eebad7d6b6c2c7d
7
+ data.tar.gz: 178fdf0d38457b057202543ad331f83c1d32a57f94372f0b7bcc846892d0202fe1ad4f675fb0a84ae149a64a78481edbc44f0cef71aba0a4f74a1443ebcbd4c2
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in adva_blog.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Micah Geisel
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.
@@ -0,0 +1,29 @@
1
+ # AdvaBlog
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'adva_blog'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install adva_blog
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,17 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/adva_blog/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Micah Geisel"]
6
+ gem.email = ["micah@botandrose.com"]
7
+ gem.description = %q{Adva Blog}
8
+ gem.summary = %q{Engine for Adva CMS blog component}
9
+ gem.homepage = ""
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "adva_blog"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = AdvaBlog::VERSION
17
+ end
@@ -0,0 +1,5 @@
1
+ class Admin::Blog::ArticlesController < Admin::Page::ArticlesController
2
+ def index
3
+ @contents = @section.articles
4
+ end
5
+ end
@@ -0,0 +1 @@
1
+ class Admin::Blog::CategoriesController < Admin::Page::CategoriesController; end
@@ -0,0 +1,5 @@
1
+ class Admin::Blog::ContentsController < Admin::Page::ContentsController
2
+ def index
3
+ redirect_to [:admin, @site, @section, :articles]
4
+ end
5
+ end
@@ -0,0 +1 @@
1
+ class Admin::BlogsController < Admin::SectionsController; end
@@ -0,0 +1,23 @@
1
+ class BlogArticlesController < ArticlesController
2
+ def index
3
+ if skip_caching? or stale?(:etag => @section, :last_modified => [@articles.to_a, @section, @site].flatten.collect(&:updated_at).compact.max.utc, :public => true)
4
+ respond_to do |format|
5
+ format.html { render :template => "blogs/articles/index" }
6
+ format.atom { render :template => "blogs/articles/index", :layout => false }
7
+ end
8
+ end
9
+ end
10
+
11
+ protected
12
+ def set_articles
13
+ scope = @category ? @category.all_contents : @section.articles
14
+ scope = scope.tagged("'#{@tags}'") if @tags.present?
15
+ scope = scope.published # (params[:year], params[:month])
16
+ scope = scope.includes(:approved_comments_counter) if defined?(Comment)
17
+ @articles = scope.paginate(page: current_page, per_page: @section.contents_per_page).order(published_at: :desc)
18
+ end
19
+
20
+ def valid_article?
21
+ @article and (@article.draft? or @article.published_at?(params.values_at(:year, :month, :day)))
22
+ end
23
+ end
@@ -0,0 +1,49 @@
1
+ module BlogHelper
2
+ def articles_title(*args)
3
+ options = args.extract_options!
4
+ category, tags, month = *args
5
+ month = archive_month(month) if month && !month.is_a?(Time)
6
+
7
+ title = []
8
+ title << t(:'adva.blog.titles.date', :date => l(month, :format => '%B %Y')) if month
9
+ title << t(:'adva.blog.titles.about', :category => category.title) if category
10
+ title << t(:'adva.blog.titles.tags', :tags => tags.to_sentence) if tags
11
+
12
+ if title.present?
13
+ title = t(:'adva.blog.titles.articles', :articles => title.join(', '))
14
+ options[:format] ? raw(options[:format]) % title : title
15
+ end
16
+ end
17
+
18
+ def archive_month(params = {})
19
+ Time.local(params[:year], params[:month]) if params[:year]
20
+ end
21
+
22
+ def blog_article_path section, article
23
+ if article.published_at
24
+ super :section_permalink => section.permalink,
25
+ :year => article.published_at.year,
26
+ :month => article.published_at.month,
27
+ :day => article.published_at.day,
28
+ :permalink => article.permalink
29
+ else
30
+ unpublished_blog_article_path section, article
31
+ end
32
+ end
33
+
34
+ def blog_article_url section, article
35
+ if article.published_at
36
+ super :section_permalink => section.permalink,
37
+ :year => article.published_at.year,
38
+ :month => article.published_at.month,
39
+ :day => article.published_at.day,
40
+ :permalink => article.permalink
41
+ else
42
+ unpublished_blog_article_url section, article
43
+ end
44
+ end
45
+
46
+ def absolutize_links html
47
+ html.gsub /(href|src)="\//, %(\\1="http://#{@site.host}/)
48
+ end
49
+ end
@@ -0,0 +1,34 @@
1
+ class Blog < Section
2
+ has_many :articles, -> { order("contents.published_at DESC") }, :foreign_key => 'section_id', :dependent => :destroy do
3
+ def permalinks
4
+ published.map(&:permalink)
5
+ end
6
+ end
7
+ alias_method :contents, :articles
8
+
9
+ class << self
10
+ def content_types
11
+ %w(Article)
12
+ end
13
+ end
14
+
15
+ def archive_months
16
+ article_counts_by_month.transpose.first
17
+ end
18
+
19
+ def article_counts_by_month
20
+ articles_by_month.map{|month, articles| [month, articles.size]}
21
+ end
22
+
23
+ def articles_by_year
24
+ @articles_by_year ||= articles.published.group_by(&:published_year)
25
+ end
26
+
27
+ def articles_by_month
28
+ @articles_by_month ||= articles.published.group_by(&:published_month)
29
+ end
30
+
31
+ def nav_children
32
+ categories.roots
33
+ end
34
+ end
@@ -0,0 +1,40 @@
1
+ <%=
2
+ table_for @contents do |t|
3
+ columns = [:content]
4
+ columns.push :categories if @section.categories.any?
5
+ columns.push :comments if defined?(Comment)
6
+ columns += [:published, :actions]
7
+
8
+ t.column *columns
9
+
10
+ t.row do |r, content|
11
+ r.add_class "level_#{content.level}"
12
+ r.cell content_status(content) + link_to(content.title, [:edit, :admin, @site, @section, content], :class => content.state)
13
+ r.cell content.category_titles.join(", ") if @section.categories.any?
14
+ r.cell content.accept_comments? && content.comments.present? ? link_to(content.comments.size, admin_comments_path) : t(:"adva.common.none") if defined?(Comment)
15
+ r.cell published_at_formatted(content)
16
+ r.cell link_to("Edit", [:edit, :admin, @site, @section, content], :class => "edit content") +
17
+ link_to("Delete", [:admin, @site, @section, content], :method => :delete, :class => "delete content")
18
+ end
19
+
20
+ t.empty :p, :class => 'empty' do
21
+ raw params[:filters] ?
22
+ t(:'adva.content.no_filtered_contents') :
23
+ t(:'adva.contents.no_contents', :section => @section.title) + "\n" +
24
+ link_to(t(:'adva.contents.links.create_now'), [:new, :admin, @site, @section, :article])
25
+ end
26
+ end
27
+ %>
28
+
29
+ <%= content_for :sidebar do -%>
30
+ <!--
31
+ <div class="tabs">
32
+ <ul>
33
+ <li class="active"><a href="#filters" onclick="return false;">Filters</a></li>
34
+ </ul>
35
+ <div class="tab active" id="tab_filters">
36
+ <%= filter_for(Article, :categories => @section.categories) %>
37
+ </div>
38
+ </div>
39
+ -->
40
+ <% end -%>
@@ -0,0 +1,11 @@
1
+ <h2><%= t(:'adva.sections.titles.blog_settings') %></h2>
2
+
3
+ <% f.field_set :blog_settings do %>
4
+ <div class="col">
5
+ <%= f.text_field :contents_per_page, :label => true %>
6
+ </div>
7
+
8
+ <div class="col">
9
+ <%= f.select :content_filter, filter_options, {}, :label => true, :hint => :'adva.sections.hints.content_filter' %>
10
+ </div>
11
+ <% end %>
@@ -0,0 +1,28 @@
1
+ <% if article %>
2
+ <div id="<%= dom_id(article) %>" class="entry clearing">
3
+ <div class="meta">
4
+ <p>
5
+ <%= datetime_with_microformat(article.published_at, :format => :long) %><br />
6
+ <%= t(:'adva.blog.attribution', :author => article.author_name) %>
7
+ <%= link_to_content_comments article if (defined?(Comment) && (article.accept_comments? || article.comments.present?)) && mode != :single %>
8
+ <% authorized_tag :span, :update, article do -%>
9
+ <%= link_to t(:'adva.common.edit'), edit_admin_article_path(@site, @section, article) %>
10
+ <% end -%>
11
+ </p>
12
+ <p>
13
+ <%= links_to_content_categories article, :'adva.common.content_categories' %>
14
+ <%= links_to_content_tags article, :'adva.common.content_tags' %>
15
+ </p>
16
+ </div>
17
+ <div class="content">
18
+ <h2>
19
+ <%= link_to article.title, [article.section, article] %>
20
+ </h2>
21
+ <% if article.has_excerpt? %>
22
+ <%= raw article.excerpt_html %>
23
+ <p><%= link_to_content t( :'adva.blog.links.more' ), article unless mode == :single %></p>
24
+ <% end %>
25
+ <%= raw article.body_html if mode == :single || !article.has_excerpt? %>
26
+ </div>
27
+ </div>
28
+ <% end %>
@@ -0,0 +1,40 @@
1
+ <% content_for :footer do %>
2
+ <div id="footer" class="clearing">
3
+ <% if @section.categories.present? %>
4
+ <div>
5
+ <h4><%=t :'adva.titles.categories' %></h4>
6
+ <ul id="categories_list">
7
+ <% @section.categories.each do |category| %>
8
+ <li><%= link_to_category @section, category %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
14
+ <% if @section.article_counts_by_month.present? %>
15
+ <div>
16
+ <h4><%=t :'adva.titles.archives' %></h4>
17
+ <ul id="archives">
18
+ <% @section.archive_months.each do |month| %>
19
+ <li><%= link_to l( month, :format => '%B %Y' ), blog_path(@section, :year => month.year, :month => month.month) %></li>
20
+ <% end %>
21
+ </ul>
22
+ </div>
23
+ <% end %>
24
+
25
+ <% if false and @section and @section.tag_counts.present? %>
26
+ <h4><%=t :'adva.titles.tags' %></h4>
27
+ <ul id="tags_list">
28
+ <% @section.tag_counts.each do |tag| %>
29
+ <li><%= link_to_tag @section, tag %></li>
30
+ <% end %>
31
+ </ul>
32
+ <% end %>
33
+ </div>
34
+
35
+ <%= render :partial => 'shared/footer' %>
36
+
37
+ <ul id="feeds">
38
+ <li><%= link_to t( :'adva.links.entries_feed' ), blog_url(@section, :format => :atom) %></li>
39
+ </ul>
40
+ <% end %>
@@ -0,0 +1,21 @@
1
+ atom_feed :url => request.url do |feed|
2
+ title = "#{@site.title} » #{@section.title}"
3
+
4
+ title = title + " » " + t( :'adva.blog.feeds.category', :category => @category.title ) if @category
5
+ title = title + " » " + t( :'adva.blog.feeds.tags', :tags => @tags.join(', '), :count => @tags.size ) if @tags.present?
6
+
7
+ feed.title title
8
+ feed.updated @articles.first ? @articles.first.updated_at : Time.now.utc
9
+
10
+ @articles[0..12].each do |article|
11
+ url = "http://#{@site.host}#{url_for([@section, article])}"
12
+ feed.entry article, :url => url do |entry|
13
+ entry.title article.title
14
+ entry.content "#{absolutize_links(article.excerpt_html)} #{absolutize_links(article.body_html)}", :type => 'html'
15
+ entry.author do |author|
16
+ author.name article.author_name
17
+ author.email article.author_email
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,4 @@
1
+ <%= articles_title @category, @tags, params, :format => '<h2 class="list_header">%s</h2>' %>
2
+
3
+ <%= render :partial => 'blogs/articles/article', :collection => @articles, :locals => { :mode => :many } %>
4
+ <%= render :partial => 'blogs/articles/footer' %>
@@ -0,0 +1,14 @@
1
+ <% if @article %>
2
+ <%= content_for :title do %>
3
+ <%= @article.title %>
4
+ <% end %>
5
+
6
+ <%= render :partial => 'blogs/articles/article', :object => @article, :locals => { :mode => :single } %>
7
+
8
+ <% if defined?(Comment) %>
9
+ <%= render :partial => 'comments/list', :locals => { :commentable => @article, :comments => @article.approved_comments } %>
10
+ <% if @article.accept_comments? %>
11
+ <%= render :partial => 'comments/form', :locals => { :commentable => @article } %>
12
+ <% end %>
13
+ <% end %>
14
+ <% end %>
@@ -0,0 +1,3 @@
1
+ ActionDispatch::Callbacks.to_prepare do
2
+ BaseController.class_eval { helper BlogHelper }
3
+ end
@@ -0,0 +1,49 @@
1
+ Rails.application.routes.draw do
2
+ scope :constraints => lambda { |req| Blog.where(:permalink => req.params[:section_permalink]).exists? } do
3
+ get "/:section_permalink" => "blog_articles#index", :as => :blog
4
+ get "/:section_permalink/categories/:category_id" => "blog_articles#index", :as => :blog_category
5
+ get "/:section_permalink/:year/:month/:day/:permalink" => "blog_articles#show", :constraints => { :year => /\d{4}/, :month => /\d{1,2}/, :day => /\d{1,2}/ }, :as => :blog_article
6
+ get "/:section_permalink/articles/:permalink" => "blog_articles#show", :as => :unpublished_blog_article
7
+ get "/:section_permalink/tags/:tags" => "blog_articles#index", :as => :blog_tag
8
+ end
9
+
10
+ namespace :admin do
11
+ resources :sites do
12
+ resources :blogs do
13
+ scope :module => :blog do
14
+ resources :contents, :articles, :categories do
15
+ put "/", :action => "update_all", :on => :collection
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ # map.blog_tag 'blogs/:section_id/tags/:tags/:year/:month',
23
+ # :controller => 'blog_articles',
24
+ # :action => 'index',
25
+ # :year => nil, :month => nil,
26
+ # :requirements => { :year => /\d{4}/, :month => /\d{1,2}/ },
27
+ # :conditions => { :method => :get }
28
+
29
+ # map.category_feed 'blogs/:section_id/categories/:category_id.:format',
30
+ # :controller => 'blog_articles',
31
+ # :action => 'index',
32
+ # :conditions => { :method => :get }
33
+
34
+ # map.tag_feed 'blogs/:section_id/tags/:tags.:format',
35
+ # :controller => 'blog_articles',
36
+ # :action => 'index',
37
+ # :conditions => { :method => :get }
38
+
39
+ # map.blog_comments 'blogs/:section_id/comments.:format',
40
+ # :controller => 'blog_articles',
41
+ # :action => 'comments',
42
+ # :conditions => { :method => :get }
43
+
44
+ # map.blog_article_comments 'blogs/:section_id/:year/:month/:day/:permalink.:format',
45
+ # :controller => 'blog_articles',
46
+ # :action => 'comments',
47
+ # :requirements => { :year => /\d{4}/, :month => /\d{1,2}/, :day => /\d{1,2}/ },
48
+ # :conditions => { :method => :get }
49
+ end