activeadmin-mongoid-blog 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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: []