publify_core 9.0.0.pre1
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 +7 -0
- data/MIT-LICENSE +21 -0
- data/README.rdoc +3 -0
- data/Rakefile +35 -0
- data/app/assets/fonts/open-sans-bold.woff +0 -0
- data/app/assets/fonts/open-sans.woff +0 -0
- data/app/assets/images/admin/loading.gif +0 -0
- data/app/assets/images/admin/typologo.gif +0 -0
- data/app/assets/images/calendar_date_select/calendar.gif +0 -0
- data/app/assets/images/close.gif +0 -0
- data/app/assets/images/closelabel.gif +0 -0
- data/app/assets/images/go.png +0 -0
- data/app/assets/images/loading.gif +0 -0
- data/app/assets/images/nextlabel.gif +0 -0
- data/app/assets/images/overlay.png +0 -0
- data/app/assets/images/powered.gif +0 -0
- data/app/assets/images/prevlabel.gif +0 -0
- data/app/assets/images/spinner-blue.gif +0 -0
- data/app/assets/images/spinner.gif +0 -0
- data/app/assets/images/thumb_blank.jpg +0 -0
- data/app/assets/javascripts/application.js +2 -0
- data/app/assets/javascripts/cookies.js +60 -0
- data/app/assets/javascripts/datetimepicker.js +1470 -0
- data/app/assets/javascripts/lang/da_DK.js +17 -0
- data/app/assets/javascripts/lang/default.js +21 -0
- data/app/assets/javascripts/lang/en_US.js +21 -0
- data/app/assets/javascripts/lang/fr_FR.js +21 -0
- data/app/assets/javascripts/lang/nl_NL.js +21 -0
- data/app/assets/javascripts/lang/zh_TW.js +17 -0
- data/app/assets/javascripts/lightbox.js +350 -0
- data/app/assets/javascripts/observe.js +28 -0
- data/app/assets/javascripts/publify.js +11 -0
- data/app/assets/javascripts/publify_admin.js +138 -0
- data/app/assets/javascripts/quicktags.js +440 -0
- data/app/assets/javascripts/set-timeago-lang.js +3 -0
- data/app/assets/javascripts/sidebar.js +28 -0
- data/app/assets/javascripts/spinnable.js +5 -0
- data/app/assets/javascripts/tagmanager.js +481 -0
- data/app/assets/javascripts/typeahead.js +1139 -0
- data/app/assets/javascripts/widearea.js +486 -0
- data/app/assets/stylesheets/accounts.css.scss +7 -0
- data/app/assets/stylesheets/administration_structure.css.scss +239 -0
- data/app/assets/stylesheets/coderay.css +135 -0
- data/app/assets/stylesheets/datetimepicker.css +306 -0
- data/app/assets/stylesheets/lightbox.css +63 -0
- data/app/assets/stylesheets/publify.css.scss +9 -0
- data/app/assets/stylesheets/publify_admin.css.scss +11 -0
- data/app/assets/stylesheets/rss.css +53 -0
- data/app/assets/stylesheets/sidebar_admin.css.scss +36 -0
- data/app/assets/stylesheets/tagmanager.css +102 -0
- data/app/assets/stylesheets/user-styles.css +29 -0
- data/app/assets/stylesheets/widearea.css +133 -0
- data/app/controllers/accounts_controller.rb +2 -0
- data/app/controllers/admin/base_controller.rb +41 -0
- data/app/controllers/admin/cache_controller.rb +33 -0
- data/app/controllers/admin/content_controller.rb +174 -0
- data/app/controllers/admin/dashboard_controller.rb +87 -0
- data/app/controllers/admin/feedback_controller.rb +159 -0
- data/app/controllers/admin/migrations_controller.rb +20 -0
- data/app/controllers/admin/notes_controller.rb +69 -0
- data/app/controllers/admin/pages_controller.rb +88 -0
- data/app/controllers/admin/post_types_controller.rb +56 -0
- data/app/controllers/admin/profiles_controller.rb +48 -0
- data/app/controllers/admin/redirects_controller.rb +47 -0
- data/app/controllers/admin/resources_controller.rb +30 -0
- data/app/controllers/admin/seo_controller.rb +45 -0
- data/app/controllers/admin/settings_controller.rb +53 -0
- data/app/controllers/admin/sidebar_controller.rb +66 -0
- data/app/controllers/admin/tags_controller.rb +53 -0
- data/app/controllers/admin/textfilters_controller.rb +6 -0
- data/app/controllers/admin/themes_controller.rb +37 -0
- data/app/controllers/admin/users_controller.rb +65 -0
- data/app/controllers/articles_controller.rb +205 -0
- data/app/controllers/authors_controller.rb +27 -0
- data/app/controllers/base_controller.rb +45 -0
- data/app/controllers/comments_controller.rb +69 -0
- data/app/controllers/content_controller.rb +31 -0
- data/app/controllers/feedback_controller.rb +47 -0
- data/app/controllers/notes_controller.rb +37 -0
- data/app/controllers/setup_controller.rb +62 -0
- data/app/controllers/tags_controller.rb +55 -0
- data/app/controllers/text_controller.rb +9 -0
- data/app/controllers/textfilter_controller.rb +3 -0
- data/app/controllers/theme_controller.rb +59 -0
- data/app/controllers/trackbacks_controller.rb +36 -0
- data/app/controllers/xml_controller.rb +70 -0
- data/app/helpers/admin/base_helper.rb +87 -0
- data/app/helpers/admin/feedback_helper.rb +42 -0
- data/app/helpers/articles_helper.rb +8 -0
- data/app/helpers/authors_helper.rb +39 -0
- data/app/helpers/base_helper.rb +246 -0
- data/app/helpers/blog_helper.rb +12 -0
- data/app/helpers/xml_helper.rb +16 -0
- data/app/mailers/notification_mailer.rb +38 -0
- data/app/models/ability.rb +52 -0
- data/app/models/archives_sidebar.rb +45 -0
- data/app/models/article/factory.rb +56 -0
- data/app/models/article/states.rb +178 -0
- data/app/models/article.rb +321 -0
- data/app/models/blog.rb +290 -0
- data/app/models/blog_sweeper.rb +86 -0
- data/app/models/comment.rb +53 -0
- data/app/models/config_manager.rb +81 -0
- data/app/models/content.rb +138 -0
- data/app/models/content_base.rb +95 -0
- data/app/models/feedback/states.rb +256 -0
- data/app/models/feedback.rb +225 -0
- data/app/models/meta_sidebar.rb +8 -0
- data/app/models/note.rb +144 -0
- data/app/models/page.rb +36 -0
- data/app/models/page_cache.rb +33 -0
- data/app/models/page_sidebar.rb +12 -0
- data/app/models/ping.rb +116 -0
- data/app/models/post_type.rb +15 -0
- data/app/models/redirect.rb +45 -0
- data/app/models/redirection.rb +4 -0
- data/app/models/resource.rb +28 -0
- data/app/models/search_sidebar.rb +7 -0
- data/app/models/sidebar.rb +138 -0
- data/app/models/static_sidebar.rb +20 -0
- data/app/models/tag.rb +63 -0
- data/app/models/tag_sidebar.rb +27 -0
- data/app/models/text_filter.rb +61 -0
- data/app/models/trackback.rb +58 -0
- data/app/models/trigger.rb +45 -0
- data/app/models/user.rb +148 -0
- data/app/services/migrator.rb +25 -0
- data/app/services/title_builder.rb +80 -0
- data/app/uploaders/resource_uploader.rb +30 -0
- data/app/views/accounts/confirm.html.erb +8 -0
- data/app/views/admin/cache/show.html.erb +18 -0
- data/app/views/admin/content/_article_list.html.erb +26 -0
- data/app/views/admin/content/_form.html.erb +165 -0
- data/app/views/admin/content/autosave.js.erb +5 -0
- data/app/views/admin/content/edit.html.erb +3 -0
- data/app/views/admin/content/index.html.erb +48 -0
- data/app/views/admin/content/index.js.erb +1 -0
- data/app/views/admin/content/new.html.erb +3 -0
- data/app/views/admin/dashboard/_comment.html.erb +18 -0
- data/app/views/admin/dashboard/_comments.html.erb +10 -0
- data/app/views/admin/dashboard/_drafts.html.erb +25 -0
- data/app/views/admin/dashboard/_inbound.html.erb +31 -0
- data/app/views/admin/dashboard/_overview.html.erb +23 -0
- data/app/views/admin/dashboard/_welcome.html.erb +28 -0
- data/app/views/admin/dashboard/index.html.erb +17 -0
- data/app/views/admin/feedback/_button.html.erb +19 -0
- data/app/views/admin/feedback/_feedback.html.erb +7 -0
- data/app/views/admin/feedback/_ham.html.erb +17 -0
- data/app/views/admin/feedback/_spam.html.erb +23 -0
- data/app/views/admin/feedback/article.html.erb +69 -0
- data/app/views/admin/feedback/edit.html.erb +48 -0
- data/app/views/admin/feedback/ham.js +1 -0
- data/app/views/admin/feedback/index.html.erb +53 -0
- data/app/views/admin/feedback/spam.js +1 -0
- data/app/views/admin/migrations/show.html.erb +39 -0
- data/app/views/admin/notes/_form.html.erb +37 -0
- data/app/views/admin/notes/_header.html.erb +6 -0
- data/app/views/admin/notes/_list.html.erb +13 -0
- data/app/views/admin/notes/_note.html.erb +14 -0
- data/app/views/admin/notes/edit.html.erb +11 -0
- data/app/views/admin/notes/index.html.erb +11 -0
- data/app/views/admin/notes/show.html.erb +14 -0
- data/app/views/admin/pages/_form.html.erb +101 -0
- data/app/views/admin/pages/_pages.html.erb +21 -0
- data/app/views/admin/pages/edit.html.erb +1 -0
- data/app/views/admin/pages/index.html.erb +17 -0
- data/app/views/admin/pages/new.html.erb +1 -0
- data/app/views/admin/post_types/_index_and_form.html.erb +65 -0
- data/app/views/admin/post_types/edit.html.erb +1 -0
- data/app/views/admin/post_types/index.html.erb +1 -0
- data/app/views/admin/profiles/index.html.erb +10 -0
- data/app/views/admin/redirects/_index_and_form.html.erb +68 -0
- data/app/views/admin/redirects/edit.html.erb +1 -0
- data/app/views/admin/redirects/index.html.erb +1 -0
- data/app/views/admin/resources/index.html.erb +68 -0
- data/app/views/admin/seo/_general.html.erb +123 -0
- data/app/views/admin/seo/_permalinks.html.erb +53 -0
- data/app/views/admin/seo/_titles.html.erb +210 -0
- data/app/views/admin/seo/show.html.erb +32 -0
- data/app/views/admin/settings/display.html.erb +110 -0
- data/app/views/admin/settings/feedback.html.erb +125 -0
- data/app/views/admin/settings/index.html.erb +73 -0
- data/app/views/admin/settings/write.html.erb +87 -0
- data/app/views/admin/shared/_edit.html.erb +4 -0
- data/app/views/admin/shared/_menu.html.erb +122 -0
- data/app/views/admin/shared/_twitter_alert.html.erb +3 -0
- data/app/views/admin/sidebar/_available.html.erb +6 -0
- data/app/views/admin/sidebar/_available.json.erb +6 -0
- data/app/views/admin/sidebar/_config.html.erb +27 -0
- data/app/views/admin/sidebar/_target.html.erb +9 -0
- data/app/views/admin/sidebar/_target_sidebar.html.erb +20 -0
- data/app/views/admin/sidebar/destroy.js.erb +1 -0
- data/app/views/admin/sidebar/index.html.erb +31 -0
- data/app/views/admin/sidebar/sortable.js.erb +3 -0
- data/app/views/admin/sidebar/update.js.erb +2 -0
- data/app/views/admin/tags/_index_and_form.html.erb +59 -0
- data/app/views/admin/tags/edit.html.erb +1 -0
- data/app/views/admin/tags/index.html.erb +1 -0
- data/app/views/admin/themes/index.html.erb +27 -0
- data/app/views/admin/users/_form.html.erb +215 -0
- data/app/views/admin/users/edit.html.erb +8 -0
- data/app/views/admin/users/index.html.erb +39 -0
- data/app/views/admin/users/new.html.erb +8 -0
- data/app/views/archives_sidebar/_content.html.erb +13 -0
- data/app/views/articles/_article.html.erb +9 -0
- data/app/views/articles/_article_collection.html.erb +8 -0
- data/app/views/articles/_article_content.html.erb +5 -0
- data/app/views/articles/_article_excerpt.html.erb +13 -0
- data/app/views/articles/_article_links.html.erb +10 -0
- data/app/views/articles/_comment.html.erb +1 -0
- data/app/views/articles/_comment_errors.html.erb +2 -0
- data/app/views/articles/_comment_form.html.erb +48 -0
- data/app/views/articles/_comment_list.html.erb +5 -0
- data/app/views/articles/_comment_preview.html.erb +4 -0
- data/app/views/articles/_full_article_content.html.erb +2 -0
- data/app/views/articles/_password_form.html.erb +10 -0
- data/app/views/articles/_protected_article_content.html.erb +6 -0
- data/app/views/articles/_trackback.html.erb +6 -0
- data/app/views/articles/archives.html.erb +25 -0
- data/app/views/articles/comment.js.erb +5 -0
- data/app/views/articles/comment_failed.js.erb +3 -0
- data/app/views/articles/error.html.erb +3 -0
- data/app/views/articles/feedback_atom_feed.atom.builder +8 -0
- data/app/views/articles/feedback_rss_feed.rss.builder +21 -0
- data/app/views/articles/index.html.erb +1 -0
- data/app/views/articles/index_atom_feed.atom.builder +8 -0
- data/app/views/articles/index_rss_feed.rss.builder +20 -0
- data/app/views/articles/live_search.html.erb +10 -0
- data/app/views/articles/read.html.erb +61 -0
- data/app/views/articles/search.html.erb +8 -0
- data/app/views/articles/trackback.xml.builder +5 -0
- data/app/views/articles/view_page.html.erb +3 -0
- data/app/views/authors/show.html.erb +40 -0
- data/app/views/authors/show_atom_feed.atom.builder +8 -0
- data/app/views/authors/show_rss_feed.rss.builder +20 -0
- data/app/views/comments/_comment.html.erb +16 -0
- data/app/views/comments/index.html.erb +1 -0
- data/app/views/comments/index_atom_feed.atom.builder +8 -0
- data/app/views/comments/index_rss_feed.rss.builder +20 -0
- data/app/views/comments/preview.html.erb +1 -0
- data/app/views/comments/preview.js.erb +3 -0
- data/app/views/devise/mailer/reset_password_instructions.html.erb +13 -0
- data/app/views/devise/passwords/edit.html.erb +28 -0
- data/app/views/devise/passwords/new.html.erb +20 -0
- data/app/views/devise/registrations/new.html.erb +36 -0
- data/app/views/devise/sessions/new.html.erb +32 -0
- data/app/views/devise/shared/_links.html.erb +15 -0
- data/app/views/errors/404.html.erb +2 -0
- data/app/views/layouts/accounts.html.erb +33 -0
- data/app/views/layouts/administration.html.erb +37 -0
- data/app/views/layouts/default.html.erb +32 -0
- data/app/views/layouts/editor.html.erb +31 -0
- data/app/views/meta_sidebar/_content.html.erb +8 -0
- data/app/views/notes/_note.html.erb +15 -0
- data/app/views/notes/error.html.erb +3 -0
- data/app/views/notes/index.html.erb +15 -0
- data/app/views/notes/show.html.erb +5 -0
- data/app/views/notes/show_in_reply.html.erb +16 -0
- data/app/views/notification_mailer/_mail_footer.html.erb +7 -0
- data/app/views/notification_mailer/_mail_header.html.erb +1 -0
- data/app/views/notification_mailer/article.html.erb +6 -0
- data/app/views/notification_mailer/comment.html.erb +11 -0
- data/app/views/notification_mailer/notif_user.html.erb +14 -0
- data/app/views/page_sidebar/_content.html.erb +12 -0
- data/app/views/search_sidebar/_content.html.erb +10 -0
- data/app/views/settings/done.html.erb +2 -0
- data/app/views/settings/install.html.erb +12 -0
- data/app/views/setup/index.html.erb +13 -0
- data/app/views/shared/_atom_header.atom.builder +6 -0
- data/app/views/shared/_atom_item_article.atom.builder +39 -0
- data/app/views/shared/_atom_item_comment.atom.builder +10 -0
- data/app/views/shared/_atom_item_trackback.atom.builder +9 -0
- data/app/views/shared/_flash.erb +10 -0
- data/app/views/shared/_page_header.html.erb +26 -0
- data/app/views/shared/_rss_item_article.rss.builder +35 -0
- data/app/views/shared/_rss_item_comment.rss.builder +8 -0
- data/app/views/shared/_rss_item_trackback.rss.builder +7 -0
- data/app/views/sidebar/_row.html.erb +1 -0
- data/app/views/sidebar/_sidebar.html.erb +5 -0
- data/app/views/sidebar/display_plugins.html.erb +5 -0
- data/app/views/sidebar/show.html.erb +1 -0
- data/app/views/static_sidebar/_content.html.erb +2 -0
- data/app/views/tag_sidebar/_content.html.erb +10 -0
- data/app/views/tags/index.html.erb +15 -0
- data/app/views/tags/show.html.erb +1 -0
- data/app/views/theme/static_view_test.html.erb +1 -0
- data/app/views/trackbacks/index_atom_feed.atom.builder +7 -0
- data/app/views/trackbacks/index_rss_feed.rss.builder +20 -0
- data/app/views/trackbacks/trackback.xml.builder +4 -0
- data/app/views/xml/_googlesitemap_item_article.googlesitemap.builder +5 -0
- data/app/views/xml/_googlesitemap_item_category.googlesitemap.builder +4 -0
- data/app/views/xml/_googlesitemap_item_page.googlesitemap.builder +4 -0
- data/app/views/xml/_googlesitemap_item_tag.googlesitemap.builder +4 -0
- data/app/views/xml/feed.googlesitemap.builder +7 -0
- data/app/views/xml/rsd.rsd.builder +8 -0
- data/config/i18n-tasks.yml +49 -0
- data/config/initializers/devise.rb +265 -0
- data/config/initializers/mime_types.rb +6 -0
- data/config/locales/da.yml +827 -0
- data/config/locales/de.yml +827 -0
- data/config/locales/en.yml +827 -0
- data/config/locales/es-MX.yml +827 -0
- data/config/locales/fr.yml +827 -0
- data/config/locales/he.yml +827 -0
- data/config/locales/it.yml +827 -0
- data/config/locales/ja.yml +827 -0
- data/config/locales/lt.yml +827 -0
- data/config/locales/nb-NO.yml +827 -0
- data/config/locales/nl.yml +827 -0
- data/config/locales/pl.yml +827 -0
- data/config/locales/pt-BR.yml +827 -0
- data/config/locales/ro.yml +827 -0
- data/config/locales/ru.yml +827 -0
- data/config/locales/sidebars.da.yml +20 -0
- data/config/locales/sidebars.de.yml +20 -0
- data/config/locales/sidebars.en.yml +20 -0
- data/config/locales/sidebars.es-MX.yml +20 -0
- data/config/locales/sidebars.fr.yml +20 -0
- data/config/locales/sidebars.he.yml +20 -0
- data/config/locales/sidebars.it.yml +20 -0
- data/config/locales/sidebars.ja.yml +20 -0
- data/config/locales/sidebars.lt.yml +20 -0
- data/config/locales/sidebars.nb-NO.yml +20 -0
- data/config/locales/sidebars.nl.yml +20 -0
- data/config/locales/sidebars.pl.yml +20 -0
- data/config/locales/sidebars.pt-BR.yml +20 -0
- data/config/locales/sidebars.ro.yml +20 -0
- data/config/locales/sidebars.ru.yml +20 -0
- data/config/locales/sidebars.zh-CN.yml +20 -0
- data/config/locales/sidebars.zh-TW.yml +20 -0
- data/config/locales/zh-CN.yml +827 -0
- data/config/locales/zh-TW.yml +827 -0
- data/config/routes.rb +177 -0
- data/db/migrate/113_initial_schema.rb +205 -0
- data/db/migrate/114_fixes_buggy_articles_and_notes.rb +52 -0
- data/db/migrate/115_drops_categories_for_tags.rb +34 -0
- data/db/migrate/20150207131657_add_missing_indexes.rb +19 -0
- data/db/migrate/20150807134129_simplify_redirect_relations.rb +38 -0
- data/db/migrate/20150808052637_add_blog_ids.rb +33 -0
- data/db/migrate/20150808191127_add_blog_id_to_redirects.rb +15 -0
- data/db/migrate/20150810094754_add_blog_id_to_tags.rb +15 -0
- data/db/migrate/20160108111120_add_devise_to_users.rb +53 -0
- data/db/migrate/20160108184201_move_last_connection_to_last_sign_in_at.rb +16 -0
- data/db/migrate/20160110094906_remove_profiles_rights.rb +14 -0
- data/db/migrate/20160605103918_replace_profile_id_with_string.rb +30 -0
- data/db/migrate/20160605154632_remove_profiles.rb +24 -0
- data/db/migrate/20160701061851_demand_blog_id_on_contents.rb +9 -0
- data/db/migrate/20160701062604_add_blog_id_to_resources.rb +28 -0
- data/db/seeds.rb +37 -0
- data/lib/email_notify.rb +26 -0
- data/lib/format.rb +17 -0
- data/lib/publify_core/engine.rb +23 -0
- data/lib/publify_core/lang.rb +5 -0
- data/lib/publify_core/version.rb +3 -0
- data/lib/publify_core.rb +56 -0
- data/lib/publify_guid.rb +9 -0
- data/lib/publify_plugins.rb +72 -0
- data/lib/publify_textfilter_markdown.rb +44 -0
- data/lib/publify_textfilter_none.rb +14 -0
- data/lib/publify_textfilter_smartypants.rb +14 -0
- data/lib/publify_textfilter_textile.rb +21 -0
- data/lib/publify_textfilter_twitterfilter.rb +33 -0
- data/lib/publify_time.rb +30 -0
- data/lib/sidebar_field.rb +115 -0
- data/lib/sidebar_registry.rb +33 -0
- data/lib/spam_protection.rb +101 -0
- data/lib/stateful.rb +106 -0
- data/lib/tasks/publify_core_tasks.rake +4 -0
- data/lib/text_filter_plugin.rb +182 -0
- data/lib/theme.rb +72 -0
- data/lib/transforms.rb +45 -0
- metadata +865 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
# Methods added to this helper will be available to all templates in the application.
|
|
3
|
+
require 'digest/sha1'
|
|
4
|
+
|
|
5
|
+
module BaseHelper
|
|
6
|
+
include BlogHelper
|
|
7
|
+
|
|
8
|
+
# Need to rewrite this one, quick hack to test my changes.
|
|
9
|
+
attr_reader :page_title
|
|
10
|
+
|
|
11
|
+
def render_sidebars(*sidebars)
|
|
12
|
+
rendered_sidebars = (sidebars.blank? ? Sidebar.order(:active_position) : sidebars).map do |sb|
|
|
13
|
+
@sidebar = sb
|
|
14
|
+
sb.parse_request(content_array, params)
|
|
15
|
+
render_sidebar(sb)
|
|
16
|
+
end
|
|
17
|
+
safe_join rendered_sidebars
|
|
18
|
+
rescue => e
|
|
19
|
+
logger.error e
|
|
20
|
+
logger.error e.backtrace.join("\n")
|
|
21
|
+
I18n.t('errors.render_sidebar')
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def render_sidebar(sidebar)
|
|
25
|
+
render_to_string(partial: sidebar.content_partial, locals: sidebar.to_locals_hash, layout: false)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def themeable_stylesheet_link_tag(name)
|
|
29
|
+
src = this_blog.current_theme.path + "/stylesheets/#{name}.css"
|
|
30
|
+
stylesheet_link_tag "/stylesheets/theme/#{name}.css" if File.exist? src
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def render_to_string(*args, &block)
|
|
34
|
+
controller.send(:render_to_string, *args, &block)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def link_to_permalink(item, title, anchor = nil, style = nil, nofollow = nil, only_path = false)
|
|
38
|
+
options = {}
|
|
39
|
+
options[:class] = style if style
|
|
40
|
+
options[:rel] = 'nofollow' if nofollow
|
|
41
|
+
link_to title, item.permalink_url(anchor, only_path), options
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def avatar_tag(options = {})
|
|
45
|
+
begin
|
|
46
|
+
avatar_class = this_blog.plugin_avatar.constantize
|
|
47
|
+
rescue NameError
|
|
48
|
+
return ''
|
|
49
|
+
end
|
|
50
|
+
return '' unless avatar_class.respond_to?(:get_avatar)
|
|
51
|
+
avatar_class.get_avatar(options)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def meta_tag(name, value)
|
|
55
|
+
tag :meta, name: name, content: value unless value.blank?
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def markup_help_popup(markup, text)
|
|
59
|
+
if markup && markup.commenthelp.size > 1
|
|
60
|
+
link_to text, url_for(controller: 'articles', action: 'markup_help', id: markup.id), onclick: "return popup(this, 'Publify Markup Help')"
|
|
61
|
+
else
|
|
62
|
+
''
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def onhover_show_admin_tools(type, id = nil)
|
|
67
|
+
admin_id = "#admin_#{[type, id].compact.join('_')}"
|
|
68
|
+
tag = []
|
|
69
|
+
tag << %{ onmouseover="if (getCookie('publify_user_profile') == 'admin') { $('#{admin_id}').show(); }" }
|
|
70
|
+
tag << %{ onmouseout="$('#{admin_id}').hide();" }
|
|
71
|
+
safe_join(tag, ' ')
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def feed_title
|
|
75
|
+
if @feed_title.present?
|
|
76
|
+
@feed_title
|
|
77
|
+
elsif @page_title.present?
|
|
78
|
+
@page_title
|
|
79
|
+
else
|
|
80
|
+
this_blog.blog_name
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def html(content, what = :all, _deprecated = false)
|
|
85
|
+
content.html(what)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def display_user_avatar(user, size = 'avatar', klass = 'alignleft')
|
|
89
|
+
if user.resource.present?
|
|
90
|
+
avatar_path = case size
|
|
91
|
+
when 'thumb'
|
|
92
|
+
user.resource.upload.thumb.url
|
|
93
|
+
when 'medium'
|
|
94
|
+
user.resource.upload.medium.url
|
|
95
|
+
when 'large'
|
|
96
|
+
user.resource.upload.large.url
|
|
97
|
+
else
|
|
98
|
+
user.resource.upload.avatar.url
|
|
99
|
+
end
|
|
100
|
+
return if avatar_path.nil?
|
|
101
|
+
avatar_url = File.join(this_blog.base_url, avatar_path)
|
|
102
|
+
elsif user.twitter_profile_image.present?
|
|
103
|
+
avatar_url = user.twitter_profile_image
|
|
104
|
+
end
|
|
105
|
+
return unless avatar_url
|
|
106
|
+
image_tag(avatar_url, alt: user.nickname, class: klass)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def author_picture(status)
|
|
110
|
+
return if status.user.twitter_profile_image.blank?
|
|
111
|
+
|
|
112
|
+
image_tag(status.user.twitter_profile_image, class: 'alignleft', alt: status.user.nickname)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def google_analytics
|
|
116
|
+
unless this_blog.google_analytics.empty?
|
|
117
|
+
<<-HTML
|
|
118
|
+
<script type="text/javascript">
|
|
119
|
+
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
|
120
|
+
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
|
121
|
+
</script>
|
|
122
|
+
<script type="text/javascript">
|
|
123
|
+
var pageTracker = _gat._getTracker("#{this_blog.google_analytics}");
|
|
124
|
+
pageTracker._trackPageview();
|
|
125
|
+
</script>
|
|
126
|
+
HTML
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def page_header_includes
|
|
131
|
+
content_array.map(&:whiteboard).map do |w|
|
|
132
|
+
w.select { |k, _v| k =~ /^page_header_/ }.map do |_, v|
|
|
133
|
+
v = v.chomp
|
|
134
|
+
# trim the same number of spaces from the beginning of each line
|
|
135
|
+
# this way plugins can indent nicely without making ugly source output
|
|
136
|
+
spaces = /\A[ \t]*/.match(v)[0].gsub(/\t/, ' ')
|
|
137
|
+
v.gsub!(/^#{spaces}/, ' ') # add 2 spaces to line up with the assumed position of the surrounding tags
|
|
138
|
+
end
|
|
139
|
+
end.flatten.uniq.join("\n")
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def feed_atom
|
|
143
|
+
feed_for('atom')
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def feed_rss
|
|
147
|
+
feed_for('rss')
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def content_array
|
|
151
|
+
if @articles
|
|
152
|
+
@articles
|
|
153
|
+
elsif @article
|
|
154
|
+
[@article]
|
|
155
|
+
elsif @page
|
|
156
|
+
[@page]
|
|
157
|
+
else
|
|
158
|
+
[]
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def display_date(date)
|
|
163
|
+
l(date, format: this_blog.date_format)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def display_time(time)
|
|
167
|
+
time.strftime(this_blog.time_format)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def display_date_and_time(timestamp)
|
|
171
|
+
if this_blog.date_format == 'setting_date_format_distance_of_time_in_words'
|
|
172
|
+
timeago_tag timestamp, date_only: false
|
|
173
|
+
else
|
|
174
|
+
"#{display_date(timestamp)} #{t('helper.at')} #{display_time(timestamp)}"
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def show_meta_keyword
|
|
179
|
+
return unless this_blog.use_meta_keyword
|
|
180
|
+
meta_tag 'keywords', @keywords unless @keywords.blank?
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def stop_index_robots?(blog)
|
|
184
|
+
stop = (params[:year].present? || params[:page].present?)
|
|
185
|
+
stop = blog.unindex_tags if controller_name == 'tags'
|
|
186
|
+
stop = blog.unindex_categories if controller_name == 'categories'
|
|
187
|
+
stop
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def get_reply_context_url(reply)
|
|
191
|
+
link_to(reply['user']['name'], reply['user']['entities']['url']['urls'][0]['expanded_url'])
|
|
192
|
+
rescue
|
|
193
|
+
link_to(reply['user']['name'], "https://twitter.com/#{reply['user']['name']}")
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def get_reply_context_twitter_link(reply)
|
|
197
|
+
link_to(display_date_and_time(reply['created_at'].to_time.in_time_zone),
|
|
198
|
+
"https://twitter.com/#{reply['user']['screen_name']}/status/#{reply['id_str']}")
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
private
|
|
202
|
+
|
|
203
|
+
def feed_for(type)
|
|
204
|
+
if params[:action] == 'search'
|
|
205
|
+
url_for(only_path: false, format: type, q: params[:q])
|
|
206
|
+
elsif !@article.nil?
|
|
207
|
+
@article.feed_url(type)
|
|
208
|
+
elsif !@auto_discovery_url_atom.nil?
|
|
209
|
+
instance_variable_get("@auto_discovery_url_#{type}")
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# fetches appropriate html content for RSS and ATOM feeds. Checks for:
|
|
214
|
+
# - article being password protected
|
|
215
|
+
# - hiding extended content on RSS. In this case if there is an excerpt we
|
|
216
|
+
# show the excerpt, or else we show the body
|
|
217
|
+
def fetch_html_content_for_feeds(item, this_blog)
|
|
218
|
+
if item.password_protected?
|
|
219
|
+
"<p>This article is password protected. Please <a href='#{item.permalink_url}'>fill in your password</a> to read it</p>"
|
|
220
|
+
elsif this_blog.hide_extended_on_rss
|
|
221
|
+
if item.excerpt? && !item.excerpt.empty?
|
|
222
|
+
item.excerpt
|
|
223
|
+
else
|
|
224
|
+
html(item, :body)
|
|
225
|
+
end
|
|
226
|
+
else
|
|
227
|
+
html(item, :all)
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def nofollowify_links(string)
|
|
232
|
+
if this_blog.dofollowify
|
|
233
|
+
string
|
|
234
|
+
else
|
|
235
|
+
string.gsub(/<a(.*?)>/i, '<a\1 rel="nofollow">')
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
def nofollowified_link_to(text, url)
|
|
240
|
+
if this_blog.dofollowify
|
|
241
|
+
link_to(text, url)
|
|
242
|
+
else
|
|
243
|
+
link_to(text, url, rel: 'nofollow')
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module BlogHelper
|
|
2
|
+
# The base URL for this request, calculated by looking up the URL for the main
|
|
3
|
+
# blog index page.
|
|
4
|
+
def blog_base_url
|
|
5
|
+
url_for(controller: '/articles', action: 'index').gsub(%r{/$}, '')
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# Find the blog whose base_url matches the current location.
|
|
9
|
+
def this_blog
|
|
10
|
+
@blog ||= Blog.find_blog(blog_base_url)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module XmlHelper
|
|
2
|
+
def collection_lastmod(collection)
|
|
3
|
+
article_updated = collection.articles.order(updated_at: :desc).first
|
|
4
|
+
article_published = collection.articles.order(published_at: :desc).first
|
|
5
|
+
|
|
6
|
+
times = []
|
|
7
|
+
times.push article_updated.updated_at if article_updated
|
|
8
|
+
times.push article_published.updated_at if article_published
|
|
9
|
+
|
|
10
|
+
if times.empty?
|
|
11
|
+
Time.at(0).xmlschema
|
|
12
|
+
else
|
|
13
|
+
times.max.xmlschema
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
class NotificationMailer < ActionMailer::Base
|
|
2
|
+
helper :base
|
|
3
|
+
layout nil
|
|
4
|
+
|
|
5
|
+
def article(article, user)
|
|
6
|
+
@user = user
|
|
7
|
+
@blog = article.blog
|
|
8
|
+
@article = article
|
|
9
|
+
build_mail @blog, @user, "New article: #{article.title}"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def comment(comment, user)
|
|
13
|
+
@user = user
|
|
14
|
+
@blog = comment.blog
|
|
15
|
+
@comment = comment
|
|
16
|
+
build_mail @blog, @user, "New comment on #{comment.article.title}"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def notif_user(user)
|
|
20
|
+
@user = user
|
|
21
|
+
# TODO: Make user blog-dependent
|
|
22
|
+
@blog = Blog.first
|
|
23
|
+
build_mail @blog, @user, 'Welcome to Publify'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def make_subject(blog, subject)
|
|
29
|
+
"[#{blog.blog_name}] #{subject}"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def build_mail(blog, user, subject)
|
|
33
|
+
headers['X-Mailer'] = "Publify #{PublifyCore::VERSION}"
|
|
34
|
+
mail(from: blog.email_from,
|
|
35
|
+
to: user.email,
|
|
36
|
+
subject: make_subject(blog, subject))
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
require 'cancancan'
|
|
2
|
+
|
|
3
|
+
class Ability
|
|
4
|
+
include CanCan::Ability
|
|
5
|
+
|
|
6
|
+
def initialize(user)
|
|
7
|
+
return unless user
|
|
8
|
+
|
|
9
|
+
case user.profile
|
|
10
|
+
when 'admin'
|
|
11
|
+
add_admin_abilities
|
|
12
|
+
add_publisher_abilities
|
|
13
|
+
add_contributor_abilities
|
|
14
|
+
when 'publisher'
|
|
15
|
+
add_publisher_abilities
|
|
16
|
+
add_contributor_abilities
|
|
17
|
+
when 'contributor'
|
|
18
|
+
add_contributor_abilities
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def add_admin_abilities
|
|
25
|
+
can :manage, 'admin/cache'
|
|
26
|
+
can :manage, 'admin/migrations'
|
|
27
|
+
can :manage, 'admin/seo'
|
|
28
|
+
can :manage, 'admin/settings'
|
|
29
|
+
can :manage, 'admin/sidebar'
|
|
30
|
+
can :manage, 'admin/textfilters'
|
|
31
|
+
can :manage, 'admin/themes'
|
|
32
|
+
can :manage, 'admin/users'
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def add_publisher_abilities
|
|
36
|
+
can :manage, 'admin/content'
|
|
37
|
+
can :manage, 'admin/feedback'
|
|
38
|
+
can :manage, 'admin/notes'
|
|
39
|
+
can :manage, 'admin/pages'
|
|
40
|
+
can :manage, 'admin/post_types'
|
|
41
|
+
can :manage, 'admin/redirects'
|
|
42
|
+
can :manage, 'admin/resources'
|
|
43
|
+
can :manage, 'admin/tags'
|
|
44
|
+
|
|
45
|
+
can :manage, 'articles'
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def add_contributor_abilities
|
|
49
|
+
can :manage, 'admin/dashboard'
|
|
50
|
+
can :manage, 'admin/profiles'
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
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'
|
|
6
|
+
|
|
7
|
+
attr_accessor :archives
|
|
8
|
+
|
|
9
|
+
def self.date_func
|
|
10
|
+
@date_func ||=
|
|
11
|
+
begin
|
|
12
|
+
if Content.connection.is_a?(ActiveRecord::ConnectionAdapters::SQLite3Adapter)
|
|
13
|
+
"strftime('%Y', published_at) as year, strftime('%m', published_at) as month"
|
|
14
|
+
else
|
|
15
|
+
'extract(year from published_at) as year,extract(month from published_at) as month'
|
|
16
|
+
end
|
|
17
|
+
rescue NameError
|
|
18
|
+
'extract(year from published_at) as year,extract(month from published_at) as month'
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def parse_request(_contents, _params)
|
|
23
|
+
# The original query that was here instantiated every article and every
|
|
24
|
+
# tag, and then sorted through them just to do a 'group by date'.
|
|
25
|
+
# Unfortunately, there's no universally-supported way to do this
|
|
26
|
+
# across all three of our supported DBs. So, we resort to a bit of
|
|
27
|
+
# DB-specific code.
|
|
28
|
+
date_func = self.class.date_func
|
|
29
|
+
|
|
30
|
+
article_counts = Content.find_by_sql(["select count(*) as count, #{date_func} from contents where type='Article' and published = ? and published_at < ? group by year,month order by year desc,month desc limit ? ", true, Time.now, count.to_i])
|
|
31
|
+
|
|
32
|
+
@archives = article_counts.map do |entry|
|
|
33
|
+
month = entry.month.to_i
|
|
34
|
+
year = entry.year.to_i
|
|
35
|
+
{
|
|
36
|
+
name: I18n.l(Date.new(year, month), format: '%B %Y'),
|
|
37
|
+
month: month,
|
|
38
|
+
year: year,
|
|
39
|
+
article_count: entry.count
|
|
40
|
+
}
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
SidebarRegistry.register_sidebar ArchivesSidebar
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
class Article::Factory
|
|
2
|
+
attr_reader :blog, :user
|
|
3
|
+
|
|
4
|
+
def initialize(blog, user)
|
|
5
|
+
@blog = blog
|
|
6
|
+
@user = user
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def default
|
|
10
|
+
blog.articles.build.tap do |art|
|
|
11
|
+
art.allow_comments = blog.default_allow_comments
|
|
12
|
+
art.allow_pings = blog.default_allow_pings
|
|
13
|
+
art.text_filter = user.default_text_filter
|
|
14
|
+
art.published = true
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def get_or_build_from(id)
|
|
19
|
+
return blog.articles.find(id) if id.present?
|
|
20
|
+
default
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def match_permalink_format(path, format)
|
|
24
|
+
article_params = extract_params(path, format)
|
|
25
|
+
requested_article(article_params) if article_params
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def requested_article(params = {})
|
|
29
|
+
params[:title] ||= params[:article_id]
|
|
30
|
+
Article.requested_article(params)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def extract_params(path, format)
|
|
34
|
+
specs = format.split('/')
|
|
35
|
+
specs.delete('')
|
|
36
|
+
parts = path.split('/')
|
|
37
|
+
parts.delete('')
|
|
38
|
+
|
|
39
|
+
return if parts.length != specs.length
|
|
40
|
+
|
|
41
|
+
specs.zip(parts).reduce({}) do |result, (spec, item)|
|
|
42
|
+
if spec =~ /(.*)%(.*)%(.*)/
|
|
43
|
+
before_format = Regexp.last_match[1]
|
|
44
|
+
format_string = Regexp.last_match[2]
|
|
45
|
+
after_format = Regexp.last_match[3]
|
|
46
|
+
item =~ /^#{before_format}(.*)#{after_format}$/
|
|
47
|
+
break unless Regexp.last_match
|
|
48
|
+
value = Regexp.last_match[1]
|
|
49
|
+
result[format_string.to_sym] = value
|
|
50
|
+
elsif spec != item
|
|
51
|
+
break
|
|
52
|
+
end
|
|
53
|
+
result
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
module Article::States
|
|
2
|
+
class Base < Stateful::State
|
|
3
|
+
alias content model
|
|
4
|
+
|
|
5
|
+
def to_s
|
|
6
|
+
self.class.to_s.demodulize
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def exit_hook(_target)
|
|
10
|
+
::Rails.logger.debug("#{content} leaving state #{self.class}")
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def enter_hook
|
|
14
|
+
::Rails.logger.debug("#{content} entering state #{self.class}")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def post_trigger
|
|
18
|
+
true
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def send_notifications
|
|
22
|
+
true
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def send_pings
|
|
26
|
+
true
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def withdraw
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
class New < Base
|
|
34
|
+
def enter_hook
|
|
35
|
+
super
|
|
36
|
+
content[:published] = false
|
|
37
|
+
content[:published_at] = nil
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def published=(boolean)
|
|
41
|
+
content.state = :just_published if boolean
|
|
42
|
+
boolean
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def published_at=(new_time)
|
|
46
|
+
unless new_time.nil?
|
|
47
|
+
content.state = new_time <= Time.new ? :just_published : :publication_pending
|
|
48
|
+
end
|
|
49
|
+
content[:published_at] = new_time
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def draft?
|
|
53
|
+
true
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
class JustPublished < Base
|
|
58
|
+
def enter_hook
|
|
59
|
+
super
|
|
60
|
+
content.just_changed_published_status = true
|
|
61
|
+
content.state = :published
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
class Published < Base
|
|
66
|
+
def enter_hook
|
|
67
|
+
super
|
|
68
|
+
content[:published] = true
|
|
69
|
+
content[:published_at] ||= Time.now
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def published=(boolean)
|
|
73
|
+
content.state = :just_withdrawn unless boolean
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def withdraw
|
|
77
|
+
content.state = :just_withdrawn
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def published_at=(new_time)
|
|
81
|
+
return if new_time.blank?
|
|
82
|
+
content[:published_at] = new_time
|
|
83
|
+
content.state = :publication_pending if new_time > Time.now
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def send_notifications
|
|
87
|
+
content.really_send_notifications if just_published?
|
|
88
|
+
true
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def send_pings
|
|
92
|
+
content.really_send_pings if just_published?
|
|
93
|
+
true
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def just_published?
|
|
97
|
+
content.just_changed_published_status?
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
class JustWithdrawn < Base
|
|
102
|
+
def enter_hook
|
|
103
|
+
super
|
|
104
|
+
content.just_changed_published_status = true
|
|
105
|
+
content.state = :withdrawn
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
class Withdrawn < Base
|
|
110
|
+
def enter_hook
|
|
111
|
+
content[:published] = false
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def published=(boolean)
|
|
115
|
+
return unless boolean
|
|
116
|
+
content.state = :published
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def published_at=(new_time)
|
|
120
|
+
content[:published_at] = new_time
|
|
121
|
+
Trigger.remove(content, trigger_method: 'publish!')
|
|
122
|
+
return if new_time.nil? || new_time <= Time.now
|
|
123
|
+
content.state = :publication_pending
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
class PublicationPending < Base
|
|
128
|
+
def enter_hook
|
|
129
|
+
content[:published] = false if content.new_record?
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def published=(published)
|
|
133
|
+
content[:published] = published
|
|
134
|
+
|
|
135
|
+
if published && content.published_at <= Time.now
|
|
136
|
+
content.state = :just_published
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def published_at=(new_time)
|
|
141
|
+
content[:published_at] = new_time
|
|
142
|
+
Trigger.remove(content, trigger_method: 'publish!')
|
|
143
|
+
if new_time.nil?
|
|
144
|
+
content.state = :draft
|
|
145
|
+
elsif new_time <= Time.now
|
|
146
|
+
content.state = :just_published
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def post_trigger
|
|
151
|
+
Trigger.post_action(content.published_at, content, 'publish!')
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def withdraw(content)
|
|
155
|
+
content.state = :draft
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
class Draft < Base
|
|
160
|
+
def enter_hook
|
|
161
|
+
super
|
|
162
|
+
content[:published] = false
|
|
163
|
+
content[:published_at] = nil
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def published=(boolean)
|
|
167
|
+
content.state = :just_published if boolean
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def published_at=(new_time)
|
|
171
|
+
# Because of the workings of the controller, we should ignore
|
|
172
|
+
# publication times before the current time.
|
|
173
|
+
return if new_time.nil? || new_time <= Time.now
|
|
174
|
+
content[:published_at] = new_time
|
|
175
|
+
content.state = :publication_pending
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|