module CamaleonCms class PostType < CamaleonCms::TermTaxonomy include CamaleonCms::CommonRelationships alias_attribute :site_id, :parent_id default_scope { where(taxonomy: :post_type) } has_many :categories, foreign_key: :parent_id, dependent: :destroy, inverse_of: :post_type_parent has_many :post_tags, foreign_key: :parent_id, dependent: :destroy, inverse_of: :post_type has_many :posts, foreign_key: :taxonomy_id, dependent: :destroy, inverse_of: :post_type has_many :comments, through: :posts has_many :posts_through_categories, foreign_key: :objectid, through: :term_relationships, source: :object has_many :posts_draft, class_name: 'CamaleonCms::Post', foreign_key: :taxonomy_id, dependent: :destroy, inverse_of: :post_type has_many :field_group_taxonomy, lambda { where('object_class LIKE ?', 'PostType_%') }, class_name: 'CamaleonCms::CustomField', foreign_key: :objectid, dependent: :destroy belongs_to :owner, class_name: CamaManager.get_user_class_name, foreign_key: :user_id, required: false belongs_to :site, foreign_key: :parent_id, required: false scope :visible_menu, -> { where(term_group: nil) } scope :hidden_menu, -> { where(term_group: -1) } before_destroy :destroy_field_groups after_create :set_default_site_user_roles after_create :refresh_routes after_destroy :refresh_routes after_update :refresh_routes, if: proc { |obj| obj.destroyed_by_association.blank? && obj.saved_change_to_attribute?(:slug) } before_update :default_category # check if current post type manage categories def manage_categories? options[:has_category] || options[:has_single_category] end # hide or show this post type on admin -> contents -> menu # true => enable, false => disable def toggle_show_for_admin_menu(flag) update(term_group: flag == true ? nil : -1) end # check if this post type is shown on admin -> contents -> menu def show_for_admin_menu? term_group.nil? end # check if this post type manage post tags def manage_tags? options[:has_tags] end # check if this post type permit to manage seo attrs in posts def manage_seo? get_option('has_seo', get_option('has_keywords', true)) end # assign settings for this post type # default values: { # has_category: false, # has_tags: false, # has_summary: true, # has_content: true, # has_comments: false, # has_picture: true, # has_template: true, # has_seo: true, # not_deleted: false, # has_layout: false, # default_layout: '', # contents_route_format: 'post' # } def set_settings(settings = {}) settings.each do |key, val| set_option(key, val) end end # set or update a setting for this post type def set_setting(key, value) set_option(key, value) end # select full_categories for the post type, include all children categories def full_categories CamaleonCms::Category.where(site_id: site_id, post_type_id: id) end # return default category for this post type # only return a category for post types that manage categories def default_category return unless manage_categories? cat = categories.find_by_slug('uncategorized') unless cat cat = categories.create({ name: 'Uncategorized', slug: 'uncategorized', parent_id: id }) cat.set_option('not_deleted', true) end cat end # add a post for current model # title: title for post, => required # content: html text content, => required # thumb: image url, => default (empty). check http://camaleon.tuzitio.com/api-methods.html#section_fileuploads # categories: [1,3,4,5], => default (empty) # tags: String comma separated, => default (empty) # slug: string key for post, => default (empty) # summary: String resume (optional) => default (empty) # post_order: Integer to define the order position in the list (optional) # fields: Hash of values for custom fields, sample => fields: {subtitle: 'abc', icon: 'test' } (optional) # settings: Hash of post settings, sample => settings: # {has_content: false, has_summary: true, default_layout: 'my_layout', default_template: 'my_template' } (optional, see more in post.set_setting(...)) # data_metas: {template: "", layout: ""} # sample: my_posttype.add_post(title: "My Title", post_order: 5, content: 'lorem_ipsum', settings: {default_template: "home/counters", has_content: false, has_seo: false, skip_fields: ["sub_tite", 'banner']}, fields: {pattern: true, bg: 'http://www.reallusion.com/de/images/3dx5/whatsnew/3dx5_features_banner_bg_02.jpg'}) # More samples here: https://gist.github.com/owen2345/eba9691585ed78ad6f7b52e9591357bf # return created post if it was created, else return errors def add_post(args) _fields = args.delete(:fields) _settings = args.delete(:settings) _summary = args.delete(:summary) _order_position = args.delete(:order_position) args[:data_categories] = _categories = args.delete(:categories) args[:data_tags] = args.delete(:tags) _thumb = args.delete(:thumb) p = posts.new(args) p.slug = site.get_valid_post_slug(p.title.parameterize) unless p.slug.present? if p.save! _settings.each { |k, v| p.set_setting(k, v) } if _settings.present? p.set_position(_order_position) if _order_position.present? p.set_summary(_summary) if _summary.present? p.set_thumb(_thumb) if _thumb.present? _fields.each { |k, v| p.save_field_value(k, v) } if _fields.present? p.decorate else p.errors end end # return all available route formats of this post type for content posts def contents_route_formats { 'post_of_post_type' => '/group/:post_type_id-:title/:slug
(Sample: http://localhost.com/group/17-services/myservice.html)', 'post_of_category' => '/category/:category_id-:title/:slug
(Sample: http://localhost.com/category/17-services/myservice.html)', 'post_of_category_post_type' => '/:post_type_title/category/:category_id-:title/:slug
(Sample: http://localhost.com/services/category/17-services/myservice.html)', 'post_of_posttype' => '/:post_type_title/:slug
(Sample: http://localhost.com/services/myservice.html)', 'post' => '/:slug
(Sample: http://localhost.com/myservice.html)', 'hierarchy_post' => '/:parent1_slug/:parent2_slug/.../:slug
(Sample: http://localhost.com/item-1/item-1-1/item-111.html)' } end # return the configuration of routes for post contents def contents_route_format get_option('contents_route_format', 'post') end # verify if this post_type support for page hierarchy (parents) def manage_hierarchy? get_option('has_parent_structure', false) end private # skip save_metas_options callback after save changes (inherit from taxonomy) to call from here manually def save_metas_options_skip true end # assign default roles for this post type # define default settings for this post type def set_default_site_user_roles set_multiple_options( { has_category: false, has_tags: false, has_summary: true, has_content: true, has_comments: false, has_picture: true, has_template: true, has_seo: true, not_deleted: false, has_layout: false, default_layout: '' }.merge(PluginRoutes.fixActionParameter(data_options || {}).to_sym) ) site.set_default_user_roles(self) default_category end # destroy all custom field groups assigned to this post type def destroy_field_groups if !destroyed_by_association.present? && (slug == 'post' || slug == 'page') errors.add(:base, 'This post type can not be deleted.') return false end get_field_groups.destroy_all end # reload routes to enable this post type url, like: http://localhost/my-slug def refresh_routes PluginRoutes.reload end end end