class FilteredCollectionIndex(CollectionIndex): inclusions = schema.ListField(schema.SchemaField(CollectionFilter), blank=True) exclusions = schema.ListField(schema.SchemaField(CollectionFilter), blank=True) parameters = schema.ListField(schema.SchemaField(CollectionParam), blank=True) def get_index(self): document = self.get_document() index = document.objects.all() inclusions = list() exclusions = list() params = list() for collection_filter in self.inclusions: inclusions.append(collection_filter.get_query_filter_operation()) for collection_filter in self.exclusions: exclusions.append(collection_filter.get_query_filter_operation()) for param in self.parameters: params.append(param.get_query_filter_operation()) index = index._add_filter_parts(inclusions=inclusions, exclusions=exclusions, indexes=params) return index def save(self, *args, **kwargs): ret = super(FilteredCollectionIndex, self).save(*args, **kwargs) self.get_index().commit() return ret class Meta: typed_key = 'dockitcms.filteredcollection'
class BaseRecipe(schema.Document): #fields to keep track of what the recipe generated generated_applications = schema.ListField( schema.ReferenceField(Application), editable=False) generated_collections = schema.ListField( schema.ReferenceField(BaseCollection), editable=False) generated_indexes = schema.ListField(schema.ReferenceField(Index), editable=False) generated_view_points = schema.ListField( schema.ReferenceField(BaseViewPoint), editable=False) generated_subsites = schema.ListField(schema.ReferenceField(Subsite), editable=False) class Meta: typed_field = 'recipe_type' verbose_name = 'Recipe' collection = 'dockitcms.recipe' def cook_recipe(self): raise NotImplementedError #build out apps, collections and such here def save(self, *args, **kwargs): if not self.pk: self.cook_recipe() return super(BaseRecipe, self).save(*args, **kwargs)
class TemplateEntry(schema.Schema): path = schema.CharField() source = schema.TextField() #TODO template validator js_files = schema.ListField(schema.FileField(upload_to='dockitcms/u-js/'), blank=True) css_files = schema.ListField(schema.FileField(upload_to='dockitcms/u-css/'), blank=True) def get_template_object(self): return Template(self.source)
class SchemaEntry(FieldEntry, DesignMixin): #inherit_from = SchemaDesignChoiceField(blank=True) fields = schema.ListField(schema.SchemaField(FieldEntry)) object_label = schema.CharField(blank=True) class Meta: proxy = True
class ThumbnailField(BaseFieldEntry): thumbnails = schema.ListField( schema.SchemaField(ThumbnailFieldEntrySchema)) field_class = properties.ThumbnailField def get_field_kwargs(self): kwargs = super(ThumbnailField, self).get_field_kwargs() if kwargs.get('verbose_name', None) == '': del kwargs['verbose_name'] thumbnails = kwargs.pop('thumbnails', list()) config = {'thumbnails': dict()} for thumb in thumbnails: key = thumb.pop('key') for key, value in thumb.items(): if value is None: thumb.pop(key) resize = {} for key in ['width', 'height', 'crop', 'upscale']: if key in thumb: resize[key] = thumb.pop(key) if resize: thumb['resize'] = resize config['thumbnails'][key] = thumb kwargs['config'] = config return kwargs class Meta: typed_key = 'ThumbnailField'
class ModelWidgets(schema.Document): ''' Associates a model with a set of defined widgets ''' content_type = schema.ModelReferenceField(ContentType) object_id = schema.CharField() widgets = schema.ListField(schema.SchemaField(BlockWidget))
class PageDefinition(SchemaEntry): unique_id = schema.CharField(default=uuid.uuid4, editable=False) templates = schema.ListField(schema.SchemaField(TemplateEntry)) def get_template(self, name): for candidate in self.templates: if candidate.path == name: return candidate.get_template_object() #CONSIDER: perhaps a page definition should have a default template return None
class FlatMenuWidget(BaseTemplateWidget): entries = schema.ListField(schema.SchemaField(FlatMenuEntry)) class Meta: typed_key = 'widgetblock.flatmenuwidget' def get_context(self, context): context = BaseTemplateWidget.get_context(self, context) #TODO find the active menu entry return context
class FlatMenuWidget(BaseTemplateWidget): template_name = schema.CharField(blank=True, default='widgetblock/menu_widget.html') entries = schema.ListField(schema.SchemaField(FlatMenuEntry)) class Meta: typed_key = 'widgetblock.flatmenuwidget' def get_context(self, context): context = BaseTemplateWidget.get_context(self, context) #TODO find the active menu entry return context
class CTAWidget(BaseTemplateWidget): template_name = schema.CharField(blank=True, default='widgetblock/cta_widget.html') default_url = schema.CharField() width = schema.CharField() height = schema.CharField() delay = schema.DecimalField(help_text=_("Display interval of each item"), max_digits=5, decimal_places=2, default=5) images = schema.ListField(schema.SchemaField(CTAImage)) class Meta: typed_key = 'widgetblock.ctawidget'
class ChoiceField(BaseFieldEntry): choices = schema.ListField(schema.SchemaField(ChoiceOptionSchema)) field_class = schema.CharField def get_field_kwargs(self): kwargs = super(ChoiceField, self).get_field_kwargs() kwargs['choices'] = [(entry['value'], entry['label']) for entry in kwargs['choices']] return kwargs class Meta: typed_key = 'ChoiceField'
class PublicCollectionResource(PublicResource): collection = schema.ReferenceField(Collection) view_points = schema.ListField(schema.SchemaField(BaseViewPoint)) @property def cms_resource(self): return self.collection.get_collection_resource() def get_public_resource_kwargs(self, **kwargs): kwargs.setdefault('view_points', self.view_points) return super(PublicCollectionResource, self).get_public_resource_kwargs(**kwargs) class Meta: typed_key = 'collection'
class FilteredModelIndex(ModelIndex): inclusions = schema.ListField(schema.SchemaField(ModelFilter), blank=True) exclusions = schema.ListField(schema.SchemaField(ModelFilter), blank=True) parameters = schema.ListField(schema.SchemaField(ModelParam), blank=True) def get_index(self): model = self.get_model() index = model.objects.all() inclusions = list() exclusions = list() params = list() for collection_filter in self.inclusions: inclusions.append(collection_filter.get_query_filter_operation()) for collection_filter in self.exclusions: exclusions.append(collection_filter.get_query_filter_operation()) if inclusions: index = index.filter(*inclusions) if exclusions: index = index.exclude(*exclusions) return index class Meta: typed_key = 'dockitcms.filteredmodel'
class CTAWidget(BaseTemplateWidget): default_url = schema.CharField() width = schema.CharField() height = schema.CharField() delay = schema.DecimalField(help_text=_("Display interval of each item"), max_digits=5, decimal_places=2, default=5) images = schema.ListField(schema.SchemaField( CTAImage)) #TODO the following will be an inline when supported class Meta: typed_key = 'widgetblock.ctawidget' @classmethod def get_admin_form_class(cls): from forms import CTAWidgetForm return CTAWidgetForm
class DocumentDesign(schema.Document, DesignMixin): title = schema.CharField() inherit_from = SchemaDesignChoiceField(blank=True) fields = schema.ListField(schema.SchemaField(FieldEntry), blank=True) object_label = schema.CharField(blank=True) def __unicode__(self): return self.title or '' def get_schema_name(self): return str(''.join([capfirst(part) for part in self.title.split()])) def get_document_kwargs(self, **kwargs): kwargs = DesignMixin.get_document_kwargs(self, **kwargs) if self.inherit_from: parent = self._meta.fields['inherit_from'].get_schema( self.inherit_from) if parent: if issubclass(parent, schema.Document): kwargs['parents'] = (parent, ) else: kwargs['parents'] = (parent, schema.Document) return kwargs
class PageCollection(Collection): title = schema.CharField() page_definitions = schema.ListField(schema.SchemaField(PageDefinition)) def get_collection_name(self): return 'dockitcms.virtual.%s' % self.key def get_schema_name(self): return str(''.join([part for part in self.title.split()])) def register_collection(self): #create a base page document params = { 'module': 'dockitcms.models.virtual', 'virtual': False, 'verbose_name': self.title, 'collection': self.get_collection_name(), 'parents': (BasePage, schema.Document), 'name': self.get_schema_name(), 'attrs': SortedDict(), 'fields': SortedDict(), 'typed_field': '_page_type', } if self.application: params['app_label'] = self.application.name params['attrs']['_collection_document'] = self base_doc = create_document(**params) force_register_documents(base_doc._meta.app_label, base_doc) base_doc.objects.index('path').commit() #loop through page_definitions and register them for page_def in self.page_definitions: params = { 'parents': (base_doc,), 'virtual': False, 'typed_key': page_def.unique_id, 'attrs': SortedDict([ ('_page_def', page_def), ]) } page_def.get_document(**params) #CONSIDER: provide page defs defined in code for unique_id, page_schema in dict().items(): #REGISTERED_PAGE_DEFS.items() params = { 'virtual': False, 'typed_key': unique_id, 'parents': (page_schema, base_doc), 'name': '', #page_schema._meta.name, 'fields': SortedDict(), } create_document(**params) return base_doc def get_document(self): key = self.get_collection_name() #TODO how do we know if we should recreate the document? ie what if the design was modified on another node try: return get_base_document(key) except KeyError: doc = self.register_collection() return doc def get_object_class(self): return self.get_document() def get_resource_class(self): from dockitcms.pagecollection.resources import PageCollectionResource return PageCollectionResource def get_collection_resource(self): admin_client = self.get_collection_admin_client() cls = self.get_object_class() try: return admin_client.registry[cls] except Exception as error: for key, resource in admin_client.registry.iteritems(): if isinstance(key, type) and issubclass(cls, key): return resource #TODO why do we need this? if issubclass(key, schema.Document) and key._meta.collection == cls._meta.collection: return resource def __unicode__(self): if self.title: return self.title else: return self.__repr__() class Meta: typed_key = 'dockitcms.page'
class ModelWidgets(schema.Document): content_type = schema.ModelReferenceField(ContentType) object_id = schema.CharField() widgets = schema.ListField(schema.SchemaField(BlockWidget))
class AuthConfiguration(schema.Schema): authenticated_users_only = schema.BooleanField(default=False) staff_only = schema.BooleanField(default=False) required_permissions = schema.ListField( schema.CharField(), blank=True) #object or app permissions required for the user
class AdminOptions(schema.Schema): list_display = schema.ListField(schema.CharField(), blank=True) list_per_page = schema.IntegerField(default=100)
def create_field(self): kwargs = self.get_field_kwargs() return schema.ListField(self.field_class(**kwargs))
class InlineSchema(schema.Schema): a_list = schema.ListField(schema.SchemaField(SimpleSchema), blank=True)
class WidgetMixinSchema(schema.Schema): widgets = schema.ListField(schema.SchemaField(BlockWidget)) class Meta: verbose_name = 'widget'