chive 0.1.1 → 0.2.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.
- checksums.yaml +4 -4
- data/README.md +25 -1
- data/app/assets/javascript/chive/application.js +8 -1
- data/app/assets/stylesheets/chive/application.scss +1 -13
- data/app/controllers/chive/application_controller.rb +1 -1
- data/app/controllers/chive/articles_controller.rb +4 -3
- data/app/controllers/chive/feed_controller.rb +10 -0
- data/app/controllers/concerns/chive/user_concerns.rb +14 -1
- data/app/helpers/chive/application_helper.rb +0 -4
- data/app/models/chive/article.rb +49 -0
- data/app/views/chive/articles/_form.html.erb +14 -12
- data/app/views/chive/articles/_pagination.html.erb +7 -0
- data/app/views/chive/articles/_status.html.erb +16 -0
- data/app/views/chive/articles/index.html.erb +14 -9
- data/app/views/chive/articles/show.html.erb +19 -12
- data/app/views/chive/feed/index.rss.builder +19 -0
- data/app/views/layouts/chive/_flash.html.erb +1 -1
- data/app/views/layouts/chive/application.html.erb +6 -4
- data/config/routes.rb +1 -1
- data/db/migrate/20210331030111_add_unique_slug_to_chive_articles.rb +5 -0
- data/db/migrate/20210331061401_add_non_unique_indexes_to_chive_articles.rb +8 -0
- data/db/seeds.rb +1 -1
- data/lib/chive/engine.rb +13 -1
- data/lib/chive/version.rb +1 -1
- data/lib/chive.rb +12 -0
- data/lib/generators/chive/migrations_generator.rb +2 -2
- data/lib/generators/chive/seeds_generator.rb +1 -1
- data/lib/tasks/chive_tasks.rake +28 -0
- data/templates/chive.rb.tt +7 -0
- metadata +11 -7
- data/app/assets/javascript/ckeditor/config.js +0 -56
- data/app/helpers/chive/articles_helper.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ebdbc5cf2ede969b8749328cdfd9923723b1bfd48c02e4e3a2220c0551780bb8
|
4
|
+
data.tar.gz: 2103ecb3b44a599644af0f1e0a3fd4a559324c7456b4e9501af108fd39addab1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 965fca49ecae82243be60508620a276ac287739e8eea1871bb8496927cfbb8b2a88551b5d6406a5557e643c53e19192105b324ef7136a29cbb17e152be402df6
|
7
|
+
data.tar.gz: 2acb628957d7dee8f6dae2ccf384214d4e2fb45fdb578a22d7a8572cd261b7c78741973c62f2d8328e1adb8690357a69ae865bccb384d8c65a780354f9674a0e
|
data/README.md
CHANGED
@@ -125,7 +125,15 @@ end
|
|
125
125
|
You can make the blog your home page by changing the `Chive::Engine` path to `/`:
|
126
126
|
|
127
127
|
```ruby
|
128
|
-
|
128
|
+
Rails.application.routes.draw do
|
129
|
+
|
130
|
+
# [...etc.]
|
131
|
+
|
132
|
+
# If you mount Chive on the home page, make sure it's the last route you
|
133
|
+
# define. Otherwise `Chive::Engine#index` will process all your website's
|
134
|
+
# paths before the other routes have a chance to evaluate them.
|
135
|
+
mount Chive::Engine => '/'
|
136
|
+
end
|
129
137
|
```
|
130
138
|
|
131
139
|
## Customizing the Layout
|
@@ -167,3 +175,19 @@ end
|
|
167
175
|
The `only: [:index, :show]` option limits the resource to the public pages.
|
168
176
|
|
169
177
|
Now you can make your own views at `app/views/blog/index.html.erb` and `app/views/blog/show.html.erb`.
|
178
|
+
|
179
|
+
## Third-Party Libraries
|
180
|
+
|
181
|
+
Chive uses the following libraries and plugins:
|
182
|
+
|
183
|
+
- [acts-as-taggable-on](https://github.com/mbleigh/acts-as-taggable-on)
|
184
|
+
- [bootstrap](https://github.com/twbs/bootstrap-rubygem)
|
185
|
+
- [ckeditor](https://github.com/galetahub/ckeditor)
|
186
|
+
- [flatpickr](https://github.com/flatpickr/flatpickr)
|
187
|
+
- [jquery-rails](https://github.com/rails/jquery-rails)
|
188
|
+
- [will_paginate](https://github.com/mislav/will_paginate)
|
189
|
+
|
190
|
+
## Sites Using Chive
|
191
|
+
|
192
|
+
- [gamefic.com](https://gamefic.com)
|
193
|
+
- [moviecrank.com](https://moviecrank.com)
|
@@ -6,12 +6,14 @@
|
|
6
6
|
//= require popper
|
7
7
|
//= require bootstrap-sprockets
|
8
8
|
|
9
|
+
//= require flatpickr
|
10
|
+
|
9
11
|
/**
|
10
12
|
* Preview an image before upload
|
11
13
|
*
|
12
14
|
* Example:
|
13
15
|
*
|
14
|
-
* <%= image_tag '
|
16
|
+
* <%= image_tag 'blank', class: 'image-preview' %>
|
15
17
|
* <%= check_box_tag :delete_preview, 'delete', false, class: 'delete-preview' %>
|
16
18
|
* <%= f.file_field :image, class: 'image-upload', data: {preview: '.image-preview', delete: '.delete-preview' } %>
|
17
19
|
*/
|
@@ -69,3 +71,8 @@ $(function () {
|
|
69
71
|
}
|
70
72
|
});
|
71
73
|
});
|
74
|
+
|
75
|
+
$(function () {
|
76
|
+
flatpickr('.flatpickr-date');
|
77
|
+
flatpickr('.flatpickr-datetime', { enableTime: true });
|
78
|
+
});
|
@@ -1,5 +1,6 @@
|
|
1
1
|
@import "bootstrap";
|
2
2
|
@import "./pagination";
|
3
|
+
@import "flatpickr";
|
3
4
|
|
4
5
|
#header {
|
5
6
|
background-color: #f2efe9;
|
@@ -13,23 +14,10 @@
|
|
13
14
|
}
|
14
15
|
|
15
16
|
.flash {
|
16
|
-
text-align: center;
|
17
17
|
margin-top: -2em;
|
18
18
|
margin-bottom: 2em;
|
19
19
|
}
|
20
20
|
|
21
|
-
.header-nav {
|
22
|
-
text-align: right;
|
23
|
-
|
24
|
-
.btn {
|
25
|
-
margin-left: 0.5em;
|
26
|
-
}
|
27
|
-
}
|
28
|
-
|
29
|
-
#footer {
|
30
|
-
padding-top: 1em;
|
31
|
-
}
|
32
|
-
|
33
21
|
.btn.btn-primary, .btn.btn-outline-primary {
|
34
22
|
min-width: 5rem;
|
35
23
|
}
|
@@ -11,16 +11,17 @@ module Chive
|
|
11
11
|
# GET /articles
|
12
12
|
# GET /articles.json
|
13
13
|
def index
|
14
|
-
@articles = if
|
14
|
+
@articles = if user_can_chive? && !params.key?(:public)
|
15
15
|
Article.latest
|
16
16
|
else
|
17
17
|
Article.latest_published
|
18
|
-
end.paginate(page: params[:page])
|
18
|
+
end.paginate(page: params[:page], per_page: Chive.per_page)
|
19
19
|
end
|
20
20
|
|
21
21
|
# GET /articles/1
|
22
22
|
# GET /articles/1.json
|
23
23
|
def show
|
24
|
+
raise ActionController::RoutingError.new('Not Found') unless @article
|
24
25
|
end
|
25
26
|
|
26
27
|
# GET /articles/new
|
@@ -80,7 +81,7 @@ module Chive
|
|
80
81
|
|
81
82
|
# Use callbacks to share common setup or constraints between actions.
|
82
83
|
def set_article
|
83
|
-
@article = Article.
|
84
|
+
@article = Article.find_by(slug: params[:slug])
|
84
85
|
end
|
85
86
|
|
86
87
|
# Only allow a list of trusted parameters through.
|
@@ -1,6 +1,11 @@
|
|
1
1
|
module Chive
|
2
2
|
module UserConcerns
|
3
|
-
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
helper_method :user_can_chive?
|
7
|
+
helper_method :chive_user
|
8
|
+
end
|
4
9
|
|
5
10
|
def authenticate_chive_user
|
6
11
|
if Chive.use_devise?
|
@@ -16,5 +21,13 @@ module Chive
|
|
16
21
|
def chive_user
|
17
22
|
send("current_#{Chive.user_model.underscore}") if Chive.use_devise?
|
18
23
|
end
|
24
|
+
|
25
|
+
def user_can_chive?
|
26
|
+
if Chive.use_devise?
|
27
|
+
user_signed_in?
|
28
|
+
else
|
29
|
+
Rails.env.development?
|
30
|
+
end
|
31
|
+
end
|
19
32
|
end
|
20
33
|
end
|
@@ -1,9 +1,5 @@
|
|
1
1
|
module Chive
|
2
2
|
module ApplicationHelper
|
3
|
-
def chive_user
|
4
|
-
send("current_#{Chive.user_model.underscore}") if Chive.use_devise?
|
5
|
-
end
|
6
|
-
|
7
3
|
# Needed to fix polymorphic_mappings.
|
8
4
|
# @see https://github.com/rails/rails/issues/31325#issuecomment-560135329
|
9
5
|
def method_missing(method, *args, &block)
|
data/app/models/chive/article.rb
CHANGED
@@ -7,6 +7,16 @@ module Chive
|
|
7
7
|
|
8
8
|
acts_as_taggable_on :tags
|
9
9
|
|
10
|
+
validates :title, presence: true
|
11
|
+
|
12
|
+
before_validation :set_slug
|
13
|
+
validate :slug_is_parameter
|
14
|
+
validates :slug, presence: true, uniqueness: true
|
15
|
+
|
16
|
+
validate :valid_status
|
17
|
+
|
18
|
+
before_save :maybe_summarize
|
19
|
+
|
10
20
|
def byline
|
11
21
|
return custom_byline if custom_byline.present?
|
12
22
|
return real_author_name if real_author_name.present?
|
@@ -22,6 +32,23 @@ module Chive
|
|
22
32
|
end
|
23
33
|
|
24
34
|
def published?
|
35
|
+
self.status == 'publish'
|
36
|
+
end
|
37
|
+
|
38
|
+
def draft?
|
39
|
+
self.status == 'draft'
|
40
|
+
end
|
41
|
+
|
42
|
+
def public?
|
43
|
+
self.status == 'publish' && !expired?
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_param
|
47
|
+
slug
|
48
|
+
end
|
49
|
+
|
50
|
+
def set_slug
|
51
|
+
self.slug = Chive.slug_formatter.call(self) if slug.blank?
|
25
52
|
end
|
26
53
|
|
27
54
|
def self.latest
|
@@ -32,5 +59,27 @@ module Chive
|
|
32
59
|
now = DateTime.now
|
33
60
|
latest.where('published_at <= ? AND (expired_at >= ? OR expired_at IS NULL) AND status = ?', now, now, 'publish')
|
34
61
|
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def valid_status
|
66
|
+
errors.add(:status, :invalid) unless ['publish', 'draft'].include?(status)
|
67
|
+
end
|
68
|
+
|
69
|
+
def slug_is_parameter
|
70
|
+
errors.add(:slug, 'must be a valid parameter') unless slug.parameterize == slug
|
71
|
+
end
|
72
|
+
|
73
|
+
def maybe_summarize
|
74
|
+
return unless autosummary
|
75
|
+
self.summary = summarize_body
|
76
|
+
end
|
77
|
+
|
78
|
+
def summarize_body
|
79
|
+
doc = Nokogiri::HTML.parse(body)
|
80
|
+
paras = doc.css('p')
|
81
|
+
return if paras.empty? || paras.one?
|
82
|
+
paras.first.text
|
83
|
+
end
|
35
84
|
end
|
36
85
|
end
|
@@ -2,18 +2,20 @@
|
|
2
2
|
|
3
3
|
<%= form_for @article, html: { multipart: true } do |f| %>
|
4
4
|
<div class="row">
|
5
|
-
<
|
6
|
-
<h1><%= params[:action].capitalize %> Article</h1>
|
7
|
-
</div>
|
8
|
-
<nav class="col header-nav">
|
5
|
+
<nav class="col text-right">
|
9
6
|
<%= f.submit 'Save', class: 'btn btn-primary' %>
|
10
|
-
<%= link_to 'Cancel',
|
7
|
+
<%= link_to 'Cancel', @article, class: 'btn btn-secondary' %>
|
11
8
|
<% if params[:action] == 'edit' %>
|
12
9
|
<%= link_to "Delete", '#', class: 'btn btn-outline-danger', data: { toggle: 'modal', target: '#delete-modal' } %>
|
13
10
|
<%= render partial: 'delete_modal' %>
|
14
11
|
<% end %>
|
15
12
|
</nav>
|
16
13
|
</div>
|
14
|
+
<div class="row">
|
15
|
+
<div class="col">
|
16
|
+
<h1><%= params[:action].capitalize %> Article</h1>
|
17
|
+
</div>
|
18
|
+
</div>
|
17
19
|
<% if @article.errors.any? %>
|
18
20
|
<div id="error_explanation">
|
19
21
|
<h2><%= pluralize(@article.errors.count, "error") %> errors prohibited this article from being saved:</h2>
|
@@ -32,7 +34,7 @@
|
|
32
34
|
<div class="col-md-9">
|
33
35
|
<div class="form-group">
|
34
36
|
<%= f.label :body %>
|
35
|
-
<%= f.cktext_area :body, class: 'form-control' %>
|
37
|
+
<%= f.cktext_area :body, class: 'form-control', ckeditor: { height: 512 } %>
|
36
38
|
</div>
|
37
39
|
</div>
|
38
40
|
<div class="col-md-3">
|
@@ -40,23 +42,23 @@
|
|
40
42
|
<%= f.label :image %>
|
41
43
|
<div class="image-previews">
|
42
44
|
<div class="image-container">
|
43
|
-
|
45
|
+
<img src="/assets/chive/no-image.png" class="align-middle" />
|
44
46
|
</div>
|
45
47
|
<div>
|
46
48
|
<% if @article.image.attached? %>
|
47
49
|
<div class="image-container">
|
48
50
|
<%= image_tag @article.image.variant(resize: '250x250'), class: 'attached-image' if @article.image.attached? %>
|
49
51
|
</div>
|
50
|
-
<label class="delete-image">
|
52
|
+
<label class="delete-image btn">
|
51
53
|
<%= check_box_tag :delete_image, @article.image.id, false %>
|
52
54
|
</label>
|
53
55
|
<% end %>
|
54
56
|
</div>
|
55
57
|
<div>
|
56
58
|
<div class="image-container">
|
57
|
-
|
59
|
+
<img src="/assets/chive/blank.png" class="image-preview" />
|
58
60
|
</div>
|
59
|
-
<label class="delete-preview">
|
61
|
+
<label class="delete-preview btn">
|
60
62
|
<%= check_box_tag :delete_preview, 'delete', false %>
|
61
63
|
</label>
|
62
64
|
</div>
|
@@ -97,11 +99,11 @@
|
|
97
99
|
</div>
|
98
100
|
<div class="form-group col-sm-4">
|
99
101
|
<%= f.label :published_at, 'Publish Date' %>
|
100
|
-
<%= f.
|
102
|
+
<%= f.text_field :published_at, class: 'form-control flatpickr-datetime' %>
|
101
103
|
</div>
|
102
104
|
<div class="form-group col-sm-4">
|
103
105
|
<%= f.label :exipred_at, 'Expire Date' %>
|
104
|
-
<%= f.
|
106
|
+
<%= f.text_field :expired_at, class: 'form-control flatpickr-datetime' %>
|
105
107
|
</div>
|
106
108
|
</div>
|
107
109
|
<% end %>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<% if user_can_chive? %>
|
2
|
+
<p>
|
3
|
+
<% if article.draft? %><span class="badge badge-info">Draft</span><% end %>
|
4
|
+
<% if article.expired? %><span class="badge badge-info">Expired</span><% end %>
|
5
|
+
<% unless article.public? %>
|
6
|
+
<% if chive_user %>
|
7
|
+
<span class="badge badge-info">Visible to authors</span>
|
8
|
+
<% elsif Rails.env.development? %>
|
9
|
+
<span class="badge badge-info">Visible in development</span>
|
10
|
+
<% end %>
|
11
|
+
<% end %>
|
12
|
+
<% if !article.draft? && !article.public? %>
|
13
|
+
<span class="badge badge-danger">Status: <%= article.status %></span>
|
14
|
+
<% end %>
|
15
|
+
</p>
|
16
|
+
<% end %>
|
@@ -1,21 +1,26 @@
|
|
1
1
|
<section>
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
2
|
+
<% if user_can_chive? %>
|
3
|
+
<div class="row">
|
4
|
+
<nav class="col text-right">
|
5
|
+
<%= link_to "New Article", new_article_path, class: 'btn btn-outline-primary' %>
|
6
|
+
</nav>
|
7
|
+
</div>
|
8
|
+
<% end %>
|
9
|
+
|
10
|
+
<%= render 'pagination' %>
|
7
11
|
|
8
12
|
<% @articles.each do |article| %>
|
13
|
+
<div class="row mb-4">
|
14
|
+
</div>
|
9
15
|
<article>
|
10
16
|
<h2 class="large"><%= link_to article.title, article_path(article) %></h2>
|
11
17
|
<address>by <%= article.byline %> on <%= article.published_at %></address>
|
12
18
|
<p>
|
13
19
|
<%= raw article.summary %>
|
14
|
-
<%= link_to 'Read More', article_path(article) %>
|
15
20
|
</p>
|
21
|
+
<%= render 'status', article: article %>
|
16
22
|
</article>
|
17
23
|
<% end %>
|
18
|
-
|
19
|
-
|
20
|
-
</div>
|
24
|
+
|
25
|
+
<%= render 'pagination' %>
|
21
26
|
</section>
|
@@ -1,26 +1,33 @@
|
|
1
|
+
<% if user_can_chive? %>
|
2
|
+
<div class="row mb-4">
|
3
|
+
<nav class="col text-right">
|
4
|
+
<%= link_to "Edit", edit_article_path(@article), class: 'btn btn-outline-primary' %>
|
5
|
+
<%= render partial: 'delete_modal' %>
|
6
|
+
</nav>
|
7
|
+
</div>
|
8
|
+
<% end %>
|
9
|
+
|
1
10
|
<section>
|
2
11
|
<article>
|
3
12
|
<div class="row">
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
13
|
+
<% if @article.image.attached? %>
|
14
|
+
<div class="col-auto">
|
15
|
+
<%= image_tag @article.image.variant(resize: '400x300') %>
|
16
|
+
</div>
|
17
|
+
<% end %>
|
18
|
+
<div class="col-md">
|
8
19
|
<h1><%= @article.title %></h1>
|
9
20
|
<address>by <%= @article.byline %> on <%= @article.published_at %></address>
|
10
21
|
<p>
|
11
22
|
<small><%= @article.tag_list.to_s %></small>
|
12
23
|
</p>
|
24
|
+
<%= render 'status', article: @article %>
|
13
25
|
</div>
|
14
|
-
<nav class="col header-nav">
|
15
|
-
<% if user_can_chive? %>
|
16
|
-
<%= link_to "Edit", edit_article_path(@article), class: 'btn btn-outline-primary' %>
|
17
|
-
<%= link_to "Delete", '#', class: 'btn btn-outline-danger', data: { toggle: 'modal', target: '#delete-modal' } %>
|
18
|
-
<%= render partial: 'delete_modal' %>
|
19
|
-
<% end %>
|
20
|
-
</nav>
|
21
26
|
</div>
|
22
27
|
<div class="row">
|
23
|
-
|
28
|
+
<div class="col">
|
29
|
+
<%= raw @article.body %>
|
30
|
+
</div>
|
24
31
|
</div>
|
25
32
|
</article>
|
26
33
|
</section>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
xml.instruct! :xml, :version => "1.0"
|
2
|
+
xml.rss :version => "2.0" do
|
3
|
+
xml.channel do
|
4
|
+
xml.title "Your Blog Title"
|
5
|
+
xml.description "A blog about software and chocolate"
|
6
|
+
# xml.link chive.articles_url
|
7
|
+
xml.link 'https://castwide.com'
|
8
|
+
|
9
|
+
for article in @articles
|
10
|
+
xml.item do
|
11
|
+
xml.title article.title
|
12
|
+
xml.description article.summary
|
13
|
+
xml.pubDate article.published_at.to_s(:rfc822)
|
14
|
+
xml.link chive.article_url(article)
|
15
|
+
xml.guid chive.article_url(article)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<% unless flash.empty? %>
|
2
|
-
<div class="
|
2
|
+
<div class="alert alert-warning alert-dismissible fade show text-center" role="alert">
|
3
3
|
<% flash.each do |type, msg| %>
|
4
4
|
<div class="container <%= type %>">
|
5
5
|
<%= msg %>
|
@@ -13,9 +13,9 @@
|
|
13
13
|
<div class="container">
|
14
14
|
<div class="row justify-content-between">
|
15
15
|
<div class="col">
|
16
|
-
<h1 class="header-title"><%= link_to '
|
16
|
+
<h1 class="header-title"><%= link_to 'Articles', articles_path, class: 'header-link align-middle' %></h1>
|
17
17
|
</div>
|
18
|
-
<nav class="
|
18
|
+
<nav class="col text-right">
|
19
19
|
<%= render "layouts/chive/userbox" %>
|
20
20
|
</nav>
|
21
21
|
</div>
|
@@ -27,8 +27,10 @@
|
|
27
27
|
<%= yield %>
|
28
28
|
</main>
|
29
29
|
|
30
|
-
<footer class="container">
|
31
|
-
<
|
30
|
+
<footer class="container text-center mb-4">
|
31
|
+
<p>
|
32
|
+
<small>Powered by Chive</small>
|
33
|
+
</p>
|
32
34
|
</footer>
|
33
35
|
</body>
|
34
36
|
</html>
|
data/config/routes.rb
CHANGED
@@ -0,0 +1,8 @@
|
|
1
|
+
class AddNonUniqueIndexesToChiveArticles < ActiveRecord::Migration[6.0]
|
2
|
+
def change
|
3
|
+
add_index :chive_articles, :author_id, unique: false
|
4
|
+
add_index :chive_articles, :status, unique: false
|
5
|
+
add_index :chive_articles, :published_at, unique: false
|
6
|
+
add_index :chive_articles, :expired_at, unique: false
|
7
|
+
end
|
8
|
+
end
|
data/db/seeds.rb
CHANGED
data/lib/chive/engine.rb
CHANGED
@@ -4,10 +4,22 @@ module Chive
|
|
4
4
|
class Engine < ::Rails::Engine
|
5
5
|
isolate_namespace Chive
|
6
6
|
|
7
|
-
initializer 'chive.assets' do |app|
|
7
|
+
initializer 'chive.assets.precompile' do |app|
|
8
8
|
app.config.assets.precompile += fetch_asset_names
|
9
9
|
end
|
10
10
|
|
11
|
+
# Enhance the assets:precompile task with the chive:public_assets task to
|
12
|
+
# ensure that the main app can access this engine's assets in production.
|
13
|
+
rake_tasks do
|
14
|
+
load Chive::Engine.root.join('lib', 'tasks', 'chive_tasks.rake')
|
15
|
+
|
16
|
+
if Rake::Task.task_defined?('assets:precompile')
|
17
|
+
Rake::Task['assets:precompile'].enhance do
|
18
|
+
Rake::Task['chive:public_assets'].invoke
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
11
23
|
private
|
12
24
|
|
13
25
|
def fetch_asset_names
|
data/lib/chive/version.rb
CHANGED
data/lib/chive.rb
CHANGED
@@ -42,5 +42,17 @@ module Chive
|
|
42
42
|
def public_layout
|
43
43
|
@public_layout ||= 'chive/application'
|
44
44
|
end
|
45
|
+
|
46
|
+
attr_writer :slug_formatter
|
47
|
+
|
48
|
+
def slug_formatter
|
49
|
+
@slug_formatter ||= proc { |article| article.title.parameterize }
|
50
|
+
end
|
51
|
+
|
52
|
+
attr_writer :per_page
|
53
|
+
|
54
|
+
def per_page
|
55
|
+
@per_page ||= 10
|
56
|
+
end
|
45
57
|
end
|
46
58
|
end
|
@@ -16,8 +16,8 @@ Generate migrations for Chive.
|
|
16
16
|
.map { |f| File.basename(f) }
|
17
17
|
.each do |src|
|
18
18
|
title = src.gsub /^[0-9]+_/, ''
|
19
|
-
migration_template src, "db/migrate/#{title}", {
|
20
|
-
migration_file_name: File.basename(src, '.rb')
|
19
|
+
migration_template src, "db/migrate/#{title}.rb", {
|
20
|
+
migration_file_name: "#{File.basename(src, '.rb')}"
|
21
21
|
}
|
22
22
|
end
|
23
23
|
end
|
data/lib/tasks/chive_tasks.rake
CHANGED
@@ -29,4 +29,32 @@ namespace :chive do
|
|
29
29
|
sh 'rails generate chive:seeds'
|
30
30
|
sh 'rails generate chive:initializer --devise'
|
31
31
|
end
|
32
|
+
|
33
|
+
# This task is necessary to ensure that Chive's compiled assets are
|
34
|
+
# available from the main app in production. the CKEditor gem performs a
|
35
|
+
# similar operation.
|
36
|
+
desc 'Create public versions of Chive assets'
|
37
|
+
task public_assets: :environment do
|
38
|
+
fingerprint = /\-[0-9a-f]{32,64}\./
|
39
|
+
path = Rails.root.join('public', 'assets', 'chive', '**', '*')
|
40
|
+
|
41
|
+
Dir[path].each do |file|
|
42
|
+
next unless file =~ fingerprint
|
43
|
+
nondigest = file.sub fingerprint, '.'
|
44
|
+
|
45
|
+
if !File.exist?(nondigest) || File.mtime(file) > File.mtime(nondigest)
|
46
|
+
FileUtils.cp file, nondigest, verbose: true, preserve: true
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
desc 'Rewrite article slugs'
|
52
|
+
task slugs: :environment do
|
53
|
+
Chive::Article.all.each do |article|
|
54
|
+
rewrite = Chive.slug_formatter.call(article)
|
55
|
+
puts "#{article.slug} -> #{rewrite}"
|
56
|
+
article.slug = rewrite
|
57
|
+
article.save!
|
58
|
+
end
|
59
|
+
end
|
32
60
|
end
|
data/templates/chive.rb.tt
CHANGED
@@ -19,4 +19,11 @@ Chive.setup do |config|
|
|
19
19
|
<% end %>
|
20
20
|
# The layout to use for public pages
|
21
21
|
# config.public_layout = 'chive/application'
|
22
|
+
|
23
|
+
# The slug formatter. This proc should generate a unique param for the
|
24
|
+
# article's URL, e.g., `my-article-title`
|
25
|
+
# config.slug_formatter = proc { |article| article.title.parameterize }
|
26
|
+
|
27
|
+
# The number of articles to display per page
|
28
|
+
# config.per_page = 10
|
22
29
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chive
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fred Snyder
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-03-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: acts-as-taggable-on
|
@@ -144,30 +144,34 @@ files:
|
|
144
144
|
- app/assets/images/chive/icon-undo.png
|
145
145
|
- app/assets/images/chive/no-image.png
|
146
146
|
- app/assets/javascript/chive/application.js
|
147
|
-
- app/assets/javascript/ckeditor/config.js
|
148
147
|
- app/assets/stylesheets/chive/application.scss
|
149
148
|
- app/assets/stylesheets/chive/articles.css
|
150
149
|
- app/assets/stylesheets/chive/pagination.sass
|
151
150
|
- app/controllers/chive/application_controller.rb
|
152
151
|
- app/controllers/chive/articles_controller.rb
|
152
|
+
- app/controllers/chive/feed_controller.rb
|
153
153
|
- app/controllers/concerns/chive/user_concerns.rb
|
154
154
|
- app/helpers/chive/application_helper.rb
|
155
|
-
- app/helpers/chive/articles_helper.rb
|
156
155
|
- app/jobs/chive/application_job.rb
|
157
156
|
- app/mailers/chive/application_mailer.rb
|
158
157
|
- app/models/chive/application_record.rb
|
159
158
|
- app/models/chive/article.rb
|
160
159
|
- app/views/chive/articles/_delete_modal.erb
|
161
160
|
- app/views/chive/articles/_form.html.erb
|
161
|
+
- app/views/chive/articles/_pagination.html.erb
|
162
|
+
- app/views/chive/articles/_status.html.erb
|
162
163
|
- app/views/chive/articles/edit.html.erb
|
163
164
|
- app/views/chive/articles/index.html.erb
|
164
165
|
- app/views/chive/articles/new.html.erb
|
165
166
|
- app/views/chive/articles/show.html.erb
|
167
|
+
- app/views/chive/feed/index.rss.builder
|
166
168
|
- app/views/layouts/chive/_flash.html.erb
|
167
169
|
- app/views/layouts/chive/_userbox.html.erb
|
168
170
|
- app/views/layouts/chive/application.html.erb
|
169
171
|
- config/routes.rb
|
170
172
|
- db/migrate/20210327092716_create_chive_articles.rb
|
173
|
+
- db/migrate/20210331030111_add_unique_slug_to_chive_articles.rb
|
174
|
+
- db/migrate/20210331061401_add_non_unique_indexes_to_chive_articles.rb
|
171
175
|
- db/seeds.rb
|
172
176
|
- lib/chive.rb
|
173
177
|
- lib/chive/ckeditor_authorization.rb
|
@@ -190,7 +194,7 @@ homepage: https://castwide.com
|
|
190
194
|
licenses:
|
191
195
|
- MIT
|
192
196
|
metadata: {}
|
193
|
-
post_install_message:
|
197
|
+
post_install_message:
|
194
198
|
rdoc_options: []
|
195
199
|
require_paths:
|
196
200
|
- lib
|
@@ -206,7 +210,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
206
210
|
version: '0'
|
207
211
|
requirements: []
|
208
212
|
rubygems_version: 3.2.0
|
209
|
-
signing_key:
|
213
|
+
signing_key:
|
210
214
|
specification_version: 4
|
211
215
|
summary: Blog plugin for Rails
|
212
216
|
test_files: []
|
@@ -1,56 +0,0 @@
|
|
1
|
-
CKEDITOR.editorConfig = function( config )
|
2
|
-
{
|
3
|
-
// Define changes to default configuration here. For example:
|
4
|
-
// config.language = 'fr';
|
5
|
-
// config.uiColor = '#AADC6E';
|
6
|
-
|
7
|
-
config.height = 420;
|
8
|
-
|
9
|
-
/* Filebrowser routes */
|
10
|
-
// The location of an external file browser, that should be launched when "Browse Server" button is pressed.
|
11
|
-
config.filebrowserBrowseUrl = "/ckeditor/attachment_files";
|
12
|
-
|
13
|
-
// The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Flash dialog.
|
14
|
-
config.filebrowserFlashBrowseUrl = "/ckeditor/attachment_files";
|
15
|
-
|
16
|
-
// The location of a script that handles file uploads in the Flash dialog.
|
17
|
-
config.filebrowserFlashUploadUrl = "/ckeditor/attachment_files";
|
18
|
-
|
19
|
-
// The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Link tab of Image dialog.
|
20
|
-
config.filebrowserImageBrowseLinkUrl = "/ckeditor/pictures";
|
21
|
-
|
22
|
-
// The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Image dialog.
|
23
|
-
config.filebrowserImageBrowseUrl = "/ckeditor/pictures";
|
24
|
-
|
25
|
-
// The location of a script that handles file uploads in the Image dialog.
|
26
|
-
config.filebrowserImageUploadUrl = "/ckeditor/pictures?";
|
27
|
-
|
28
|
-
// The location of a script that handles file uploads.
|
29
|
-
config.filebrowserUploadUrl = "/ckeditor/attachment_files";
|
30
|
-
|
31
|
-
config.allowedContent = true;
|
32
|
-
config.filebrowserUploadMethod = 'form';
|
33
|
-
|
34
|
-
// Toolbar groups configuration.
|
35
|
-
config.toolbar = [
|
36
|
-
{ name: 'document', groups: [ 'mode', 'document', 'doctools' ], items: [ 'Source'] },
|
37
|
-
{ name: 'clipboard', groups: [ 'clipboard', 'undo' ], items: [ 'Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo' ] },
|
38
|
-
// { name: 'editing', groups: [ 'find', 'selection', 'spellchecker' ], items: [ 'Find', 'Replace', '-', 'SelectAll', '-', 'Scayt' ] },
|
39
|
-
// { name: 'forms', items: [ 'Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField' ] },
|
40
|
-
{ name: 'links', items: [ 'Link', 'Unlink', 'Anchor' ] },
|
41
|
-
{ name: 'insert', items: [ 'Image', 'Flash', 'Table', 'HorizontalRule', 'SpecialChar' ] },
|
42
|
-
{ name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ], items: [ 'NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote', 'CreateDiv', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock' ] },
|
43
|
-
'/',
|
44
|
-
{ name: 'styles', items: [ 'Styles', 'Format', 'Font', 'FontSize' ] },
|
45
|
-
{ name: 'colors', items: [ 'TextColor', 'BGColor' ] },
|
46
|
-
{ name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ], items: [ 'Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat' ] }
|
47
|
-
];
|
48
|
-
|
49
|
-
config.toolbar_mini = [
|
50
|
-
{ name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ], items: [ 'NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote', 'CreateDiv', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock' ] },
|
51
|
-
{ name: 'styles', items: [ 'Font', 'FontSize' ] },
|
52
|
-
{ name: 'colors', items: [ 'TextColor', 'BGColor' ] },
|
53
|
-
{ name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ], items: [ 'Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat' ] },
|
54
|
-
{ name: 'insert', items: [ 'Image', 'Table', 'HorizontalRule', 'SpecialChar' ] }
|
55
|
-
];
|
56
|
-
};
|