class BaseTemplateWidget(Widget): template_source = schema.CharField(choices=TEMPLATE_SOURCE_CHOICES, default='name') template_name = schema.CharField(blank=True) template_html = schema.TextField(blank=True) class Meta: proxy = True def get_template(self): if self.template_source == 'name': return get_template(self.template_name) else: return Template(self.template_html) def get_context(self, context): return Context({'widget': self}) def render(self, context): template = self.get_template() context = self.get_context(context) return mark_safe(template.render(context)) @classmethod def get_admin_form_class(cls): from forms import BaseTemplateWidgetForm return BaseTemplateWidgetForm
class ConfigurableWidget(SchemaEntry, schema.Document): ''' Allows for a widget class to be dynamically defined ''' template_source = schema.CharField(choices=TEMPLATE_SOURCE_CHOICES, default='name') template_name = schema.CharField(blank=True) template_html = schema.TextField(blank=True) def get_template(self): if self.template_source == 'name': return get_template(self.template_name) else: return Template(self.template_html) def get_schema_name(self): return str(''.join([part for part in self.title.split()])) def register_widget(self): #presumably this would be called on save or site load params = { 'module': 'dockitcms.widgetblock.models.virtual', 'virtual': False, 'verbose_name': self.title, #'collection': self.get_collection_name(), 'parents': (ConfiguredWidget,), 'name': self.get_schema_name(), 'attrs': SortedDict(), 'fields': self.get_fields(), 'typed_key': 'configured.%s' % self.get_schema_name(), } params['attrs']['_configurable_widget'] = self return create_schema(**params)
class Subsite(schema.Document, ManageUrlsMixin, create_document_mixin(SUBSITE_MIXINS)): url = schema.CharField() name = schema.CharField() slug = schema.SlugField() sites = schema.ModelSetField(Site, blank=True) def __unicode__(self): return '%s - %s' % (self.name, self.url) def get_logger(self): from dockitcms.sites import logger return logger @property def resource_definitions(self): return PublicResource.objects.filter(subsite=self) def get_site_client(self): """ Returns a hyperadmin client for public consumption """ from dockitcms.resources.virtual import site from dockitcms.resources.public import PublicSubsite subsite_api = PublicSubsite(api_endpoint=site, name=self.name, subsite=self) for resource_def in self.resource_definitions: try: resource_def.register_public_resource(subsite_api) except Exception as error: self.get_logger().exception( 'Could not register public resource') return subsite_api def get_urls(self): if not hasattr(self, '_client'): self._client = self.get_site_client() client = self._client return client.get_urls() @property def urls(self): #urls, app_name, namespace try: self.urlpatterns except Exception as error: logger = self.get_logger() logger.exception('Error while constructing urls') raise return self, None, self.name @property def urlpatterns(self): return self.get_urls()
class TemporaryDocumentInfo(schema.Schema): user = schema.ModelReferenceField(User, blank=True, null=True) created = schema.DateTimeField(default=datetime.datetime.now) object_collection = schema.CharField() object_id = schema.CharField() number_of_changes = schema.IntegerField(default=0)
class Subsite(schema.Document, ManageUrlsMixin, create_document_mixin(SUBSITE_MIXINS)): url = schema.CharField() name = schema.CharField() sites = schema.ModelSetField(Site, blank=True) def __unicode__(self): return u'%s - %s' % (self.name, self.url)
def test_force_register_documents(self): doc = create_document('testDocument', fields={'title':schema.CharField()}) doc = create_document('testDocument', fields={'title':schema.CharField(), 'slug':schema.SlugField()}) force_register_documents(doc._meta.app_label, doc) doc = get_base_document(doc._meta.collection) self.assertTrue('slug' in doc._meta.fields)
class ImageWidget(BaseTemplateWidget): template_name = schema.CharField(blank=True, default='widgetblock/image_widget.html') image = schema.FileField() alt = schema.CharField(blank=True) link = schema.CharField(blank=True) class Meta: typed_key = 'widgetblock.imagewidget'
class CollectionParam(schema.Schema): key = schema.CharField() operation = schema.CharField(choices=FILTER_OPERATION_CHOICES, default='exact') def get_query_filter_operation(self): return QueryFilterOperation(key=self.key, operation=self.operation, value=None)
class BaseField(schema.Schema): name = schema.SlugField() required = schema.BooleanField(default=True) label = schema.CharField(blank=True) initial = schema.CharField(blank=True) help_text = schema.CharField(blank=True) class Meta: typed_field = 'field_type'
class BaseFieldEntry(FieldEntry): verbose_name = schema.CharField(blank=True, null=True) blank = schema.BooleanField(default=True) null = schema.BooleanField(default=True) default = schema.CharField(blank=True, null=True) help_text = schema.CharField(blank=True, null=True) scaffold_template_name = 'dockitcms/scaffold/field.html' class Meta: proxy = True
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 ThumbnailFieldEntrySchema(schema.Schema): key = schema.SlugField() format = schema.CharField(blank=True, null=True, choices=IMAGE_FORMATS) quality = schema.IntegerField(blank=True, null=True) width = schema.IntegerField(blank=True, null=True) height = schema.IntegerField(blank=True, null=True) upscale = schema.BooleanField( default=False, help_text='Upsize the image if it doesn\'t match the width and height') crop = schema.CharField(blank=True, null=True, choices=CROP_CHOICES) autocrop = schema.BooleanField( default=False, help_text='Remove white space from around the image') def __unicode__(self): return self.key or repr(self)
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 Recipe( BaseRecipe ): #represents typical recipe design pattern; creates an app and attaches view points to an existing subsite application_name = schema.CharField() #name of app to create subsite = schema.ReferenceField(Subsite) def get_application_kwargs(self): return {'name': self.application_name} def create_application(self): application = Application(**self.get_application_kwargs()) application.save() self.generated_applications.append(application) def get_view_point_kwargs(self): return {'subsite': self.subsite} def get_collection_kwargs(self): return { 'application': self.applications[0], 'admin_options': { 'list_per_page': 100 }, } class Meta: proxy = True
class FileField(BaseFieldEntry): upload_to = schema.CharField(blank=True) field_class = schema.FileField class Meta: typed_key = 'FileField'
class ViewPoint(BaseViewPoint): url = schema.CharField( help_text='May be a regular expression that the url has to match') def contains_url(self, url): return bool(self.url_regexp.match(url)) @property def url_regexp(self): return re.compile(self.base_url) def _base_url(self): url = self.url or '' if url.startswith('/'): url = '.' + url return urlparse.urljoin(self.subsite.url, url) base_url = property(_base_url) def get_absolute_url(self): return self.base_url def __unicode__(self): if self.url: return self.url else: return self.__repr__() class Meta: proxy = True
class Index(schema.Document, create_document_mixin(INDEX_MIXINS)): name = schema.CharField() def get_index_kwargs(self, **kwargs): params = { 'name': self.name, 'query': self.get_index_query(), } params.update(kwargs) return params def get_index_class(self): return ResourceIndex def get_index(self, **kwargs): params = self.get_index_kwargs(**kwargs) klass = self.get_index_class() return klass(**params) def get_index_query(self): raise NotImplementedError def get_parameters(self): raise NotImplementedError def get_object_class(self): raise NotImplementedError def register_index(self): raise NotImplementedError class Meta: typed_field = 'index_type'
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 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 CTAImage(schema.Schema): image = schema.FileField(upload_to='ctas') url = schema.CharField(blank=True) def __unicode__(self): if self.image: return unicode(self.image) return repr(self)
class ModelFilter(schema.Schema): key = schema.CharField() operation = schema.CharField(choices=FILTER_OPERATION_CHOICES, default='exact') value = schema.CharField() value_type = schema.CharField(choices=VALUE_TYPE_CHOICES, default='string') def get_value(self): #TODO this is cheesy value = self.value if self.value_type == 'integer': value = int(value) elif self.value_type == 'boolean': value = bool(value.lower() in ('1', 'true')) return value def get_query_filter_operation(self): value = self.get_value() return Q(**{'%s__%s' % (self.key, self.operation): value})
class Application(schema.Document): name = schema.CharField() slug = schema.SlugField(unique=True) def create_natural_key(self): return {'slug':self.slug} def __unicode__(self): return self.name
class ImageWidget(Widget): image = schema.FileField() alt = schema.CharField(blank=True) link = schema.CharField(blank=True) class Meta: typed_key = 'widgetblock.imagewidget' def get_template(self): return get_template('widgetblock/image_widget.html') def get_context(self, context): return Context({'widget': self}) def render(self, context): template = self.get_template() context = self.get_context(context) return mark_safe(template.render(context))
class ImageField(BaseFieldEntry): upload_to = schema.CharField(blank=True) #TODO schema.ImageField field_class = schema.FileField scaffold_template_name = 'dockitcms/scaffold/image.html' class Meta: typed_key = 'ImageField'
class BasePage(schema.Schema): parent = schema.ReferenceField('self', blank=True, null=True) url = schema.CharField(blank=True) url_name = schema.SlugField(blank=True, help_text='registers the page with the url tag with this name') path = schema.CharField(editable=False) title = schema.CharField() slug = schema.SlugField() published = schema.BooleanField() template = schema.CharField() inline_css = schema.TextField(blank=True) inline_js = schema.TextField(blank=True) def clean_path(self): if self.url: return self.url if self.parent: return self.parent.path + self.slug + '/' return self.slug + '/'
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 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 BlockWidget(Widget): block_key = schema.CharField() widget_type = schema.SchemaTypeField(block_widget_schemas, editable=False) @classmethod def get_admin_class(cls): from admin import BlockWidgetAdmin return BlockWidgetAdmin class Meta: proxy = True
class ViewPoint(BaseViewPoint): url = schema.CharField( help_text='May be a regular expression that the url has to match', blank=True) endpoint_name = schema.CharField(blank=True) url_name = schema.CharField(blank=True) default_endpoint_name = None def get_endpoint_name(self): return self.endpoint_name or self.default_endpoint_name def get_view_endpoint_kwargs(self, **kwargs): params = { 'url_suffix': self.get_url(), } if self.url_name: params['name_suffix'] = self.url_name params.update(kwargs) return params def get_url(self): url = self.url or '' if url.startswith('/'): url = url[1:] if not url.startswith('^'): url = '^' + url return url def get_url_regexp(self): url = self.get_url() return r'%s' % url def __unicode__(self): if self.url: return self.url else: return self.view_type class Meta: proxy = True
class TemplateMixin(schema.Schema): ''' View point mixin that allows for template rendering to be overriden. ''' template_source = schema.CharField(choices=TEMPLATE_SOURCE_CHOICES, default='name') template_name = schema.CharField(default='dockitcms/list.html', blank=True) template_html = schema.TextField(blank=True) content = schema.TextField(blank=True) def render_content(self, context): if self.content: template = Template(self.content) return mark_safe(template.render(Context(context))) return '' def get_template_names(self): if self.template_source == 'name': return [self.template_name] if self.template_source == 'html': return Template(self.template_html)