thredded 0.10.1 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +30 -10
- data/app/assets/images/favicons/README.md +3 -0
- data/app/assets/images/favicons/amazon.png +0 -0
- data/app/assets/images/favicons/github.png +0 -0
- data/app/assets/images/favicons/google_branding/logo_calendar_128px.png +0 -0
- data/app/assets/images/favicons/google_branding/logo_docs_48px.png +0 -0
- data/app/assets/images/favicons/google_branding/logo_drive_48px.png +0 -0
- data/app/assets/images/favicons/google_branding/logo_forms_48px.png +0 -0
- data/app/assets/images/favicons/google_branding/logo_sheets_48px.png +0 -0
- data/app/assets/images/favicons/google_branding/logo_slides_48px.png +0 -0
- data/app/assets/images/favicons/stackexchange.png +0 -0
- data/app/assets/images/favicons/twitter.png +0 -0
- data/app/assets/images/favicons/wikipedia.png +0 -0
- data/app/assets/javascripts/thredded/components/user_preferences_form.es6 +16 -1
- data/app/assets/stylesheets/thredded/_email.scss +52 -0
- data/app/assets/stylesheets/thredded/_thredded.scss +1 -0
- data/app/assets/stylesheets/thredded/base/_grid.scss +14 -1
- data/app/assets/stylesheets/thredded/base/_typography.scss +4 -0
- data/app/assets/stylesheets/thredded/base/_variables.scss +24 -1
- data/app/assets/stylesheets/thredded/components/_main-section.scss +6 -0
- data/app/assets/stylesheets/thredded/components/_messageboard.scss +4 -1
- data/app/assets/stylesheets/thredded/components/_onebox.scss +284 -0
- data/app/assets/stylesheets/thredded/components/_post.scss +10 -6
- data/app/assets/stylesheets/thredded/components/_topic-header.scss +1 -1
- data/app/assets/stylesheets/thredded/components/_topics.scss +5 -5
- data/app/assets/stylesheets/thredded/layout/_main-navigation.scss +0 -6
- data/app/assets/stylesheets/thredded/layout/_moderation.scss +1 -1
- data/app/commands/thredded/autofollow_users.rb +56 -0
- data/app/controllers/thredded/preferences_controller.rb +2 -0
- data/app/forms/thredded/user_preferences_form.rb +18 -0
- data/app/helpers/thredded/application_helper.rb +3 -3
- data/app/jobs/thredded/auto_follow_and_notify_job.rb +1 -1
- data/app/mailer_previews/thredded/base_mailer_preview.rb +19 -8
- data/app/mailers/thredded/base_mailer.rb +1 -1
- data/app/models/concerns/thredded/post_common.rb +2 -4
- data/app/models/thredded/category.rb +4 -0
- data/app/models/thredded/messageboard.rb +12 -6
- data/app/models/thredded/private_topic.rb +4 -0
- data/app/models/thredded/topic.rb +9 -5
- data/app/models/thredded/user_messageboard_preference.rb +24 -0
- data/app/models/thredded/user_preference.rb +2 -0
- data/app/models/thredded/user_topic_follow.rb +1 -1
- data/app/notifiers/thredded/email_notifier.rb +1 -15
- data/app/views/thredded/messageboard_groups/new.html.erb +15 -13
- data/app/views/thredded/messageboards/_form.html.erb +22 -22
- data/app/views/thredded/messageboards/edit.html.erb +3 -1
- data/app/views/thredded/messageboards/new.html.erb +3 -1
- data/app/views/thredded/moderation/_post.html.erb +1 -1
- data/app/views/thredded/moderation/_user_post.html.erb +1 -1
- data/app/views/thredded/moderation/activity.html.erb +3 -3
- data/app/views/thredded/moderation/history.html.erb +2 -2
- data/app/views/thredded/moderation/pending.html.erb +2 -2
- data/app/views/thredded/moderation/user.html.erb +43 -41
- data/app/views/thredded/moderation/users.html.erb +32 -30
- data/app/views/thredded/post_mailer/post_notification.html.erb +21 -12
- data/app/views/thredded/posts/_content.html.erb +1 -1
- data/app/views/thredded/posts_common/_content.html.erb +1 -3
- data/app/views/thredded/preferences/_form.html.erb +25 -8
- data/app/views/thredded/private_posts/_content.html.erb +1 -1
- data/app/views/thredded/private_topic_mailer/message_notification.html.erb +17 -14
- data/app/views/thredded/private_topics/edit.html.erb +21 -19
- data/app/views/thredded/topics/edit.html.erb +32 -30
- data/app/views/thredded/topics/new.html.erb +8 -6
- data/app/views/thredded/topics/show.html.erb +1 -1
- data/app/views/thredded/users/_post.html.erb +1 -1
- data/bin/rubocop +17 -0
- data/config/locales/en.yml +13 -1
- data/config/locales/es.yml +14 -0
- data/config/locales/pl.yml +13 -0
- data/config/locales/pt-BR.yml +12 -0
- data/config/locales/ru.yml +197 -0
- data/db/migrate/20160329231848_create_thredded.rb +2 -8
- data/db/upgrade_migrations/20161113161801_upgrade_v0_8_to_v0_9.rb +6 -5
- data/db/upgrade_migrations/20170312131417_upgrade_thredded_v0_10_to_v0_11.rb +20 -0
- data/lib/generators/thredded/install/templates/initializer.rb +12 -0
- data/lib/thredded.rb +12 -3
- data/lib/thredded/content_formatter.rb +16 -25
- data/lib/thredded/email_transformer.rb +21 -0
- data/lib/thredded/email_transformer/base.rb +47 -0
- data/lib/thredded/email_transformer/onebox.rb +20 -0
- data/lib/thredded/formatting_demo_content.rb +29 -0
- data/lib/thredded/html_pipeline/kramdown_filter.rb +5 -1
- data/lib/thredded/html_pipeline/onebox_filter.rb +136 -0
- data/lib/thredded/version.rb +1 -1
- metadata +62 -22
- data/app/commands/thredded/autofollow_mentioned_users.rb +0 -31
- data/app/commands/thredded/members_marked_notified.rb +0 -19
- data/app/models/thredded/post_notification.rb +0 -18
@@ -0,0 +1,197 @@
|
|
1
|
+
---
|
2
|
+
ru:
|
3
|
+
thredded:
|
4
|
+
content_moderation_states:
|
5
|
+
content_blocked_notice: Блокировано
|
6
|
+
content_blocked_notice_with_record_html: Блокировано %{moderator} %{time_ago}
|
7
|
+
email_notifier:
|
8
|
+
by_email: email
|
9
|
+
errors:
|
10
|
+
login_required: Необходимо зайти на форум.
|
11
|
+
not_authorized: Вы не авторизованы.
|
12
|
+
private_topic_create_denied: Вы не авторизованы для создания личных сообщений.
|
13
|
+
private_topic_not_found: Личное сообщение не найдено.
|
14
|
+
form:
|
15
|
+
create_btn_submitting: Создаю...
|
16
|
+
preview: Обзор
|
17
|
+
update: Обновить
|
18
|
+
update_btn_submitting: Обновляю...
|
19
|
+
messageboard:
|
20
|
+
create: Создать форум
|
21
|
+
form:
|
22
|
+
create_btn_submitting: :thredded.form.create_btn_submitting
|
23
|
+
description_label: Описание
|
24
|
+
messageboard_group_id_label: Выбрать группу
|
25
|
+
no_group: Не группировать
|
26
|
+
title_label: Название форума
|
27
|
+
update_btn_submitting: :thredded.form.update_btn_submitting
|
28
|
+
index:
|
29
|
+
page_title: Форумы
|
30
|
+
last_updated_by_html: Обновлено %{time_ago} <cite>пользователем %{user}</cite>
|
31
|
+
topics_and_posts_counts: "%{topics_count} тем / %{posts_count} постов"
|
32
|
+
update: :thredded.form.update
|
33
|
+
updated_notice: Форум обновлен
|
34
|
+
messageboard_group:
|
35
|
+
create: Создать группу форумов
|
36
|
+
form:
|
37
|
+
create_btn_submitting: :thredded.form.create_btn_submitting
|
38
|
+
saved: Группа форумов %{name} создана
|
39
|
+
moderation:
|
40
|
+
approve_btn: Одобрить
|
41
|
+
block_btn: Заблокировать
|
42
|
+
pending:
|
43
|
+
empty:
|
44
|
+
content: Все посты промодерированы.
|
45
|
+
title: Хорошая работа!
|
46
|
+
post_approved_html: Пост одобрен %{moderator} %{time_ago}.
|
47
|
+
post_blocked_html: Пост заблокирован %{moderator} %{time_ago}.
|
48
|
+
post_deleted_notice: Этот пост "удален".
|
49
|
+
posts_content_changed_since_moderation_html: <a href="%{post_url}">пост</a> был изменен с даты последней модерации.
|
50
|
+
Ниже - контент на момент модерации.
|
51
|
+
search_users:
|
52
|
+
form_label: Поиск пользователей
|
53
|
+
form_placeholder: :thredded.moderation.search_users.form_label
|
54
|
+
no_results_message: Не найдено пользователей %{query}
|
55
|
+
results_message: Пользователи, начинающиеся с ... %{query}
|
56
|
+
nav:
|
57
|
+
all_messageboards: Все форумы
|
58
|
+
edit_messageboard: Редактировать форум
|
59
|
+
edit_post: Редактировать пост
|
60
|
+
edit_private_topic: :thredded.nav.edit_topic
|
61
|
+
edit_topic: Редактировать
|
62
|
+
mark_all_read: Пометить все как прочитанное
|
63
|
+
moderation: Модерация
|
64
|
+
moderation_activity: Активность
|
65
|
+
moderation_history: История
|
66
|
+
moderation_pending: В ожидании
|
67
|
+
moderation_users: Пользователи
|
68
|
+
private_topics: Личное
|
69
|
+
settings: Уведомления
|
70
|
+
null_user_name: Пользователь удален
|
71
|
+
posts:
|
72
|
+
delete: Удалить пост
|
73
|
+
delete_confirm: Вы уверены что хотите удалить пост?
|
74
|
+
deleted_notice: Пост был удален.
|
75
|
+
edit: :thredded.nav.edit_post
|
76
|
+
form:
|
77
|
+
content_label: Контент
|
78
|
+
create_btn: Ответить
|
79
|
+
create_btn_submitting: Отправляется...
|
80
|
+
title_label: Добавить пост
|
81
|
+
update_btn: Обновить пост
|
82
|
+
update_btn_submitting: :thredded.form.update_btn_submitting
|
83
|
+
pending_moderation_notice: Ваш пост будет опубликован, когда будет одобрен модератором.
|
84
|
+
preferences:
|
85
|
+
edit:
|
86
|
+
page_title: :thredded.nav.settings
|
87
|
+
form:
|
88
|
+
auto_follow_topics:
|
89
|
+
hint: Автоматически следовать всем новым темам. Изменение этого параметра будет изменить его для всех
|
90
|
+
messageboards.
|
91
|
+
label: Соблюдайте все новые темы
|
92
|
+
follow_topics_on_mention:
|
93
|
+
hint: 'Когда кто-то упоминает вас на форуме (например: @sam), Вы будете наблюдать за этой темой.'
|
94
|
+
label: Наблюдать за темой, в которой Вы упомянуты
|
95
|
+
global_preferences_label: Настройки форума
|
96
|
+
messageboard_auto_follow_topics:
|
97
|
+
hint: Автоматически следовать все новые темы в этом ОБЪЯВЛЕНИЯ. Это отменяет соответствующую настройку
|
98
|
+
выше.
|
99
|
+
label: Соблюдайте все новые темы
|
100
|
+
messageboard_follow_topics_on_mention:
|
101
|
+
hint: 'Когда кто-то упоминает вас на форуме (например: @sam), Вы будете наблюдать за этой темой.'
|
102
|
+
label: :thredded.preferences.form.follow_topics_on_mention.label
|
103
|
+
messageboard_notifications_for_followed_topics:
|
104
|
+
label: :thredded.preferences.form.notifications_for_followed_topics.label
|
105
|
+
messageboard_preferences_label_html: Настройки уведомлений для <em>%{messageboard}</em>
|
106
|
+
notifications_for_followed_topics:
|
107
|
+
label: Уведомления для отслеживаемых тем
|
108
|
+
notifications_for_private_topics:
|
109
|
+
label: Уведомления для личных сообщений
|
110
|
+
submit_btn: Сохранить настройки
|
111
|
+
title: Настройки
|
112
|
+
update_btn_submitting: :thredded.form.update_btn_submitting
|
113
|
+
updated_notice: Ваши настройки были обновлены.
|
114
|
+
private_posts:
|
115
|
+
form:
|
116
|
+
content_label: Сообшение
|
117
|
+
create_btn: Послать сообщение
|
118
|
+
create_btn_submitting: Посылаю...
|
119
|
+
update_btn_submitting: :thredded.form.update_btn_submitting
|
120
|
+
private_topics:
|
121
|
+
edit: Редактировать
|
122
|
+
errors:
|
123
|
+
user_ids_length: Выберите хотя-бы одного пользователя.
|
124
|
+
form:
|
125
|
+
content_label: :thredded.private_posts.form.content_label
|
126
|
+
create_btn: :thredded.private_posts.form.create_btn
|
127
|
+
create_btn_submitting: :thredded.private_posts.form.create_btn_submitting
|
128
|
+
title_label: :thredded.topics.form.title_label
|
129
|
+
title_placeholder_new: Необходимо написать предмет переписки
|
130
|
+
title_placeholder_start: Начать новую переписку
|
131
|
+
update_btn: Обновить
|
132
|
+
update_btn_submitting: :thredded.private_posts.form.update_btn_submitting
|
133
|
+
users_label: Участники
|
134
|
+
users_placeholder: Выберите пользователей для участия в переписке
|
135
|
+
no_private_topics:
|
136
|
+
create_btn: Начать вашу первую приватную переписку
|
137
|
+
title: У вас нет личных сообщений.
|
138
|
+
updated_notice: Заголовок обновлен
|
139
|
+
recent_activity: Активность
|
140
|
+
search:
|
141
|
+
form:
|
142
|
+
btn_submit: :thredded.search.form.label
|
143
|
+
label: Поиск
|
144
|
+
placeholder: Поиск тем или записей
|
145
|
+
time_ago: "%{time} назад"
|
146
|
+
topics:
|
147
|
+
delete_confirm: Вы уверены что хотите удалить эту тему? Это безвозвратно.
|
148
|
+
delete_topic: Удалить тему
|
149
|
+
deleted_notice: Тема "удалена"
|
150
|
+
edit: Редактировать тему
|
151
|
+
follow: Наблюдать за темой
|
152
|
+
followed_by: Наблюдаю
|
153
|
+
followed_by_noone: Никто не наблюдает за этой темой
|
154
|
+
followed_notice: Вы следите за темой
|
155
|
+
following:
|
156
|
+
auto: Вы подписаны на эту тему, потому что автоматическое наблюдение включено.
|
157
|
+
manual: Вы следите за этой темой.
|
158
|
+
mentioned: Вы следите за этой темой, потому что упомянуты в ней.
|
159
|
+
posted: Вы следите за темой, потому что Вы писали в ней.
|
160
|
+
form:
|
161
|
+
categories_placeholder: Категории
|
162
|
+
content_label: :thredded.posts.form.content_label
|
163
|
+
create_btn: Создать новую тему
|
164
|
+
messageboard_label: Форум
|
165
|
+
title_label: Заголовок
|
166
|
+
title_placeholder: :thredded.topics.form.title_label
|
167
|
+
title_placeholder_start: Начать новую тему
|
168
|
+
update_btn: Обновление темы
|
169
|
+
locked:
|
170
|
+
label: Заблокировать тему
|
171
|
+
mark_as_unread: Пометить как непрочитанное
|
172
|
+
not_following: не отслеживаю
|
173
|
+
search:
|
174
|
+
no_results_message: Там нет никаких результатов для этой категории - %{query}
|
175
|
+
page_title: Темы Результаты поиска
|
176
|
+
results_message: Результаты поиска для %{query}
|
177
|
+
started_by_html: Начат %{user} %{time_ago}
|
178
|
+
sticky:
|
179
|
+
label: Закрепить
|
180
|
+
unfollow: Не следить за темой
|
181
|
+
unfollowed_notice: Вы не следите за темой
|
182
|
+
updated_notice: Тема обновлена
|
183
|
+
users:
|
184
|
+
currently_online: Онлайн
|
185
|
+
last_active_html: Последняя активность %{time_ago}
|
186
|
+
posted_in_topic_html: Сделан пост в %{topic_link}
|
187
|
+
posts_count:
|
188
|
+
one: Сделан пост
|
189
|
+
other: Сделано постов %{count} раз
|
190
|
+
recent_activity: :thredded.recent_activity
|
191
|
+
started_topic_html: Начато %{topic_link}
|
192
|
+
started_topics_count:
|
193
|
+
one: Начата тема
|
194
|
+
other: Начато %{count} тем
|
195
|
+
user_posted_in_topic_html: "%{user_link} сделал запись в %{topic_link}"
|
196
|
+
user_since_html: Пользователь был %{time_ago}
|
197
|
+
user_started_topic_html: "%{user_link} начал %{topic_link}"
|
@@ -45,14 +45,6 @@ class CreateThredded < ActiveRecord::Migration
|
|
45
45
|
t.index [:slug], name: :index_thredded_messageboards_on_slug
|
46
46
|
end
|
47
47
|
|
48
|
-
create_table :thredded_post_notifications do |t|
|
49
|
-
t.string :email, limit: 191, null: false
|
50
|
-
t.references :post, null: false
|
51
|
-
t.timestamps null: false
|
52
|
-
t.string :post_type, limit: 191
|
53
|
-
t.index [:post_id, :post_type], name: :index_thredded_post_notifications_on_post
|
54
|
-
end
|
55
|
-
|
56
48
|
create_table :thredded_posts do |t|
|
57
49
|
t.integer :user_id, limit: 4
|
58
50
|
t.text :content, limit: 65_535
|
@@ -161,6 +153,7 @@ class CreateThredded < ActiveRecord::Migration
|
|
161
153
|
create_table :thredded_user_preferences do |t|
|
162
154
|
t.references :user, null: false
|
163
155
|
t.boolean :follow_topics_on_mention, default: true, null: false
|
156
|
+
t.boolean :auto_follow_topics, default: false, null: false
|
164
157
|
t.timestamps null: false
|
165
158
|
t.index [:user_id], name: :index_thredded_user_preferences_on_user_id
|
166
159
|
end
|
@@ -169,6 +162,7 @@ class CreateThredded < ActiveRecord::Migration
|
|
169
162
|
t.references :user, null: false
|
170
163
|
t.references :messageboard, null: false
|
171
164
|
t.boolean :follow_topics_on_mention, default: true, null: false
|
165
|
+
t.boolean :auto_follow_topics, default: false, null: false
|
172
166
|
t.timestamps null: false
|
173
167
|
t.index [:user_id, :messageboard_id],
|
174
168
|
name: :thredded_user_messageboard_preferences_user_id_messageboard_id,
|
@@ -25,16 +25,17 @@ class UpgradeV08ToV09 < ActiveRecord::Migration
|
|
25
25
|
name: 'thredded_messageboard_notifications_for_followed_topics_unique', unique: true
|
26
26
|
end
|
27
27
|
|
28
|
-
Thredded::UserPreference.
|
28
|
+
Thredded::UserPreference.all.each do |pref|
|
29
29
|
pref.notifications_for_private_topics.create(notifier_key: 'email', enabled: pref.notify_on_message)
|
30
30
|
pref.notifications_for_followed_topics.create(notifier_key: 'email', enabled: pref.followed_topic_emails)
|
31
31
|
end
|
32
|
-
Thredded::UserMessageboardPreference.
|
32
|
+
Thredded::UserMessageboardPreference.pluck(:user_id, :messageboard_id, :followed_topic_emails)
|
33
|
+
.each do |user_id, messageboard_id, emails|
|
33
34
|
Thredded::MessageboardNotificationsForFollowedTopics.create(
|
34
|
-
user_id:
|
35
|
-
messageboard_id:
|
35
|
+
user_id: user_id,
|
36
|
+
messageboard_id: messageboard_id,
|
36
37
|
notifier_key: 'email',
|
37
|
-
enabled:
|
38
|
+
enabled: emails
|
38
39
|
)
|
39
40
|
end
|
40
41
|
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
class UpgradeThreddedV010ToV011 < ActiveRecord::Migration
|
3
|
+
def up
|
4
|
+
drop_table :thredded_post_notifications
|
5
|
+
add_column :thredded_user_preferences, :auto_follow_topics, :boolean, default: false, null: false
|
6
|
+
add_column :thredded_user_messageboard_preferences, :auto_follow_topics, :boolean, default: false, null: false
|
7
|
+
end
|
8
|
+
|
9
|
+
def down
|
10
|
+
remove_column :thredded_user_messageboard_preferences, :auto_follow_topics
|
11
|
+
remove_column :thredded_user_preferences, :auto_follow_topics
|
12
|
+
create_table :thredded_post_notifications do |t|
|
13
|
+
t.string :email, limit: 191, null: false
|
14
|
+
t.references :post, null: false
|
15
|
+
t.timestamps null: false
|
16
|
+
t.string :post_type, limit: 191
|
17
|
+
t.index [:post_id, :post_type], name: :index_thredded_post_notifications_on_post
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -68,11 +68,23 @@ Thredded.messageboards_order = :position
|
|
68
68
|
|
69
69
|
# Emails going out will prefix the "Subject:" with the following string
|
70
70
|
# Thredded.email_outgoing_prefix = '[My Forum] '
|
71
|
+
#
|
72
|
+
# The parent mailer for all Thredded mailers
|
73
|
+
# Thredded.parent_mailer = 'ActionMailer::Base'
|
71
74
|
|
72
75
|
# ==> View Configuration
|
73
76
|
# Set the layout for rendering the thredded views.
|
74
77
|
Thredded.layout = 'thredded/application'
|
75
78
|
|
79
|
+
# ==> URLs
|
80
|
+
# How Thredded generates URL slugs from text.
|
81
|
+
|
82
|
+
# Default:
|
83
|
+
# Thredded.slugifier = ->(input) { input.parameterize }
|
84
|
+
|
85
|
+
# If your forum is in a language other than English, you might want to use the babosa gem instead
|
86
|
+
# Thredded.slugifier = ->(input) { Babosa::Identifier.new(input).normalize.to_s }
|
87
|
+
|
76
88
|
# ==> Post Content Formatting
|
77
89
|
# Customize the way Thredded handles post formatting.
|
78
90
|
|
data/lib/thredded.rb
CHANGED
@@ -6,8 +6,6 @@ require 'db_text_search'
|
|
6
6
|
require 'friendly_id'
|
7
7
|
require 'html/pipeline'
|
8
8
|
require 'html/pipeline/sanitization_filter'
|
9
|
-
require 'html/pipeline/vimeo/vimeo_filter'
|
10
|
-
require 'html/pipeline/youtube/youtube_filter'
|
11
9
|
require 'rinku'
|
12
10
|
require 'kaminari'
|
13
11
|
require 'rb-gravatar'
|
@@ -16,9 +14,11 @@ require 'inline_svg'
|
|
16
14
|
|
17
15
|
# Require these explictly to make sure they are not reloaded.
|
18
16
|
# This allows for configuring them by accessing class methods in the initializer.
|
17
|
+
require 'thredded/formatting_demo_content'
|
19
18
|
require 'thredded/html_pipeline/at_mention_filter'
|
20
19
|
require 'thredded/html_pipeline/autolink_filter'
|
21
20
|
require 'thredded/html_pipeline/kramdown_filter'
|
21
|
+
require 'thredded/html_pipeline/onebox_filter'
|
22
22
|
require 'thredded/html_pipeline/wrap_iframes_filter'
|
23
23
|
|
24
24
|
# Asset compilation
|
@@ -36,8 +36,9 @@ require 'thredded/errors'
|
|
36
36
|
require 'thredded/view_hooks/config'
|
37
37
|
require 'thredded/view_hooks/renderer'
|
38
38
|
|
39
|
-
# Require
|
39
|
+
# Require these explicitly so that they do not need to be required if used in the initializer:
|
40
40
|
require 'thredded/content_formatter'
|
41
|
+
require 'thredded/email_transformer'
|
41
42
|
|
42
43
|
require 'thredded/collection_to_strings_with_cache_renderer'
|
43
44
|
|
@@ -77,6 +78,14 @@ module Thredded
|
|
77
78
|
# @return [Symbol] The name of the method used by Thredded to display users
|
78
79
|
mattr_accessor :user_display_name_method
|
79
80
|
|
81
|
+
# @return [String] The name of the parent mailer class for Thredded mailers.
|
82
|
+
mattr_accessor :parent_mailer
|
83
|
+
self.parent_mailer = 'ActionMailer::Base'
|
84
|
+
|
85
|
+
# @return [Proc] The proc that Thredded uses to generate URL slugs from text.
|
86
|
+
mattr_accessor :slugifier
|
87
|
+
self.slugifier = ->(input) { input.parameterize }
|
88
|
+
|
80
89
|
# @return [Boolean] Whether the user should get subscribed to a new topic they've created.
|
81
90
|
mattr_accessor :auto_follow_when_creating_topic
|
82
91
|
self.auto_follow_when_creating_topic = true
|
@@ -9,34 +9,19 @@ module Thredded
|
|
9
9
|
elements: HTML::Pipeline::SanitizationFilter::WHITELIST[:elements] + %w(iframe span figure figcaption),
|
10
10
|
transformers: HTML::Pipeline::SanitizationFilter::WHITELIST[:transformers] + [
|
11
11
|
lambda do |env|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
a_tag['
|
17
|
-
|
18
|
-
a_tag['target'] = '_blank'
|
19
|
-
a_tag['rel'] = 'nofollow noopener'
|
20
|
-
end
|
12
|
+
next unless env[:node_name] == 'a'
|
13
|
+
a_tag = env[:node]
|
14
|
+
a_tag['href'] ||= '#'
|
15
|
+
if a_tag['href'] =~ %r{^(?:[a-z]+:)?//}
|
16
|
+
a_tag['target'] = '_blank'
|
17
|
+
a_tag['rel'] = 'nofollow noopener'
|
21
18
|
end
|
22
19
|
end
|
23
20
|
],
|
24
|
-
attributes:
|
21
|
+
attributes: {
|
25
22
|
'a' => %w(href rel),
|
26
|
-
'iframe' => %w(src width height frameborder allowfullscreen sandbox seamless),
|
27
23
|
'span' => %w(class),
|
28
24
|
'div' => %w(class)
|
29
|
-
},
|
30
|
-
add_attributes: {
|
31
|
-
'iframe' => {
|
32
|
-
'seamless' => 'seamless',
|
33
|
-
'sandbox' => 'allow-same-origin allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox',
|
34
|
-
}
|
35
|
-
},
|
36
|
-
protocols: {
|
37
|
-
'iframe' => {
|
38
|
-
'src' => ['https', 'http', :relative]
|
39
|
-
}
|
40
25
|
}
|
41
26
|
)
|
42
27
|
|
@@ -44,8 +29,6 @@ module Thredded
|
|
44
29
|
# input: markup, output: markup.
|
45
30
|
mattr_accessor :before_markup_filters
|
46
31
|
self.before_markup_filters = [
|
47
|
-
HTML::Pipeline::VimeoFilter,
|
48
|
-
HTML::Pipeline::YoutubeFilter,
|
49
32
|
]
|
50
33
|
|
51
34
|
# Markup filters, such as BBCode, Markdown, Autolink, etc.
|
@@ -64,7 +47,6 @@ module Thredded
|
|
64
47
|
Thredded::HtmlPipeline::AutolinkFilter,
|
65
48
|
HTML::Pipeline::EmojiFilter,
|
66
49
|
Thredded::HtmlPipeline::AtMentionFilter,
|
67
|
-
Thredded::HtmlPipeline::WrapIframesFilter,
|
68
50
|
]
|
69
51
|
|
70
52
|
# Filters that sanitize the resulting HTML.
|
@@ -74,6 +56,14 @@ module Thredded
|
|
74
56
|
HTML::Pipeline::SanitizationFilter,
|
75
57
|
]
|
76
58
|
|
59
|
+
# Filters that run after sanitization
|
60
|
+
# input: sanitized html, output: html
|
61
|
+
mattr_accessor :after_sanitization_filters
|
62
|
+
self.after_sanitization_filters = [
|
63
|
+
Thredded::HtmlPipeline::OneboxFilter,
|
64
|
+
Thredded::HtmlPipeline::WrapIframesFilter,
|
65
|
+
]
|
66
|
+
|
77
67
|
# All the HTML::Pipeline filters, read-only.
|
78
68
|
def self.pipeline_filters
|
79
69
|
filters = [
|
@@ -81,6 +71,7 @@ module Thredded
|
|
81
71
|
*markup_filters,
|
82
72
|
*after_markup_filters,
|
83
73
|
*sanitization_filters,
|
74
|
+
*after_sanitization_filters
|
84
75
|
]
|
85
76
|
# Changing the result in-place has no effect on the ContentFormatter output,
|
86
77
|
# and is most likely the result of a programmer error.
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'thredded/email_transformer/onebox'
|
3
|
+
|
4
|
+
module Thredded
|
5
|
+
# This transformer should applied to emails so that they render correctly in the email clients.
|
6
|
+
#
|
7
|
+
# For example, if you use roadie, you can configure it to use the transformer in the initializer:
|
8
|
+
#
|
9
|
+
# # config/initializers/roadie.rb
|
10
|
+
# Rails.application.config.roadie.before_transformation = Thredded::EmailTransformer
|
11
|
+
#
|
12
|
+
module EmailTransformer
|
13
|
+
mattr_accessor :transformers
|
14
|
+
self.transformers = [Onebox]
|
15
|
+
|
16
|
+
# @param doc [Nokogiri::HTML::Document]
|
17
|
+
def self.call(doc)
|
18
|
+
transformers.each { |transformer| transformer.call(doc) }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Thredded
|
4
|
+
module EmailTransformer
|
5
|
+
# A helper module with common functions for constructing Nokogiri elements.
|
6
|
+
module Helpers
|
7
|
+
# Creates a `<p>` node with the given child
|
8
|
+
def paragraph(child)
|
9
|
+
Nokogiri::XML::Node.new('p', doc).tap do |p|
|
10
|
+
p.add_child child
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Creates an `<a>` node with the given attributes and content
|
15
|
+
def anchor(href, target: '_blank', content: href)
|
16
|
+
Nokogiri::XML::Node.new('a', doc).tap do |a|
|
17
|
+
a['href'] = href
|
18
|
+
a['target'] = target
|
19
|
+
a.content = content
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Base
|
25
|
+
include Helpers
|
26
|
+
|
27
|
+
# @return [Nokogiri::HTML::Document]
|
28
|
+
attr_reader :doc
|
29
|
+
|
30
|
+
# @param doc [Nokogiri::HTML::Document]
|
31
|
+
def initialize(doc)
|
32
|
+
@doc = doc
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.inherited(base)
|
36
|
+
base.extend ClassMethods
|
37
|
+
end
|
38
|
+
|
39
|
+
module ClassMethods
|
40
|
+
# @param doc [Nokogiri::HTML::Document]
|
41
|
+
def call(doc)
|
42
|
+
new(doc).call
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|