ecm_blog 1.2.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
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