biovision-post 0.0.171104 → 0.1.171229
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/app/assets/images/biovision/post/icons/view.svg +1 -0
- data/app/assets/stylesheets/biovision/post/posts.scss +150 -0
- data/app/controllers/admin/post_types_controller.rb +1 -1
- data/app/controllers/admin/posts_controller.rb +26 -1
- data/app/controllers/articles_controller.rb +35 -0
- data/app/controllers/blog_posts_controller.rb +37 -0
- data/app/controllers/news_controller.rb +37 -0
- data/app/controllers/posts_controller.rb +11 -32
- data/app/helpers/biovision_posts_helper.rb +21 -4
- data/app/models/post.rb +21 -9
- data/app/models/post_type.rb +1 -1
- data/app/services/post_manager/article_handler.rb +10 -0
- data/app/services/post_manager/blog_post_handler.rb +10 -0
- data/app/services/post_manager/news_handler.rb +10 -0
- data/app/services/post_manager.rb +9 -0
- data/app/views/admin/index/_biovision_post.html.erb +29 -0
- data/app/views/admin/index/biovision_post/_additional_items.html.erb +0 -0
- data/app/views/admin/post_categories/show.html.erb +22 -21
- data/app/views/admin/post_types/show.html.erb +8 -5
- data/app/views/admin/posts/entity/_in_list.html.erb +38 -0
- data/app/views/admin/posts/index.html.erb +14 -0
- data/app/views/admin/posts/show.html.erb +99 -0
- data/app/views/articles/category.html.erb +18 -0
- data/app/views/articles/index.html.erb +14 -0
- data/app/views/articles/index.jbuilder +11 -0
- data/app/views/articles/show.html.erb +8 -0
- data/app/views/blog_posts/category.html.erb +18 -0
- data/app/views/blog_posts/index.html.erb +14 -0
- data/app/views/blog_posts/index.jbuilder +11 -0
- data/app/views/blog_posts/show.html.erb +8 -0
- data/app/views/index/index/_recent_posts.html.erb +5 -0
- data/app/views/news/category.html.erb +18 -0
- data/app/views/news/index.html.erb +14 -0
- data/app/views/news/index.jbuilder +11 -0
- data/app/views/news/show.html.erb +8 -0
- data/app/views/posts/_breadcrumbs.html.erb +11 -0
- data/app/views/posts/_form.html.erb +151 -122
- data/app/views/posts/_list.html.erb +9 -0
- data/app/views/posts/_post.html.erb +73 -67
- data/app/views/posts/_preview.html.erb +35 -0
- data/app/views/posts/edit.html.erb +12 -0
- data/app/views/posts/entity/_metadata.html.erb +4 -2
- data/app/views/posts/form/_wysiwyg.html.erb +1 -1
- data/config/locales/posts-en.yml +175 -0
- data/config/locales/posts-ru.yml +52 -3
- data/config/routes.rb +28 -2
- data/db/migrate/20170930000001_create_post_types.rb +1 -0
- data/db/migrate/20170930000002_create_post_categories.rb +1 -1
- data/db/migrate/20170930000003_create_posts.rb +11 -7
- data/db/migrate/20171218111111_add_meta_fields_to_posts.rb +15 -0
- data/db/migrate/20171219111112_add_author_fields_to_posts.rb +11 -0
- data/lib/biovision/post/version.rb +1 -1
- metadata +34 -59
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: be80d9c2f7d4d049810beb5d10445ad941141a6984fedefc72afc66f5d8aa26c
|
4
|
+
data.tar.gz: 18afaf4b8bd45ccce8ed430f44ebb2ba29782b81ea0ed835fb7a1f77ae1e83a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b7e5489d2ca7af603433b61f51fa4b9c15871b4e0c146eb2fd19840bc52e73788f894386859b85700fd7fc5c09e0f60634bc9bda5e9e6ef942a6c90817ba1c01
|
7
|
+
data.tar.gz: 1b5a1c2fad734dea9eb2c582a4f95fbc3bdb5eab16e2f5458fe42d9709ad8506e1708685b3e54d68be2850199d77771730f11bb0616c0a94fb5dacc87f6b80e4
|
@@ -0,0 +1 @@
|
|
1
|
+
<?xml version="1.0" ?><svg style="enable-background:new 0 0 93.388 75.594;" version="1.1" viewBox="0 0 93.388 75.594" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g id="search"><g><path d="M57.158,42.7l-2.041,1.076l-6.061-4.054l-0.669,0.762l5.607,3.994l-0.503,0.572c-0.836,0.953-1.522,2.376-2.059,4.268 c-0.615,2.047-0.683,3.534-0.204,4.461l-9.422-5.318c-3.705,3.835-8.748,5.736-15.131,5.702 c-6.593-0.05-12.336-2.224-17.228-6.518C4.747,43.517,1.864,39.496,0.8,35.581c-0.656-2.264-0.909-7.07-0.758-14.419 c0.685,6.845,3.648,12.568,8.89,17.17c5.591,4.909,11.841,7.752,18.752,8.531c7.753,0.845,13.986-1.419,18.699-6.788 c0.697-0.794,1.534-1.747,2.51-2.859L57.158,42.7z"/><path d="M51.853,21.927c-0.862-5.425-3.85-10.383-8.965-14.873c-5.147-4.518-11.186-6.866-18.116-7.044 C17.392-0.17,11.498,2.25,7.092,7.269c-8.952,10.197-7.9,20.149,3.154,29.854c5.401,4.742,11.505,7.4,18.311,7.975 c7.472,0.653,13.507-1.642,18.109-6.884C51.073,33.196,52.801,27.767,51.853,21.927z M44.868,36.804 c-4.156,4.734-9.637,6.812-16.444,6.236c-6.202-0.495-11.765-2.904-16.69-7.227C1.727,27.029,0.767,18.03,8.855,8.817 c4.016-4.574,9.369-6.794,16.057-6.66c6.326,0.098,11.825,2.197,16.495,6.296c4.67,4.1,7.405,8.61,8.204,13.53 C50.465,27.289,48.884,32.23,44.868,36.804z"/><path d="M38.683,13.453c6.735,5.913,8.805,13.102,6.21,21.568c-0.974-7.605-3.875-13.527-8.704-17.766 c-4.701-4.127-9.898-6.074-15.589-5.838c-5.692,0.235-10.666,2.619-14.924,7.149c0.623-1.927,1.66-3.717,3.11-5.369 c3.625-4.129,8.548-6.051,14.767-5.768C29.383,7.708,34.426,9.716,38.683,13.453z"/><path d="M31.133,32.963c-1.589,0.913-3.873,0.791-6.854-0.363c-2.456-0.918-4.541-2.131-6.257-3.637 c-2.097-1.84-3.291-3.845-3.581-6.012C19.638,25.488,25.202,28.826,31.133,32.963z"/><path d="M91.741,65.298c1.08,0.948,1.628,2.245,1.646,3.892c0.016,1.646-0.491,3.057-1.522,4.232 c-1.088,1.239-2.525,1.947-4.311,2.123c-1.547,0.16-2.776-0.075-3.685-0.704L53.183,54.82c-1.156-0.733-1.474-2.165-0.953-4.296 c0.468-2.007,1.442-3.853,2.92-5.537c1.004-1.144,2.281-1.541,3.832-1.192L87.85,62.81L91.741,65.298z"/></g></g><g id="Слой_1"/></svg>
|
@@ -0,0 +1,150 @@
|
|
1
|
+
$block-shadow: .2rem .2rem .4rem .2rem rgba(0, 0, 0, .125) !default;
|
2
|
+
$border-primary: .1rem solid rgb(192, 192, 192) !default;
|
3
|
+
$border-secondary: .1rem solid rgb(230, 230, 230) !default;
|
4
|
+
$text-color-secondary: #777 !default;
|
5
|
+
$font-size-large: 2rem !default;
|
6
|
+
$font-size-decreased: 1.2rem !default;
|
7
|
+
$font-family-heading: serif !default;
|
8
|
+
|
9
|
+
$background-post-footer: rgb(248, 248, 248) !default;
|
10
|
+
$background-post-preview-image: linear-gradient(to top, #f0f0f0, #fff) !default;
|
11
|
+
|
12
|
+
.recent-posts {
|
13
|
+
.list {
|
14
|
+
align-items: stretch;
|
15
|
+
display: flex;
|
16
|
+
flex-wrap: wrap;
|
17
|
+
justify-content: space-around;
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
.post-preview {
|
22
|
+
border-radius: .2rem;
|
23
|
+
box-shadow: $block-shadow;
|
24
|
+
display: flex;
|
25
|
+
flex: 1;
|
26
|
+
flex-direction: column;
|
27
|
+
margin: 1rem;
|
28
|
+
position: relative;
|
29
|
+
max-width: 30rem;
|
30
|
+
min-width: 28rem;
|
31
|
+
|
32
|
+
.image {
|
33
|
+
background: $background-post-preview-image;
|
34
|
+
border-radius: .2rem .2rem 0 0;
|
35
|
+
height: 20rem;
|
36
|
+
overflow: hidden;
|
37
|
+
width: 100%;
|
38
|
+
}
|
39
|
+
|
40
|
+
img {
|
41
|
+
height: 100%;
|
42
|
+
object-fit: cover;
|
43
|
+
width: 100%;
|
44
|
+
}
|
45
|
+
|
46
|
+
.title {
|
47
|
+
font: 500 $font-size-large $font-family-heading;
|
48
|
+
min-height: 6.4rem;
|
49
|
+
padding: .4rem;
|
50
|
+
}
|
51
|
+
|
52
|
+
.lead {
|
53
|
+
color: $text-color-secondary;
|
54
|
+
padding: .4rem;
|
55
|
+
}
|
56
|
+
|
57
|
+
.counters {
|
58
|
+
margin-top: auto;
|
59
|
+
padding: .4rem;
|
60
|
+
text-align: right;
|
61
|
+
}
|
62
|
+
|
63
|
+
.category {
|
64
|
+
padding: .4rem;
|
65
|
+
}
|
66
|
+
|
67
|
+
.info {
|
68
|
+
align-items: center;
|
69
|
+
-webkit-backdrop-filter: blur(.2rem);
|
70
|
+
background: rgba(255, 255, 255, .75);
|
71
|
+
border-radius: .2rem .2rem 0 0;
|
72
|
+
display: flex;
|
73
|
+
flex-wrap: wrap;
|
74
|
+
left: 0;
|
75
|
+
padding: .2rem .4rem;
|
76
|
+
position: absolute;
|
77
|
+
right: 0;
|
78
|
+
|
79
|
+
time {
|
80
|
+
font-size: $font-size-decreased;
|
81
|
+
font-style: italic;
|
82
|
+
line-height: 2rem;
|
83
|
+
margin-left: auto;
|
84
|
+
}
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
.view_count {
|
89
|
+
background: image_url('biovision/post/icons/view.svg') no-repeat center left / 1.6rem auto;
|
90
|
+
margin: 0 .4rem;
|
91
|
+
padding-left: 1.8rem;
|
92
|
+
}
|
93
|
+
|
94
|
+
article.post {
|
95
|
+
figure {
|
96
|
+
border-bottom: $border-secondary;
|
97
|
+
margin: 0 auto;
|
98
|
+
max-width: 64rem;
|
99
|
+
padding: 0 0 .8rem 0;
|
100
|
+
}
|
101
|
+
|
102
|
+
figcaption {
|
103
|
+
align-items: flex-end;
|
104
|
+
display: flex;
|
105
|
+
flex-wrap: wrap;
|
106
|
+
}
|
107
|
+
|
108
|
+
.image_author {
|
109
|
+
color: $text-color-secondary;
|
110
|
+
font-size: $font-size-decreased;
|
111
|
+
margin-left: auto;
|
112
|
+
}
|
113
|
+
|
114
|
+
.body {
|
115
|
+
padding: .4rem;
|
116
|
+
}
|
117
|
+
|
118
|
+
footer {
|
119
|
+
align-items: center;
|
120
|
+
background: $background-post-footer;
|
121
|
+
display: flex;
|
122
|
+
flex-wrap: wrap;
|
123
|
+
font-size: $font-size-decreased;
|
124
|
+
padding: .8rem;
|
125
|
+
|
126
|
+
.author {
|
127
|
+
margin: 0 1.6rem 0 0;
|
128
|
+
}
|
129
|
+
|
130
|
+
.author-title {
|
131
|
+
&::before {
|
132
|
+
content: '(';
|
133
|
+
}
|
134
|
+
|
135
|
+
&::after {
|
136
|
+
content: ')';
|
137
|
+
}
|
138
|
+
}
|
139
|
+
|
140
|
+
.source {
|
141
|
+
color: $text-color-secondary;
|
142
|
+
margin-left: auto;
|
143
|
+
}
|
144
|
+
|
145
|
+
.time {
|
146
|
+
margin: .8rem 0 0 0;
|
147
|
+
width: 100%;
|
148
|
+
}
|
149
|
+
}
|
150
|
+
}
|
@@ -1,2 +1,27 @@
|
|
1
|
-
class Admin::PostsController <
|
1
|
+
class Admin::PostsController < AdminController
|
2
|
+
include ToggleableEntity
|
3
|
+
|
4
|
+
before_action :set_entity, except: [:index]
|
5
|
+
|
6
|
+
# get /admin/posts
|
7
|
+
def index
|
8
|
+
@collection = Post.page_for_administration(current_page)
|
9
|
+
end
|
10
|
+
|
11
|
+
# get /admin/posts/:id
|
12
|
+
def show
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def set_entity
|
18
|
+
@entity = Post.find_by(id: params[:id])
|
19
|
+
if @entity.nil?
|
20
|
+
handle_http_404('Cannot find post')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def restrict_access
|
25
|
+
require_privilege_group :editors
|
26
|
+
end
|
2
27
|
end
|
@@ -1,2 +1,37 @@
|
|
1
1
|
class ArticlesController < ApplicationController
|
2
|
+
before_action :set_category, only: [:category]
|
3
|
+
before_action :set_entity, only: [:show]
|
4
|
+
|
5
|
+
# get /articles
|
6
|
+
def index
|
7
|
+
post_type = PostType.find_by(slug: 'article')
|
8
|
+
@collection = post_type.posts.page_for_visitors(current_page)
|
9
|
+
end
|
10
|
+
|
11
|
+
# get /articles/:category_slug
|
12
|
+
def category
|
13
|
+
@collection = @category.posts.page_for_visitors(current_page)
|
14
|
+
end
|
15
|
+
|
16
|
+
# get /articles/:post_id-:post_slug
|
17
|
+
def show
|
18
|
+
@entity.increment!(:view_count)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def set_category
|
24
|
+
type = PostType.find_by(slug: 'article')
|
25
|
+
@category = type.post_categories.find_by(long_slug: params[:category_slug])
|
26
|
+
if @category.nil?
|
27
|
+
handle_http_404('Cannot find post category (article)')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def set_entity
|
32
|
+
@entity = Post.visible.find_by(id: params[:post_id])
|
33
|
+
if @entity.nil?
|
34
|
+
handle_http_404('Cannot find article')
|
35
|
+
end
|
36
|
+
end
|
2
37
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class BlogPostsController < ApplicationController
|
2
|
+
before_action :set_category, only: [:category]
|
3
|
+
before_action :set_entity, only: [:show]
|
4
|
+
|
5
|
+
# get /blog_posts
|
6
|
+
def index
|
7
|
+
post_type = PostType.find_by(slug: 'blog_post')
|
8
|
+
@collection = post_type.posts.page_for_visitors(current_page)
|
9
|
+
end
|
10
|
+
|
11
|
+
# get /blog_posts/:category_slug
|
12
|
+
def category
|
13
|
+
@collection = @category.posts.page_for_visitors(current_page)
|
14
|
+
end
|
15
|
+
|
16
|
+
# get /blog_posts/:post_id-:post_slug
|
17
|
+
def show
|
18
|
+
@entity.increment!(:view_count)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def set_category
|
24
|
+
type = PostType.find_by(slug: 'blog_post')
|
25
|
+
@category = type.post_categories.find_by(long_slug: params[:category_slug])
|
26
|
+
if @category.nil?
|
27
|
+
handle_http_404('Cannot find post category (blog_post)')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def set_entity
|
32
|
+
@entity = Post.visible.find_by(id: params[:post_id])
|
33
|
+
if @entity.nil?
|
34
|
+
handle_http_404('Cannot find blog_post')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class NewsController < ApplicationController
|
2
|
+
before_action :set_category, only: [:category]
|
3
|
+
before_action :set_entity, only: [:show]
|
4
|
+
|
5
|
+
# get /news
|
6
|
+
def index
|
7
|
+
post_type = PostType.find_by(slug: 'news')
|
8
|
+
@collection = post_type.posts.page_for_visitors(current_page)
|
9
|
+
end
|
10
|
+
|
11
|
+
# get /news/:category_slug
|
12
|
+
def category
|
13
|
+
@collection = @category.posts.page_for_visitors(current_page)
|
14
|
+
end
|
15
|
+
|
16
|
+
# get /news/:post_id-:post_slug
|
17
|
+
def show
|
18
|
+
@entity.increment!(:view_count)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def set_category
|
24
|
+
type = PostType.find_by(slug: 'news')
|
25
|
+
@category = type.post_categories.find_by(long_slug: params[:category_slug])
|
26
|
+
if @category.nil?
|
27
|
+
handle_http_404('Cannot find post category (news)')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def set_entity
|
32
|
+
@entity = Post.visible.find_by(id: params[:post_id])
|
33
|
+
if @entity.nil?
|
34
|
+
handle_http_404('Cannot find news')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -10,12 +10,6 @@ class PostsController < ApplicationController
|
|
10
10
|
@collection = Post.page_for_visitors(current_page)
|
11
11
|
end
|
12
12
|
|
13
|
-
# get /posts/:category_slug
|
14
|
-
def category
|
15
|
-
@category = PostCategory.find_by! long_slug: params[:category_slug]
|
16
|
-
@collection = @category.posts.page_for_visitors(current_page)
|
17
|
-
end
|
18
|
-
|
19
13
|
# post /posts
|
20
14
|
def create
|
21
15
|
@entity = Post.new(creation_parameters)
|
@@ -33,26 +27,12 @@ class PostsController < ApplicationController
|
|
33
27
|
|
34
28
|
# get /posts/:id
|
35
29
|
def show
|
36
|
-
@entity = Post.find_by(id: params[:id], deleted: false)
|
30
|
+
@entity = Post.find_by(id: params[:id], visible: true, deleted: false)
|
37
31
|
if @entity.nil?
|
38
32
|
handle_http_404("Cannot find non-deleted post #{params[:id]}")
|
39
33
|
end
|
40
34
|
end
|
41
35
|
|
42
|
-
# get /posts/:category_slug/:slug
|
43
|
-
def show_in_category
|
44
|
-
@category = PostCategory.find_by(slug: params[:category_slug])
|
45
|
-
@entity = Post.find_by(slug: params[:slug], deleted: false)
|
46
|
-
if @entity.nil? || !@entity.visible_to?(current_user)
|
47
|
-
handle_http_404("Cannot show posts #{params[:slug]} to user #{current_user&.id}")
|
48
|
-
elsif @entity.posts_category == @category
|
49
|
-
@entity.increment! :view_count
|
50
|
-
else
|
51
|
-
parameters = { category_slug: @entity.posts_category.slug, slug: @entity.slug }
|
52
|
-
redirect_to posts_in_category_posts_index_path(parameters)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
36
|
# get /posts/:id/edit
|
57
37
|
def edit
|
58
38
|
end
|
@@ -73,24 +53,29 @@ class PostsController < ApplicationController
|
|
73
53
|
|
74
54
|
# delete /posts/:id
|
75
55
|
def destroy
|
76
|
-
if @entity.update(deleted: true)
|
56
|
+
if @entity.destroy #@entity.update(deleted: true)
|
77
57
|
flash[:notice] = t('posts.destroy.success')
|
78
58
|
end
|
79
|
-
redirect_to
|
59
|
+
redirect_to admin_posts_path
|
80
60
|
end
|
81
61
|
|
82
62
|
private
|
83
63
|
|
84
64
|
def set_entity
|
85
|
-
@entity = Post.
|
65
|
+
@entity = Post.find_by(id: params[:id])
|
66
|
+
if @entity.nil?
|
67
|
+
handle_http_404('Cannot find post')
|
68
|
+
end
|
86
69
|
end
|
87
70
|
|
88
71
|
def restrict_access
|
89
|
-
require_privilege_group :
|
72
|
+
require_privilege_group :editors
|
90
73
|
end
|
91
74
|
|
92
75
|
def restrict_editing
|
93
|
-
|
76
|
+
if @entity.locked? || !@entity.editable_by?(current_user)
|
77
|
+
handle_http_403('Post is locked or not editable by current user')
|
78
|
+
end
|
94
79
|
end
|
95
80
|
|
96
81
|
def entity_parameters
|
@@ -101,10 +86,4 @@ class PostsController < ApplicationController
|
|
101
86
|
parameters = params.require(:post).permit(Post.creation_parameters)
|
102
87
|
parameters.merge(owner_for_entity(true))
|
103
88
|
end
|
104
|
-
|
105
|
-
def add_figures
|
106
|
-
params[:figures].values.reject { |f| f[:slug].blank? || f[:image].blank? }.each do |data|
|
107
|
-
@entity.figures.create!(data.select { |key, _| Figure.creation_parameters.include? key.to_sym })
|
108
|
-
end
|
109
|
-
end
|
110
89
|
end
|
@@ -37,8 +37,23 @@ module BiovisionPostsHelper
|
|
37
37
|
end
|
38
38
|
|
39
39
|
# @param [Post] entity
|
40
|
-
|
41
|
-
|
40
|
+
# @param [String] text
|
41
|
+
# @param [Hash] options
|
42
|
+
def post_link(entity, text = entity.title, options = {})
|
43
|
+
link_to(text, PostManager.handler(entity).post_path, options)
|
44
|
+
end
|
45
|
+
|
46
|
+
# @param [Post] entity
|
47
|
+
# @param [Hash] options
|
48
|
+
def post_author_link(entity, options = {})
|
49
|
+
if entity.author_url.blank?
|
50
|
+
entity.author_name
|
51
|
+
else
|
52
|
+
link_options = {
|
53
|
+
rel: 'external nofollow noopener noreferrer'
|
54
|
+
}
|
55
|
+
link_to(entity.author_name, entity.author_url, link_options.merge(options))
|
56
|
+
end
|
42
57
|
end
|
43
58
|
|
44
59
|
# Post image preview for displaying in "administrative" lists
|
@@ -58,8 +73,9 @@ module BiovisionPostsHelper
|
|
58
73
|
def post_image_small(entity, add_options = {})
|
59
74
|
return '' if entity.image.blank?
|
60
75
|
|
76
|
+
alt_text = entity.image_alt_text.to_s
|
61
77
|
versions = "#{entity.image.medium.url} 2x"
|
62
|
-
options = { alt:
|
78
|
+
options = { alt: alt_text, srcset: versions }.merge(add_options)
|
63
79
|
image_tag(entity.image.small.url, options)
|
64
80
|
end
|
65
81
|
|
@@ -70,8 +86,9 @@ module BiovisionPostsHelper
|
|
70
86
|
def post_image_medium(entity, add_options = {})
|
71
87
|
return '' if entity.image.blank?
|
72
88
|
|
89
|
+
alt_text = entity.image_alt_text.to_s
|
73
90
|
versions = "#{entity.image.big.url} 2x"
|
74
|
-
options = { alt:
|
91
|
+
options = { alt: alt_text, srcset: versions }.merge(add_options)
|
75
92
|
image_tag(entity.image.medium.url, options)
|
76
93
|
end
|
77
94
|
end
|
data/app/models/post.rb
CHANGED
@@ -2,15 +2,19 @@ class Post < ApplicationRecord
|
|
2
2
|
include HasOwner
|
3
3
|
include CommentableItem if 'CommentableItem'.safe_constantize
|
4
4
|
include VotableItem if 'VotableItem'.safe_constantize
|
5
|
+
include Toggleable
|
5
6
|
|
6
7
|
TITLE_LIMIT = 140
|
7
8
|
SLUG_LIMIT = 200
|
8
9
|
SLUG_PATTERN = /\A[a-z0-9]+[-_.a-z0-9]*[a-z0-9]+\z/
|
9
10
|
LEAD_LIMIT = 350
|
10
11
|
BODY_LIMIT = 50000
|
11
|
-
META_LIMIT =
|
12
|
+
META_LIMIT = 250
|
13
|
+
ALT_LIMIT = 200
|
12
14
|
PER_PAGE = 10
|
13
15
|
|
16
|
+
toggleable :visible, :show_owner, :allow_comments
|
17
|
+
|
14
18
|
mount_uploader :image, PostImageUploader
|
15
19
|
|
16
20
|
belongs_to :user
|
@@ -22,7 +26,6 @@ class Post < ApplicationRecord
|
|
22
26
|
after_initialize { self.uuid = SecureRandom.uuid if uuid.nil? }
|
23
27
|
before_validation { self.slug = Canonizer.transliterate(title.to_s) if slug.blank? }
|
24
28
|
before_validation { self.slug = slug.downcase }
|
25
|
-
before_validation { self.publication_time = Time.now if publication_time.nil? }
|
26
29
|
before_validation :prepare_source_names
|
27
30
|
before_save { self.parsed_body = PostManager.handler(self).parsed_body }
|
28
31
|
|
@@ -32,15 +35,23 @@ class Post < ApplicationRecord
|
|
32
35
|
validates_length_of :lead, maximum: LEAD_LIMIT
|
33
36
|
validates_length_of :body, maximum: BODY_LIMIT
|
34
37
|
validates_length_of :image_name, maximum: META_LIMIT
|
38
|
+
validates_length_of :image_alt_text, maximum: ALT_LIMIT
|
35
39
|
validates_length_of :image_author_name, maximum: META_LIMIT
|
36
40
|
validates_length_of :image_author_link, maximum: META_LIMIT
|
37
41
|
validates_length_of :source_link, maximum: META_LIMIT
|
38
42
|
validates_length_of :source_name, maximum: META_LIMIT
|
43
|
+
validates_length_of :meta_title, maximum: TITLE_LIMIT
|
44
|
+
validates_length_of :meta_description, maximum: META_LIMIT
|
45
|
+
validates_length_of :meta_keywords, maximum: META_LIMIT
|
46
|
+
validates_length_of :author_name, maximum: META_LIMIT
|
47
|
+
validates_length_of :author_title, maximum: META_LIMIT
|
48
|
+
validates_length_of :author_url, maximum: META_LIMIT
|
39
49
|
validates_format_of :slug, with: SLUG_PATTERN
|
40
50
|
validate :category_consistency
|
41
51
|
|
42
|
-
scope :recent, -> { order('
|
52
|
+
scope :recent, -> { order('id desc') }
|
43
53
|
scope :visible, -> { where(visible: true, deleted: false, approved: true) }
|
54
|
+
scope :list_for_visitors, -> { visible.recent }
|
44
55
|
|
45
56
|
# @param [Integer] page
|
46
57
|
def self.page_for_administration(page = 1)
|
@@ -49,16 +60,17 @@ class Post < ApplicationRecord
|
|
49
60
|
|
50
61
|
# @param [Integer] page
|
51
62
|
def self.page_for_visitors(page = 1)
|
52
|
-
|
63
|
+
list_for_visitors.page(page).per(PER_PAGE)
|
53
64
|
end
|
54
65
|
|
55
66
|
def self.entity_parameters
|
56
|
-
main_data
|
57
|
-
image_data
|
58
|
-
meta_data
|
59
|
-
flags_data
|
67
|
+
main_data = %i(post_category_id title slug lead body visible translation region_id)
|
68
|
+
image_data = %i(image image_alt_text image_name image_author_name image_author_link)
|
69
|
+
meta_data = %i(source_name source_link meta_title meta_description meta_keywords)
|
70
|
+
flags_data = %i(show_owner allow_comments)
|
71
|
+
author_data = %i(author_name author_title author_url)
|
60
72
|
|
61
|
-
main_data + image_data + meta_data + flags_data
|
73
|
+
main_data + image_data + meta_data + author_data + flags_data
|
62
74
|
end
|
63
75
|
|
64
76
|
def self.creation_parameters
|
data/app/models/post_type.rb
CHANGED
@@ -8,7 +8,7 @@ class PostType < ApplicationRecord
|
|
8
8
|
DEPTH_RANGE = (0..10)
|
9
9
|
|
10
10
|
has_many :post_categories, dependent: :destroy
|
11
|
-
has_many :posts
|
11
|
+
has_many :posts
|
12
12
|
|
13
13
|
validates_length_of :name, maximum: NAME_LIMIT
|
14
14
|
validates_length_of :slug, maximum: SLUG_LIMIT
|
@@ -0,0 +1,29 @@
|
|
1
|
+
<% if current_user_in_group?(:editors) %>
|
2
|
+
<nav>
|
3
|
+
<div class="heading" id="biovision-post-nav-heading">
|
4
|
+
<%= t('.heading') %>
|
5
|
+
</div>
|
6
|
+
<ul aria-labelledby="biovision-post-nav-heading">
|
7
|
+
<li>
|
8
|
+
<%= render 'admin/post_types/nav_item' %>
|
9
|
+
<ul>
|
10
|
+
<% PostType.page_for_administration.each do |post_type| %>
|
11
|
+
<li>
|
12
|
+
<div><%= admin_post_type_link(post_type) %></div>
|
13
|
+
<div class="description">
|
14
|
+
<%= t(:post_count, count: post_type.posts_count) %>
|
15
|
+
</div>
|
16
|
+
<ul class="actions">
|
17
|
+
<li>
|
18
|
+
<%= create_icon(new_post_admin_post_type_path(post_type.id)) %>
|
19
|
+
</li>
|
20
|
+
</ul>
|
21
|
+
</li>
|
22
|
+
<% end %>
|
23
|
+
</ul>
|
24
|
+
</li>
|
25
|
+
<li><%= render 'admin/posts/nav_item' %></li>
|
26
|
+
<%= render 'admin/index/biovision_post/additional_items' %>
|
27
|
+
</ul>
|
28
|
+
</nav>
|
29
|
+
<% end %>
|
File without changes
|