module Locomotive module Liquid module Drops class ContentTypes < ::Liquid::Drop def before_method(meth) type = @context.registers[:site].content_types.where(slug: meth.to_s).first ContentTypeProxyCollection.new(type) end end class ContentTypeProxyCollection < ProxyCollection def initialize(content_type) @content_type = content_type @collection = nil end def public_submission_url @context.registers[:controller].main_app.locomotive_entry_submissions_url(@content_type.slug) end def api Locomotive.log :warn, "[Liquid template] the api for content_types has been deprecated and replaced by public_submission_url instead." { 'create' => public_submission_url } end def before_method(meth) klass = @content_type.entries.klass # delegate to the proxy class if (meth.to_s =~ /^group_by_(.+)$/) == 0 klass.send(:group_by_select_option, $1, @content_type.order_by_definition) elsif (meth.to_s =~ /^(.+)_options$/) == 0 klass.send(:"#{$1}_options").map { |option| option['name'] } else Locomotive.log :warn, "[Liquid template] trying to call #{meth} on a content_type object" end end protected def collection if @context['with_scope'] self.modify_with_scope end @collection ||= @content_type.ordered_entries(@context['with_scope']).visible end def modify_with_scope fields = @content_type.ordered_custom_fields(:entries) @context['with_scope'].dup.each do |key, value| if relation = self.relation_with(key) # belongs_to, has_many, many_to_many relationships: use the _id self.modify_with_scope_with_relation(key, value, relation) elsif field = fields.detect { |f| f.name == key && f.type == 'select' } # use the id of the option instead of the name self.modify_with_scope_with_select(key, value, field) end end end def modify_with_scope_with_relation(key, value, relation) model = Locomotive::ContentType.class_name_to_content_type(relation.class_name, @context.registers[:site]) entry = model.entries.where(model.label_field_name => value).first # modify the scope @context['with_scope'].delete(key) @context['with_scope'][relation.key] = entry end def relation_with(name) @relations ||= @content_type.klass_with_custom_fields(:entries).relations if @relations.keys.include?(name.to_s) @relations[name] elsif @relations.keys.include?(name.to_s.pluralize) @relations[name.to_s.pluralize] end end def modify_with_scope_with_select(key, value, field) option = field.select_options.detect { |option| [option.name, option._id.to_s].include?(value) } # modify the scope @context['with_scope'].delete(key) @context['with_scope']["#{key}_id"] = option.try(:_id) end end end end end