publify_core 10.0.4 → 11.0.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/CHANGELOG.md +243 -53
- data/app/assets/javascripts/publify.js +0 -1
- data/app/assets/javascripts/publify_admin.js +10 -9
- data/app/assets/stylesheets/accounts.css.scss +0 -2
- data/app/assets/stylesheets/administration_structure.css.scss +0 -4
- data/app/assets/stylesheets/publify.css.scss +0 -1
- data/app/assets/stylesheets/publify_admin.css.scss +0 -2
- data/app/assets/stylesheets/sidebar_admin.css.scss +0 -6
- data/app/controllers/admin/articles_controller.rb +1 -1
- data/app/controllers/admin/base_controller.rb +2 -2
- data/app/controllers/admin/redirects_controller.rb +2 -2
- data/app/controllers/admin/resources_controller.rb +1 -1
- data/app/controllers/admin/seo_controller.rb +2 -2
- data/app/controllers/admin/settings_controller.rb +2 -2
- data/app/controllers/admin/tags_controller.rb +1 -1
- data/app/controllers/admin/users_controller.rb +2 -2
- data/app/controllers/articles_controller.rb +2 -5
- data/app/controllers/authors_controller.rb +0 -2
- data/app/controllers/comments_controller.rb +5 -2
- data/app/controllers/content_controller.rb +0 -4
- data/app/controllers/notes_controller.rb +1 -6
- data/app/controllers/setup_controller.rb +1 -1
- data/app/controllers/tags_controller.rb +0 -1
- data/app/controllers/users/registrations_controller.rb +1 -0
- data/app/helpers/admin/base_helper.rb +20 -13
- data/app/helpers/admin/feedback_helper.rb +4 -4
- data/app/helpers/base_helper.rb +10 -6
- data/app/helpers/xml_helper.rb +4 -0
- data/app/models/article.rb +7 -7
- data/app/models/blog.rb +3 -3
- data/app/models/comment.rb +1 -1
- data/app/models/config_manager.rb +1 -3
- data/app/models/content.rb +4 -5
- data/app/models/content_base.rb +4 -3
- data/app/models/feedback.rb +1 -1
- data/app/models/note.rb +74 -8
- data/app/models/page.rb +1 -1
- data/app/models/redirect.rb +0 -4
- data/app/models/resource.rb +1 -0
- data/app/models/sidebar.rb +6 -14
- data/app/models/tag.rb +2 -2
- data/app/models/text_filter.rb +2 -2
- data/app/models/trigger.rb +1 -1
- data/app/models/user.rb +12 -21
- data/app/uploaders/resource_uploader.rb +1 -0
- data/app/views/admin/articles/_form.html.erb +99 -105
- data/app/views/admin/articles/index.html.erb +15 -23
- data/app/views/admin/dashboard/_comment.html.erb +1 -1
- data/app/views/admin/dashboard/_comments.html.erb +4 -6
- data/app/views/admin/dashboard/_drafts.html.erb +4 -6
- data/app/views/admin/dashboard/_overview.html.erb +2 -5
- data/app/views/admin/dashboard/_welcome.html.erb +19 -19
- data/app/views/admin/dashboard/index.html.erb +3 -3
- data/app/views/admin/feedback/_button.html.erb +7 -13
- data/app/views/admin/feedback/article.html.erb +17 -17
- data/app/views/admin/feedback/edit.html.erb +17 -21
- data/app/views/admin/feedback/index.html.erb +8 -8
- data/app/views/admin/notes/_form.html.erb +5 -5
- data/app/views/admin/notes/_list.html.erb +1 -1
- data/app/views/admin/notes/_note.html.erb +1 -1
- data/app/views/admin/notes/edit.html.erb +1 -1
- data/app/views/admin/notes/index.html.erb +1 -1
- data/app/views/admin/pages/_form.html.erb +23 -27
- data/app/views/admin/post_types/_index_and_form.html.erb +5 -5
- data/app/views/admin/redirects/_index_and_form.html.erb +2 -2
- data/app/views/admin/resources/index.html.erb +20 -8
- data/app/views/admin/seo/_general.html.erb +36 -36
- data/app/views/admin/seo/_permalinks.html.erb +22 -14
- data/app/views/admin/seo/_titles.html.erb +63 -63
- data/app/views/admin/settings/display.html.erb +23 -23
- data/app/views/admin/settings/feedback.html.erb +29 -29
- data/app/views/admin/settings/index.html.erb +21 -21
- data/app/views/admin/settings/write.html.erb +18 -18
- data/app/views/admin/shared/_flash.html.erb +6 -0
- data/app/views/admin/shared/_menu.html.erb +56 -68
- data/app/views/admin/sidebar/_config.html.erb +15 -19
- data/app/views/admin/sidebar/_target.html.erb +3 -3
- data/app/views/admin/sidebar/_target_sidebar.html.erb +14 -13
- data/app/views/admin/sidebar/index.html.erb +2 -2
- data/app/views/admin/tags/_index_and_form.html.erb +3 -3
- data/app/views/admin/themes/index.html.erb +21 -19
- data/app/views/admin/users/_form.html.erb +79 -79
- data/app/views/articles/search.html.erb +1 -1
- data/app/views/layouts/accounts.html.erb +7 -9
- data/app/views/layouts/administration.html.erb +2 -2
- data/app/views/notes/show.html.erb +15 -0
- data/app/views/setup/index.html.erb +1 -1
- data/app/views/shared/_atom_item_article.atom.builder +1 -3
- data/app/views/shared/_rss_item_article.rss.builder +1 -2
- data/config/i18n-tasks.yml +0 -1
- data/config/locales/ar.yml +3 -2
- data/config/locales/da.yml +3 -2
- data/config/locales/de.yml +3 -2
- data/config/locales/en.yml +3 -2
- data/config/locales/es-MX.yml +3 -2
- data/config/locales/fr.yml +3 -2
- data/config/locales/he.yml +3 -2
- data/config/locales/it.yml +3 -2
- data/config/locales/ja.yml +3 -2
- data/config/locales/lt.yml +3 -2
- data/config/locales/nb.yml +3 -2
- data/config/locales/nl.yml +3 -2
- data/config/locales/pl.yml +3 -2
- data/config/locales/pt-BR.yml +3 -2
- data/config/locales/ro.yml +3 -2
- data/config/locales/ru.yml +3 -2
- data/config/locales/zh-CN.yml +3 -2
- data/config/locales/zh-TW.yml +3 -2
- data/config/routes.rb +0 -11
- data/db/migrate/114_fixes_buggy_articles_and_notes.rb +2 -2
- data/db/migrate/20150807134129_simplify_redirect_relations.rb +1 -1
- data/db/migrate/20160605154632_remove_profiles.rb +1 -1
- data/db/migrate/20190208152646_move_text_filter_to_name.rb +2 -2
- data/lib/format.rb +2 -2
- data/lib/publify_core/engine.rb +10 -0
- data/lib/publify_core/string_ext.rb +1 -13
- data/lib/publify_core/text_filter/markdown.rb +5 -1
- data/lib/publify_core/text_filter/markdown_smartquotes.rb +6 -1
- data/lib/publify_core/version.rb +1 -1
- data/lib/publify_core.rb +2 -2
- data/lib/text_filter_plugin.rb +20 -22
- data/lib/theme.rb +56 -37
- metadata +100 -397
- data/app/assets/javascripts/bootstrap/affix.js +0 -164
- data/app/assets/javascripts/bootstrap/alert.js +0 -95
- data/app/assets/javascripts/bootstrap/button.js +0 -125
- data/app/assets/javascripts/bootstrap/collapse.js +0 -212
- data/app/assets/javascripts/bootstrap/dropdown.js +0 -165
- data/app/assets/javascripts/bootstrap/modal.js +0 -358
- data/app/assets/javascripts/bootstrap/tab.js +0 -155
- data/app/assets/javascripts/bootstrap/transition.js +0 -59
- data/app/assets/javascripts/bootstrap-sprockets.js +0 -8
- data/app/assets/javascripts/lightbox.js +0 -350
- data/app/assets/stylesheets/_bootstrap-compass.scss +0 -9
- data/app/assets/stylesheets/_bootstrap-mincer.scss +0 -19
- data/app/assets/stylesheets/_bootstrap-sprockets.scss +0 -9
- data/app/assets/stylesheets/_bootstrap.scss +0 -42
- data/app/assets/stylesheets/bootstrap/_alerts.scss +0 -73
- data/app/assets/stylesheets/bootstrap/_button-groups.scss +0 -242
- data/app/assets/stylesheets/bootstrap/_buttons.scss +0 -168
- data/app/assets/stylesheets/bootstrap/_close.scss +0 -37
- data/app/assets/stylesheets/bootstrap/_code.scss +0 -69
- data/app/assets/stylesheets/bootstrap/_component-animations.scss +0 -38
- data/app/assets/stylesheets/bootstrap/_dropdowns.scss +0 -213
- data/app/assets/stylesheets/bootstrap/_forms.scss +0 -586
- data/app/assets/stylesheets/bootstrap/_grid.scss +0 -94
- data/app/assets/stylesheets/bootstrap/_labels.scss +0 -66
- data/app/assets/stylesheets/bootstrap/_media.scss +0 -66
- data/app/assets/stylesheets/bootstrap/_mixins.scss +0 -37
- data/app/assets/stylesheets/bootstrap/_modals.scss +0 -150
- data/app/assets/stylesheets/bootstrap/_navbar.scss +0 -479
- data/app/assets/stylesheets/bootstrap/_navs.scss +0 -242
- data/app/assets/stylesheets/bootstrap/_normalize.scss +0 -427
- data/app/assets/stylesheets/bootstrap/_pagination.scss +0 -86
- data/app/assets/stylesheets/bootstrap/_panels.scss +0 -222
- data/app/assets/stylesheets/bootstrap/_print.scss +0 -99
- data/app/assets/stylesheets/bootstrap/_scaffolding.scss +0 -160
- data/app/assets/stylesheets/bootstrap/_tables.scss +0 -234
- data/app/assets/stylesheets/bootstrap/_theme.scss +0 -224
- data/app/assets/stylesheets/bootstrap/_type.scss +0 -296
- data/app/assets/stylesheets/bootstrap/_utilities.scss +0 -55
- data/app/assets/stylesheets/bootstrap/_variables.scss +0 -638
- data/app/assets/stylesheets/bootstrap/_wells.scss +0 -29
- data/app/assets/stylesheets/bootstrap/mixins/_alerts.scss +0 -15
- data/app/assets/stylesheets/bootstrap/mixins/_background-variant.scss +0 -12
- data/app/assets/stylesheets/bootstrap/mixins/_border-radius.scss +0 -18
- data/app/assets/stylesheets/bootstrap/mixins/_buttons.scss +0 -56
- data/app/assets/stylesheets/bootstrap/mixins/_center-block.scss +0 -7
- data/app/assets/stylesheets/bootstrap/mixins/_clearfix.scss +0 -22
- data/app/assets/stylesheets/bootstrap/mixins/_forms.scss +0 -82
- data/app/assets/stylesheets/bootstrap/mixins/_gradients.scss +0 -56
- data/app/assets/stylesheets/bootstrap/mixins/_grid-framework.scss +0 -81
- data/app/assets/stylesheets/bootstrap/mixins/_grid.scss +0 -122
- data/app/assets/stylesheets/bootstrap/mixins/_hide-text.scss +0 -21
- data/app/assets/stylesheets/bootstrap/mixins/_image.scss +0 -28
- data/app/assets/stylesheets/bootstrap/mixins/_labels.scss +0 -12
- data/app/assets/stylesheets/bootstrap/mixins/_nav-divider.scss +0 -10
- data/app/assets/stylesheets/bootstrap/mixins/_nav-vertical-align.scss +0 -9
- data/app/assets/stylesheets/bootstrap/mixins/_opacity.scss +0 -7
- data/app/assets/stylesheets/bootstrap/mixins/_pagination.scss +0 -24
- data/app/assets/stylesheets/bootstrap/mixins/_panels.scss +0 -20
- data/app/assets/stylesheets/bootstrap/mixins/_reset-filter.scss +0 -8
- data/app/assets/stylesheets/bootstrap/mixins/_resize.scss +0 -6
- data/app/assets/stylesheets/bootstrap/mixins/_responsive-visibility.scss +0 -17
- data/app/assets/stylesheets/bootstrap/mixins/_size.scss +0 -10
- data/app/assets/stylesheets/bootstrap/mixins/_tab-focus.scss +0 -9
- data/app/assets/stylesheets/bootstrap/mixins/_table-row.scss +0 -28
- data/app/assets/stylesheets/bootstrap/mixins/_text-emphasis.scss +0 -12
- data/app/assets/stylesheets/bootstrap/mixins/_text-overflow.scss +0 -8
- data/app/assets/stylesheets/bootstrap/mixins/_vendor-prefixes.scss +0 -222
- data/app/assets/stylesheets/lightbox.css +0 -63
- data/app/controllers/theme_controller.rb +0 -63
- data/app/views/notes/show_in_reply.html.erb +0 -18
- data/app/views/theme/static_view_test.html.erb +0 -1
- data/lib/publify_core/text_filter/twitterfilter.rb +0 -55
- data/lib/tasks/manifest.rake +0 -30
- /data/app/views/layouts/{default.html.erb → application.html.erb} +0 -0
- /data/themes/plain/javascripts/{theme.js → plain/theme.js} +0 -0
- /data/themes/plain/stylesheets/{theme.css → plain/theme.css} +0 -0
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
class NotesController < ContentController
|
|
4
4
|
require "json"
|
|
5
5
|
|
|
6
|
-
layout :theme_layout
|
|
7
|
-
|
|
8
6
|
after_action :set_blog_infos
|
|
9
7
|
|
|
10
8
|
def index
|
|
@@ -19,10 +17,7 @@ class NotesController < ContentController
|
|
|
19
17
|
def show
|
|
20
18
|
@note = Note.published.find_by! permalink: CGI.escape(params[:permalink])
|
|
21
19
|
|
|
22
|
-
if @note.in_reply_to_message.present?
|
|
23
|
-
@reply = JSON.parse(@note.in_reply_to_message)
|
|
24
|
-
render :show_in_reply
|
|
25
|
-
end
|
|
20
|
+
@reply = JSON.parse(@note.in_reply_to_message) if @note.in_reply_to_message.present?
|
|
26
21
|
end
|
|
27
22
|
|
|
28
23
|
private
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
module Admin::BaseHelper
|
|
4
4
|
include ActionView::Helpers::DateHelper
|
|
5
5
|
|
|
6
|
-
def toggle_element(element, label = t("generic.change"))
|
|
7
|
-
link_to
|
|
6
|
+
def toggle_element(element, label = t("generic.change"), **)
|
|
7
|
+
link_to(label, "##{element}", data: { "bs-toggle": :collapse }, **)
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def class_for_admin_state(sidebar, this_position)
|
|
@@ -35,15 +35,13 @@ module Admin::BaseHelper
|
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
def show_actions(item)
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
button_to_short_url(item)], " "
|
|
42
|
-
end
|
|
38
|
+
safe_join [button_to_edit(item),
|
|
39
|
+
button_to_delete(item),
|
|
40
|
+
button_to_short_url(item)], " "
|
|
43
41
|
end
|
|
44
42
|
|
|
45
43
|
def display_pagination(collection, cols, _first = "", _last = "")
|
|
46
|
-
return if collection.
|
|
44
|
+
return if collection.none?
|
|
47
45
|
|
|
48
46
|
tag.tr do
|
|
49
47
|
tag.td(paginate(collection), class: "paginate", colspan: cols)
|
|
@@ -53,7 +51,7 @@ module Admin::BaseHelper
|
|
|
53
51
|
def button_to_edit(item)
|
|
54
52
|
link_to(t("generic.edit"),
|
|
55
53
|
{ action: "edit", id: item.id },
|
|
56
|
-
{ class: "btn btn-primary btn-
|
|
54
|
+
{ class: "btn btn-primary btn-sm" })
|
|
57
55
|
end
|
|
58
56
|
|
|
59
57
|
def button_to_delete(item)
|
|
@@ -61,7 +59,7 @@ module Admin::BaseHelper
|
|
|
61
59
|
element: item.class.model_name.human.downcase)
|
|
62
60
|
link_to(t("generic.delete"),
|
|
63
61
|
{ action: "destroy", id: item.id },
|
|
64
|
-
{ class: "btn btn-danger btn-
|
|
62
|
+
{ class: "btn btn-danger btn-sm", method: :delete,
|
|
65
63
|
data: { confirm: confirm_text } })
|
|
66
64
|
end
|
|
67
65
|
|
|
@@ -69,18 +67,27 @@ module Admin::BaseHelper
|
|
|
69
67
|
return "" if item.short_url.nil?
|
|
70
68
|
|
|
71
69
|
link_to(t("generic.short_url"), item.short_url,
|
|
72
|
-
class: "btn btn-success btn-
|
|
70
|
+
class: "btn btn-success btn-sm")
|
|
73
71
|
end
|
|
74
72
|
|
|
75
73
|
def twitter_available?(blog, user)
|
|
76
74
|
blog.has_twitter_configured? && user.has_twitter_configured?
|
|
77
75
|
end
|
|
78
76
|
|
|
77
|
+
def top_menu_item(name, url)
|
|
78
|
+
if current_page? url
|
|
79
|
+
tag.li(link_to(name, "#", class: "active nav-link", "aria-current": "page"),
|
|
80
|
+
class: "nav-item")
|
|
81
|
+
else
|
|
82
|
+
tag.li(link_to(name, url, class: "nav-link"), class: "nav-item")
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
79
86
|
def menu_item(name, url)
|
|
80
87
|
if current_page? url
|
|
81
|
-
tag.li(link_to(name, "#"
|
|
88
|
+
tag.li(link_to(name, "#", class: "active dropdown-item", "aria-current": "page"))
|
|
82
89
|
else
|
|
83
|
-
tag.li(link_to(name, url))
|
|
90
|
+
tag.li(link_to(name, url, class: "dropdown-item"))
|
|
84
91
|
end
|
|
85
92
|
end
|
|
86
93
|
end
|
|
@@ -23,19 +23,19 @@ module Admin::FeedbackHelper
|
|
|
23
23
|
def button_to_edit_comment(item)
|
|
24
24
|
link_to(t("generic.edit"),
|
|
25
25
|
{ controller: "admin/feedback", action: "edit", id: item.id },
|
|
26
|
-
{ class: "btn btn-primary btn-
|
|
26
|
+
{ class: "btn btn-primary btn-sm" })
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
def button_to_delete_comment(item)
|
|
30
30
|
link_to(t("generic.delete"),
|
|
31
31
|
{ controller: "admin/feedback", action: "destroy", id: item.id },
|
|
32
|
-
{ class: "btn btn-danger btn-
|
|
32
|
+
{ class: "btn btn-danger btn-sm" })
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def button_to_conversation(item)
|
|
36
36
|
link_to(t("generic.conversation"),
|
|
37
37
|
{ controller: "admin/feedback", action: "article", id: item.article_id },
|
|
38
|
-
{ class: "btn btn-default btn-
|
|
38
|
+
{ class: "btn btn-default btn-sm" })
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
def change_status(item, context = "listing")
|
|
@@ -46,7 +46,7 @@ module Admin::FeedbackHelper
|
|
|
46
46
|
link_to(link_text,
|
|
47
47
|
{ controller: "admin/feedback", action: "change_state",
|
|
48
48
|
id: item.id, context: context },
|
|
49
|
-
{ class: "btn btn-#{button_type} btn-
|
|
49
|
+
{ class: "btn btn-#{button_type} btn-sm",
|
|
50
50
|
method: :post, remote: true })
|
|
51
51
|
end
|
|
52
52
|
end
|
data/app/helpers/base_helper.rb
CHANGED
|
@@ -28,17 +28,21 @@ module BaseHelper
|
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def themeable_stylesheet_link_tag(name)
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
theme = this_blog.current_theme
|
|
32
|
+
src = theme.path.join("stylesheets", theme.name, "#{name}.css")
|
|
33
|
+
|
|
34
|
+
stylesheet_link_tag "#{theme.name}/#{name}.css" if File.exist? src
|
|
33
35
|
end
|
|
34
36
|
|
|
35
37
|
def themeable_javascript_include_tag(name)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
theme = this_blog.current_theme
|
|
39
|
+
src = theme.path.join("javascripts", theme.name, "#{name}.js")
|
|
40
|
+
|
|
41
|
+
javascript_include_tag "#{theme.name}/#{name}.js" if File.exist? src
|
|
38
42
|
end
|
|
39
43
|
|
|
40
|
-
def render_to_string(
|
|
41
|
-
controller.send(:render_to_string,
|
|
44
|
+
def render_to_string(...)
|
|
45
|
+
controller.send(:render_to_string, ...)
|
|
42
46
|
end
|
|
43
47
|
|
|
44
48
|
def link_to_permalink(item, title,
|
data/app/helpers/xml_helper.rb
CHANGED
data/app/models/article.rb
CHANGED
|
@@ -8,7 +8,7 @@ class Article < Content
|
|
|
8
8
|
include PublifyGuid
|
|
9
9
|
include ConfigManager
|
|
10
10
|
|
|
11
|
-
serialize :settings, Hash
|
|
11
|
+
serialize :settings, type: Hash, coder: YAML
|
|
12
12
|
|
|
13
13
|
content_fields :body, :extended
|
|
14
14
|
|
|
@@ -36,7 +36,7 @@ class Article < Content
|
|
|
36
36
|
"contents.state" => "published")
|
|
37
37
|
.group("contents.id")
|
|
38
38
|
.select("contents.*, count(feedback.id) as comment_count")
|
|
39
|
-
.order(
|
|
39
|
+
.order(comment_count: :desc)
|
|
40
40
|
.limit(5)
|
|
41
41
|
}
|
|
42
42
|
|
|
@@ -101,12 +101,12 @@ class Article < Content
|
|
|
101
101
|
|
|
102
102
|
def self.search_with(params)
|
|
103
103
|
params ||= {}
|
|
104
|
-
scoped = super
|
|
104
|
+
scoped = super
|
|
105
105
|
if %w(no_draft drafts published withdrawn pending).include?(params[:state])
|
|
106
106
|
scoped = scoped.send(params[:state])
|
|
107
107
|
end
|
|
108
108
|
|
|
109
|
-
scoped.order(
|
|
109
|
+
scoped.order(created_at: :desc)
|
|
110
110
|
end
|
|
111
111
|
|
|
112
112
|
# FIXME: Use keyword params to clean up call sites.
|
|
@@ -140,12 +140,12 @@ class Article < Content
|
|
|
140
140
|
end
|
|
141
141
|
|
|
142
142
|
def next
|
|
143
|
-
Article.where("published_at > ?", published_at).order(
|
|
143
|
+
Article.where("published_at > ?", published_at).order(:published_at)
|
|
144
144
|
.limit(1).first
|
|
145
145
|
end
|
|
146
146
|
|
|
147
147
|
def previous
|
|
148
|
-
Article.where(
|
|
148
|
+
Article.where(published_at: ...published_at).order(published_at: :desc)
|
|
149
149
|
.limit(1).first
|
|
150
150
|
end
|
|
151
151
|
|
|
@@ -155,7 +155,7 @@ class Article < Content
|
|
|
155
155
|
|
|
156
156
|
def self.publication_months
|
|
157
157
|
result = select("published_at").where.not(published_at: nil).where(type: "Article")
|
|
158
|
-
result.map {
|
|
158
|
+
result.map { [_1.publication_month] }.uniq
|
|
159
159
|
end
|
|
160
160
|
|
|
161
161
|
# Finds one article which was posted on a certain date and matches the
|
data/app/models/blog.rb
CHANGED
|
@@ -24,15 +24,15 @@ class Blog < ApplicationRecord
|
|
|
24
24
|
has_many :notes
|
|
25
25
|
|
|
26
26
|
has_many :redirects
|
|
27
|
-
has_many :sidebars, ->() { order(
|
|
27
|
+
has_many :sidebars, ->() { order(:active_position) }
|
|
28
28
|
|
|
29
29
|
attr_accessor :custom_permalink
|
|
30
30
|
|
|
31
|
-
default_scope -> { order(
|
|
31
|
+
default_scope -> { order(:id) }
|
|
32
32
|
|
|
33
33
|
validates :blog_name, presence: true
|
|
34
34
|
|
|
35
|
-
serialize :settings, Hash
|
|
35
|
+
serialize :settings, type: Hash, coder: YAML
|
|
36
36
|
|
|
37
37
|
# Description
|
|
38
38
|
setting :blog_name, :string, "My Shiny Weblog!"
|
data/app/models/comment.rb
CHANGED
|
@@ -16,7 +16,7 @@ class Comment < Feedback
|
|
|
16
16
|
scope :ham, -> { where(state: "ham") }
|
|
17
17
|
scope :unconfirmed, -> { where(state: %w(presumed_spam presumed_ham)) }
|
|
18
18
|
|
|
19
|
-
scope :last_published, -> { published.limit(5).order(
|
|
19
|
+
scope :last_published, -> { published.limit(5).order(created_at: :desc) }
|
|
20
20
|
|
|
21
21
|
def notify_user_via_email(user)
|
|
22
22
|
EmailNotify.send_comment(self, user) if user.notify_via_email?
|
data/app/models/content.rb
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "set"
|
|
4
3
|
require "uri"
|
|
5
4
|
|
|
6
5
|
class Content < ApplicationRecord
|
|
@@ -22,8 +21,8 @@ class Content < ApplicationRecord
|
|
|
22
21
|
published.where(published_at: PublifyTime.delta(*time_params))
|
|
23
22
|
}
|
|
24
23
|
scope :not_published, -> { where.not(state: "published") }
|
|
25
|
-
scope :drafts, -> { where(state: "draft").order(
|
|
26
|
-
scope :no_draft, -> { where.not(state: "draft").order(
|
|
24
|
+
scope :drafts, -> { where(state: "draft").order(created_at: :desc) }
|
|
25
|
+
scope :no_draft, -> { where.not(state: "draft").order(published_at: :desc) }
|
|
27
26
|
scope :searchstring, lambda { |search_string|
|
|
28
27
|
result = where(state: "published")
|
|
29
28
|
|
|
@@ -40,7 +39,7 @@ class Content < ApplicationRecord
|
|
|
40
39
|
where(published_at: PublifyTime.delta_like(date_at))
|
|
41
40
|
}
|
|
42
41
|
|
|
43
|
-
serialize :whiteboard
|
|
42
|
+
serialize :whiteboard, coder: YAML
|
|
44
43
|
|
|
45
44
|
validates_default_string_length :title, :author, :permalink, :name,
|
|
46
45
|
:post_type, :text_filter_name
|
|
@@ -120,6 +119,6 @@ class Content < ApplicationRecord
|
|
|
120
119
|
end
|
|
121
120
|
|
|
122
121
|
def short_url
|
|
123
|
-
redirect
|
|
122
|
+
redirect&.from_url
|
|
124
123
|
end
|
|
125
124
|
end
|
data/app/models/content_base.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
module ContentBase
|
|
4
4
|
def self.included(base)
|
|
5
5
|
base.extend ClassMethods
|
|
6
|
+
base.include ActionView::Helpers::SanitizeHelper
|
|
6
7
|
end
|
|
7
8
|
|
|
8
9
|
attr_accessor :just_changed_published_status
|
|
@@ -33,7 +34,7 @@ module ContentBase
|
|
|
33
34
|
# Generate HTML for a specific field using the text_filter in use for this
|
|
34
35
|
# object.
|
|
35
36
|
def generate_html(field, text = nil)
|
|
36
|
-
text ||= self[field]
|
|
37
|
+
text ||= self[field] || ""
|
|
37
38
|
html = (text_filter || default_text_filter).filter_text(text) || text
|
|
38
39
|
html_postprocess(field, html).to_s
|
|
39
40
|
end
|
|
@@ -49,13 +50,13 @@ module ContentBase
|
|
|
49
50
|
end
|
|
50
51
|
|
|
51
52
|
def excerpt_text(length = 160)
|
|
52
|
-
text = if respond_to?(:excerpt) &&
|
|
53
|
+
text = if respond_to?(:excerpt) && excerpt.present?
|
|
53
54
|
generate_html(:excerpt, excerpt)
|
|
54
55
|
else
|
|
55
56
|
html(:all)
|
|
56
57
|
end
|
|
57
58
|
|
|
58
|
-
text = text
|
|
59
|
+
text = strip_tags(text)
|
|
59
60
|
|
|
60
61
|
text.slice(0, length) +
|
|
61
62
|
(text.length > length ? "..." : "")
|
data/app/models/feedback.rb
CHANGED
data/app/models/note.rb
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "twitter"
|
|
4
|
+
require "json"
|
|
5
|
+
require "uri"
|
|
6
|
+
require "html_pipeline"
|
|
7
|
+
require "html_pipeline/node_filter/mention_filter"
|
|
8
|
+
|
|
3
9
|
class Note < Content
|
|
4
|
-
require "twitter"
|
|
5
|
-
require "json"
|
|
6
|
-
require "uri"
|
|
7
10
|
include PublifyGuid
|
|
8
11
|
include ConfigManager
|
|
9
12
|
|
|
10
|
-
serialize :settings, Hash
|
|
13
|
+
serialize :settings, type: Hash, coder: YAML
|
|
11
14
|
|
|
12
15
|
setting :twitter_id, :string, ""
|
|
13
16
|
setting :in_reply_to_status_id, :string, ""
|
|
@@ -21,15 +24,63 @@ class Note < Content
|
|
|
21
24
|
after_create :set_permalink, :shorten_url
|
|
22
25
|
|
|
23
26
|
scope :published, lambda {
|
|
24
|
-
where(state: "published").where(
|
|
27
|
+
where(state: "published").where(published_at: ..Time.zone.now).order(default_order)
|
|
25
28
|
}
|
|
26
|
-
default_scope { order(
|
|
29
|
+
default_scope { order(published_at: :desc) }
|
|
27
30
|
|
|
28
31
|
TWITTER_FTP_URL_LENGTH = 19
|
|
29
32
|
TWITTER_HTTP_URL_LENGTH = 20
|
|
30
33
|
TWITTER_HTTPS_URL_LENGTH = 21
|
|
31
34
|
TWITTER_LINK_LENGTH = 22
|
|
32
35
|
|
|
36
|
+
class TwitterHashtagFilter < HTMLPipeline::NodeFilter
|
|
37
|
+
def after_initialize
|
|
38
|
+
context[:tag_url] ||= "https://twitter.com/search?q=%%23%<tag>s&src=tren&mode=realtime"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
SELECTOR = Selma::Selector.new(match_text_within: "*",
|
|
42
|
+
ignore_text_within: ["a"])
|
|
43
|
+
|
|
44
|
+
def selector
|
|
45
|
+
SELECTOR
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
HASHTAG_PATTERN = /(?<=^|\W)#([-_A-Za-z0-9]+)(?=\W|$)/
|
|
49
|
+
|
|
50
|
+
def handle_text_chunk(chunk)
|
|
51
|
+
text = chunk.to_s
|
|
52
|
+
|
|
53
|
+
html = text.gsub(HASHTAG_PATTERN) do |match|
|
|
54
|
+
tag = Regexp.last_match(1)
|
|
55
|
+
url = format context[:tag_url], tag: tag
|
|
56
|
+
"<a href=\"#{url}\">#{match}</a>"
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
return chunk if html == text
|
|
60
|
+
|
|
61
|
+
chunk.replace(html, as: :html)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
class TwitterMentionFilter < HTMLPipeline::NodeFilter::MentionFilter
|
|
66
|
+
def after_initialize
|
|
67
|
+
super
|
|
68
|
+
context[:base_url] ||= "https://twitter.com"
|
|
69
|
+
context[:info_url] ||= "https://foo.com"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Override base link creator, removing the class
|
|
73
|
+
def link_to_mentioned_user(base_url, login)
|
|
74
|
+
result[:mentioned_usernames] |= [login]
|
|
75
|
+
|
|
76
|
+
url = base_url.dup
|
|
77
|
+
excluded_prefixes = %r{[/(?:~|@]\z}
|
|
78
|
+
url << "/" unless excluded_prefixes.match?(url)
|
|
79
|
+
|
|
80
|
+
"<a href=\"#{url << login}\">@#{login}</a>"
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
33
84
|
def set_permalink
|
|
34
85
|
self.permalink = "#{id}-#{body.to_permalink[0..79]}" if permalink.blank?
|
|
35
86
|
save
|
|
@@ -43,8 +94,23 @@ class Note < Content
|
|
|
43
94
|
[]
|
|
44
95
|
end
|
|
45
96
|
|
|
97
|
+
def generate_html(field, text = nil)
|
|
98
|
+
if field == :in_reply_to
|
|
99
|
+
helper = PublifyCore::ContentTextHelpers.new
|
|
100
|
+
html = helper.simple_format(text)
|
|
101
|
+
html_postprocess(field, html).to_s
|
|
102
|
+
else
|
|
103
|
+
super
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
46
107
|
def html_postprocess(field, html)
|
|
47
|
-
|
|
108
|
+
helper = PublifyCore::ContentTextHelpers.new
|
|
109
|
+
html = helper.auto_link(html)
|
|
110
|
+
|
|
111
|
+
html = TwitterHashtagFilter.call(html)
|
|
112
|
+
html = TwitterMentionFilter.call(html).to_s
|
|
113
|
+
super
|
|
48
114
|
end
|
|
49
115
|
|
|
50
116
|
def truncate(message, length)
|
|
@@ -56,7 +122,7 @@ class Note < Content
|
|
|
56
122
|
end
|
|
57
123
|
|
|
58
124
|
def twitter_message
|
|
59
|
-
base_message = body
|
|
125
|
+
base_message = strip_tags(body)
|
|
60
126
|
if too_long?("#{base_message} (#{short_link})")
|
|
61
127
|
max_length = 140 - "... (#{redirect.from_url})".length - 1
|
|
62
128
|
"#{truncate(base_message, max_length)}... (#{redirect.from_url})"
|
data/app/models/page.rb
CHANGED
data/app/models/redirect.rb
CHANGED
data/app/models/resource.rb
CHANGED
data/app/models/sidebar.rb
CHANGED
|
@@ -4,7 +4,7 @@ require "sidebar_field"
|
|
|
4
4
|
|
|
5
5
|
# This class cannot be autoloaded since other sidebar classes depend on it.
|
|
6
6
|
class Sidebar < ApplicationRecord
|
|
7
|
-
serialize :config, Hash
|
|
7
|
+
serialize :config, type: Hash, coder: YAML
|
|
8
8
|
|
|
9
9
|
belongs_to :blog
|
|
10
10
|
|
|
@@ -32,7 +32,7 @@ class Sidebar < ApplicationRecord
|
|
|
32
32
|
def self.setting(key, default = nil, options = {})
|
|
33
33
|
key = key.to_s
|
|
34
34
|
|
|
35
|
-
return if
|
|
35
|
+
return if method_defined?(key)
|
|
36
36
|
|
|
37
37
|
fields << SidebarField.build(key, default, options)
|
|
38
38
|
|
|
@@ -97,9 +97,7 @@ class Sidebar < ApplicationRecord
|
|
|
97
97
|
|
|
98
98
|
def parse_request(_contents, _params); end
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
self.class.fields
|
|
102
|
-
end
|
|
100
|
+
delegate :fields, to: :class
|
|
103
101
|
|
|
104
102
|
def fieldmap(field = nil)
|
|
105
103
|
if field
|
|
@@ -109,17 +107,11 @@ class Sidebar < ApplicationRecord
|
|
|
109
107
|
end
|
|
110
108
|
end
|
|
111
109
|
|
|
112
|
-
|
|
113
|
-
self.class.description
|
|
114
|
-
end
|
|
110
|
+
delegate :description, to: :class
|
|
115
111
|
|
|
116
|
-
|
|
117
|
-
self.class.short_name
|
|
118
|
-
end
|
|
112
|
+
delegate :short_name, to: :class
|
|
119
113
|
|
|
120
|
-
|
|
121
|
-
self.class.display_name
|
|
122
|
-
end
|
|
114
|
+
delegate :display_name, to: :class
|
|
123
115
|
|
|
124
116
|
def content_partial
|
|
125
117
|
"/#{self.class.path_name}/content"
|
data/app/models/tag.rb
CHANGED
|
@@ -43,11 +43,11 @@ class Tag < ApplicationRecord
|
|
|
43
43
|
.where(contents: { state: "published" })
|
|
44
44
|
.select(*Tag.column_names, "COUNT(contents_tags.content_id) as content_counter")
|
|
45
45
|
.group(*Tag.column_names)
|
|
46
|
-
.order(
|
|
46
|
+
.order(content_counter: :desc).limit(1000)
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
def self.find_with_char(char)
|
|
50
|
-
where("name LIKE ? ", "%#{char}%").order(
|
|
50
|
+
where("name LIKE ? ", "%#{char}%").order(:name)
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
def self.collection_to_string(tags)
|
data/app/models/text_filter.rb
CHANGED
|
@@ -44,7 +44,7 @@ class TextFilter
|
|
|
44
44
|
if f.help_text.blank?
|
|
45
45
|
""
|
|
46
46
|
else
|
|
47
|
-
"<h3>#{f.display_name}</h3>\n#{
|
|
47
|
+
"<h3>#{f.display_name}</h3>\n#{Commonmarker.to_html(f.help_text)}"
|
|
48
48
|
end
|
|
49
49
|
end
|
|
50
50
|
|
|
@@ -56,7 +56,7 @@ class TextFilter
|
|
|
56
56
|
.expand_filter_list([markup, filters].flatten)
|
|
57
57
|
|
|
58
58
|
help_filters.map do |f|
|
|
59
|
-
f.help_text.blank? ? "" :
|
|
59
|
+
f.help_text.blank? ? "" : Commonmarker.to_html(f.help_text)
|
|
60
60
|
end.join("\n")
|
|
61
61
|
end
|
|
62
62
|
|