activeadmin-blog 0.4.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 +20 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +215 -0
- data/README.md +162 -0
- data/Rakefile +7 -0
- data/activeadmin-blog.gemspec +30 -0
- data/app/controllers/activeadmin_blog/posts_controller.rb +50 -0
- data/app/models/activeadmin_blog/blog_category.rb +23 -0
- data/app/models/activeadmin_blog/blog_post.rb +81 -0
- data/app/views/activeadmin_blog/posts/_footer.html.erb +10 -0
- data/app/views/activeadmin_blog/posts/_header.html.erb +11 -0
- data/app/views/activeadmin_blog/posts/_post.html.erb +31 -0
- data/app/views/activeadmin_blog/posts/archive.html.erb +9 -0
- data/app/views/activeadmin_blog/posts/category.html.erb +9 -0
- data/app/views/activeadmin_blog/posts/feed.rss.builder +18 -0
- data/app/views/activeadmin_blog/posts/index.html.erb +9 -0
- data/app/views/activeadmin_blog/posts/search.html.erb +9 -0
- data/app/views/activeadmin_blog/posts/show.html.erb +35 -0
- data/app/views/activeadmin_blog/posts/tag.html.erb +9 -0
- data/app/views/admin/categories/_form.html.erb +26 -0
- data/app/views/admin/posts/_categories.html.erb +18 -0
- data/config/routes.rb +9 -0
- data/install.sh +160 -0
- data/lib/activeadmin-blog.rb +8 -0
- data/lib/activeadmin-blog/engine.rb +5 -0
- data/lib/activeadmin-blog/version.rb +3 -0
- data/lib/generators/activeadmin_blog/install_generator.rb +40 -0
- data/lib/generators/activeadmin_blog/templates/README +5 -0
- data/lib/generators/activeadmin_blog/templates/admin/blog_categories.rb +86 -0
- data/lib/generators/activeadmin_blog/templates/admin/blog_posts.rb +101 -0
- data/lib/generators/activeadmin_blog/views_generator.rb +16 -0
- data/vendor/assets/javascripts/activeadmin_blog.js.coffee +56 -0
- data/vendor/assets/stylesheets/activeadmin_blog.css.scss +51 -0
- 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,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,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,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
|
+
|