ecm_blog 1.2.1 → 1.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ed06e1d64976f3a1563ab81483d4f255ce14a5c6
4
- data.tar.gz: 26d97170469dce60dbb658d1e822abb4798cffa9
3
+ metadata.gz: aa66850e4536529d4ee1ffe08a0946b1a7c3e56a
4
+ data.tar.gz: 41de1a1a851302250642ae3aa66d6202ac48c0d4
5
5
  SHA512:
6
- metadata.gz: b525df7f75466358db2f64793e891eec9cc2f85a8e210d511e831146e1ad0a5aa47c75bbf674aa8d16bcb54dadb7c3b6baaeda0c2e94abb2b46c2d6a90b652b2
7
- data.tar.gz: dfc5d12e3cea8ab229a947427478c02d74e3c708e9ae3e49992cf3298a1fc45f9ce8e213af890df3820b9513c5f67ca60d38da8ab199731f8e9b72f5a6dbe215
6
+ metadata.gz: 66e12ee3c548916d10b3b7e94e5e61920bd89a72f2f186cd57f555da01a9082934bfd2ab35278fc76b287fa2acd95852741b7b3ca5bfab79d2294e4d0f63e505
7
+ data.tar.gz: 44a5f83d35c810f7ac2cb13030707fd13fa2aba202e7ff498793b34912a0dd8a4eaaaf561f993ff349ce0c74383d1bbf69a61978d5fef2112235fbf15a104f5e
@@ -10,6 +10,8 @@ module Ecm
10
10
 
11
11
  helper Ecm::Comments::ApplicationHelper
12
12
 
13
+ helper Rails::AddOns::TableHelper
14
+
13
15
  def self.resource_class
14
16
  Ecm::Blog::Post
15
17
  end
@@ -17,7 +19,11 @@ module Ecm
17
19
  private
18
20
 
19
21
  def load_collection_scope
20
- super.published.friendly.order(created_at: :desc)
22
+ if params.has_key?(:year)
23
+ super.published.for_date(params[:year], params[:month], params[:day])
24
+ else
25
+ super.published
26
+ end
21
27
  end
22
28
 
23
29
  def load_resource_scope
@@ -1,6 +1,28 @@
1
1
  module Ecm
2
2
  module Blog
3
3
  module ApplicationHelper
4
+ # Prerequisites:
5
+ #
6
+ # You have to add the simple-navigation gem to your Gemfile:
7
+ #
8
+ # # Gemfile
9
+ # gem 'simple-navigation'
10
+ #
11
+ # Usage:
12
+ #
13
+ # # app/controllers/application_controller.rb
14
+ # class ApplicationController < ActionController::Base
15
+ # helper Ecm::Blog::ApplicationHelper
16
+ # end
17
+ #
18
+ # # app/views/layouts/application.html.haml
19
+ # = blog_render_monthly_navigation if controller.class.name.deconstantize == 'Ecm::Blog'
20
+ #
21
+ def blog_render_monthly_navigation
22
+ posts = Ecm::Blog::Post.published.all.pluck(:created_at)
23
+ posts_by_month = posts.group_by {|t| t.beginning_of_month }
24
+ render partial: 'ecm/blog/posts/monthly_navigation', locals: { posts_by_month: posts_by_month}
25
+ end
4
26
  end
5
27
  end
6
28
  end
@@ -0,0 +1,19 @@
1
+ module Ecm::Blog
2
+ class AssetDetail < ApplicationRecord
3
+ belongs_to :post
4
+ belongs_to :asset, class_name: 'ActiveStorage::Attachment', dependent: :destroy
5
+
6
+ acts_as_list scope: :post_id
7
+
8
+ scope :images, -> { joins(asset: [:blob]).where("active_storage_blobs.content_type LIKE '%image/%'") }
9
+ scope :non_images, -> { joins(asset: [:blob]).where("active_storage_blobs.content_type NOT LIKE '%image/%'") }
10
+
11
+ def filename
12
+ asset.blob.filename
13
+ end
14
+
15
+ def human
16
+ filename
17
+ end
18
+ end
19
+ end
@@ -3,10 +3,17 @@ module Ecm::Blog
3
3
  include Model::Ecm::Comments::CommentableConcern
4
4
  include Model::Ecm::Tags::TaggableConcern
5
5
 
6
- # acts as published
6
+ # publishing
7
7
  include ActsAsPublished::ActiveRecord
8
8
  acts_as_published
9
9
 
10
+ # positioning
11
+ acts_as_list
12
+ default_scope { order(position: :asc) }
13
+
14
+ # assets
15
+ has_many_attached :assets if respond_to?(:has_many_attached)
16
+
10
17
  # slugs
11
18
  extend FriendlyId
12
19
  friendly_id :title, use: :slugged
@@ -14,6 +21,8 @@ module Ecm::Blog
14
21
  belongs_to :creator, class_name: Ecm::Blog.creator_class_name, foreign_key: 'created_by_id'
15
22
  belongs_to :updater, class_name: Ecm::Blog.creator_class_name, foreign_key: 'updated_by_id', optional: true
16
23
 
24
+ scope :for_date, ->(year, month, day) { where(created_at: "#{year}-#{month || 1}-#{day || 1}".to_date.beginning_of_month.."#{year}-#{month || 1}-#{day || 1}".to_date.end_of_month) }
25
+
17
26
  def human
18
27
  title
19
28
  end
@@ -36,5 +45,49 @@ module Ecm::Blog
36
45
  end
37
46
 
38
47
  include Markdown
48
+
49
+ module AssetDetailsConcern
50
+ extend ActiveSupport::Concern
51
+
52
+ included do
53
+ has_many :asset_details, dependent: :destroy
54
+ before_validation :cleanup_orphaned_asset_details
55
+ before_validation :ensure_asset_details
56
+ end
57
+
58
+ def asset_details_count
59
+ asset_details.count
60
+ end
61
+
62
+ private
63
+
64
+ def cleanup_orphaned_asset_details
65
+ asset_details.each do |asset_detail|
66
+ asset_detail.destroy if asset_detail.asset.nil?
67
+ end
68
+ end
69
+
70
+ def ensure_asset_details
71
+ (assets - asset_details.all.map(&:asset)).map do |asset|
72
+ build_asset_detail_for_asset(asset)
73
+ end
74
+ end
75
+
76
+ def build_asset_detail_for_asset(asset)
77
+ asset_details.build(asset: asset)
78
+ end
79
+ end
80
+
81
+ include AssetDetailsConcern if respond_to?(:has_many_attached)
82
+
83
+ module PreviewPictureConcern
84
+ extend ActiveSupport::Concern
85
+
86
+ def preview_picture
87
+ asset_details.images.first
88
+ end
89
+ end
90
+
91
+ include PreviewPictureConcern
39
92
  end
40
93
  end
@@ -0,0 +1,3 @@
1
+ = render_navigation do |primary|
2
+ - posts_by_month.sort.reverse.each do |month, posts|
3
+ - primary.item "posts_for_#{month}", "#{I18n.l(month, format: '%B %Y')} (#{posts.size})", ecm_blog.month_posts_path(year: month.year, month: month.month)
@@ -11,4 +11,22 @@
11
11
  %span.post-tags
12
12
  = tag_labels_for(post)
13
13
 
14
- %p.post-body= post.body(format: :html).html_safe
14
+ %p.post-body= post.body(format: :html).html_safe
15
+
16
+ - if post.asset_details.images.any?
17
+ .row
18
+ - post.asset_details.images.order(position: :asc).each do |picture_detail|
19
+ .col-lg-4.d-flex.align-items-stretch
20
+ = bootstrap_card(image_options: { src: main_app.url_for(picture_detail.asset)}, additional_css_classes: 'text-center border-0' ) do
21
+ .card-body
22
+ %h5.card-title
23
+ = picture_detail.title
24
+ %p.card-text
25
+ = picture_detail.description
26
+
27
+ - if post.asset_details.non_images.any?
28
+ = collection_table(collection: post.asset_details.non_images.order(position: :asc)) do |t|
29
+ = t.column :filename
30
+ = t.column :actions do |resource|
31
+ - link_to(main_app.url_for(resource.asset), class: 'btn btn-primary') do
32
+ - t('.download')
@@ -1,15 +1,16 @@
1
- %div{ id: dom_id(post), class: "#{dom_class(post)} bottom-margin-5" }
2
- %h2.post-title
3
- = link_to(post.title, ecm_blog.url_for(post))
4
- %small
5
- %span.post-creation-information.text-muted
6
- = "#{l(post.created_at)} | #{post.creator.try(:human)}"
7
- |
8
- %span.comments-information
9
- = link_to(t('ecm.comments.commentable.comments_information', comments_count: post.comments.count), ecm_blog.post_url(post, anchor: 'comments'))
10
- |
11
- %span.post-tags
12
- = tag_labels_for(post)
1
+ %div{ id: dom_id(post), class: "row #{dom_class(post)} bottom-margin-5" }
2
+ .col-lg-12
3
+ %h2.post-title
4
+ = link_to(post.title, ecm_blog.url_for(post))
5
+ %small
6
+ %span.post-creation-information.text-muted
7
+ = "#{l(post.created_at)} | #{post.creator.try(:human)}"
8
+ |
9
+ %span.comments-information
10
+ = link_to(t('ecm.comments.commentable.comments_information', comments_count: post.comments.count), ecm_blog.post_url(post, anchor: 'comments'))
11
+ |
12
+ %span.post-tags
13
+ = tag_labels_for(post)
13
14
 
14
- .post-body.truncate-lines-3
15
- = post.body(format: :html).html_safe
15
+ .post-body.truncate-lines-3
16
+ = post.body(format: :html).html_safe
@@ -0,0 +1,18 @@
1
+ %div{ id: dom_id(post), class: "row #{dom_class(post)} bottom-margin-5" }
2
+ .col-lg-4
3
+ = image_tag(main_app.url_for(post.preview_picture.asset.variant(Ecm::Blog::Configuration.preview_picture_asset_variant_options)), class: 'img-fluid')
4
+ .col-lg-8
5
+ %h2.post-title
6
+ = link_to(post.title, ecm_blog.url_for(post))
7
+ %small
8
+ %span.post-creation-information.text-muted
9
+ = "#{l(post.created_at)} | #{post.creator.try(:human)}"
10
+ |
11
+ %span.comments-information
12
+ = link_to(t('ecm.comments.commentable.comments_information', comments_count: post.comments.count), ecm_blog.post_url(post, anchor: 'comments'))
13
+ |
14
+ %span.post-tags
15
+ = tag_labels_for(post)
16
+
17
+ .post-body.truncate-lines-3
18
+ = post.body(format: :html).html_safe
@@ -1,6 +1,10 @@
1
1
  %h1#page-title= Ecm::Blog::Configuration.posts_index_page_title_proc.call(self)
2
2
 
3
- = render partial: "post_in_index", collection: @collection, as: :post
3
+ - @collection.each do |resource|
4
+ - if resource.preview_picture.present?
5
+ = render partial: "post_in_index_with_preview_picture", locals: { post: resource }
6
+ - else
7
+ = render partial: "post_in_index", locals: { post: resource }
4
8
 
5
9
  .row
6
10
  .col-lg-12.text-center
@@ -6,12 +6,18 @@ de:
6
6
  ecm/blog/post:
7
7
  one: Post
8
8
  other: Posts
9
+ ecm/blog/asset_detail:
10
+ one: Anhang
11
+ other: Anhänge
9
12
  attributes:
10
13
  ecm/blog/post:
11
14
  id: ID
15
+ assets: Anhänge
16
+ asset_details_count: Anhänge
12
17
  title: Titel
13
18
  tags: Tags
14
19
  body: Inhalt
20
+ position: Position
15
21
  published: Veröffentlicht
16
22
  published_at: Veröffentlicht am
17
23
  created_by_id: Erstellt von
@@ -21,5 +27,20 @@ de:
21
27
  updater: Aktualisiert von
22
28
  created_at: Erstellt am
23
29
  updated_at: Aktualisiert am
30
+ ecm/blog/asset_detail:
31
+ id: ID
32
+ post: Post
33
+ post_id: Post
34
+ asset: Datei
35
+ asset_id: Datei
36
+ asset_actions: ''
37
+ description: Beschreibung
38
+ filename: Dateiname
39
+ title: Titel
40
+ preview_picture: Vorschau
41
+ position: Position
42
+ published_at: Veröffentlicht am
43
+ created_at: Erstellt am
44
+ updated_at: Aktualisiert am
24
45
  routes:
25
46
  ecm_blog_engine: blog
@@ -6,12 +6,18 @@ en:
6
6
  ecm/blog/post:
7
7
  one: Post
8
8
  other: Posts
9
+ ecm/blog/asset_detail:
10
+ one: Asset
11
+ other: Assets
9
12
  attributes:
10
13
  ecm/blog/post:
11
14
  id: ID
15
+ assets: Asset
16
+ asset_details_count: Assets
12
17
  title: Title
13
18
  tags: Tags
14
19
  body: Body
20
+ position: Position
15
21
  published: Published
16
22
  published_at: Published at
17
23
  created_by_id: Created by
@@ -21,5 +27,20 @@ en:
21
27
  updater: Updated by
22
28
  created_at: Created at
23
29
  updated_at: Updated at
30
+ ecm/blog/asset_detail:
31
+ id: ID
32
+ post: Post
33
+ post_id: Post
34
+ asset: File
35
+ asset_id: File
36
+ asset_actions: ''
37
+ description: Description
38
+ filename: Filename
39
+ title: Title
40
+ preview_picture: Preview
41
+ position: Position
42
+ published_at: Published at
43
+ created_at: Created at
44
+ updated_at: Updated at
24
45
  routes:
25
46
  ecm_blog_engine: blog
data/config/routes.rb CHANGED
@@ -3,6 +3,9 @@ Ecm::Blog::Engine.routes.draw do
3
3
  scope :ecm_blog_engine do
4
4
  resources :posts, only: [:index, :show] do
5
5
  get 'page/:page', action: :index, on: :collection
6
+ get ':year/:month/:day', action: :index, on: :collection, constraints: { year: /\d+/, month: /\d+/, day: /\d+/ }, as: :day
7
+ get ':year/:month', action: :index, on: :collection, constraints: { year: /\d+/, month: /\d+/ }, as: :month
8
+ get ':year', action: :index, on: :collection, constraints: { year: /\d+/ }, as: :year
6
9
  end
7
10
 
8
11
  root to: 'posts#index'
@@ -0,0 +1,14 @@
1
+ class CreateEcmBlogAssetDetails < ActiveRecord::Migration[5.2]
2
+ def change
3
+ create_table :ecm_blog_asset_details do |t|
4
+ t.references :post
5
+ t.references :asset
6
+ t.string :title
7
+ t.text :description
8
+ t.integer :position
9
+ t.timestamp :published_at
10
+
11
+ t.timestamps
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,5 @@
1
+ class AddPositionToEcmBlogPosts < ActiveRecord::Migration[5.2]
2
+ def change
3
+ add_column :ecm_blog_posts, :position, :integer
4
+ end
5
+ end
@@ -13,6 +13,7 @@ module Ecm
13
13
  mattr_accessor(:creator_class_name) { 'User' }
14
14
  mattr_accessor(:posts_index_page_title_proc) { ->(view) { view.resource_class.model_name.human(count: :other) } }
15
15
  mattr_accessor(:pagination_options_proc) { ->(view) { { theme: 'twitter-bootstrap-3' } } }
16
+ mattr_accessor(:preview_picture_asset_variant_options) { { resize: '320x240' } }
16
17
  end
17
18
  end
18
19
  end
@@ -1,5 +1,5 @@
1
1
  module Ecm
2
2
  module Blog
3
- VERSION = '1.2.1'.freeze
3
+ VERSION = '1.3.0'.freeze
4
4
  end
5
5
  end
data/lib/ecm_blog.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'ecm_comments'
2
+ require 'acts_as_list'
2
3
  require 'acts_as_published'
3
4
  require 'friendly_id'
4
5
  require 'html2markdown'
@@ -33,4 +33,10 @@ Ecm::Blog.configure do |config|
33
33
  # default: config.pagination_options_proc = ->(view) { { theme: 'twitter-bootstrap-4', pagination_class: 'justify-content-center' } }
34
34
  #
35
35
  config.pagination_options_proc = ->(view) { { theme: 'twitter-bootstrap-4', pagination_class: 'justify-content-center' } }
36
+
37
+ # Options for rendering the ActiveStorage preview picture in the posts index view.
38
+ #
39
+ # Default: config.preview_picture_asset_variant_options = { resize: '320x240' }
40
+ #
41
+ config.preview_picture_asset_variant_options = { resize: '320x240' }
36
42
  end
@@ -0,0 +1,10 @@
1
+ namespace :ecm do
2
+ namespace :blog do
3
+ desc "Initializes Post positions"
4
+ task initialize_post_positions: :environment do
5
+ Ecm::Blog::Post.order(created_at: :desc).each.with_index(1) do |post, index|
6
+ post.update_column :position, index
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,13 @@
1
+ FactoryGirl.define do
2
+ factory :ecm_blog_asset_detail, class: Ecm::Blog::AssetDetail do
3
+ association(:post, factory: :ecm_blog_post)
4
+ after(:build) { |ad|
5
+ assets = ad.post.assets.attach(
6
+ io: File.open(File.join(Ecm::Blog::Engine.root.join(*%w( spec files ecm blog asset example.jpg)))),
7
+ filename: 'example.jpg',
8
+ content_type: 'image/jpeg'
9
+ )
10
+ ad.asset = assets.first
11
+ }
12
+ end
13
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ecm_blog
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roberto Vasquez Angel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-05 00:00:00.000000000 Z
11
+ date: 2018-12-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: acts_as_list
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: acts_as_published
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -122,11 +136,14 @@ files:
122
136
  - app/controllers/ecm/blog/application_controller.rb
123
137
  - app/controllers/ecm/blog/posts_controller.rb
124
138
  - app/helpers/ecm/blog/application_helper.rb
139
+ - app/models/ecm/blog/asset_detail.rb
125
140
  - app/models/ecm/blog/post.rb
126
141
  - app/services/ecm/blog/application_service.rb
127
142
  - app/services/ecm/blog/import_posts_service.rb
143
+ - app/views/ecm/blog/posts/_monthly_navigation.html.haml
128
144
  - app/views/ecm/blog/posts/_post.haml
129
145
  - app/views/ecm/blog/posts/_post_in_index.haml
146
+ - app/views/ecm/blog/posts/_post_in_index_with_preview_picture.haml
130
147
  - app/views/ecm/blog/posts/index.haml
131
148
  - app/views/ecm/blog/posts/show.haml
132
149
  - app/views/layouts/ecm/blog/application.html.erb
@@ -134,6 +151,8 @@ files:
134
151
  - config/locales/en.yml
135
152
  - config/routes.rb
136
153
  - db/migrate/20160214133500_create_ecm_blog_posts.rb
154
+ - db/migrate/20180429134813_create_ecm_blog_asset_details.rb
155
+ - db/migrate/20181219233939_add_position_to_ecm_blog_posts.rb
137
156
  - lib/ecm/blog.rb
138
157
  - lib/ecm/blog/configuration.rb
139
158
  - lib/ecm/blog/engine.rb
@@ -143,7 +162,10 @@ files:
143
162
  - lib/generators/ecm/blog/install/templates/initializer.rb
144
163
  - lib/generators/ecm/blog/install/templates/routes.source
145
164
  - lib/tasks/ecm/blog_tasks.rake
165
+ - lib/tasks/ecm_blog_tasks.rake
166
+ - spec/factories/ecm_blog_asset_details.rb
146
167
  - spec/factories/ecm_blog_posts.rb
168
+ - spec/files/ecm/blog/asset/example.jpg
147
169
  homepage: https://github.com/robotex82/ecm_blog
148
170
  licenses:
149
171
  - MIT