dm_cms 4.2.1.5
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 +22 -0
- data/README.md +31 -0
- data/Rakefile +34 -0
- data/app/assets/javascripts/dm_cms/admin.js +58 -0
- data/app/assets/javascripts/dm_cms/application.js +16 -0
- data/app/assets/stylesheets/dm_cms/admin.css +3 -0
- data/app/assets/stylesheets/dm_cms/application.css +13 -0
- data/app/controllers/dm_cms/admin/admin_controller.rb +14 -0
- data/app/controllers/dm_cms/admin/cms_blogs_controller.rb +89 -0
- data/app/controllers/dm_cms/admin/cms_contentitems_controller.rb +96 -0
- data/app/controllers/dm_cms/admin/cms_pages_controller.rb +100 -0
- data/app/controllers/dm_cms/admin/cms_posts_controller.rb +67 -0
- data/app/controllers/dm_cms/admin/cms_snippets_controller.rb +73 -0
- data/app/controllers/dm_cms/admin/dashboard_controller.rb +12 -0
- data/app/controllers/dm_cms/admin/media_files_controller.rb +80 -0
- data/app/controllers/dm_cms/application_controller.rb +9 -0
- data/app/controllers/dm_cms/blogs_controller.rb +50 -0
- data/app/controllers/dm_cms/comments_controller.rb +3 -0
- data/app/controllers/dm_cms/contact_form_controller.rb +27 -0
- data/app/controllers/dm_cms/pages_controller.rb +67 -0
- data/app/controllers/dm_cms/posts_controller.rb +69 -0
- data/app/datatables/blog_user_datatable.rb +79 -0
- data/app/helpers/dm_cms/analytics_helper.rb +27 -0
- data/app/helpers/dm_cms/application_helper.rb +4 -0
- data/app/helpers/dm_cms/cms_contentitems_helper.rb +8 -0
- data/app/helpers/dm_cms/cms_pages_helper.rb +30 -0
- data/app/helpers/dm_cms/pages_helper.rb +204 -0
- data/app/helpers/dm_cms/posts_helper.rb +26 -0
- data/app/helpers/dm_cms/render_helper.rb +50 -0
- data/app/inputs/media_input.rb +17 -0
- data/app/liquid/tags/markdown.rb +30 -0
- data/app/mailers/post_notify_mailer.rb +36 -0
- data/app/models/cms_blog.rb +89 -0
- data/app/models/cms_contentitem.rb +76 -0
- data/app/models/cms_page.rb +227 -0
- data/app/models/cms_post.rb +76 -0
- data/app/models/cms_snippet.rb +42 -0
- data/app/models/contact_form.rb +28 -0
- data/app/models/dm_cms/concerns/ability.rb +54 -0
- data/app/models/dm_cms/permitted_params.rb +34 -0
- data/app/models/media_file.rb +102 -0
- data/app/presenters/cms_blog_presenter.rb +15 -0
- data/app/presenters/cms_page_presenter.rb +23 -0
- data/app/presenters/cms_post_presenter.rb +11 -0
- data/app/presenters/cms_snippet_presenter.rb +10 -0
- data/app/uploaders/media_uploader.rb +169 -0
- data/app/views/customized/analytics/_google_analytics.html.erb +11 -0
- data/app/views/dm_cms/admin/cms_blogs/_form.html.erb +34 -0
- data/app/views/dm_cms/admin/cms_blogs/edit.html.erb +2 -0
- data/app/views/dm_cms/admin/cms_blogs/index.html.erb +44 -0
- data/app/views/dm_cms/admin/cms_blogs/new.html.erb +2 -0
- data/app/views/dm_cms/admin/cms_blogs/show.html.erb +167 -0
- data/app/views/dm_cms/admin/cms_contentitems/_form.html.erb +43 -0
- data/app/views/dm_cms/admin/cms_contentitems/_form_dialog.html.erb +17 -0
- data/app/views/dm_cms/admin/cms_contentitems/edit.html.erb +1 -0
- data/app/views/dm_cms/admin/cms_contentitems/markdown.html.erb +21 -0
- data/app/views/dm_cms/admin/cms_contentitems/new_content.html.erb +1 -0
- data/app/views/dm_cms/admin/cms_pages/_content_toolbar.html.erb +11 -0
- data/app/views/dm_cms/admin/cms_pages/_form.html.erb +50 -0
- data/app/views/dm_cms/admin/cms_pages/_tree.html.erb +20 -0
- data/app/views/dm_cms/admin/cms_pages/_tree_sidebar.html.erb +8 -0
- data/app/views/dm_cms/admin/cms_pages/edit.html.erb +2 -0
- data/app/views/dm_cms/admin/cms_pages/index.html.erb +32 -0
- data/app/views/dm_cms/admin/cms_pages/new_page.html.erb +2 -0
- data/app/views/dm_cms/admin/cms_pages/show.html.erb +54 -0
- data/app/views/dm_cms/admin/cms_posts/_form.html.erb +59 -0
- data/app/views/dm_cms/admin/cms_posts/edit.html.erb +2 -0
- data/app/views/dm_cms/admin/cms_posts/new.html.erb +1 -0
- data/app/views/dm_cms/admin/cms_snippets/_form.html.erb +28 -0
- data/app/views/dm_cms/admin/cms_snippets/edit.html.erb +1 -0
- data/app/views/dm_cms/admin/cms_snippets/index.html.erb +29 -0
- data/app/views/dm_cms/admin/cms_snippets/new.html.erb +1 -0
- data/app/views/dm_cms/admin/dashboard/_widget_blog_comments.html.erb +37 -0
- data/app/views/dm_cms/admin/dashboard/widget_blog_comments.js.erb +1 -0
- data/app/views/dm_cms/admin/media_files/_form.html.erb +102 -0
- data/app/views/dm_cms/admin/media_files/edit.html.erb +3 -0
- data/app/views/dm_cms/admin/media_files/index.html.erb +98 -0
- data/app/views/dm_cms/admin/media_files/new.html.erb +3 -0
- data/app/views/dm_cms/admin/shared/_liquid_tags_ref.html.erb +35 -0
- data/app/views/dm_cms/blogs/show.html.erb +0 -0
- data/app/views/dm_cms/blogs/toggle_follow.js.coffee +5 -0
- data/app/views/dm_cms/contact_form/create.html.erb +2 -0
- data/app/views/dm_cms/contact_form/create.js.erb +2 -0
- data/app/views/dm_cms/pages/_content_fragment.html.erb +13 -0
- data/app/views/dm_cms/pages/_snippet_fragment.html.erb +12 -0
- data/app/views/dm_cms/pages/coming_soon.html.erb +2 -0
- data/app/views/dm_cms/pages/show.html.erb +0 -0
- data/app/views/dm_cms/posts/show.html.erb +0 -0
- data/app/views/dm_cms/shared/_comment.html.erb +22 -0
- data/app/views/dm_cms/shared/_comment_form.html.erb +16 -0
- data/app/views/dm_cms/shared/_comment_list.html.erb +11 -0
- data/app/views/dm_cms/shared/_social_buttons.html.erb +6 -0
- data/app/views/layouts/email_templates/dm_cms_email_layout.html.erb +320 -0
- data/app/views/layouts/email_templates/dm_cms_email_layout.text.erb +1 -0
- data/app/views/layouts/email_templates/dm_cms_post_notify.html.erb +13 -0
- data/app/views/layouts/email_templates/dm_cms_post_notify.text.erb +9 -0
- data/app/views/liquid_tags/_contact_form.html.erb +17 -0
- data/config/initializers/liquid_init.rb +2 -0
- data/config/locales/cms.cs.yml +42 -0
- data/config/locales/cms.de.yml +42 -0
- data/config/locales/cms.en.yml +42 -0
- data/config/locales/cms.fi.yml +42 -0
- data/config/locales/cms.ja.yml +42 -0
- data/config/routes.rb +70 -0
- data/db/migrate/20121103181909_create_cms.rb +91 -0
- data/db/migrate/20130206213720_add_account_to_cms.rb +10 -0
- data/db/migrate/20130507123255_create_blog.rb +61 -0
- data/db/migrate/20130531212537_add_notification_sent.rb +5 -0
- data/db/migrate/20130605184116_add_blog_comment.rb +7 -0
- data/db/migrate/20131128201053_add_blog_image.rb +5 -0
- data/db/migrate/20140217135228_rename_snippet_slug.rb +13 -0
- data/db/migrate/20140303121217_add_requires_subscription_blog.rb +7 -0
- data/db/migrate/20140328205246_add_pages_ranked_model.rb +22 -0
- data/db/migrate/20140423113417_add_blog_owner.rb +6 -0
- data/db/migrate/20140428122156_create_media_files.rb +29 -0
- data/db/migrate/20140523134543_add_cmspage_summary.rb +6 -0
- data/db/migrate/20140601151631_add_blog_image_email_header.rb +5 -0
- data/db/migrate/20141004154725_add_header_image.rb +9 -0
- data/db/migrate/20160821150108_index_foreign_keys_in_cms_blogs.rb +6 -0
- data/db/migrate/20160821150109_index_foreign_keys_in_cms_media_files.rb +6 -0
- data/db/migrate/20160821150110_index_foreign_keys_in_cms_posts.rb +6 -0
- data/lib/dm_cms.rb +4 -0
- data/lib/dm_cms/engine.rb +16 -0
- data/lib/dm_cms/liquid/filters/liquid_filters.rb +11 -0
- data/lib/dm_cms/liquid/tags/contact_form.rb +35 -0
- data/lib/dm_cms/liquid/tags/div.rb +42 -0
- data/lib/dm_cms/liquid/tags/image.rb +76 -0
- data/lib/dm_cms/liquid/tags/quote.rb +38 -0
- data/lib/dm_cms/liquid/tags/snippet.rb +37 -0
- data/lib/dm_cms/liquid/tags/url_asset.rb +41 -0
- data/lib/dm_cms/liquid/tags/url_media.rb +42 -0
- data/lib/dm_cms/liquid/tags/url_protected.rb +31 -0
- data/lib/tasks/dm_cms_tasks.rake +4 -0
- data/spec/controllers/admin/cms_blogs_controller_spec.rb +173 -0
- data/spec/controllers/admin/cms_pages_controller_spec.rb +182 -0
- data/spec/controllers/admin/cms_posts_controller_spec.rb +166 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/ability.rb +12 -0
- data/spec/dummy/app/models/user.rb +6 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +26 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +82 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/_themes_for_rails.rb +39 -0
- data/spec/dummy/config/initializers/account_initialization.rb +28 -0
- data/spec/dummy/config/initializers/assets.rb +8 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/dm_core.rb +6 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +19 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20141114170927_add_globalize_countries.dm_core.rb +50 -0
- data/spec/dummy/db/migrate/20141114170928_devise_create_users.dm_core.rb +46 -0
- data/spec/dummy/db/migrate/20141114170929_add_user_fields.dm_core.rb +14 -0
- data/spec/dummy/db/migrate/20141114170930_rolify_create_roles.dm_core.rb +20 -0
- data/spec/dummy/db/migrate/20141114170931_add_last_access.dm_core.rb +10 -0
- data/spec/dummy/db/migrate/20141114170932_create_versions.dm_core.rb +19 -0
- data/spec/dummy/db/migrate/20141114170933_add_object_changes_column_to_versions.dm_core.rb +12 -0
- data/spec/dummy/db/migrate/20141114170934_create_dm_core_accounts.dm_core.rb +13 -0
- data/spec/dummy/db/migrate/20141114170935_add_account_to_users.dm_core.rb +9 -0
- data/spec/dummy/db/migrate/20141114170936_create_preferences.dm_core.rb +13 -0
- data/spec/dummy/db/migrate/20141114170937_create_comments.dm_core.rb +22 -0
- data/spec/dummy/db/migrate/20141114170938_add_activity.dm_core.rb +21 -0
- data/spec/dummy/db/migrate/20141114170939_add_type_to_comments.dm_core.rb +9 -0
- data/spec/dummy/db/migrate/20141114170940_add_category.dm_core.rb +28 -0
- data/spec/dummy/db/migrate/20141114170941_create_email_table.dm_core.rb +26 -0
- data/spec/dummy/db/migrate/20141114170942_add_user_profile.dm_core.rb +46 -0
- data/spec/dummy/db/migrate/20141114170943_add_profile_email.dm_core.rb +14 -0
- data/spec/dummy/db/migrate/20141114170944_create_payment_history.dm_core.rb +37 -0
- data/spec/dummy/db/migrate/20141114170945_change_anchor_field.dm_core.rb +10 -0
- data/spec/dummy/db/migrate/20141114170946_create_user_site_profile.dm_core.rb +27 -0
- data/spec/dummy/db/migrate/20141114170947_add_avatar.dm_core.rb +12 -0
- data/spec/dummy/db/migrate/20141114170948_add_notify_to_payment_history.dm_core.rb +8 -0
- data/spec/dummy/db/migrate/20141114170949_acts_as_votable_migration.dm_core.rb +28 -0
- data/spec/dummy/db/migrate/20141114170950_add_user_site_profile_uuid.dm_core.rb +19 -0
- data/spec/dummy/db/migrate/20141114170951_add_invoice_id.dm_core.rb +7 -0
- data/spec/dummy/db/migrate/20141114170952_acts_as_follower_migration.dm_core.rb +18 -0
- data/spec/dummy/db/migrate/20141114170953_rename_invoice_id.dm_core.rb +12 -0
- data/spec/dummy/db/migrate/20141114170954_add_core_addresses.dm_core.rb +18 -0
- data/spec/dummy/db/migrate/20141114170955_papertrail_increase_column.dm_core.rb +9 -0
- data/spec/dummy/db/migrate/20141114170956_acts_as_taggable_on_migration.dm_core.rb +32 -0
- data/spec/dummy/db/migrate/20141114170957_add_missing_unique_indices.dm_core.rb +23 -0
- data/spec/dummy/db/migrate/20141114170958_add_taggings_counter_cache_to_tags.dm_core.rb +16 -0
- data/spec/dummy/db/migrate/20141114170959_create_custom_fields.dm_core.rb +40 -0
- data/spec/dummy/db/migrate/20141114170960_add_missing_taggable_index.dm_core.rb +11 -0
- data/spec/dummy/db/migrate/20141114170961_create_documents.dm_knowledge.rb +19 -0
- data/spec/dummy/db/migrate/20141114170962_add_document_notes.dm_knowledge.rb +7 -0
- data/spec/dummy/db/migrate/20160128134522_add_favored_locale.dm_core.rb +17 -0
- data/spec/dummy/db/migrate/20160128134523_update_papertrail_v4.dm_core.rb +41 -0
- data/spec/dummy/db/schema.rb +590 -0
- data/spec/dummy/db/seeds.rb +18 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/themes/_mbus/_readme.md +6 -0
- data/spec/dummy/themes/_mbus/_theme.yml +21 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/javascripts/application.js +9 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/javascripts/bootstrap.js +2114 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/javascripts/bootstrap.min.js +6 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/javascripts/contact_me.js +75 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/javascripts/jqBootstrapValidation.js +912 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/javascripts/jquery-1.11.0.js +4 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/application.css +14 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/bootstrap.css +6203 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/bootstrap.min.css +5 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/css/font-awesome.css +1566 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/css/font-awesome.min.css +4 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/fonts/FontAwesome.otf +0 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/fonts/fontawesome-webfont.eot +0 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/fonts/fontawesome-webfont.svg +504 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/fonts/fontawesome-webfont.ttf +0 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/fonts/fontawesome-webfont.woff +0 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/less/bordered-pulled.less +16 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/less/core.less +12 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/less/fixed-width.less +6 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/less/font-awesome.less +17 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/less/icons.less +506 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/less/larger.less +13 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/less/list.less +19 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/less/mixins.less +20 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/less/path.less +14 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/less/rotated-flipped.less +9 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/less/spinning.less +32 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/less/stacked.less +20 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/less/variables.less +515 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/scss/_bordered-pulled.scss +16 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/scss/_core.scss +12 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/scss/_fixed-width.scss +6 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/scss/_icons.scss +506 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/scss/_larger.scss +13 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/scss/_list.scss +19 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/scss/_mixins.scss +20 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/scss/_path.scss +14 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/scss/_rotated-flipped.scss +9 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/scss/_spinning.scss +32 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/scss/_stacked.scss +20 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/scss/_variables.scss +515 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/scss/font-awesome.scss +17 -0
- data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/modern-business.css +93 -0
- data/spec/dummy/themes/_mbus/theme_support/config/load_theme.rb +0 -0
- data/spec/dummy/themes/_mbus/theme_support/locales/site.cs.yml +57 -0
- data/spec/dummy/themes/_mbus/theme_support/locales/site.de.yml +57 -0
- data/spec/dummy/themes/_mbus/theme_support/locales/site.en.yml +57 -0
- data/spec/dummy/themes/_mbus/theme_support/locales/site.fi.yml +58 -0
- data/spec/dummy/themes/_mbus/theme_support/locales/site.ja.yml +57 -0
- data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/_blog_right_sidebar.html.erb +91 -0
- data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/_comment.html.erb +21 -0
- data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/_comment_form.html.erb +16 -0
- data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/_comment_list.html.erb +7 -0
- data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/_comment_section.html.erb +17 -0
- data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/_page_footer.html.erb +11 -0
- data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/_page_header.html.erb +39 -0
- data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/_page_top.html.erb +24 -0
- data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/_post_summary_item.html.erb +11 -0
- data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/_social_buttons_initialization.html.erb +10 -0
- data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/blog.html.erb +47 -0
- data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/blog_post.html.erb +55 -0
- data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/content_full_width.html.erb +28 -0
- data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/content_with_left_nav.html.erb +44 -0
- data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/index.html.erb +19 -0
- data/spec/dummy/themes/local/_theme.yml +8 -0
- data/spec/factories/accounts.rb +17 -0
- data/spec/factories/blogs.rb +19 -0
- data/spec/factories/posts.rb +23 -0
- data/spec/factories/user_profiles.rb +10 -0
- data/spec/factories/users.rb +19 -0
- data/spec/features/admin/blog_admin_spec.rb +16 -0
- data/spec/models/cms_blog_spec.rb +37 -0
- data/spec/models/cms_page_spec.rb +9 -0
- data/spec/models/cms_post_spec.rb +44 -0
- data/spec/rails_helper.rb +70 -0
- data/spec/spec_helper.rb +85 -0
- data/spec/support/accounts.rb +17 -0
- data/spec/support/devise.rb +44 -0
- data/spec/support/fix_locale.rb +57 -0
- metadata +545 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
class CmsPost < ActiveRecord::Base
|
|
2
|
+
|
|
3
|
+
# --- globalize (don't use versioning: true, translations erased when updating regular model data. Maybe fixed in github version)
|
|
4
|
+
translates :title, :summary, :content, :fallbacks_for_empty_translations => true #, :versioning => true
|
|
5
|
+
globalize_accessors :locales => DmCore::Language.language_array
|
|
6
|
+
|
|
7
|
+
# --- FriendlyId
|
|
8
|
+
extend FriendlyId
|
|
9
|
+
include DmCore::Concerns::FriendlyId
|
|
10
|
+
|
|
11
|
+
# --- re-define so it can be scoped to the blog as well
|
|
12
|
+
friendly_id :model_slug, use: :scoped, scope: [:account_id, :cms_blog]
|
|
13
|
+
|
|
14
|
+
acts_as_commentable
|
|
15
|
+
|
|
16
|
+
belongs_to :cms_blog
|
|
17
|
+
belongs_to :account
|
|
18
|
+
|
|
19
|
+
default_scope { where(account_id: Account.current.id) }
|
|
20
|
+
scope :published, -> { where("published_on IS NOT NULL AND published_on <= ?", Time.now ) }
|
|
21
|
+
|
|
22
|
+
validates :title, presence_default_locale: true
|
|
23
|
+
validates :summary, liquid: { :locales => true }, presence_default_locale: true
|
|
24
|
+
validates :content, liquid: { :locales => true }, presence_default_locale: true
|
|
25
|
+
validates_uniqueness_of :slug, scope: [:account_id, :cms_blog_id]
|
|
26
|
+
|
|
27
|
+
self.per_page = 10
|
|
28
|
+
|
|
29
|
+
# Base the slug on the default locale
|
|
30
|
+
#------------------------------------------------------------------------------
|
|
31
|
+
def model_slug
|
|
32
|
+
send("title_#{Account.current.preferred_default_locale}")
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
#------------------------------------------------------------------------------
|
|
36
|
+
def is_published?
|
|
37
|
+
!published_on.nil? && published_on <= Time.now
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Allow comments if also enabled in the blog
|
|
41
|
+
#------------------------------------------------------------------------------
|
|
42
|
+
def comments_allowed?
|
|
43
|
+
cms_blog.comments_allowed? && comments_allowed
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Send post notification to any members and followers. Updates the
|
|
47
|
+
# :notification_sent_on column after emails sent.
|
|
48
|
+
# Use 'sets' to only end up with a unique list of users
|
|
49
|
+
#------------------------------------------------------------------------------
|
|
50
|
+
def send_notification_emails(test_user = nil)
|
|
51
|
+
if test_user
|
|
52
|
+
email = PostNotifyMailer.post_notify(test_user, self, self.account).deliver_now
|
|
53
|
+
return (email ? 1 : 0)
|
|
54
|
+
else
|
|
55
|
+
user_list = cms_blog.member_list(:all).to_set
|
|
56
|
+
cms_blog.followers.each {|follower| user_list << follower.user}
|
|
57
|
+
async_send_notification_emails(user_list)
|
|
58
|
+
return user_list.size
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
#------------------------------------------------------------------------------
|
|
64
|
+
def async_send_notification_emails(user_list)
|
|
65
|
+
success = failed = 0
|
|
66
|
+
Rails.logger.info "=== Sending #{user_list.size} emails for blog post '#{title}'"
|
|
67
|
+
user_list.each do |user|
|
|
68
|
+
email = PostNotifyMailer.post_notify(user, self, self.account).deliver_later
|
|
69
|
+
success += 1 if email
|
|
70
|
+
failed += 1 if email.nil?
|
|
71
|
+
end
|
|
72
|
+
update_attribute(:notification_sent_on, Time.now)
|
|
73
|
+
Rails.logger.info " Completed sending: successes (#{success}) -- failures (#{failed}) "
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Note: fragment caching is used during rendering. The cache key is based
|
|
2
|
+
# on both the model and the current locale (because each model supports
|
|
3
|
+
# multiple translations). The cache will be busted automatically since
|
|
4
|
+
# the updated_at attribute will be updated on save.
|
|
5
|
+
#------------------------------------------------------------------------------
|
|
6
|
+
class CmsSnippet < ActiveRecord::Base
|
|
7
|
+
class Translation < ::Globalize::ActiveRecord::Translation
|
|
8
|
+
has_paper_trail
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# --- FriendlyId
|
|
12
|
+
extend FriendlyId
|
|
13
|
+
include DmCore::Concerns::FriendlyId
|
|
14
|
+
|
|
15
|
+
default_scope { where(account_id: Account.current.id) }
|
|
16
|
+
|
|
17
|
+
# --- globalize (don't use versioning: true, translations erased when updating regular model data. Maybe fixed in github version)
|
|
18
|
+
translates :content, :fallbacks_for_empty_translations => true
|
|
19
|
+
globalize_accessors :locales => DmCore::Language.language_array
|
|
20
|
+
|
|
21
|
+
# --- versioning - skip anything translated
|
|
22
|
+
has_paper_trail :skip => :content
|
|
23
|
+
|
|
24
|
+
# --- validations
|
|
25
|
+
validates_presence_of :itemtype, :slug
|
|
26
|
+
validates_length_of :itemtype, :maximum => 30
|
|
27
|
+
validates :content, liquid: { :locales => true }, presence_default_locale: true
|
|
28
|
+
|
|
29
|
+
# --- content types supported
|
|
30
|
+
CONTENT_TYPES = [ 'Markdown', 'Textile', 'HTML' ]
|
|
31
|
+
|
|
32
|
+
#------------------------------------------------------------------------------
|
|
33
|
+
def is_published?
|
|
34
|
+
published
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
#------------------------------------------------------------------------------
|
|
38
|
+
def to_liquid
|
|
39
|
+
{}
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Generic contact form class. If changes are needed, then a new version should
|
|
2
|
+
# be created in the theme's models folder
|
|
3
|
+
#------------------------------------------------------------------------------
|
|
4
|
+
class ContactForm < ::MailForm::Base
|
|
5
|
+
|
|
6
|
+
attribute :name, :validate => true
|
|
7
|
+
attribute :email, :validate => /\A([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})\z/i
|
|
8
|
+
attribute :organization # Not validated
|
|
9
|
+
attribute :subject, :validate => true
|
|
10
|
+
attribute :message, :validate => true
|
|
11
|
+
attribute :reason, :validate => true
|
|
12
|
+
attribute :nickname, :captcha => true
|
|
13
|
+
|
|
14
|
+
# append :remote_ip, :user_agent, :session # append these values to the end of all emails
|
|
15
|
+
|
|
16
|
+
# for a contact form, the "from" address should be a valid email address
|
|
17
|
+
# within the domain that is doing the actual sending, instead of the contacter's
|
|
18
|
+
# address. This important for services like Sparkpost or Mandrill, that checks
|
|
19
|
+
# the validity of the sending domain.
|
|
20
|
+
#------------------------------------------------------------------------------
|
|
21
|
+
def headers
|
|
22
|
+
{ subject: "#{I18n.t('cms.contact_form.subject_prefix')}: #{reason}: #{subject}" ,
|
|
23
|
+
to: Account.current.preferred_support_email,
|
|
24
|
+
from: Account.current.preferred_support_email,
|
|
25
|
+
reply_to: %("#{name}" <#{email}>)
|
|
26
|
+
}
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Wrap blog/cms specific CanCan rules. Should be included in the main app's
|
|
2
|
+
# Ability class.
|
|
3
|
+
# NOTE: When checking abilities, don't check for Class level abilities,
|
|
4
|
+
# unless you don't care about the instance level. For example, don't
|
|
5
|
+
# use both styles
|
|
6
|
+
# can? :moderate, Forum
|
|
7
|
+
# can? :moderate, @forum
|
|
8
|
+
# In this case, if you need to check the class level, then use specific
|
|
9
|
+
# current_user.has_role? :moderator, Forum
|
|
10
|
+
#------------------------------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
module DmCms
|
|
13
|
+
module Concerns
|
|
14
|
+
module Ability
|
|
15
|
+
def dm_cms_abilities(user)
|
|
16
|
+
if user
|
|
17
|
+
#--- Admin
|
|
18
|
+
if user.has_role?(:content_manager)
|
|
19
|
+
can :manage_content, :all
|
|
20
|
+
can :access_admin, :all
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
#--- Blog
|
|
24
|
+
can(:read, CmsBlog) { |blog| blog.can_be_read_by?(user) }
|
|
25
|
+
can(:reply, CmsBlog) { |blog| blog.can_be_replied_by?(user) }
|
|
26
|
+
# can :moderate, CmsBlog, :id => CmsBlog.published.with_role(:moderator, user).map(&:id)
|
|
27
|
+
|
|
28
|
+
can(:read, CmsPost) { |post| post.is_published? || user.has_role?(:reviewer) || user.has_role?(:content_manager)}
|
|
29
|
+
|
|
30
|
+
#--- Pages
|
|
31
|
+
can(:read, CmsPage) { |page| page.is_published? || user.has_role?(:reviewer) || user.has_role?(:content_manager)}
|
|
32
|
+
else
|
|
33
|
+
#--- can only read/see public blogs when not logged in
|
|
34
|
+
can(:read, CmsBlog) { |blog| blog.can_be_read_by?(user) }
|
|
35
|
+
can(:read, CmsPost) { |post| post.is_published? }
|
|
36
|
+
can(:read, CmsPage) { |page| page.is_published? }
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
#------------------------------------------------------------------------------
|
|
44
|
+
# The abilities get basically compiled. So if you use
|
|
45
|
+
#
|
|
46
|
+
# can :moderate, Forum, :id => Forum.with_role(:moderator, user).map(&:id)
|
|
47
|
+
#
|
|
48
|
+
# this will execute the Forum.with_role query once during Ability.new. However
|
|
49
|
+
#
|
|
50
|
+
# can :moderate, Forum do |forum|
|
|
51
|
+
# user.has_role? :moderator, forum
|
|
52
|
+
# end
|
|
53
|
+
#
|
|
54
|
+
# this will execute the has_role? block on each call to can?
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module DmCms
|
|
2
|
+
module PermittedParams
|
|
3
|
+
|
|
4
|
+
#------------------------------------------------------------------------------
|
|
5
|
+
def cms_snippet_params
|
|
6
|
+
params.require(:cms_snippet).permit! if can? :manage_content, :all
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
#------------------------------------------------------------------------------
|
|
10
|
+
def cms_blog_params
|
|
11
|
+
params.require(:cms_blog).permit! if can? :manage_content, :all
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
#------------------------------------------------------------------------------
|
|
15
|
+
def cms_post_params
|
|
16
|
+
params.require(:cms_post).permit! if can? :manage_content, :all
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
#------------------------------------------------------------------------------
|
|
20
|
+
def cms_page_params
|
|
21
|
+
params.require(:cms_page).permit! if can? :manage_content, :all
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
#------------------------------------------------------------------------------
|
|
25
|
+
def cms_contentitem_params
|
|
26
|
+
params.require(:cms_contentitem).permit! if can? :manage_content, :all
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
#------------------------------------------------------------------------------
|
|
30
|
+
def media_file_params
|
|
31
|
+
params.require(:media_file).permit! if can? :manage_content, :all
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#------------------------------------------------------------------------------
|
|
2
|
+
class MediaFile < ActiveRecord::Base
|
|
3
|
+
|
|
4
|
+
self.table_name = 'cms_media_files'
|
|
5
|
+
|
|
6
|
+
translates :title, :description, fallbacks_for_empty_translations: true
|
|
7
|
+
globalize_accessors :locales => DmCore::Language.language_array
|
|
8
|
+
acts_as_taggable
|
|
9
|
+
|
|
10
|
+
belongs_to :user
|
|
11
|
+
default_scope { where(account_id: Account.current.id) }
|
|
12
|
+
validate :validate_name_is_unique
|
|
13
|
+
|
|
14
|
+
#--- Using Carrierwave
|
|
15
|
+
mount_uploader :media, MediaUploader
|
|
16
|
+
before_save :prepare_attributes
|
|
17
|
+
|
|
18
|
+
#------------------------------------------------------------------------------
|
|
19
|
+
def image?
|
|
20
|
+
self.media_content_type.start_with? 'image'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
#------------------------------------------------------------------------------
|
|
24
|
+
def pdf?
|
|
25
|
+
self.media_content_type.end_with? 'pdf'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
#------------------------------------------------------------------------------
|
|
29
|
+
def short_location(version = nil)
|
|
30
|
+
filename = version ? self.media.versions[version].file.filename : self.media.file.filename
|
|
31
|
+
folder.blank? ? filename : "#{folder}/#{filename}"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# return a list of tags for all media objects
|
|
35
|
+
#------------------------------------------------------------------------------
|
|
36
|
+
def self.tag_list_all
|
|
37
|
+
MediaFile.tag_counts_on(:tags).map(&:name).sort
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Given a name in the form 'folder/filename.ext', grab the url with the correct version
|
|
41
|
+
# Use 'version: :original' to allow the original version to be pulled
|
|
42
|
+
#------------------------------------------------------------------------------
|
|
43
|
+
def self.url_by_name(name, options = {version: :original})
|
|
44
|
+
asset = MediaFile.find_by_name(name)
|
|
45
|
+
if asset
|
|
46
|
+
options[:version] == :original ? asset.media.url : asset.media.url(options[:version])
|
|
47
|
+
else
|
|
48
|
+
nil
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Given a name in the form 'folder/filename.ext', check if the version exists.
|
|
53
|
+
# Use 'version: :original' to allow the original version to be pulled
|
|
54
|
+
#------------------------------------------------------------------------------
|
|
55
|
+
def self.version_exists?(name, options = {version: :original})
|
|
56
|
+
asset = MediaFile.find_by_name(name)
|
|
57
|
+
if asset
|
|
58
|
+
options[:version] == :original ? true : asset.media.version_exists?(options[:version])
|
|
59
|
+
else
|
|
60
|
+
false
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Given a name in the form 'folder/filename.ext', return the correct media file
|
|
65
|
+
#------------------------------------------------------------------------------
|
|
66
|
+
def self.find_by_name(name)
|
|
67
|
+
components = name.split('/')
|
|
68
|
+
filename = components[-1]
|
|
69
|
+
folder = components[-2] || ''
|
|
70
|
+
asset = MediaFile.where(folder: folder, media: filename).first
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
|
|
75
|
+
#------------------------------------------------------------------------------
|
|
76
|
+
def validate_name_is_unique
|
|
77
|
+
if self.new_record?
|
|
78
|
+
if self.media.file.nil?
|
|
79
|
+
errors.add :media, "please select a file to upload"
|
|
80
|
+
elsif MediaFile.where(media: self.media.file.original_filename, folder: self.folder, account_id: self.account_id).count > 0
|
|
81
|
+
errors.add :media, "'#{self.short_location}' already exists"
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Save the media metadata, and add the 'folder' as a tag
|
|
87
|
+
#------------------------------------------------------------------------------
|
|
88
|
+
def prepare_attributes
|
|
89
|
+
if media.present? && media_changed?
|
|
90
|
+
self.media_content_type = media.file.content_type
|
|
91
|
+
self.media_file_size = media.file.size
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
if self.new_record?
|
|
95
|
+
self.folder = self.folder.sanitize_filename
|
|
96
|
+
self.tag_list.add(self.folder)
|
|
97
|
+
self.tag_list.add(media.file.extension)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
class CmsBlogPresenter < BasePresenter
|
|
2
|
+
|
|
3
|
+
presents :cms_blog
|
|
4
|
+
|
|
5
|
+
#------------------------------------------------------------------------------
|
|
6
|
+
def label_published
|
|
7
|
+
cms_blog.is_published? ? h.colored_label('Published', :success) : h.colored_label('Draft')
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
#------------------------------------------------------------------------------
|
|
11
|
+
def visibility
|
|
12
|
+
cms_blog.visibility_to_s
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
class CmsPagePresenter < BasePresenter
|
|
2
|
+
|
|
3
|
+
presents :cms_page
|
|
4
|
+
|
|
5
|
+
#------------------------------------------------------------------------------
|
|
6
|
+
def label_published
|
|
7
|
+
cms_page.is_published? ? h.colored_label('Published', :success) : h.colored_label('Draft')
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Prepare a title for admin Page views. page/menu title with slug in <small>
|
|
11
|
+
#------------------------------------------------------------------------------
|
|
12
|
+
def admin_edit_title
|
|
13
|
+
main_title = (cms_page.title.present? ? cms_page.title : (cms_page.menutitle.present? ? cms_page.menutitle : '(no title)'))
|
|
14
|
+
sub_title = cms_page.slug
|
|
15
|
+
|
|
16
|
+
#--- make sure it's built safely...
|
|
17
|
+
html = "".html_safe
|
|
18
|
+
html << main_title
|
|
19
|
+
html << "<small>".html_safe
|
|
20
|
+
html << sub_title
|
|
21
|
+
html << "</small>".html_safe
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
class CmsPostPresenter < BasePresenter
|
|
2
|
+
|
|
3
|
+
presents :cms_post
|
|
4
|
+
|
|
5
|
+
#------------------------------------------------------------------------------
|
|
6
|
+
def label_published
|
|
7
|
+
date_formatted = cms_post.published_on.nil? ? 'Draft' : format_datetime(cms_post.published_on)
|
|
8
|
+
cms_post.is_published? ? h.colored_label(date_formatted, :success) : h.colored_label(date_formatted)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
class CmsSnippetPresenter < BasePresenter
|
|
2
|
+
|
|
3
|
+
presents :cms_snippet
|
|
4
|
+
|
|
5
|
+
#------------------------------------------------------------------------------
|
|
6
|
+
def label_published
|
|
7
|
+
cms_snippet.is_published? ? h.colored_label('Published', :success) : h.colored_label('Draft')
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
end
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# For uploading files into the media library. Creates versions based on
|
|
2
|
+
# settings in the Account. Will also create retina versions automatically.
|
|
3
|
+
# Files are stored in the theme's 'media' folder. User can specify a single
|
|
4
|
+
# subfolder to store the file, giving a little extra flexibility.
|
|
5
|
+
# At the moment, files are in the public folders. Future version will
|
|
6
|
+
# allow uploading protected files.
|
|
7
|
+
#
|
|
8
|
+
# make sure ghostscript is installed for PDF thumbnailing
|
|
9
|
+
# on OSX, `brew install ghostscript`
|
|
10
|
+
#------------------------------------------------------------------------------
|
|
11
|
+
class MediaUploader < CarrierWave::Uploader::Base
|
|
12
|
+
include DmCore::AccountHelper
|
|
13
|
+
|
|
14
|
+
# Include RMagick or MiniMagick support:
|
|
15
|
+
include CarrierWave::MimeTypes
|
|
16
|
+
include CarrierWave::MiniMagick
|
|
17
|
+
|
|
18
|
+
# Choose what kind of storage to use for this uploader:
|
|
19
|
+
storage :file
|
|
20
|
+
process :set_content_type
|
|
21
|
+
|
|
22
|
+
# Everything gets stored in the 'media' folder
|
|
23
|
+
#------------------------------------------------------------------------------
|
|
24
|
+
def store_dir
|
|
25
|
+
partition_dir = model.folder
|
|
26
|
+
"#{account_site_assets_media(false)}/#{partition_dir}"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# We basically want the width to be the max, allowing the height to grow
|
|
30
|
+
#------------------------------------------------------------------------------
|
|
31
|
+
def resize_to_width(width)
|
|
32
|
+
manipulate! do |img|
|
|
33
|
+
img.resize "#{width}>"
|
|
34
|
+
img = yield(img) if block_given?
|
|
35
|
+
img
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# If a pdf, convert to jpg and size, maintain aspect ration and pad to square
|
|
40
|
+
# If an image, resize it to a cropped square
|
|
41
|
+
#------------------------------------------------------------------------------
|
|
42
|
+
def thumb_image_pdf(width, height)
|
|
43
|
+
if pdf?(self)
|
|
44
|
+
self.convert(:jpg)
|
|
45
|
+
self.resize_and_pad(width, height)
|
|
46
|
+
else
|
|
47
|
+
self.resize_to_fill(width, height)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Convert to png if a pdf, then size to a specfic width
|
|
52
|
+
#------------------------------------------------------------------------------
|
|
53
|
+
def size_image_pdf(width)
|
|
54
|
+
self.convert(:jpg) if pdf?(self)
|
|
55
|
+
self.resize_to_width(width)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# From: https://github.com/jhnvz/retina_rails
|
|
59
|
+
# Process retina quality of the image.
|
|
60
|
+
# Works with ImageMagick and MiniMagick
|
|
61
|
+
# === Parameters
|
|
62
|
+
#
|
|
63
|
+
# [percentage (Int)] quality in percentage
|
|
64
|
+
#
|
|
65
|
+
def retina_quality(percentage)
|
|
66
|
+
manipulate! do |img|
|
|
67
|
+
if defined?(Magick)
|
|
68
|
+
img.write(current_path) { self.quality = percentage } unless img.quality == percentage
|
|
69
|
+
elsif defined?(MiniMagick)
|
|
70
|
+
img.quality(percentage.to_s)
|
|
71
|
+
end
|
|
72
|
+
img = yield(img) if block_given?
|
|
73
|
+
img
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Create different versions of image files
|
|
78
|
+
# Retina naming: http://blog.remarkablelabs.com/2013/01/creating-retina-images-with-carrierwave
|
|
79
|
+
#------------------------------------------------------------------------------
|
|
80
|
+
version :retina_lg, :if => :thumbnable_retina? do
|
|
81
|
+
# process :size_image_pdf => [Account.current.preferred_image_large_width * 2]
|
|
82
|
+
process :size_image_pdf => [900 * 2]
|
|
83
|
+
process :retina_quality => 60
|
|
84
|
+
def full_filename(for_file = model.media.file)
|
|
85
|
+
name = super.tap {|file_name| file_name.gsub!(/\.+[0-9a-zA-Z]{3,4}$/){ "@2x#{$&}" }.gsub!('retina_', '') }
|
|
86
|
+
model.pdf? ? (name.chomp(File.extname(name)) + '.jpg') : name
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
version :lg, :if => :thumbnable? do
|
|
90
|
+
# process :size_image_pdf => [Account.current.preferred_image_large_width]
|
|
91
|
+
process :size_image_pdf => [900]
|
|
92
|
+
def full_filename (for_file = model.file.file)
|
|
93
|
+
model.pdf? ? (super.chomp(File.extname(super)) + '.jpg') : super
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
version :retina_md, :if => :thumbnable_retina?, :from_version => :retina_lg do
|
|
98
|
+
# process :size_image_pdf => [Account.current.preferred_image_medium_width * 2]
|
|
99
|
+
process :size_image_pdf => [600 * 2]
|
|
100
|
+
process :retina_quality => 60
|
|
101
|
+
def full_filename(for_file = model.media.file)
|
|
102
|
+
name = super.tap {|file_name| file_name.gsub!(/\.+[0-9a-zA-Z]{3,4}$/){ "@2x#{$&}" }.gsub!('retina_', '') }
|
|
103
|
+
model.pdf? ? (name.chomp(File.extname(name)) + '.jpg') : name
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
version :md, :if => :thumbnable?, :from_version => :lg do
|
|
107
|
+
# process :size_image_pdf => [Account.current.preferred_image_medium_width]
|
|
108
|
+
process :size_image_pdf => [600]
|
|
109
|
+
def full_filename (for_file = model.file.file)
|
|
110
|
+
model.pdf? ? (super.chomp(File.extname(super)) + '.jpg') : super
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
version :retina_sm, :if => :thumbnable_retina?, :from_version => :retina_md do
|
|
115
|
+
# process :size_image_pdf => [Account.current.preferred_image_small_width * 2]
|
|
116
|
+
process :size_image_pdf => [300 * 2]
|
|
117
|
+
process :retina_quality => 60
|
|
118
|
+
def full_filename(for_file = model.media.file)
|
|
119
|
+
name = super.tap {|file_name| file_name.gsub!(/\.+[0-9a-zA-Z]{3,4}$/){ "@2x#{$&}" }.gsub!('retina_', '') }
|
|
120
|
+
model.pdf? ? (name.chomp(File.extname(name)) + '.jpg') : name
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
version :sm, :if => :thumbnable?, :from_version => :retina_md do
|
|
124
|
+
# process :size_image_pdf => [Account.current.preferred_image_small_width]
|
|
125
|
+
process :size_image_pdf => [300]
|
|
126
|
+
def full_filename (for_file = model.file.file)
|
|
127
|
+
model.pdf? ? (super.chomp(File.extname(super)) + '.jpg') : super
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
version :thumb, :if => :thumbnable?, :from_version => :retina_md do
|
|
132
|
+
# process thumb_image_pdf: [Account.current.preferred_image_thumbnail_width, Account.current.preferred_image_thumbnail_width]
|
|
133
|
+
process thumb_image_pdf: [200, 200]
|
|
134
|
+
def full_filename (for_file = model.file.file)
|
|
135
|
+
model.pdf? ? (super.chomp(File.extname(super)) + '.jpg') : super
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
# Add a white list of extensions which are allowed to be uploaded.
|
|
141
|
+
# For images you might use something like this:
|
|
142
|
+
#------------------------------------------------------------------------------
|
|
143
|
+
def extension_white_list
|
|
144
|
+
%w(jpg jpeg gif png mp3 mp4 m4v ogg webm pdf css js)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
protected
|
|
148
|
+
|
|
149
|
+
#------------------------------------------------------------------------------
|
|
150
|
+
def thumbnable?(new_file)
|
|
151
|
+
image?(new_file) || pdf?(new_file)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
#------------------------------------------------------------------------------
|
|
155
|
+
def thumbnable_retina?(new_file)
|
|
156
|
+
model.generate_retina? ? (image?(new_file) || pdf?(new_file)) : false
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
#------------------------------------------------------------------------------
|
|
160
|
+
def image?(new_file)
|
|
161
|
+
new_file.content_type.start_with? 'image'
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
#------------------------------------------------------------------------------
|
|
165
|
+
def pdf?(new_file)
|
|
166
|
+
new_file.content_type.end_with? 'pdf'
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
end
|