publify_core 9.1.0 → 9.2.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.
Files changed (357) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +34 -1
  3. data/app/assets/javascripts/bootstrap-sprockets.js +8 -0
  4. data/app/assets/javascripts/bootstrap/affix.js +164 -0
  5. data/app/assets/javascripts/bootstrap/alert.js +95 -0
  6. data/app/assets/javascripts/bootstrap/button.js +125 -0
  7. data/app/assets/javascripts/bootstrap/collapse.js +212 -0
  8. data/app/assets/javascripts/bootstrap/dropdown.js +165 -0
  9. data/app/assets/javascripts/bootstrap/modal.js +358 -0
  10. data/app/assets/javascripts/bootstrap/tab.js +155 -0
  11. data/app/assets/javascripts/bootstrap/transition.js +59 -0
  12. data/app/assets/javascripts/lightbox.js +4 -4
  13. data/app/assets/javascripts/publify_admin.js +1 -35
  14. data/app/assets/stylesheets/_bootstrap-compass.scss +9 -0
  15. data/app/assets/stylesheets/_bootstrap-mincer.scss +19 -0
  16. data/app/assets/stylesheets/_bootstrap-sprockets.scss +9 -0
  17. data/app/assets/stylesheets/_bootstrap.scss +42 -0
  18. data/app/assets/stylesheets/administration_structure.css.scss +1 -45
  19. data/app/assets/stylesheets/bootstrap/_alerts.scss +73 -0
  20. data/app/assets/stylesheets/bootstrap/_button-groups.scss +242 -0
  21. data/app/assets/stylesheets/bootstrap/_buttons.scss +168 -0
  22. data/app/assets/stylesheets/bootstrap/_close.scss +37 -0
  23. data/app/assets/stylesheets/bootstrap/_code.scss +69 -0
  24. data/app/assets/stylesheets/bootstrap/_component-animations.scss +38 -0
  25. data/app/assets/stylesheets/bootstrap/_dropdowns.scss +213 -0
  26. data/app/assets/stylesheets/bootstrap/_forms.scss +586 -0
  27. data/app/assets/stylesheets/bootstrap/_grid.scss +94 -0
  28. data/app/assets/stylesheets/bootstrap/_labels.scss +66 -0
  29. data/app/assets/stylesheets/bootstrap/_media.scss +66 -0
  30. data/app/assets/stylesheets/bootstrap/_mixins.scss +37 -0
  31. data/app/assets/stylesheets/bootstrap/_modals.scss +150 -0
  32. data/app/assets/stylesheets/bootstrap/_navbar.scss +479 -0
  33. data/app/assets/stylesheets/bootstrap/_navs.scss +242 -0
  34. data/app/assets/stylesheets/bootstrap/_normalize.scss +427 -0
  35. data/app/assets/stylesheets/bootstrap/_pagination.scss +86 -0
  36. data/app/assets/stylesheets/bootstrap/_panels.scss +222 -0
  37. data/app/assets/stylesheets/bootstrap/_print.scss +99 -0
  38. data/app/assets/stylesheets/bootstrap/_scaffolding.scss +160 -0
  39. data/app/assets/stylesheets/bootstrap/_tables.scss +234 -0
  40. data/app/assets/stylesheets/bootstrap/_theme.scss +224 -0
  41. data/app/assets/stylesheets/bootstrap/_type.scss +296 -0
  42. data/app/assets/stylesheets/bootstrap/_utilities.scss +55 -0
  43. data/app/assets/stylesheets/bootstrap/_variables.scss +638 -0
  44. data/app/assets/stylesheets/bootstrap/_wells.scss +29 -0
  45. data/app/assets/stylesheets/bootstrap/mixins/_alerts.scss +15 -0
  46. data/app/assets/stylesheets/bootstrap/mixins/_background-variant.scss +12 -0
  47. data/app/assets/stylesheets/bootstrap/mixins/_border-radius.scss +18 -0
  48. data/app/assets/stylesheets/bootstrap/mixins/_buttons.scss +56 -0
  49. data/app/assets/stylesheets/bootstrap/mixins/_center-block.scss +7 -0
  50. data/app/assets/stylesheets/bootstrap/mixins/_clearfix.scss +22 -0
  51. data/app/assets/stylesheets/bootstrap/mixins/_forms.scss +82 -0
  52. data/app/assets/stylesheets/bootstrap/mixins/_gradients.scss +56 -0
  53. data/app/assets/stylesheets/bootstrap/mixins/_grid-framework.scss +81 -0
  54. data/app/assets/stylesheets/bootstrap/mixins/_grid.scss +122 -0
  55. data/app/assets/stylesheets/bootstrap/mixins/_hide-text.scss +21 -0
  56. data/app/assets/stylesheets/bootstrap/mixins/_image.scss +28 -0
  57. data/app/assets/stylesheets/bootstrap/mixins/_labels.scss +12 -0
  58. data/app/assets/stylesheets/bootstrap/mixins/_nav-divider.scss +10 -0
  59. data/app/assets/stylesheets/bootstrap/mixins/_nav-vertical-align.scss +9 -0
  60. data/app/assets/stylesheets/bootstrap/mixins/_opacity.scss +7 -0
  61. data/app/assets/stylesheets/bootstrap/mixins/_pagination.scss +24 -0
  62. data/app/assets/stylesheets/bootstrap/mixins/_panels.scss +20 -0
  63. data/app/assets/stylesheets/bootstrap/mixins/_reset-filter.scss +8 -0
  64. data/app/assets/stylesheets/bootstrap/mixins/_resize.scss +6 -0
  65. data/app/assets/stylesheets/bootstrap/mixins/_responsive-visibility.scss +17 -0
  66. data/app/assets/stylesheets/bootstrap/mixins/_size.scss +10 -0
  67. data/app/assets/stylesheets/bootstrap/mixins/_tab-focus.scss +9 -0
  68. data/app/assets/stylesheets/bootstrap/mixins/_table-row.scss +28 -0
  69. data/app/assets/stylesheets/bootstrap/mixins/_text-emphasis.scss +12 -0
  70. data/app/assets/stylesheets/bootstrap/mixins/_text-overflow.scss +8 -0
  71. data/app/assets/stylesheets/bootstrap/mixins/_vendor-prefixes.scss +222 -0
  72. data/app/assets/stylesheets/lightbox.css +3 -3
  73. data/app/assets/stylesheets/publify_admin.css.scss +0 -1
  74. data/app/controllers/accounts_controller.rb +2 -0
  75. data/app/controllers/admin/base_controller.rb +8 -5
  76. data/app/controllers/admin/content_controller.rb +37 -24
  77. data/app/controllers/admin/dashboard_controller.rb +16 -64
  78. data/app/controllers/admin/feedback_controller.rb +45 -38
  79. data/app/controllers/admin/notes_controller.rb +15 -9
  80. data/app/controllers/admin/pages_controller.rb +18 -15
  81. data/app/controllers/admin/post_types_controller.rb +7 -5
  82. data/app/controllers/admin/profiles_controller.rb +4 -2
  83. data/app/controllers/admin/redirects_controller.rb +9 -5
  84. data/app/controllers/admin/resources_controller.rb +7 -4
  85. data/app/controllers/admin/seo_controller.rb +14 -10
  86. data/app/controllers/admin/settings_controller.rb +7 -5
  87. data/app/controllers/admin/sidebar_controller.rb +7 -4
  88. data/app/controllers/admin/tags_controller.rb +6 -3
  89. data/app/controllers/admin/themes_controller.rb +10 -7
  90. data/app/controllers/admin/users_controller.rb +9 -6
  91. data/app/controllers/articles_controller.rb +49 -33
  92. data/app/controllers/authors_controller.rb +6 -3
  93. data/app/controllers/base_controller.rb +9 -5
  94. data/app/controllers/comments_controller.rb +12 -8
  95. data/app/controllers/content_controller.rb +4 -2
  96. data/app/controllers/feedback_controller.rb +4 -2
  97. data/app/controllers/notes_controller.rb +5 -3
  98. data/app/controllers/setup_controller.rb +14 -10
  99. data/app/controllers/tags_controller.rb +6 -4
  100. data/app/controllers/text_controller.rb +2 -4
  101. data/app/controllers/textfilter_controller.rb +2 -0
  102. data/app/controllers/theme_controller.rb +14 -12
  103. data/app/controllers/xml_controller.rb +2 -0
  104. data/app/helpers/admin/base_helper.rb +28 -28
  105. data/app/helpers/admin/feedback_helper.rb +34 -24
  106. data/app/helpers/articles_helper.rb +4 -2
  107. data/app/helpers/authors_helper.rb +6 -3
  108. data/app/helpers/base_helper.rb +50 -34
  109. data/app/helpers/blog_helper.rb +4 -2
  110. data/app/helpers/xml_helper.rb +2 -0
  111. data/app/jobs/application_job.rb +2 -0
  112. data/app/mailers/notification_mailer.rb +5 -3
  113. data/app/models/ability.rb +25 -23
  114. data/app/models/archives_sidebar.rb +14 -11
  115. data/app/models/article.rb +44 -32
  116. data/app/models/article/factory.rb +14 -6
  117. data/app/models/blog.rb +85 -65
  118. data/app/models/comment.rb +10 -7
  119. data/app/models/config_manager.rb +4 -2
  120. data/app/models/content.rb +34 -40
  121. data/app/models/content_base.rb +9 -3
  122. data/app/models/feedback.rb +19 -16
  123. data/app/models/meta_sidebar.rb +5 -2
  124. data/app/models/note.rb +25 -23
  125. data/app/models/page.rb +8 -6
  126. data/app/models/page_sidebar.rb +4 -2
  127. data/app/models/ping.rb +2 -0
  128. data/app/models/post_type.rb +3 -1
  129. data/app/models/redirect.rb +11 -6
  130. data/app/models/redirection.rb +2 -0
  131. data/app/models/resource.rb +4 -2
  132. data/app/models/search_sidebar.rb +4 -2
  133. data/app/models/sidebar.rb +10 -5
  134. data/app/models/static_sidebar.rb +15 -12
  135. data/app/models/tag.rb +14 -10
  136. data/app/models/tag_sidebar.rb +6 -3
  137. data/app/models/text_filter.rb +85 -11
  138. data/app/models/trackback.rb +7 -11
  139. data/app/models/trigger.rb +6 -3
  140. data/app/models/user.rb +43 -42
  141. data/app/services/title_builder.rb +56 -45
  142. data/app/uploaders/resource_uploader.rb +7 -3
  143. data/app/views/accounts/confirm.html.erb +3 -3
  144. data/app/views/admin/content/_article_list.html.erb +23 -8
  145. data/app/views/admin/content/_form.html.erb +71 -47
  146. data/app/views/admin/content/edit.html.erb +1 -1
  147. data/app/views/admin/content/index.html.erb +25 -15
  148. data/app/views/admin/content/new.html.erb +2 -2
  149. data/app/views/admin/dashboard/_comment.html.erb +5 -5
  150. data/app/views/admin/dashboard/_comments.html.erb +2 -2
  151. data/app/views/admin/dashboard/_drafts.html.erb +5 -5
  152. data/app/views/admin/dashboard/_overview.html.erb +7 -9
  153. data/app/views/admin/dashboard/_welcome.html.erb +11 -11
  154. data/app/views/admin/dashboard/index.html.erb +12 -7
  155. data/app/views/admin/feedback/_button.html.erb +6 -6
  156. data/app/views/admin/feedback/_feedback.html.erb +3 -3
  157. data/app/views/admin/feedback/_ham.html.erb +27 -9
  158. data/app/views/admin/feedback/_spam.html.erb +26 -16
  159. data/app/views/admin/feedback/article.html.erb +20 -21
  160. data/app/views/admin/feedback/edit.html.erb +14 -15
  161. data/app/views/admin/feedback/{ham.js → ham.js.erb} +0 -0
  162. data/app/views/admin/feedback/index.html.erb +25 -23
  163. data/app/views/admin/feedback/{spam.js → spam.js.erb} +0 -0
  164. data/app/views/admin/migrations/show.html.erb +10 -11
  165. data/app/views/admin/notes/_form.html.erb +13 -13
  166. data/app/views/admin/notes/_list.html.erb +19 -8
  167. data/app/views/admin/notes/_note.html.erb +12 -7
  168. data/app/views/admin/notes/edit.html.erb +6 -1
  169. data/app/views/admin/notes/index.html.erb +5 -1
  170. data/app/views/admin/notes/show.html.erb +2 -2
  171. data/app/views/admin/pages/_form.html.erb +86 -77
  172. data/app/views/admin/pages/_pages.html.erb +11 -4
  173. data/app/views/admin/pages/edit.html.erb +3 -1
  174. data/app/views/admin/pages/index.html.erb +10 -6
  175. data/app/views/admin/pages/new.html.erb +3 -1
  176. data/app/views/admin/post_types/_index_and_form.html.erb +15 -16
  177. data/app/views/admin/post_types/edit.html.erb +1 -1
  178. data/app/views/admin/post_types/index.html.erb +1 -1
  179. data/app/views/admin/profiles/index.html.erb +2 -3
  180. data/app/views/admin/redirects/_index_and_form.html.erb +10 -11
  181. data/app/views/admin/redirects/edit.html.erb +1 -1
  182. data/app/views/admin/redirects/index.html.erb +1 -1
  183. data/app/views/admin/resources/index.html.erb +19 -16
  184. data/app/views/admin/seo/_general.html.erb +23 -47
  185. data/app/views/admin/seo/_permalinks.html.erb +14 -14
  186. data/app/views/admin/seo/_titles.html.erb +63 -64
  187. data/app/views/admin/seo/show.html.erb +14 -19
  188. data/app/views/admin/settings/display.html.erb +22 -25
  189. data/app/views/admin/settings/feedback.html.erb +31 -32
  190. data/app/views/admin/settings/index.html.erb +23 -24
  191. data/app/views/admin/settings/write.html.erb +21 -22
  192. data/app/views/admin/shared/_edit.html.erb +3 -3
  193. data/app/views/admin/shared/_menu.html.erb +26 -26
  194. data/app/views/admin/shared/_twitter_alert.html.erb +1 -1
  195. data/app/views/admin/sidebar/_config.html.erb +5 -5
  196. data/app/views/admin/sidebar/_target_sidebar.html.erb +4 -4
  197. data/app/views/admin/sidebar/index.html.erb +7 -7
  198. data/app/views/admin/tags/_index_and_form.html.erb +11 -12
  199. data/app/views/admin/tags/edit.html.erb +1 -1
  200. data/app/views/admin/tags/index.html.erb +1 -1
  201. data/app/views/admin/themes/index.html.erb +5 -6
  202. data/app/views/admin/users/_form.html.erb +34 -34
  203. data/app/views/admin/users/edit.html.erb +2 -2
  204. data/app/views/admin/users/index.html.erb +10 -12
  205. data/app/views/admin/users/new.html.erb +2 -2
  206. data/app/views/archives_sidebar/_content.html.erb +2 -2
  207. data/app/views/articles/_archives_article.html.erb +3 -3
  208. data/app/views/articles/_article.html.erb +7 -9
  209. data/app/views/articles/_article_author.html.erb +4 -0
  210. data/app/views/articles/_article_content.html.erb +2 -2
  211. data/app/views/articles/_article_excerpt.html.erb +2 -2
  212. data/app/views/articles/_article_links.html.erb +1 -1
  213. data/app/views/articles/_comment_errors.html.erb +1 -1
  214. data/app/views/articles/_comment_form.html.erb +12 -12
  215. data/app/views/articles/_comment_preview.html.erb +3 -3
  216. data/app/views/articles/_password_form.html.erb +4 -4
  217. data/app/views/articles/_trackback.html.erb +2 -2
  218. data/app/views/articles/archives.html.erb +1 -1
  219. data/app/views/articles/feedback_atom_feed.atom.builder +3 -1
  220. data/app/views/articles/feedback_rss_feed.rss.builder +9 -7
  221. data/app/views/articles/index_atom_feed.atom.builder +5 -3
  222. data/app/views/articles/index_rss_feed.rss.builder +10 -8
  223. data/app/views/articles/live_search.html.erb +3 -3
  224. data/app/views/articles/read.html.erb +16 -8
  225. data/app/views/articles/search.html.erb +2 -2
  226. data/app/views/articles/trackback.xml.builder +3 -1
  227. data/app/views/articles/view_page.html.erb +1 -1
  228. data/app/views/authors/show.html.erb +9 -9
  229. data/app/views/authors/show_atom_feed.atom.builder +4 -2
  230. data/app/views/authors/show_rss_feed.rss.builder +10 -8
  231. data/app/views/comments/_comment.html.erb +3 -3
  232. data/app/views/devise/mailer/reset_password_instructions.html.erb +7 -9
  233. data/app/views/devise/passwords/edit.html.erb +4 -4
  234. data/app/views/devise/passwords/new.html.erb +1 -1
  235. data/app/views/devise/registrations/new.html.erb +5 -5
  236. data/app/views/devise/sessions/new.html.erb +3 -3
  237. data/app/views/errors/404.html.erb +2 -2
  238. data/app/views/feedback/index.atom.builder +3 -1
  239. data/app/views/feedback/index.rss.builder +9 -7
  240. data/app/views/layouts/accounts.html.erb +26 -26
  241. data/app/views/layouts/administration.html.erb +31 -31
  242. data/app/views/layouts/default.html.erb +3 -3
  243. data/app/views/layouts/editor.html.erb +5 -19
  244. data/app/views/meta_sidebar/_content.html.erb +2 -2
  245. data/app/views/notes/_note.html.erb +1 -1
  246. data/app/views/notes/index.html.erb +1 -1
  247. data/app/views/notes/show_in_reply.html.erb +1 -1
  248. data/app/views/notification_mailer/_mail_footer.html.erb +3 -3
  249. data/app/views/notification_mailer/article.html.erb +2 -2
  250. data/app/views/notification_mailer/comment.html.erb +5 -5
  251. data/app/views/notification_mailer/notif_user.html.erb +1 -1
  252. data/app/views/page_sidebar/_content.html.erb +1 -1
  253. data/app/views/search_sidebar/_content.html.erb +2 -2
  254. data/app/views/settings/install.html.erb +2 -2
  255. data/app/views/setup/index.html.erb +7 -7
  256. data/app/views/shared/_atom_header.atom.builder +4 -2
  257. data/app/views/shared/_atom_item_article.atom.builder +11 -6
  258. data/app/views/shared/_atom_item_comment.atom.builder +4 -2
  259. data/app/views/shared/_atom_item_trackback.atom.builder +4 -2
  260. data/app/views/shared/_page_header.html.erb +9 -12
  261. data/app/views/shared/_rss_item_article.rss.builder +6 -3
  262. data/app/views/shared/_rss_item_comment.rss.builder +3 -1
  263. data/app/views/shared/_rss_item_trackback.rss.builder +3 -1
  264. data/app/views/sidebar/display_plugins.html.erb +1 -1
  265. data/app/views/tag_sidebar/_content.html.erb +1 -1
  266. data/app/views/tags/index.html.erb +1 -1
  267. data/app/views/xml/_googlesitemap_item_article.googlesitemap.builder +2 -0
  268. data/app/views/xml/_googlesitemap_item_category.googlesitemap.builder +2 -0
  269. data/app/views/xml/_googlesitemap_item_page.googlesitemap.builder +2 -0
  270. data/app/views/xml/_googlesitemap_item_tag.googlesitemap.builder +2 -0
  271. data/app/views/xml/sitemap.googlesitemap.builder +4 -2
  272. data/config/i18n-tasks.yml +0 -5
  273. data/config/initializers/devise.rb +10 -4
  274. data/config/initializers/mime_types.rb +3 -1
  275. data/config/locales/da.yml +134 -71
  276. data/config/locales/de.yml +142 -75
  277. data/config/locales/en.yml +128 -66
  278. data/config/locales/es-MX.yml +135 -69
  279. data/config/locales/fr.yml +167 -86
  280. data/config/locales/he.yml +128 -70
  281. data/config/locales/it.yml +136 -72
  282. data/config/locales/ja.yml +110 -64
  283. data/config/locales/lt.yml +153 -74
  284. data/config/locales/nb-NO.yml +123 -65
  285. data/config/locales/nl.yml +140 -75
  286. data/config/locales/pl.yml +160 -69
  287. data/config/locales/pt-BR.yml +137 -70
  288. data/config/locales/ro.yml +148 -70
  289. data/config/locales/ru.yml +161 -69
  290. data/config/locales/zh-CN.yml +106 -59
  291. data/config/locales/zh-TW.yml +109 -61
  292. data/config/routes.rb +68 -63
  293. data/db/migrate/113_initial_schema.rb +192 -190
  294. data/db/migrate/114_fixes_buggy_articles_and_notes.rb +9 -6
  295. data/db/migrate/115_drops_categories_for_tags.rb +3 -1
  296. data/db/migrate/20150207131657_add_missing_indexes.rb +2 -0
  297. data/db/migrate/20150807134129_simplify_redirect_relations.rb +8 -1
  298. data/db/migrate/20150808052637_add_blog_ids.rb +4 -2
  299. data/db/migrate/20150808191127_add_blog_id_to_redirects.rb +2 -0
  300. data/db/migrate/20150810094754_add_blog_id_to_tags.rb +2 -0
  301. data/db/migrate/20160108111120_add_devise_to_users.rb +4 -2
  302. data/db/migrate/20160108184201_move_last_connection_to_last_sign_in_at.rb +2 -0
  303. data/db/migrate/20160110094906_remove_profiles_rights.rb +2 -0
  304. data/db/migrate/20160605103918_replace_profile_id_with_string.rb +2 -0
  305. data/db/migrate/20160605154632_remove_profiles.rb +10 -5
  306. data/db/migrate/20160701061851_demand_blog_id_on_contents.rb +2 -0
  307. data/db/migrate/20160701062604_add_blog_id_to_resources.rb +2 -0
  308. data/db/migrate/20170528093024_move_resources_to_content.rb +2 -0
  309. data/db/migrate/20170528094923_move_tags_to_content.rb +2 -0
  310. data/db/migrate/20170528201606_remove_separate_published_flag.rb +2 -0
  311. data/db/migrate/20170605071626_remove_extra_state_columns_from_feedback.rb +2 -0
  312. data/db/migrate/20170702105201_remove_published_at_from_feedback.rb +2 -0
  313. data/db/migrate/20190208151235_add_text_filter_name_fields.rb +9 -0
  314. data/db/migrate/20190208152646_move_text_filter_to_name.rb +97 -0
  315. data/db/migrate/20190209155717_remove_text_filter_ids.rb +19 -0
  316. data/db/migrate/20190209160610_remove_text_filters.rb +17 -0
  317. data/db/migrate/20200413140440_add_unique_indexes.rb +10 -0
  318. data/db/seeds.rb +9 -19
  319. data/lib/email_notify.rb +3 -1
  320. data/lib/format.rb +4 -2
  321. data/lib/publify_core.rb +36 -35
  322. data/lib/publify_core/engine.rb +8 -6
  323. data/lib/publify_core/lang.rb +5 -1
  324. data/lib/publify_core/testing_support/dns_mock.rb +15 -0
  325. data/lib/publify_core/testing_support/factories.rb +240 -0
  326. data/lib/publify_core/testing_support/feed_assertions.rb +48 -0
  327. data/lib/publify_core/testing_support/fixtures/exploit.svg +4 -0
  328. data/lib/publify_core/testing_support/fixtures/fakepng.png +1 -0
  329. data/lib/publify_core/testing_support/fixtures/otherfile.txt +1 -0
  330. data/lib/publify_core/testing_support/fixtures/testfile.png +0 -0
  331. data/lib/publify_core/testing_support/fixtures/testfile.txt +1 -0
  332. data/lib/publify_core/testing_support/upload_fixtures.rb +15 -0
  333. data/lib/publify_core/version.rb +3 -1
  334. data/lib/publify_guid.rb +3 -1
  335. data/lib/publify_plugins.rb +10 -5
  336. data/lib/publify_textfilter_markdown.rb +38 -25
  337. data/lib/publify_textfilter_none.rb +5 -3
  338. data/lib/publify_textfilter_smartypants.rb +5 -3
  339. data/lib/publify_textfilter_textile.rb +7 -4
  340. data/lib/publify_textfilter_twitterfilter.rb +13 -7
  341. data/lib/publify_time.rb +4 -0
  342. data/lib/sidebar_field.rb +15 -13
  343. data/lib/sidebar_registry.rb +5 -3
  344. data/lib/spam_protection.rb +16 -13
  345. data/lib/tasks/i18n.rake +9 -0
  346. data/lib/tasks/manifest.rake +30 -0
  347. data/lib/tasks/publify_core_tasks.rake +2 -0
  348. data/lib/text_filter_plugin.rb +27 -25
  349. data/lib/theme.rb +5 -3
  350. data/lib/transforms.rb +22 -19
  351. metadata +217 -87
  352. data/app/assets/javascripts/widearea.js +0 -486
  353. data/app/assets/stylesheets/widearea.css +0 -133
  354. data/app/controllers/admin/textfilters_controller.rb +0 -6
  355. data/app/views/admin/dashboard/_inbound.html.erb +0 -31
  356. data/app/views/admin/notes/_header.html.erb +0 -6
  357. data/app/views/articles/_protected_article_content.html.erb +0 -6
@@ -1,12 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module BlogHelper
2
4
  # The base URL for this request, calculated by looking up the URL for the main
3
5
  # blog index page.
4
6
  def blog_base_url
5
- url_for(controller: '/articles', action: 'index').gsub(%r{/$}, '')
7
+ url_for(controller: "/articles", action: "index").gsub(%r{/$}, "")
6
8
  end
7
9
 
8
10
  # Find the blog whose base_url matches the current location.
9
11
  def this_blog
10
- @blog ||= Blog.find_blog(blog_base_url)
12
+ @this_blog ||= Blog.find_blog(blog_base_url)
11
13
  end
12
14
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module XmlHelper
2
4
  def collection_lastmod(collection)
3
5
  article_updated = collection.contents.order(updated_at: :desc).first
@@ -1,2 +1,4 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ApplicationJob < ActiveJob::Base
2
4
  end
@@ -1,4 +1,6 @@
1
- class NotificationMailer < ActionMailer::Base
1
+ # frozen_string_literal: true
2
+
3
+ class NotificationMailer < ApplicationMailer
2
4
  helper :base
3
5
  layout nil
4
6
 
@@ -20,7 +22,7 @@ class NotificationMailer < ActionMailer::Base
20
22
  @user = user
21
23
  # TODO: Make user blog-dependent
22
24
  @blog = Blog.first
23
- build_mail @blog, @user, 'Welcome to Publify'
25
+ build_mail @blog, @user, "Welcome to Publify"
24
26
  end
25
27
 
26
28
  private
@@ -30,7 +32,7 @@ class NotificationMailer < ActionMailer::Base
30
32
  end
31
33
 
32
34
  def build_mail(blog, user, subject)
33
- headers['X-Mailer'] = "Publify #{PublifyCore::VERSION}"
35
+ headers["X-Mailer"] = "Publify #{PublifyCore::VERSION}"
34
36
  mail(from: blog.email_from,
35
37
  to: user.email,
36
38
  subject: make_subject(blog, subject))
@@ -1,4 +1,6 @@
1
- require 'cancancan'
1
+ # frozen_string_literal: true
2
+
3
+ require "cancancan"
2
4
 
3
5
  class Ability
4
6
  include CanCan::Ability
@@ -7,14 +9,14 @@ class Ability
7
9
  return unless user
8
10
 
9
11
  case user.profile
10
- when 'admin'
12
+ when "admin"
11
13
  add_admin_abilities
12
14
  add_publisher_abilities
13
15
  add_contributor_abilities
14
- when 'publisher'
16
+ when "publisher"
15
17
  add_publisher_abilities
16
18
  add_contributor_abilities
17
- when 'contributor'
19
+ when "contributor"
18
20
  add_contributor_abilities
19
21
  end
20
22
  end
@@ -22,30 +24,30 @@ class Ability
22
24
  private
23
25
 
24
26
  def add_admin_abilities
25
- can :manage, 'admin/migrations'
26
- can :manage, 'admin/seo'
27
- can :manage, 'admin/settings'
28
- can :manage, 'admin/sidebar'
29
- can :manage, 'admin/textfilters'
30
- can :manage, 'admin/themes'
31
- can :manage, 'admin/users'
27
+ can :manage, "admin/migrations"
28
+ can :manage, "admin/seo"
29
+ can :manage, "admin/settings"
30
+ can :manage, "admin/sidebar"
31
+ can :manage, "admin/textfilters"
32
+ can :manage, "admin/themes"
33
+ can :manage, "admin/users"
32
34
  end
33
35
 
34
36
  def add_publisher_abilities
35
- can :manage, 'admin/content'
36
- can :manage, 'admin/feedback'
37
- can :manage, 'admin/notes'
38
- can :manage, 'admin/pages'
39
- can :manage, 'admin/post_types'
40
- can :manage, 'admin/redirects'
41
- can :manage, 'admin/resources'
42
- can :manage, 'admin/tags'
43
-
44
- can :manage, 'articles'
37
+ can :manage, "admin/content"
38
+ can :manage, "admin/feedback"
39
+ can :manage, "admin/notes"
40
+ can :manage, "admin/pages"
41
+ can :manage, "admin/post_types"
42
+ can :manage, "admin/redirects"
43
+ can :manage, "admin/resources"
44
+ can :manage, "admin/tags"
45
+
46
+ can :manage, "articles"
45
47
  end
46
48
 
47
49
  def add_contributor_abilities
48
- can :manage, 'admin/dashboard'
49
- can :manage, 'admin/profiles'
50
+ can :manage, "admin/dashboard"
51
+ can :manage, "admin/profiles"
50
52
  end
51
53
  end
@@ -1,17 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ArchivesSidebar < Sidebar
2
- description 'Displays links to monthly archives'
3
- setting :title, 'Archives'
4
- setting :show_count, true, label: 'Show article counts', input_type: :checkbox
5
- setting :count, 10, label: 'Number of Months'
4
+ description "Displays links to monthly archives"
5
+ setting :title, "Archives"
6
+ setting :show_count, true, label: "Show article counts", input_type: :checkbox
7
+ setting :count, 10, label: "Number of Months"
6
8
 
7
9
  attr_accessor :archives
8
10
 
9
11
  def self.date_funcs
10
- @date_func ||=
11
- if Content.connection.class.name =~ /SQLite3Adapter/
12
+ @date_funcs ||=
13
+ if /SQLite3Adapter/.match?(Content.connection.class.name)
12
14
  ["strftime('%Y', published_at) as year", "strftime('%m', published_at) as month"]
13
15
  else
14
- ['extract(year from published_at) as year', 'extract(month from published_at) as month']
16
+ ["extract(year from published_at) as year",
17
+ "extract(month from published_at) as month"]
15
18
  end
16
19
  end
17
20
 
@@ -23,17 +26,17 @@ class ArchivesSidebar < Sidebar
23
26
  # DB-specific code.
24
27
  date_funcs = self.class.date_funcs
25
28
 
26
- article_counts = Article.published.select('count(*) as count', *date_funcs).
27
- group(:year, :month).reorder('year desc', 'month desc').limit(count.to_i)
29
+ article_counts = Article.published.select("count(*) as count", *date_funcs).
30
+ group(:year, :month).reorder("year desc", "month desc").limit(count.to_i)
28
31
 
29
32
  @archives = article_counts.map do |entry|
30
33
  month = entry.month.to_i
31
34
  year = entry.year.to_i
32
35
  {
33
- name: I18n.l(Date.new(year, month), format: '%B %Y'),
36
+ name: I18n.l(Date.new(year, month), format: "%B %Y"),
34
37
  month: month,
35
38
  year: year,
36
- article_count: entry.count
39
+ article_count: entry.count,
37
40
  }
38
41
  end
39
42
  end
@@ -1,6 +1,8 @@
1
- require 'aasm'
2
- require 'uri'
3
- require 'net/http'
1
+ # frozen_string_literal: true
2
+
3
+ require "aasm"
4
+ require "uri"
5
+ require "net/http"
4
6
 
5
7
  class Article < Content
6
8
  include PublifyGuid
@@ -19,26 +21,26 @@ class Article < Content
19
21
  has_many :triggers, as: :pending_item
20
22
  has_many :comments, dependent: :destroy
21
23
 
22
- before_create :create_guid
23
24
  before_save :set_permalink
25
+ before_create :create_guid
24
26
  after_save :keywords_to_tags, :shorten_url
25
27
 
26
28
  scope :child_of, ->(article_id) { where(parent_id: article_id) }
27
- scope :published_since, ->(time) { published.where('published_at > ?', time) }
28
- scope :withdrawn, -> { where(state: 'withdrawn').order(default_order) }
29
- scope :pending, -> { where(state: 'publication_pending'). order(default_order) }
29
+ scope :published_since, ->(time) { published.where("published_at > ?", time) }
30
+ scope :withdrawn, -> { where(state: "withdrawn").order(default_order) }
31
+ scope :pending, -> { where(state: "publication_pending").order(default_order) }
30
32
 
31
33
  scope :bestof, lambda {
32
34
  joins(:feedback).
33
- where('feedback.type' => 'Comment',
34
- 'contents.state' => 'published').
35
- group('contents.id').
36
- order('count(feedback.id) DESC').
37
- select('contents.*, count(feedback.id) as comment_count').
35
+ where("feedback.type" => "Comment",
36
+ "contents.state" => "published").
37
+ group("contents.id").
38
+ select("contents.*, count(feedback.id) as comment_count").
39
+ order("comment_count DESC").
38
40
  limit(5)
39
41
  }
40
42
 
41
- setting :password, :string, ''
43
+ setting :password, :string, ""
42
44
 
43
45
  attr_accessor :draft, :keywords
44
46
 
@@ -77,6 +79,7 @@ class Article < Content
77
79
 
78
80
  def set_permalink
79
81
  return if draft? || permalink.present?
82
+
80
83
  self.permalink = title.to_permalink
81
84
  end
82
85
 
@@ -86,7 +89,7 @@ class Article < Content
86
89
 
87
90
  def post_type
88
91
  post_type = self[:post_type]
89
- post_type = 'read' if post_type.blank?
92
+ post_type = "read" if post_type.blank?
90
93
  post_type
91
94
  end
92
95
 
@@ -99,16 +102,20 @@ class Article < Content
99
102
  def self.search_with(params)
100
103
  params ||= {}
101
104
  scoped = super(params)
102
- scoped = scoped.send(params[:state]) if %w(no_draft drafts published withdrawn pending).include?(params[:state])
105
+ if %w(no_draft drafts published withdrawn pending).include?(params[:state])
106
+ scoped = scoped.send(params[:state])
107
+ end
103
108
 
104
- scoped.order('created_at DESC')
109
+ scoped.order("created_at DESC")
105
110
  end
106
111
 
107
112
  # FIXME: Use keyword params to clean up call sites.
108
113
  def permalink_url(anchor = nil, only_path = false)
109
114
  return unless published?
115
+
110
116
  @cached_permalink_url ||= {}
111
- @cached_permalink_url["#{anchor}#{only_path}"] ||= blog.url_for(permalink_url_options, anchor: anchor, only_path: only_path)
117
+ @cached_permalink_url["#{anchor}#{only_path}"] ||=
118
+ blog.url_for(permalink_url_options, anchor: anchor, only_path: only_path)
112
119
  end
113
120
 
114
121
  def save_attachments!(files)
@@ -129,28 +136,30 @@ class Article < Content
129
136
  end
130
137
 
131
138
  def feed_url(format)
132
- "#{permalink_url}.#{format.gsub(/\d/, '')}"
139
+ "#{permalink_url}.#{format.gsub(/\d/, "")}"
133
140
  end
134
141
 
135
142
  def next
136
- Article.where('published_at > ?', published_at).order('published_at asc').limit(1).first
143
+ Article.where("published_at > ?", published_at).order("published_at asc").
144
+ limit(1).first
137
145
  end
138
146
 
139
147
  def previous
140
- Article.where('published_at < ?', published_at).order('published_at desc').limit(1).first
148
+ Article.where("published_at < ?", published_at).order("published_at desc").
149
+ limit(1).first
141
150
  end
142
151
 
143
152
  def publication_month
144
- published_at.strftime('%Y-%m')
153
+ published_at.strftime("%Y-%m")
145
154
  end
146
155
 
147
156
  def self.publication_months
148
- result = select('published_at').where('published_at is not NULL').where(type: 'Article')
157
+ result = select("published_at").where("published_at is not NULL").where(type: "Article")
149
158
  result.map { |it| [it.publication_month] }.uniq
150
159
  end
151
160
 
152
- # Finds one article which was posted on a certain date and matches the supplied dashed-title
153
- # params is a Hash
161
+ # Finds one article which was posted on a certain date and matches the
162
+ # supplied dashed-title params is a Hash
154
163
  def self.requested_article(params)
155
164
  date_range = PublifyTime.delta(params[:year], params[:month], params[:day])
156
165
 
@@ -159,6 +168,7 @@ class Article < Content
159
168
  req_params[:published_at] = date_range if date_range
160
169
 
161
170
  return if req_params.empty? # no search if no params send
171
+
162
172
  article = published.find_by(req_params)
163
173
  return article if article
164
174
 
@@ -226,7 +236,7 @@ class Article < Content
226
236
  if extended.blank?
227
237
  body
228
238
  else
229
- body + "\n<!--more-->\n" + extended
239
+ "#{body}\n<!--more-->\n#{extended}"
230
240
  end
231
241
  end
232
242
 
@@ -235,7 +245,7 @@ class Article < Content
235
245
  def body_and_extended=(value)
236
246
  parts = value.split(/\n?<!--more-->\n?/, 2)
237
247
  self.body = parts[0]
238
- self.extended = parts[1] || ''
248
+ self.extended = parts[1] || ""
239
249
  end
240
250
 
241
251
  def password_protected?
@@ -252,11 +262,13 @@ class Article < Content
252
262
 
253
263
  def allow_comments?
254
264
  return allow_comments unless allow_comments.nil?
265
+
255
266
  blog.default_allow_comments
256
267
  end
257
268
 
258
269
  def allow_pings?
259
270
  return allow_pings unless allow_pings.nil?
271
+
260
272
  blog.default_allow_pings
261
273
  end
262
274
 
@@ -276,11 +288,11 @@ class Article < Content
276
288
 
277
289
  def permalink_url_options
278
290
  format_url = blog.permalink_format.dup
279
- format_url.gsub!('%year%', published_at.year.to_s)
280
- format_url.gsub!('%month%', sprintf('%.2d', published_at.month))
281
- format_url.gsub!('%day%', sprintf('%.2d', published_at.day))
282
- format_url.gsub!('%title%', URI.encode(permalink.to_s))
283
- if format_url[0, 1] == '/'
291
+ format_url.gsub!("%year%", published_at.year.to_s)
292
+ format_url.gsub!("%month%", sprintf("%<month>.2d", month: published_at.month))
293
+ format_url.gsub!("%day%", sprintf("%<day>.2d", day: published_at.day))
294
+ format_url.gsub!("%title%", URI::DEFAULT_PARSER.escape(permalink.to_s))
295
+ if format_url[0, 1] == "/"
284
296
  format_url[1..-1]
285
297
  else
286
298
  format_url
@@ -289,6 +301,6 @@ class Article < Content
289
301
 
290
302
  def trigger_publication
291
303
  # TODO: Skip if already published, update when published_at changes
292
- Trigger.post_action(published_at, self, 'publish!')
304
+ Trigger.post_action(published_at, self, "publish!")
293
305
  end
294
306
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Article::Factory
2
4
  attr_reader :blog, :user
3
5
 
@@ -10,13 +12,14 @@ class Article::Factory
10
12
  blog.articles.build.tap do |art|
11
13
  art.allow_comments = blog.default_allow_comments
12
14
  art.allow_pings = blog.default_allow_pings
13
- art.text_filter = user.default_text_filter
14
- art.state = 'draft'
15
+ art.text_filter_name = default_text_filter
16
+ art.state = "draft"
15
17
  end
16
18
  end
17
19
 
18
20
  def get_or_build_from(id)
19
21
  return blog.articles.find(id) if id.present?
22
+
20
23
  default
21
24
  end
22
25
 
@@ -31,10 +34,10 @@ class Article::Factory
31
34
  end
32
35
 
33
36
  def extract_params(path, format)
34
- specs = format.split('/')
35
- specs.delete('')
36
- parts = path.split('/')
37
- parts.delete('')
37
+ specs = format.split("/")
38
+ specs.delete("")
39
+ parts = path.split("/")
40
+ parts.delete("")
38
41
 
39
42
  return if parts.length != specs.length
40
43
 
@@ -45,6 +48,7 @@ class Article::Factory
45
48
  after_format = Regexp.last_match[3]
46
49
  item =~ /^#{before_format}(.*)#{after_format}$/
47
50
  break unless Regexp.last_match
51
+
48
52
  value = Regexp.last_match[1]
49
53
  result[format_string.to_sym] = value
50
54
  elsif spec != item
@@ -53,4 +57,8 @@ class Article::Factory
53
57
  result
54
58
  end
55
59
  end
60
+
61
+ def default_text_filter
62
+ user.text_filter_name || blog.text_filter
63
+ end
56
64
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # The Blog class represents the one and only blog. It stores most
2
4
  # configuration settings and is linked to most of the assorted content
3
5
  # classes via has_many.
@@ -13,65 +15,65 @@ class Blog < ApplicationRecord
13
15
  has_many :articles
14
16
  has_many :feedback, through: :articles
15
17
 
16
- has_many :published_articles, ->() { published }, class_name: 'Article'
18
+ has_many :published_articles, ->() { published }, class_name: "Article"
17
19
 
18
20
  has_many :pages
19
21
  has_many :tags
20
22
  has_many :notes
21
23
 
22
24
  has_many :redirects
23
- has_many :sidebars, ->() { order('active_position ASC') }
25
+ has_many :sidebars, ->() { order("active_position ASC") }
24
26
 
25
27
  attr_accessor :custom_permalink
26
28
 
27
- default_scope -> { order('id') }
29
+ default_scope -> { order("id") }
28
30
 
29
31
  validates :blog_name, presence: true
30
32
 
31
33
  serialize :settings, Hash
32
34
 
33
35
  # Description
34
- setting :blog_name, :string, 'My Shiny Weblog!'
35
- setting :blog_subtitle, :string, ''
36
- setting :geourl_location, :string, ''
37
- setting :canonical_server_url, :string, '' # Deprecated
38
- setting :lang, :string, 'en_US'
39
- setting :title_prefix, :integer, 0 # Deprecated but needed for a migration
36
+ setting :blog_name, :string, "My Shiny Weblog!"
37
+ setting :blog_subtitle, :string, ""
38
+ setting :geourl_location, :string, ""
39
+ setting :canonical_server_url, :string, "" # Deprecated
40
+ setting :lang, :string, "en_US"
40
41
 
41
42
  # Spam
42
43
  setting :sp_global, :boolean, false
43
44
  setting :sp_article_auto_close, :integer, 0
44
45
  setting :sp_url_limit, :integer, 0
45
- setting :sp_akismet_key, :string, ''
46
+ setting :sp_akismet_key, :string, ""
46
47
  setting :use_recaptcha, :boolean, false
47
48
 
48
49
  # Mostly Behaviour
49
- setting :text_filter, :string, 'markdown smartypants'
50
- setting :comment_text_filter, :string, 'markdown smartypants'
50
+ setting :text_filter, :string, "markdown smartypants"
51
+ setting :comment_text_filter, :string, "markdown smartypants"
51
52
  setting :limit_article_display, :integer, 10
52
53
  setting :limit_archives_display, :integer, 20
53
54
  setting :limit_rss_display, :integer, 10
54
55
  setting :default_allow_pings, :boolean, false
55
56
  setting :default_allow_comments, :boolean, true
56
57
  setting :default_moderate_comments, :boolean, false
57
- setting :show_extended_on_rss, :boolean, true # deprecated but still needed for backward compatibility
58
+ # deprecated but still needed for backward compatibility
59
+ setting :show_extended_on_rss, :boolean, true
58
60
  setting :hide_extended_on_rss, :boolean, false
59
- setting :theme, :string, 'plain'
60
- setting :plugin_avatar, :string, ''
61
+ setting :theme, :string, "plain"
62
+ setting :plugin_avatar, :string, ""
61
63
  setting :global_pings_disable, :boolean, false
62
64
  setting :send_outbound_pings, :boolean, true
63
- setting :email_from, :string, 'publify@example.com'
65
+ setting :email_from, :string, "publify@example.com"
64
66
  setting :allow_signup, :integer, 0
65
- setting :date_format, :string, '%d/%m/%Y'
66
- setting :time_format, :string, '%Hh%M'
67
+ setting :date_format, :string, "%d/%m/%Y"
68
+ setting :time_format, :string, "%Hh%M"
67
69
  setting :image_avatar_size, :integer, 48
68
70
  setting :image_thumb_size, :integer, 125
69
71
  setting :image_medium_size, :integer, 600
70
72
 
71
73
  # SEO
72
- setting :meta_description, :string, ''
73
- setting :meta_keywords, :string, ''
74
- setting :google_analytics, :string, ''
74
+ setting :meta_description, :string, ""
75
+ setting :meta_keywords, :string, ""
76
+ setting :google_analytics, :string, ""
75
77
  setting :rss_description, :boolean, false
76
78
  setting :rss_description_text, :string, <<-HTML.strip_heredoc
77
79
  <hr />
@@ -80,7 +82,7 @@ class Blog < ApplicationRecord
80
82
  | If you are reading this article anywhere other than on <a href='%blog_url%'>%blog_name%</a>,
81
83
  it has been illegally reproduced and without proper authorization.</small></p>
82
84
  HTML
83
- setting :permalink_format, :string, '/%year%/%month%/%day%/%title%'
85
+ setting :permalink_format, :string, "/%year%/%month%/%day%/%title%"
84
86
  setting :robots, :string, 'User-agent: *\nAllow: /\nDisallow: /admin\n'
85
87
  setting :humans, :string, <<-TEXT.strip_heredoc
86
88
  /* TEAM */
@@ -89,45 +91,50 @@ class Blog < ApplicationRecord
89
91
  Twitter: your Twitter username.
90
92
 
91
93
  /* SITE */
92
- Software: Publify [http://publify.co] #{PublifyCore::VERSION}
94
+ Software: Publify [https://publify.github.io/] #{PublifyCore::VERSION}
93
95
  TEXT
94
- setting :index_categories, :boolean, true # deprecated but still needed for backward compatibility
96
+ # deprecated but still needed for backward compatibility
97
+ setting :index_categories, :boolean, true
95
98
  setting :unindex_categories, :boolean, false
96
- setting :index_tags, :boolean, true # deprecated but still needed for backward compatibility
99
+ # deprecated but still needed for backward compatibility
100
+ setting :index_tags, :boolean, true
97
101
  setting :unindex_tags, :boolean, false
98
102
  setting :admin_display_elements, :integer, 10
99
- setting :google_verification, :string, ''
100
- setting :nofollowify, :boolean, true # deprecated but still needed for backward compatibility
103
+ setting :google_verification, :string, ""
104
+ # deprecated but still needed for backward compatibility
105
+ setting :nofollowify, :boolean, true
101
106
  setting :dofollowify, :boolean, false
102
- setting :use_canonical_url, :boolean, false
103
107
  setting :use_meta_keyword, :boolean, true
104
- setting :home_title_template, :string, '%blog_name% | %blog_subtitle%' # spec OK
105
- setting :home_desc_template, :string, '%blog_name% | %blog_subtitle% | %meta_keywords%' # OK
106
- setting :article_title_template, :string, '%title% | %blog_name%'
107
- setting :article_desc_template, :string, '%excerpt%'
108
- setting :page_title_template, :string, '%title% | %blog_name%'
109
- setting :page_desc_template, :string, '%excerpt%'
110
- setting :paginated_title_template, :string, '%blog_name% | %blog_subtitle% %page%'
111
- setting :paginated_desc_template, :string, '%blog_name% | %blog_subtitle% | %meta_keywords% %page%'
112
- setting :tag_title_template, :string, 'Tag: %name% | %blog_name% %page%'
113
- setting :tag_desc_template, :string, '%name% | %blog_name% | %blog_subtitle% %page%'
114
- setting :author_title_template, :string, '%author% | %blog_name%'
115
- setting :author_desc_template, :string, '%author% | %blog_name% | %blog_subtitle%'
116
- setting :archives_title_template, :string, 'Archives for %blog_name% %date% %page%'
117
- setting :archives_desc_template, :string, 'Archives for %blog_name% %date% %page% %blog_subtitle%'
118
- setting :search_title_template, :string, 'Results for %search% | %blog_name% %page%'
119
- setting :search_desc_template, :string, 'Results for %search% | %blog_name% | %blog_subtitle% %page%'
120
- setting :statuses_title_template, :string, 'Notes | %blog_name% %page%'
121
- setting :statuses_desc_template, :string, 'Notes | %blog_name% | %blog_subtitle% %page%'
122
- setting :status_title_template, :string, '%body% | %blog_name%'
123
- setting :status_desc_template, :string, '%excerpt%'
124
-
125
- setting :custom_tracking_field, :string, ''
108
+ setting :home_title_template, :string, "%blog_name% | %blog_subtitle%"
109
+ setting :home_desc_template, :string, "%blog_name% | %blog_subtitle% | %meta_keywords%"
110
+ setting :article_title_template, :string, "%title% | %blog_name%"
111
+ setting :article_desc_template, :string, "%excerpt%"
112
+ setting :page_title_template, :string, "%title% | %blog_name%"
113
+ setting :page_desc_template, :string, "%excerpt%"
114
+ setting :paginated_title_template, :string, "%blog_name% | %blog_subtitle% %page%"
115
+ setting :paginated_desc_template, :string,
116
+ "%blog_name% | %blog_subtitle% | %meta_keywords% %page%"
117
+ setting :tag_title_template, :string, "Tag: %name% | %blog_name% %page%"
118
+ setting :tag_desc_template, :string, "%name% | %blog_name% | %blog_subtitle% %page%"
119
+ setting :author_title_template, :string, "%author% | %blog_name%"
120
+ setting :author_desc_template, :string, "%author% | %blog_name% | %blog_subtitle%"
121
+ setting :archives_title_template, :string, "Archives for %blog_name% %date% %page%"
122
+ setting :archives_desc_template, :string,
123
+ "Archives for %blog_name% %date% %page% %blog_subtitle%"
124
+ setting :search_title_template, :string, "Results for %search% | %blog_name% %page%"
125
+ setting :search_desc_template, :string,
126
+ "Results for %search% | %blog_name% | %blog_subtitle% %page%"
127
+ setting :statuses_title_template, :string, "Notes | %blog_name% %page%"
128
+ setting :statuses_desc_template, :string, "Notes | %blog_name% | %blog_subtitle% %page%"
129
+ setting :status_title_template, :string, "%body% | %blog_name%"
130
+ setting :status_desc_template, :string, "%excerpt%"
131
+
132
+ setting :custom_tracking_field, :string, ""
126
133
  # setting :meta_author_template, :string, "%blog_name% | %nickname%"
127
134
 
128
- setting :twitter_consumer_key, :string, ''
129
- setting :twitter_consumer_secret, :string, ''
130
- setting :custom_url_shortener, :string, ''
135
+ setting :twitter_consumer_key, :string, ""
136
+ setting :twitter_consumer_secret, :string, ""
137
+ setting :custom_url_shortener, :string, ""
131
138
  setting :statuses_in_timeline, :boolean, true
132
139
 
133
140
  validate :permalink_has_identifier
@@ -146,13 +153,13 @@ class Blog < ApplicationRecord
146
153
 
147
154
  # Check that all required blog settings have a value.
148
155
  def configured?
149
- settings.key?('blog_name')
156
+ settings.key?("blog_name")
150
157
  end
151
158
 
152
159
  # The +Theme+ object for the current theme.
153
160
  def current_theme(reload = nil)
154
161
  @current_theme = nil if reload
155
- @current_theme ||= Theme.find(theme) || Theme.new('', '')
162
+ @current_theme ||= Theme.find(theme) || Theme.new("", "")
156
163
  end
157
164
 
158
165
  module BasedUrlFor
@@ -165,21 +172,25 @@ class Blog < ApplicationRecord
165
172
  def url_for(options = {}, extra_params = {})
166
173
  case options
167
174
  when String
175
+ options = options.sub(%r{^/}, "")
168
176
  url_generated = if extra_params[:only_path]
169
177
  root_path
170
178
  else
171
179
  base_url
172
180
  end
173
- url_generated += "/#{options}" # They asked for 'url_for "/some/path"', so return it unedited.
181
+ # They asked for 'url_for "/some/path"', so return it unedited.
182
+ url_generated += "/#{options}"
174
183
  url_generated += "##{extra_params[:anchor]}" if extra_params[:anchor]
175
184
  url_generated
176
185
  when Hash
177
- merged_opts = options.reverse_merge!(only_path: false, controller: '',
178
- action: 'permalink',
186
+ merged_opts = options.reverse_merge!(only_path: false, controller: "",
187
+ action: "permalink",
179
188
  host: host_with_port,
180
189
  script_name: root_path)
181
- cache_key = merged_opts.values.prepend('blog-urlfor-withbaseurl').join('-')
182
- Rails.cache.write(cache_key, super(merged_opts)) unless Rails.cache.exist?(cache_key)
190
+ cache_key = merged_opts.values.prepend("blog-urlfor-withbaseurl").join("-")
191
+ unless Rails.cache.exist?(cache_key)
192
+ Rails.cache.write(cache_key, super(merged_opts))
193
+ end
183
194
  Rails.cache.read(cache_key)
184
195
  else
185
196
  raise "Invalid URL in url_for: #{options.inspect}"
@@ -191,7 +202,7 @@ class Blog < ApplicationRecord
191
202
 
192
203
  # The URL for a static file.
193
204
  def file_url(filename)
194
- if CarrierWave.configure { |config| config.storage.name == 'CarrierWave::Storage::Fog' }
205
+ if CarrierWave.configure { |config| config.storage.name == "CarrierWave::Storage::Fog" }
195
206
  filename
196
207
  else
197
208
  url_for filename, only_path: false
@@ -203,7 +214,8 @@ class Blog < ApplicationRecord
203
214
  end
204
215
 
205
216
  def per_page(format)
206
- return limit_article_display if format.nil? || format == 'html'
217
+ return limit_article_display if format.nil? || format == "html"
218
+
207
219
  limit_rss_display
208
220
  end
209
221
 
@@ -217,9 +229,13 @@ class Blog < ApplicationRecord
217
229
  end
218
230
 
219
231
  def permalink_has_identifier
220
- errors.add(:base, I18n.t('errors.permalink_need_a_title')) unless permalink_format =~ /(%title%)/
232
+ unless /(%title%)/.match?(permalink_format)
233
+ errors.add(:base, I18n.t("errors.permalink_need_a_title"))
234
+ end
221
235
 
222
- errors.add(:permalink_format, I18n.t('errors.cant_end_with_rss_or_atom')) if permalink_format =~ /\.(atom|rss)$/
236
+ if /\.(atom|rss)$/.match?(permalink_format)
237
+ errors.add(:permalink_format, I18n.t("errors.cant_end_with_rss_or_atom"))
238
+ end
223
239
  end
224
240
 
225
241
  def root_path
@@ -233,6 +249,7 @@ class Blog < ApplicationRecord
233
249
  def has_twitter_configured?
234
250
  return false if twitter_consumer_key.nil? || twitter_consumer_secret.nil?
235
251
  return false if twitter_consumer_key.empty? || twitter_consumer_secret.empty?
252
+
236
253
  true
237
254
  end
238
255
 
@@ -253,7 +270,10 @@ class Blog < ApplicationRecord
253
270
  def split_base_url
254
271
  unless @split_base_url
255
272
  raise "Invalid base_url: #{base_url}" unless base_url =~ %r{(https?)://([^/]*)(.*)}
256
- @split_base_url = { protocol: Regexp.last_match[1], host_with_port: Regexp.last_match[2], root_path: Regexp.last_match[3].gsub(%r{/$}, '') }
273
+
274
+ @split_base_url = { protocol: Regexp.last_match[1],
275
+ host_with_port: Regexp.last_match[2],
276
+ root_path: Regexp.last_match[3].gsub(%r{/$}, "") }
257
277
  end
258
278
  @split_base_url
259
279
  end