activeadmin-mongoid-blog 0.3.0

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.
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ *.rbc
2
+ *.sassc
3
+ .sass-cache
4
+ capybara-*.html
5
+ .rspec
6
+ /.bundle
7
+ /vendor/bundle
8
+ /log/*
9
+ /tmp/*
10
+ /db/*.sqlite3
11
+ /public/system/*
12
+ /coverage/
13
+ /spec/tmp/*
14
+ **.orig
15
+ rerun.txt
16
+ pickle-email-*.html
17
+ pkg
18
+ *.swp
19
+ *.swo
20
+ .DS_Store
data/README.md ADDED
@@ -0,0 +1,60 @@
1
+ ## activeadmin-mongoid-blog
2
+
3
+ Blog app on the top of activeadmin and mongoid, using redactor and select2 plugins. Could be useful for almost every activeadmin based project.
4
+
5
+ ### Start a new rails project
6
+
7
+ $ rails new appname --skip-active-record
8
+
9
+ ### Setup and configure ActiveAdmin
10
+
11
+ Add these gems to Gemfile and run `bundle` command:
12
+
13
+ gem 'bson_ext'
14
+ gem 'mongoid'
15
+ gem 'activeadmin-mongoid'
16
+ gem 'activeadmin-mongoid-blog'
17
+ gem 'devise'
18
+
19
+ Run generators to and check settings in `/config/mongoid.yml`, `/config/initializers/active_admin.rb`:
20
+
21
+ $ rails g mongoid:config
22
+ $ rails g devise:install
23
+ $ rails g active_admin:install
24
+
25
+ Check that the generated `/config/initializers/devise.rb` file requires mongoid orm. You should see a line like this:
26
+
27
+ require 'devise/orm/mongoid'
28
+
29
+ Create the activeadmin user:
30
+
31
+ $ rails c
32
+ >> AdminUser.create :email => 'admin@example.com', :password => 'password', :password_confirmation => 'password'
33
+
34
+ At this point **activeadmin** should be ready to work. Run `rails s` and check out `http://localhost:3000/admin`.
35
+
36
+ ### Setup activeadmin-mongoid-blog
37
+
38
+ Install blog models, admin files, routes and blog controller, replace `blog` value with a prefix you want the blog be accessible at (e.g. `http://localhost:3000/blog`):
39
+
40
+ $ rails g active_admin:blog:install blog
41
+
42
+ As blog post editor `redactor.js` is used. It comes with a image uploading featured supported by **carrierwave**, install `Picture` model with command:
43
+
44
+ $ rails generate redactor:install
45
+
46
+ Add to your `active_admin.js.coffee`:
47
+
48
+ #= require activeadmin_mongoid_blog
49
+
50
+ Add to your `active_admin.css.scss`:
51
+
52
+ //= require activeadmin_mongoid_blog
53
+
54
+ ### Customizing blog views
55
+
56
+ Install default views templates to `/app/views/blog`:
57
+
58
+ $ rails g active_admin:blog:views
59
+
60
+ ### The End
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'rubygems/package_task'
2
+
3
+ spec = Gem::Specification.load(Dir['*.gemspec'].first)
4
+ gem = Gem::PackageTask.new(spec)
5
+ gem.define()
6
+
7
+ #gem push pkg/activeadmin-mongoid-blog-version.gem
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = 'activeadmin-mongoid-blog'
6
+ gem.version = '0.3.0'
7
+ gem.summary = 'Blog app on the top of activeadmin and mongoid, using redactor and select2 plugins.'
8
+ gem.description = ''
9
+ gem.license = 'MIT'
10
+
11
+ gem.authors = ['Alex Kravets']
12
+ gem.email = 'santyor@gmail.com'
13
+ gem.homepage = 'https://github.com/alexkravets/activeadmin-mongoid-blog'
14
+
15
+ gem.files = `git ls-files`.split($\)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ['lib']
19
+
20
+ # Supress the warning about no rubyforge project
21
+ gem.rubyforge_project = 'nowarning'
22
+ end
@@ -0,0 +1,8 @@
1
+ <header>
2
+ <a href="<%= blog_path %>" title="Blog Title"><h1>Blog Title</h1></a>
3
+ <ul>
4
+ <% BlogCategory.all.each do |c| %>
5
+ <li><a href="<%= blog_path %>?category=<%= c.permalink %>" title="<%= c.name %>"><%= c.name %></a></li>
6
+ <% end %>
7
+ </ul>
8
+ </header>
@@ -0,0 +1,25 @@
1
+ <div>
2
+ <!-- TITLE -->
3
+ <h2><%= post.title %></h2>
4
+
5
+ <!-- DATE -->
6
+ <span>Date: <%= post.date %></span>
7
+
8
+ <!-- CATEGORIES -->
9
+ <% if post.categories.size > 0 %>
10
+ <span>Posted in: <%= post.category_links_string %></span>
11
+ <% end %>
12
+
13
+ <!-- FEATURED IMAGE LINK --!>
14
+ <% if post.has_featured_image? %>
15
+ <a href="<%= blog_post_path(post) %>" title="Read More">
16
+ <%= image_tag post.featured_image_url, :alt=>post.title %>
17
+ </a>
18
+ <% end %>
19
+
20
+ <!-- EXCERPT -->
21
+ <p><%= post.excerpt %></p>
22
+
23
+ <!-- READ MORE --!>
24
+ <a href="<%= blog_post_path(post) %>" title="Read More">Read More</a>
25
+ </div>
@@ -0,0 +1,3 @@
1
+ <header>
2
+ <a href="<%= blog_path %>" title="Blog Title"><h1>Blog Title</h1></a>
3
+ </header>
@@ -0,0 +1,18 @@
1
+ xml.instruct! :xml, :version => "1.0"
2
+ xml.rss :version => "2.0" do
3
+ xml.channel do
4
+ xml.title "Blog title goes here"
5
+ xml.description "Blog description goes here"
6
+ xml.link blog_url
7
+
8
+ for post in @posts
9
+ xml.item do
10
+ xml.title post.title
11
+ xml.description post.excerpt
12
+ xml.pubDate post.date.to_s(:rfc822)
13
+ xml.link blog_post_url(post)
14
+ xml.guid blog_post_url(post)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,3 @@
1
+ <%= render :partial => "header" %>
2
+
3
+ <%= render :partial => "post", :collection => @posts %>
@@ -0,0 +1,17 @@
1
+ <%= render :partial => "header" %>
2
+
3
+ <div>
4
+ <!-- TITLE -->
5
+ <h2><%= @post.title %></h2>
6
+
7
+ <!-- DATE -->
8
+ <span>Date: <%= @post.date %></span>
9
+
10
+ <!-- CATEGORIES -->
11
+ <% if @post.categories.size > 0 %>
12
+ <span>Posted in: <%= post.category_links_string %></span>
13
+ <% end %>
14
+
15
+ <!-- CONTENT -->
16
+ <div><%= @post.content.html_safe %></div>
17
+ </div>
@@ -0,0 +1,7 @@
1
+ module ActiveAdmin
2
+ module Mongoid
3
+ module Blog
4
+ require "activeadmin-mongoid-blog/engine"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ module ActiveAdmin
2
+ module Mongoid
3
+ module Blog
4
+ class Engine < ::Rails::Engine
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,48 @@
1
+ module ActiveAdmin
2
+ module Blog
3
+ module Generators
4
+ class InstallGenerator < Rails::Generators::NamedBase
5
+ desc << "Description:\n Copies blog source files to your application's app directory, adds routes and missing gems."
6
+
7
+ source_root File.expand_path('../templates', __FILE__)
8
+
9
+ def copy_files
10
+ # models
11
+ puts "Installing models:"
12
+ copy_file "models/blog_category.rb", "app/models/blog_category.rb"
13
+ copy_file "models/blog_post.rb", "app/models/blog_post.rb"
14
+
15
+ # controllers
16
+ puts "Installing controllers:"
17
+ copy_file "controllers/blog_controller.rb", "app/controllers/blog_controller.rb"
18
+
19
+ # admin
20
+ puts "Installing admin:"
21
+ copy_file "admin/blog_categories.rb", "app/admin/blog_categories.rb"
22
+ copy_file "admin/blog_posts.rb", "app/admin/blog_posts.rb"
23
+ end
24
+
25
+ def setup_routes
26
+ route "get '/#{file_name}' => 'blog#index', :as => :blog"
27
+ route "get '/#{file_name}/feed' => 'blog#feed', :as => :blog_rss_feed"
28
+ route "get '/#{file_name}/posts/:slug' => 'blog#post', :as => :blog_post"
29
+ end
30
+
31
+ def add_gems
32
+ gem "mongoid_slug"
33
+ gem "mongoid_search"
34
+ gem "nokogiri"
35
+ gem "activeadmin-mongoid-reorder"
36
+ gem "redactor-rails", :git => "git://github.com/alexkravets/redactor-rails.git"
37
+ gem "carrierwave-mongoid", :require => 'carrierwave/mongoid'
38
+ gem "mini_magick"
39
+ gem "select2-rails"
40
+ end
41
+
42
+ def show_congrats
43
+ readme("README")
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,7 @@
1
+
2
+
3
+ Blog app for active admin is now installed. Please run bundle to install missing gems. Then install redactor image model, this enables uploading images feature via activeadmin:
4
+
5
+ rails generate redactor:install
6
+
7
+ Thanks for installing activeadmin-mongoid-blog!
@@ -0,0 +1,34 @@
1
+ ActiveAdmin.register BlogCategory, :as => "Category" do
2
+ menu :parent => "Blog", :priority => 3
3
+
4
+ controller do
5
+ defaults :finder => :find_by_permalink
6
+ end
7
+
8
+ index :as => :reorder_table do
9
+ column :name
10
+ default_actions
11
+ end
12
+
13
+ #show :title => :name do
14
+ # panel "Posts" do
15
+ # if category.blog_posts.size > 0
16
+ # table_for(category.blog_posts, {:class => "index_table blog_posts"}) do |t|
17
+ # post_table_item(t)
18
+ # end
19
+ # end
20
+ # end
21
+ #end
22
+
23
+ form do |f|
24
+ f.inputs "Details" do
25
+ f.input :name, :required => true
26
+ end
27
+
28
+ f.buttons
29
+ end
30
+
31
+ collection_action :reorder, :method => :put do
32
+ render :text => resource_class.reorder_objects(params[:ids])
33
+ end
34
+ end
@@ -0,0 +1,93 @@
1
+ ActiveAdmin.register BlogPost, :as => "Post" do
2
+ menu :parent => "Blog",
3
+ :label => "All Posts",
4
+ :priority => 1
5
+
6
+ actions :new, :create, :index, :update, :edit, :destroy
7
+
8
+ # Scopes
9
+ scope :all, :default => true
10
+ scope :drafts
11
+ scope :published
12
+
13
+ controller do
14
+ defaults :finder => :find_by_permalink
15
+ end
16
+
17
+ index do
18
+ # Hiding this column until get support of images
19
+ #column("") do |p| # Thumbnail
20
+ # url = p.featured_image.admin_thumb.url
21
+ # if url.nil?
22
+ # url = "http://placehold.it/60x40?text=IMG"
23
+ # end
24
+ # image_tag(url, :alt => p.title, :size=>"60x40")
25
+ #end
26
+
27
+ column("Title") do |p|
28
+ html = "<strong>#{p.title}</strong>"
29
+ html.html_safe
30
+ end
31
+
32
+ column("Details") do |p|
33
+ html = ""
34
+ if p.categories.size > 0
35
+ html << "Published in: " + p.categories.collect{|c| link_to(c.name, admin_category_path(c))}.join(", ")
36
+ html << "<br/>"
37
+ end
38
+ if not p.tags.empty?
39
+ html << "Tags: <em>" + p.tags.gsub(',', ', ') + "</em>"
40
+ end
41
+ html.html_safe
42
+ end
43
+
44
+ column("Date") do |p|
45
+ """#{p.date.to_s.gsub('-', '/')}<br/>
46
+ <i>#{p.draft ? 'Draft' : 'Published'}</i>""".html_safe
47
+ end
48
+
49
+ default_actions
50
+ end
51
+
52
+ form do |f|
53
+ f.inputs "Title" do
54
+ f.input :title, :required => true
55
+ end
56
+ f.inputs "Content" do
57
+ f.input :content, :as => :text,
58
+ :input_html => { :class => "redactor" }
59
+ end
60
+ f.inputs "Details" do
61
+ unless f.object.new?
62
+ f.input :permalink
63
+ end
64
+
65
+ f.input :date, :input_html => { :class => "datepicker" }
66
+
67
+ f.input :draft, :as => :select,
68
+ :label => "State",
69
+ :collection => [["draft", "true"], ["published", "false"]],
70
+ :include_blank => false,
71
+ :input_html => { :class => "select2" }
72
+
73
+ categories = BlogCategory.all
74
+ if categories.size > 0
75
+ f.input :categories, :as => :select,
76
+ :label => "Published in",
77
+ :input_html => { :multiple => true, :class => "select2" },
78
+ :collection => categories,
79
+ :include_blank => false,
80
+ :hint => "Click on field and select category from dropdown"
81
+ end
82
+
83
+ f.input :tags, :hint => "Select from the list or type a new one and press ENTER",
84
+ :input_html => { "data-url" => "/admin/posts/tags" }
85
+ end
86
+ f.buttons
87
+ end
88
+
89
+ collection_action :tags, :method => :get do
90
+ tags = BlogPost.all.collect{ |p| p.tags }.join(",").split(',').uniq
91
+ render :json => tags
92
+ end
93
+ end
@@ -0,0 +1,34 @@
1
+ class BlogController < ApplicationController
2
+ def index
3
+ category_slug = params[:category]
4
+ search_query = params[:search]
5
+ archive_month = params[:month]
6
+
7
+ if category_slug
8
+ @posts = BlogPost.published_in_category(category_slug)
9
+ elsif search_query
10
+ @posts = BlogPost.blog_search(search_query)
11
+ elsif archive_month
12
+ month = archive_month.split("-")[0].to_i
13
+ year = archive_month.split("-")[1].to_i
14
+ @posts = BlogPost.published_in_month(month, year)
15
+ else
16
+ @posts = BlogPost.published
17
+ end
18
+
19
+ @posts = @posts.page params[:page]
20
+ end
21
+
22
+ def post
23
+ @post = BlogPost.find_by_permalink!(params[:slug])
24
+ end
25
+
26
+ def feed
27
+ @posts = BlogPost.published
28
+
29
+ respond_to do |format|
30
+ format.rss { render :layout => false } #index.rss.builder
31
+ format.all { head :not_found }
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,23 @@
1
+ class BlogCategory
2
+ include Mongoid::Document
3
+ include Mongoid::Timestamps
4
+ include Mongoid::Slug
5
+ include Mongoid::Reorder
6
+
7
+ # Fields
8
+ field :name
9
+ field :_position, :type => Float, :default => 0.0
10
+
11
+ # Validations
12
+ validates_presence_of :name
13
+ validates_uniqueness_of :name
14
+
15
+ # Features
16
+ slug :name, :as => :permalink, :permanent => true
17
+
18
+ # Relations
19
+ has_and_belongs_to_many :blog_posts
20
+
21
+ # Scope
22
+ default_scope order_by(:_position => :desc)
23
+ end
@@ -0,0 +1,83 @@
1
+ class BlogPost
2
+ include Mongoid::Document
3
+ include Mongoid::Timestamps
4
+ include Mongoid::Slug
5
+ include Mongoid::Search
6
+
7
+ include ActionView::Helpers::TextHelper
8
+ require 'nokogiri'
9
+
10
+ # Fields
11
+ field :title
12
+ field :content
13
+ field :tags, :default => ""
14
+ field :draft, :type => Boolean, :default => true
15
+ field :date, :type => Date
16
+
17
+ field :featured_image # This is temporary value until redactor with file uploading functionality is off
18
+
19
+ # Validations
20
+ validates_presence_of :title
21
+ validates_uniqueness_of :title
22
+
23
+ # Features
24
+ slug :title, :as => :permalink, :permanent => true
25
+ search_in :title, :content, :tags
26
+ paginates_per 6
27
+
28
+ # Relations
29
+ has_and_belongs_to_many :categories, :class_name => "BlogCategory"
30
+
31
+ # Scopes
32
+ default_scope order_by(:date => :desc)
33
+ scope :drafts, where(draft: true)
34
+ scope :published, where(draft: false)
35
+
36
+ # Helpers
37
+ def has_featured_image?
38
+ false
39
+ end
40
+
41
+ def category_links_string
42
+ categories.collect{|c| link_to(c.name, admin_category_path(c))}.join(", ")
43
+ end
44
+
45
+ def excerpt
46
+ html = Nokogiri::HTML(content)
47
+ begin
48
+ html.css('p').select{|p| not p.content.empty? }.first.content
49
+ rescue
50
+ ""
51
+ end
52
+ end
53
+
54
+ def page_description
55
+ Nokogiri::HTML(excerpt).text
56
+ end
57
+
58
+ # Class methods
59
+ def published_in_category(category_slug)
60
+ category = BlogCategory.find_by_permalink!(category_slug)
61
+ category.blog_posts.published
62
+ end
63
+
64
+ def self.published_in_month(month, year)
65
+ begin
66
+ start_date = Date.new(year, month, 1)
67
+ end_date = start_date + 1.month
68
+ rescue
69
+ BlogPost.published
70
+ end
71
+ BlogPost.published.where(:date=>{'$gte' => start_date,'$lt' => end_date})
72
+ end
73
+
74
+ def self.blog_search(query)
75
+ self.search(query).published
76
+ end
77
+
78
+ def self.archive
79
+ BlogPost.all.collect do |p|
80
+ [p.date.month, p.date.year]
81
+ end.uniq
82
+ end
83
+ end
@@ -0,0 +1,18 @@
1
+ module ActiveAdmin
2
+ module Blog
3
+ module Generators
4
+ class ViewsGenerator < Rails::Generators::NamedBase
5
+ desc << "Description:\n Copies blog templates to your application."
6
+
7
+ source_root File.expand_path('../../../../../app/views/blog', __FILE__)
8
+
9
+ def copy_default_views
10
+ filename_pattern = File.join self.class.source_root, "*.html.erb"
11
+ Dir.glob(filename_pattern).map {|f| File.basename f}.each do |f|
12
+ copy_file f, "app/views/blog/#{f}"
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ #= require redactor-rails
2
+ #= require select2
3
+ #= require activeadmin_reorder_table
4
+
5
+ $ ->
6
+ # Enable redactor
7
+ $('.redactor').redactor
8
+ imageUpload: "/redactor_rails/pictures"
9
+ imageGetJson: "/redactor_rails/pictures"
10
+
11
+ # Enable select2
12
+ $('.select2').select2
13
+ minimumResultsForSearch: 10
14
+
15
+ tags_input = $("#post_tags")
16
+ if tags_input.length > 0
17
+ tags_url = tags_input.attr("data-url")
18
+ $.get tags_url, (tags) => tags_input.select2({tags: tags })
@@ -0,0 +1,13 @@
1
+ //= require select2
2
+ //= require redactor-rails
3
+
4
+ #edit_post {
5
+ #post_content_input label { display:none; }
6
+ #post_title_input label { display:none; }
7
+
8
+ #post_title { font-size:2em; }
9
+
10
+ #post_category_ids { width:76%; }
11
+ #post_draft { width:160px; }
12
+ #post_date { width:138px; }
13
+ }
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activeadmin-mongoid-blog
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Alex Kravets
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-07-26 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: ''
15
+ email: santyor@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - .gitignore
21
+ - README.md
22
+ - Rakefile
23
+ - activeadmin-mongoid-blog.gemspec
24
+ - app/views/blog/_header.html.erb
25
+ - app/views/blog/_post.html.erb
26
+ - app/views/blog/_sidebar.html.erb
27
+ - app/views/blog/feed.rss.builder
28
+ - app/views/blog/index.html.erb
29
+ - app/views/blog/post.html.erb
30
+ - lib/activeadmin-mongoid-blog.rb
31
+ - lib/activeadmin-mongoid-blog/engine.rb
32
+ - lib/generators/active_admin/blog/install_generator.rb
33
+ - lib/generators/active_admin/blog/templates/README
34
+ - lib/generators/active_admin/blog/templates/admin/blog_categories.rb
35
+ - lib/generators/active_admin/blog/templates/admin/blog_posts.rb
36
+ - lib/generators/active_admin/blog/templates/controllers/blog_controller.rb
37
+ - lib/generators/active_admin/blog/templates/models/blog_category.rb
38
+ - lib/generators/active_admin/blog/templates/models/blog_post.rb
39
+ - lib/generators/active_admin/blog/views_generator.rb
40
+ - vendor/assets/javascripts/activeadmin_mongoid_blog.js.coffee
41
+ - vendor/assets/stylesheets/activeadmin_mongoid_blog.css.scss
42
+ homepage: https://github.com/alexkravets/activeadmin-mongoid-blog
43
+ licenses:
44
+ - MIT
45
+ post_install_message:
46
+ rdoc_options: []
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubyforge_project: nowarning
63
+ rubygems_version: 1.8.24
64
+ signing_key:
65
+ specification_version: 3
66
+ summary: Blog app on the top of activeadmin and mongoid, using redactor and select2
67
+ plugins.
68
+ test_files: []