activeadmin-blog 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. data/.gitignore +20 -0
  2. data/Gemfile +4 -0
  3. data/Gemfile.lock +215 -0
  4. data/README.md +162 -0
  5. data/Rakefile +7 -0
  6. data/activeadmin-blog.gemspec +30 -0
  7. data/app/controllers/activeadmin_blog/posts_controller.rb +50 -0
  8. data/app/models/activeadmin_blog/blog_category.rb +23 -0
  9. data/app/models/activeadmin_blog/blog_post.rb +81 -0
  10. data/app/views/activeadmin_blog/posts/_footer.html.erb +10 -0
  11. data/app/views/activeadmin_blog/posts/_header.html.erb +11 -0
  12. data/app/views/activeadmin_blog/posts/_post.html.erb +31 -0
  13. data/app/views/activeadmin_blog/posts/archive.html.erb +9 -0
  14. data/app/views/activeadmin_blog/posts/category.html.erb +9 -0
  15. data/app/views/activeadmin_blog/posts/feed.rss.builder +18 -0
  16. data/app/views/activeadmin_blog/posts/index.html.erb +9 -0
  17. data/app/views/activeadmin_blog/posts/search.html.erb +9 -0
  18. data/app/views/activeadmin_blog/posts/show.html.erb +35 -0
  19. data/app/views/activeadmin_blog/posts/tag.html.erb +9 -0
  20. data/app/views/admin/categories/_form.html.erb +26 -0
  21. data/app/views/admin/posts/_categories.html.erb +18 -0
  22. data/config/routes.rb +9 -0
  23. data/install.sh +160 -0
  24. data/lib/activeadmin-blog.rb +8 -0
  25. data/lib/activeadmin-blog/engine.rb +5 -0
  26. data/lib/activeadmin-blog/version.rb +3 -0
  27. data/lib/generators/activeadmin_blog/install_generator.rb +40 -0
  28. data/lib/generators/activeadmin_blog/templates/README +5 -0
  29. data/lib/generators/activeadmin_blog/templates/admin/blog_categories.rb +86 -0
  30. data/lib/generators/activeadmin_blog/templates/admin/blog_posts.rb +101 -0
  31. data/lib/generators/activeadmin_blog/views_generator.rb +16 -0
  32. data/vendor/assets/javascripts/activeadmin_blog.js.coffee +56 -0
  33. data/vendor/assets/stylesheets/activeadmin_blog.css.scss +51 -0
  34. metadata +180 -0
@@ -0,0 +1,23 @@
1
+ class ActiveadminBlog::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, :class_name => "ActiveadminBlog::BlogPost"
20
+
21
+ # Scope
22
+ default_scope order_by(:_position => :desc)
23
+ end
@@ -0,0 +1,81 @@
1
+ class ActiveadminBlog::BlogPost
2
+ include Mongoid::Document
3
+ include Mongoid::Timestamps
4
+ include Mongoid::Slug
5
+ include Mongoid::Search
6
+
7
+ include ActionView::Helpers::TextHelper
8
+
9
+ # Fields
10
+ field :title
11
+ field :content
12
+ field :tags, :default => ""
13
+ field :published, :type => Boolean, :default => false
14
+ field :date, :type => Date
15
+
16
+ # Validations
17
+ validates_presence_of :title
18
+ validates_uniqueness_of :title
19
+
20
+ # Features
21
+ slug :title, :as => :permalink, :permanent => true
22
+ search_in :title, :content, :tags
23
+ mount_uploader :featured_image, ActiveadminSettings::RedactorPictureUploader
24
+ paginates_per 6
25
+
26
+ # Relations
27
+ has_and_belongs_to_many :categories, :class_name => "ActiveadminBlog::BlogCategory"
28
+
29
+ # Scopes
30
+ default_scope order_by(:date => :desc)
31
+ scope :ideas, where(published: false)
32
+ scope :published, where(published: true)
33
+
34
+ # Helpers
35
+ def has_featured_image?
36
+ not featured_image.to_s.empty?
37
+ end
38
+
39
+ def excerpt
40
+ html = Nokogiri::HTML(content)
41
+ begin
42
+ html.css('p').select{|p| not p.content.empty? }.first.content
43
+ rescue
44
+ ""
45
+ end
46
+ end
47
+
48
+ def page_description
49
+ Nokogiri::HTML(excerpt).text
50
+ end
51
+
52
+ # Class methods
53
+ def self.published_in_category(category_slug)
54
+ category = ActiveadminBlog::BlogCategory.find_by_permalink!(category_slug)
55
+ category.blog_posts.published
56
+ end
57
+
58
+ def self.published_in_month(month, year)
59
+ begin
60
+ start_date = Date.new(year, month, 1)
61
+ end_date = start_date + 1.month
62
+ rescue
63
+ self.published
64
+ end
65
+ self.published.where(:date=>{'$gte' => start_date,'$lt' => end_date})
66
+ end
67
+
68
+ def self.blog_search(query)
69
+ self.search(query).published
70
+ end
71
+
72
+ def self.archive
73
+ self.all.collect do |p|
74
+ [p.date.month, p.date.year]
75
+ end.uniq
76
+ end
77
+
78
+ def self.tagged_with(tag)
79
+ self.published
80
+ end
81
+ end
@@ -0,0 +1,10 @@
1
+ <footer>
2
+ <form class="well form-search" action="<%= blog_search_path %>" method="GET">
3
+ <input name="q" type="text" class="input-medium search-query">
4
+ <button type="submit" class="btn">Search</button>
5
+ </form>
6
+ <p>
7
+ <a href="<%= blog_rss_feed_path %>.rss" title="RSS Feed">RSS Feed</a></br>
8
+ Dlivered by <%= settings_link_value "Delivered By", :target => "_blank" %>
9
+ </p>
10
+ </footer>
@@ -0,0 +1,11 @@
1
+ <header style="margin-bottom:2em;">
2
+ <h1><%= settings_value "Blog Title" %></h1>
3
+ <p>
4
+ <ul>
5
+ <li><a href="<%= blog_path %>" title="All Posts">All Posts</a></li>
6
+ <% @categories.all.each do |c| %>
7
+ <li><a href="<%= blog_category_path(c) %>" title="<%= c.name %>"><%= c.name %></a></li>
8
+ <% end %>
9
+ </ul>
10
+ </p>
11
+ </header>
@@ -0,0 +1,31 @@
1
+ <div style="margin-bottom:2em;">
2
+ <!-- TITLE -->
3
+ <a href="<%= blog_post_path(post) %>" title="Read this post"><h2><%= post.title %></h2></a>
4
+
5
+ <!-- DATE & CATEGORIES -->
6
+ <p>
7
+ <span>Published at <em><%= post.date %></em> <% if post.categories.size > 0 %>in:<% end %></span>
8
+ <% if post.categories.size > 0 %>
9
+ <ul>
10
+ <% post.categories.each do |c| %>
11
+ <li><a href="<%= blog_category_path(c) %>" title="<%= c.name %>"><%= c.name %></a></li>
12
+ <% end %>
13
+ </ul>
14
+ <% end %>
15
+ </p>
16
+
17
+ <!-- FEATURED IMAGE LINK -->
18
+ <% if post.has_featured_image? %>
19
+ <p>
20
+ <a href="<%= blog_post_path(post) %>" title="Read More">
21
+ <%= image_tag post.featured_image_url, :alt=>post.title %>
22
+ </a>
23
+ </p>
24
+ <% end %>
25
+
26
+ <!-- EXCERPT -->
27
+ <p><%= post.excerpt %></p>
28
+
29
+ <!-- READ MORE -->
30
+ <a href="<%= blog_post_path(post) %>" title="Read More">Read More</a>
31
+ </div>
@@ -0,0 +1,9 @@
1
+ <div class="container">
2
+ <%= render :partial => "header" %>
3
+
4
+ <%= render :partial => "post", :collection => @posts %>
5
+
6
+ <%= paginate @posts %>
7
+
8
+ <%= render :partial => "footer" %>
9
+ </div>
@@ -0,0 +1,9 @@
1
+ <div class="container">
2
+ <%= render :partial => "header" %>
3
+
4
+ <%= render :partial => "post", :collection => @posts %>
5
+
6
+ <%= paginate @posts %>
7
+
8
+ <%= render :partial => "footer" %>
9
+ </div>
@@ -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,9 @@
1
+ <div class="container">
2
+ <%= render :partial => "header" %>
3
+
4
+ <%= render :partial => "post", :collection => @posts %>
5
+
6
+ <%= paginate @posts %>
7
+
8
+ <%= render :partial => "footer" %>
9
+ </div>
@@ -0,0 +1,9 @@
1
+ <div class="container">
2
+ <%= render :partial => "header" %>
3
+
4
+ <%= render :partial => "post", :collection => @posts %>
5
+
6
+ <%= paginate @posts %>
7
+
8
+ <%= render :partial => "footer" %>
9
+ </div>
@@ -0,0 +1,35 @@
1
+ <div class="container">
2
+ <%= render :partial => "header" %>
3
+
4
+ <div style="margin-bottom:2em;">
5
+ <!-- TITLE -->
6
+ <h2><%= @post.title %></h2>
7
+
8
+ <!-- DATE & CATEGORIES -->
9
+ <p>
10
+ <span>Published at <em><%= @post.date %></em> <% if @post.categories.size > 0 %>in:<% end %></span>
11
+ <% if @post.categories.size > 0 %>
12
+ <ul>
13
+ <% @post.categories.each do |c| %>
14
+ <li><a href="<%= blog_category_path(c) %>" title="<%= c.name %>"><%= c.name %></a></li>
15
+ <% end %>
16
+ </ul>
17
+ <% end %>
18
+ </p>
19
+
20
+ <!-- CONTENT -->
21
+ <div><%= @post.content.html_safe %></div>
22
+
23
+ <!-- TAGS -->
24
+ <% if @post.tags? %>
25
+ <span>Tags:</span>
26
+ <ul>
27
+ <% @post.tags.split(',').each do |t| %>
28
+ <li><%= link_to t, blog_tag_path(t) %></li>
29
+ <% end %>
30
+ </ul>
31
+ <% end %>
32
+ </div>
33
+
34
+ <%= render :partial => "footer" %>
35
+ </div>
@@ -0,0 +1,9 @@
1
+ <div class="container">
2
+ <%= render :partial => "header" %>
3
+
4
+ <%= render :partial => "post", :collection => @posts %>
5
+
6
+ <%= paginate @posts %>
7
+
8
+ <%= render :partial => "footer" %>
9
+ </div>
@@ -0,0 +1,26 @@
1
+ <fieldset class="inputs"><legend><span>Details</span></legend><ol>
2
+ <%= f.input :name, :required => true %>
3
+ <%= f.input :permalink %>
4
+ </ol></fieldset>
5
+
6
+ <fieldset class="buttons">
7
+ <ol>
8
+ <li class="commit button">
9
+ <input class="update" id="proposal_submit" name="commit" type="submit"
10
+ value="<% if f.object.new? %>Create<% else %>Update<% end %> Category">
11
+ </li>
12
+ <li class="cancel">
13
+ <a href="<%= admin_posts_path %>">Cancel</a>
14
+ </li>
15
+ <!--
16
+ <% if not f.object.new? %>
17
+ <li style="float:right;">
18
+ <%= link_to "Delete Category", resource_path(f.object),
19
+ :method => :delete,
20
+ :confirm => "Are you sure, you want to delte this category?",
21
+ :class => "delete button" %>
22
+ </li>
23
+ <% end %>
24
+ -->
25
+ </ol>
26
+ </fieldset>
@@ -0,0 +1,18 @@
1
+ <% if categories.size > 0 %>
2
+ <ul id="blog_categories_list">
3
+ <% categories.each do |c| %>
4
+ <li id="category_<%= c.id %>">
5
+ <span>
6
+ <%= link_to c.name, admin_category_path(c) %>
7
+ <% if c.blog_posts.size > 0 %>(<%= c.blog_posts.size %>)<% end %>
8
+ </span>
9
+ <span class="action-buttons">
10
+ <%= link_to "Edit", edit_admin_category_path(c) %>
11
+ </span>
12
+ </li>
13
+ <% end %>
14
+ </ul>
15
+ <br/>
16
+ <% end %>
17
+
18
+ <%= link_to "New Category", new_admin_category_path %>
data/config/routes.rb ADDED
@@ -0,0 +1,9 @@
1
+ ActiveadminBlog::Engine.routes.draw do
2
+ get '/' => 'posts#index', :as => :blog
3
+ get '/search' => 'posts#search', :as => :blog_search
4
+ get '/feed' => 'posts#feed', :as => :blog_rss_feed
5
+ get '/archive/:y/:m' => 'posts#archive', :as => :blog_archive
6
+ get '/tags/:tag' => 'posts#tag', :as => :blog_tag
7
+ get '/posts/:slug' => 'posts#show', :as => :blog_post
8
+ get '/:slug' => 'posts#category', :as => :blog_category
9
+ end
data/install.sh ADDED
@@ -0,0 +1,160 @@
1
+ #!/bin/sh
2
+
3
+
4
+ # === activeadmin-mongoid-blog ===
5
+ # https://github.com/alexkravets/activeadmin-blog
6
+ #
7
+ # Description:
8
+ # Blog app on the top of activeadmin and mongoid.
9
+ #
10
+ # Installation:
11
+ # export project_name=new_blog ; curl https://raw.github.com/alexkravets/activeadmin-blog/master/install.sh | sh
12
+
13
+
14
+ set -e
15
+
16
+ rails new $project_name -T -O --skip-bundle
17
+ cd $project_name
18
+
19
+
20
+ # Gems
21
+ echo '
22
+ # Activeadmin
23
+ gem "bson_ext"
24
+ gem "mongoid"
25
+ gem "devise"
26
+ gem "activeadmin-mongoid"
27
+
28
+ # Blog
29
+ gem "activeadmin-blog"
30
+
31
+ # Bootstrap styles
32
+ gem "therubyracer"
33
+ gem "twitter-bootstrap-rails"
34
+
35
+ # Assets
36
+ gem "asset_sync"
37
+ ' >> Gemfile
38
+
39
+
40
+ bundle
41
+
42
+
43
+ rails g mongoid:config
44
+ rails g devise:install
45
+ rails g active_admin:install
46
+ rails g activeadmin_settings:install
47
+ rails g activeadmin_blog:install blog
48
+ rails g bootstrap:install
49
+
50
+
51
+ # Add blog settings
52
+ echo '\nGeneral:
53
+ Blog Title:
54
+ description: You can change blog title with this setting
55
+ default_value: <%= Rails.application.class.parent_name %>
56
+
57
+ Delivered By:
58
+ description: Link in the footer of the website
59
+ default_value: (Slate Studio) http://slatestudio.com
60
+ type: link' >> config/activeadmin_settings.yml
61
+
62
+
63
+ # Tweak application.css.scss
64
+ echo '/*
65
+ *= require bootstrap_and_overrides
66
+ *= require_self
67
+ */
68
+
69
+ .pagination .page.current {
70
+ float:left;
71
+ padding:0 14px;
72
+ line-height:34px;
73
+ text-decoration:none;
74
+ border:1px solid #DDD;
75
+ border-left-width:0;
76
+ color:#999;
77
+ cursor:default;
78
+ background-color:whiteSmoke;
79
+ }
80
+ .pagination span:first-child, .pagination .first a { border-left-width:1px; }' > app/assets/stylesheets/application.css
81
+
82
+
83
+ # Tweak application.js
84
+ echo '//= require jquery
85
+ //= require jquery_ujs
86
+ //= require twitter/bootstrap
87
+ //= require bootstrap
88
+ ' > app/assets/javascripts/application.js
89
+
90
+
91
+ # Fix default mongoid.yml
92
+ echo 'development:
93
+ host: localhost
94
+ database: '$project_name'
95
+
96
+ test:
97
+ host: localhost
98
+ database: '$project_name'_test
99
+
100
+ production:
101
+ uri: <%= ENV["MONGO_URL"] %>' > config/mongoid.yml
102
+
103
+
104
+ # Remove migrations, we don't need them with mongoid
105
+ rm -Rfd db/migrate
106
+
107
+
108
+ # Fix seeds.rb file to generate first admin user
109
+ echo 'puts "EMPTY THE MONGODB DATABASE"
110
+ Mongoid.master.collections.reject { |c| c.name =~ /^system/}.each(&:drop)
111
+
112
+ puts "SETTING UP DEFAULT ADMIN USER"
113
+ Rake::Task["activeadmin:settings:create_admin"].invoke
114
+ ' > db/seeds.rb
115
+
116
+
117
+ # Create default admin user
118
+ rake db:seed
119
+
120
+
121
+ # Create carrierwave default configuration
122
+ echo 'CarrierWave.configure do |config|
123
+ config.cache_dir = File.join(Rails.root, "tmp", "uploads")
124
+ config.storage = :fog
125
+
126
+ config.fog_credentials = {
127
+ :provider => "AWS",
128
+ :aws_access_key_id => ENV["AWS_ACCESS_KEY_ID"],
129
+ :aws_secret_access_key => ENV["AWS_SECRET_ACCESS_KEY"]
130
+ }
131
+
132
+ case Rails.env.to_sym
133
+ when :development
134
+ config.storage = :file
135
+ when :production
136
+ config.fog_directory = ENV["FOG_MEDIA_DIRECTORY"]
137
+ config.fog_host = "//#{ ENV["FOG_MEDIA_DIRECTORY"] }.s3.amazonaws.com"
138
+ config.fog_attributes = {"Cache-Control"=>"max-age=315576000"} # optional, defaults to {}
139
+ end
140
+ end' > config/initializers/carrierwave.rb
141
+
142
+
143
+ # Fix production assets to include all required files
144
+ mv config/environments/production.rb config/environments/production-old.rb
145
+ sed '/# config.assets.precompile += %w( search.js )/ a\
146
+ config.assets.precompile += ["active_admin.js", "active_admin.css", "redactor/css/style.css"]' config/environments/production-old.rb 1> config/environments/production.rb
147
+ rm config/environments/production-old.rb
148
+
149
+
150
+ echo ""
151
+ echo "Please make sure you've set Heroku environment settings:"
152
+ echo " FOG_MEDIA_DIRECTORY"
153
+ echo " AWS_ACCESS_KEY_ID"
154
+ echo " AWS_SECRET_ACCESS_KEY"
155
+ echo " MONGO_URL"
156
+ echo ""
157
+
158
+
159
+
160
+