chive 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +25 -1
  3. data/app/assets/javascript/chive/application.js +8 -1
  4. data/app/assets/stylesheets/chive/application.scss +1 -13
  5. data/app/controllers/chive/application_controller.rb +1 -1
  6. data/app/controllers/chive/articles_controller.rb +4 -3
  7. data/app/controllers/chive/feed_controller.rb +10 -0
  8. data/app/controllers/concerns/chive/user_concerns.rb +14 -1
  9. data/app/helpers/chive/application_helper.rb +0 -4
  10. data/app/models/chive/article.rb +49 -0
  11. data/app/views/chive/articles/_form.html.erb +14 -12
  12. data/app/views/chive/articles/_pagination.html.erb +7 -0
  13. data/app/views/chive/articles/_status.html.erb +16 -0
  14. data/app/views/chive/articles/index.html.erb +14 -9
  15. data/app/views/chive/articles/show.html.erb +19 -12
  16. data/app/views/chive/feed/index.rss.builder +19 -0
  17. data/app/views/layouts/chive/_flash.html.erb +1 -1
  18. data/app/views/layouts/chive/application.html.erb +6 -4
  19. data/config/routes.rb +1 -1
  20. data/db/migrate/20210331030111_add_unique_slug_to_chive_articles.rb +5 -0
  21. data/db/migrate/20210331061401_add_non_unique_indexes_to_chive_articles.rb +8 -0
  22. data/db/seeds.rb +1 -1
  23. data/lib/chive/engine.rb +13 -1
  24. data/lib/chive/version.rb +1 -1
  25. data/lib/chive.rb +12 -0
  26. data/lib/generators/chive/migrations_generator.rb +2 -2
  27. data/lib/generators/chive/seeds_generator.rb +1 -1
  28. data/lib/tasks/chive_tasks.rake +28 -0
  29. data/templates/chive.rb.tt +7 -0
  30. metadata +11 -7
  31. data/app/assets/javascript/ckeditor/config.js +0 -56
  32. data/app/helpers/chive/articles_helper.rb +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5518cd19d73a5810f596e2133cc1d7c24c805a5aa527bcf9d140cb4d6d5a5905
4
- data.tar.gz: d68b9899479eeb673d6f11fb9c425dba4e44a817872ae34902ac9dbaf48457c8
3
+ metadata.gz: ebdbc5cf2ede969b8749328cdfd9923723b1bfd48c02e4e3a2220c0551780bb8
4
+ data.tar.gz: 2103ecb3b44a599644af0f1e0a3fd4a559324c7456b4e9501af108fd39addab1
5
5
  SHA512:
6
- metadata.gz: da2b3bf280731a66918d42d16289c03c4c0980e3de78bf9cb16e337a0d4de22f81b1db6460128ebe21ed234a4b927ee1f860830a558e08f2f21f370d487fdd4b
7
- data.tar.gz: 40369e984d1fe8e2cc4295cb5170d2ac2c20985e72b71200610bd7b49f5ea1dd56c9b26759c3044365de42d4ba05f404868c52f72eb2d5cd53be330aec748685
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
- mount Chive::Engine => "/"
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 'chive/blank', class: 'image-preview' %>
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
  }
@@ -6,7 +6,7 @@ module Chive
6
6
 
7
7
  protect_from_forgery with: :exception
8
8
 
9
- after_action :store_action
9
+ after_action(:store_action) if Chive.use_devise?
10
10
 
11
11
  # Needed to fix polymorphic_mappings.
12
12
  # @see https://github.com/rails/rails/issues/31325#issuecomment-560135329
@@ -11,16 +11,17 @@ module Chive
11
11
  # GET /articles
12
12
  # GET /articles.json
13
13
  def index
14
- @articles = if (chive_user || Rails.env.development?) && !params.key?(:public)
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.find(params[:id])
84
+ @article = Article.find_by(slug: params[:slug])
84
85
  end
85
86
 
86
87
  # Only allow a list of trusted parameters through.
@@ -0,0 +1,10 @@
1
+ module Chive
2
+ class FeedController < ApplicationController
3
+ def index
4
+ @articles = Article.latest_published.limit(Chive.per_page)
5
+ respond_to do |format|
6
+ format.rss { render layout: false }
7
+ end
8
+ end
9
+ end
10
+ end
@@ -1,6 +1,11 @@
1
1
  module Chive
2
2
  module UserConcerns
3
- extended ActiveSupport::Concern
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)
@@ -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
- <div class="col">
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', articles_path, class: 'btn btn-secondary' %>
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
- <%= image_tag 'chive/no-image', class: 'align-middle' %>
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
- <%= image_tag 'chive/blank', class: 'image-preview' %>
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.datetime_field :published_at, class: 'form-control datepicker-field' %>
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.datetime_field :expired_at, class: 'form-control datepicker-field' %>
106
+ <%= f.text_field :expired_at, class: 'form-control flatpickr-datetime' %>
105
107
  </div>
106
108
  </div>
107
109
  <% end %>
@@ -0,0 +1,7 @@
1
+ <div class="row mb-4">
2
+ <div class="col"></div>
3
+ <div class="flickr_pagination col-auto">
4
+ <%= will_paginate @articles %>
5
+ </div>
6
+ <div class="col"></div>
7
+ </div>
@@ -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
- <nav class="header-nav float-right">
3
- <% if user_can_chive? %>
4
- <%= link_to "New Article", new_article_path, class: 'btn btn-outline-primary' %>
5
- <% end %>
6
- </nav>
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
- <div class="digg_pagination">
19
- <%= will_paginate @articles, page_links: false, previous_label: '« Newer', next_label: 'Older »' %>
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
- <div class="float-left">
5
- <%= image_tag @article.image.variant(resize: '250x250') if @article.image.attached? %>
6
- </div>
7
- <div class="col">
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
- <%= raw @article.body %>
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="flash alert alert-warning alert-dismissible fade show" role="alert">
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 'Chive', articles_path, class: 'header-link align-middle' %></h1>
16
+ <h1 class="header-title"><%= link_to 'Articles', articles_path, class: 'header-link align-middle' %></h1>
17
17
  </div>
18
- <nav class="header-nav col">
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
- <small>Powered by Chive</small>
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
@@ -1,3 +1,3 @@
1
1
  Chive::Engine.routes.draw do
2
- resources :articles, path: '/'
2
+ resources :articles, path: '/', param: :slug
3
3
  end
@@ -0,0 +1,5 @@
1
+ class AddUniqueSlugToChiveArticles < ActiveRecord::Migration[6.0]
2
+ def change
3
+ add_index :chive_articles, :slug, unique: true
4
+ end
5
+ end
@@ -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
@@ -15,7 +15,7 @@ if Rails.env.development?
15
15
  <p>This is an example article created by the development seeds (db/seeds.rb).</p>
16
16
  ),
17
17
  author: user,
18
- status: 'published',
18
+ status: 'publish',
19
19
  published_at: DateTime.now
20
20
  )
21
21
  end
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
@@ -1,3 +1,3 @@
1
1
  module Chive
2
- VERSION = '0.1.1'
2
+ VERSION = '0.2.0'
3
3
  end
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
@@ -24,7 +24,7 @@ if Rails.env.development?
24
24
  <p>This is an example article created by the development seeds (db/seeds.rb).</p>
25
25
  ),
26
26
  author: user,
27
- status: 'published',
27
+ status: 'publish',
28
28
  published_at: DateTime.now
29
29
  )
30
30
  end
@@ -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
@@ -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.1.1
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: 2021-03-29 00:00:00.000000000 Z
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
- };
@@ -1,11 +0,0 @@
1
- module Chive
2
- module ArticlesHelper
3
- def user_can_chive?
4
- if Chive.use_devise?
5
- user_signed_in?
6
- else
7
- Rails.env.development?
8
- end
9
- end
10
- end
11
- end