def __new__(cls, name, bases, attrs): if name in cls.plugins_with_extrafields: ExtraFieldsMixin.media = media_property(ExtraFieldsMixin) bases = (ExtraFieldsMixin,) + bases if name in cls.plugins_with_sharables: SharableGlossaryMixin.media = media_property(SharableGlossaryMixin) bases = (SharableGlossaryMixin,) + bases attrs['fields'] += (('save_shared_glossary', 'save_as_identifier'), 'shared_glossary',) attrs['sharable_fields'] = cls.plugins_with_sharables[name] base_model = SharableCascadeElement else: base_model = CascadeElement if name in getattr(settings, 'CASCADE_PLUGINS_WITH_EXTRA_RENDER_TEMPLATES').keys(): RenderTemplateMixin.media = media_property(RenderTemplateMixin) bases = (RenderTemplateMixin,) + bases model_mixins = attrs.pop('model_mixins', ()) if name == 'SegmentPlugin': # SegmentPlugin shall additionally inherit from configured mixin classes model_mixins += tuple(import_string(mc[0]) for mc in settings.CASCADE_SEGMENTATION_MIXINS) attrs['model'] = create_proxy_model(name, model_mixins, base_model) if is_installed('reversion'): import reversion if not reversion.is_registered(base_model): reversion.register(base_model) return super(CascadePluginBaseMetaclass, cls).__new__(cls, name, bases, attrs)
def check_sekizai(output): with output.section("Sekizai") as section: sekizai_installed = is_installed('sekizai') if sekizai_installed: section.success("Sekizai is installed") else: section.error("Sekizai is not installed, could not find 'sekizai' in INSTALLED_APPS") processors = list( chain(*[template['OPTIONS'].get('context_processors', []) for template in settings.TEMPLATES])) if 'sekizai.context_processors.sekizai' in processors: section.success("Sekizai template context processor is installed") else: section.error("Sekizai template context processor is not installed, could not find " "'sekizai.context_processors.sekizai' in TEMPLATES option context_processors") if not sekizai_installed: # sekizai is not installed. # we can't reliable check templates # because template loading won't work return for template, _ in get_cms_setting('TEMPLATES'): if template == constants.TEMPLATE_INHERITANCE_MAGIC: continue if validate_template(template, ['js', 'css']): section.success("Sekizai namespaces 'js' and 'css' found in %r" % template) else: section.error("Sekizai namespaces 'js' and 'css' not found in %r" % template) if section.successful: section.finish_success("Sekizai configuration okay") else: section.finish_error("Sekizai configuration has errors")
def validate_settings(): if "django.core.context_processors.request" not in d_settings.TEMPLATE_CONTEXT_PROCESSORS: raise ImproperlyConfigured('django-cms needs django.core.context_processors.request in settings.TEMPLATE_CONTEXT_PROCESSORS to work correctly.') if not is_installed('mptt'): raise ImproperlyConfigured('django-cms needs django-mptt installed.') if 'cms.middleware.multilingual.MultilingualURLMiddleware' in d_settings.MIDDLEWARE_CLASSES and 'django.middleware.locale.LocaleMiddleware' in d_settings.MIDDLEWARE_CLASSES: raise ImproperlyConfigured('django-cms MultilingualURLMiddleware replaces django.middleware.locale.LocaleMiddleware! Please remove django.middleware.locale.LocaleMiddleware from your MIDDLEWARE_CLASSES settings.')
def check_sekizai(output): with output.section("Sekizai") as section: if is_installed('sekizai'): section.success("Sekizai is installed") else: section.error("Sekizai is not installed, could not find 'sekizai' in INSTALLED_APPS") if DJANGO_1_7: if 'sekizai.context_processors.sekizai' in settings.TEMPLATE_CONTEXT_PROCESSORS: section.success("Sekizai template context processor is installed") else: section.error("Sekizai template context processor is not installed, could not find 'sekizai.context_processors.sekizai' in TEMPLATE_CONTEXT_PROCESSORS") else: processors = list(chain(*[template['OPTIONS'].get('context_processors', []) for template in settings.TEMPLATES])) if 'sekizai.context_processors.sekizai' in processors: section.success("Sekizai template context processor is installed") else: section.error("Sekizai template context processor is not installed, could not find 'sekizai.context_processors.sekizai' in TEMPLATES option context_processors") for template, _ in get_cms_setting('TEMPLATES'): if template == constants.TEMPLATE_INHERITANCE_MAGIC: continue if validate_template(template, ['js', 'css']): section.success("Sekizai namespaces 'js' and 'css' found in %r" % template) else: section.error("Sekizai namespaces 'js' and 'css' not found in %r" % template) if section.successful: section.finish_success("Sekizai configuration okay") else: section.finish_error("Sekizai configuration has errors")
def __new__(cls, name, bases, attrs): if name in cls.plugins_with_extra_fields: ExtraFieldsMixin.media = media_property(ExtraFieldsMixin) bases = (ExtraFieldsMixin,) + bases if name in cls.plugins_with_sharables: SharableGlossaryMixin.media = media_property(SharableGlossaryMixin) bases = (SharableGlossaryMixin,) + bases attrs['fields'] += (('save_shared_glossary', 'save_as_identifier'), 'shared_glossary',) attrs['sharable_fields'] = cls.plugins_with_sharables[name] base_model = SharableCascadeElement else: base_model = CascadeElement if name in settings.CMSPLUGIN_CASCADE['plugins_with_extra_render_templates'].keys(): RenderTemplateMixin.media = media_property(RenderTemplateMixin) bases = (RenderTemplateMixin,) + bases model_mixins = attrs.pop('model_mixins', ()) if name == 'SegmentPlugin': # SegmentPlugin shall additionally inherit from configured mixin classes model_mixins += tuple(import_string(mc[0]) for mc in settings.CMSPLUGIN_CASCADE['segmentation_mixins']) module = attrs.get('__module__') app_label = attrs.get('app_label', module.split('.')[0]) attrs['model'] = create_proxy_model(name, app_label, model_mixins, base_model, module=module) if is_installed('reversion'): import reversion.revisions if not reversion.revisions.is_registered(base_model): reversion.revisions.register(base_model) # handle ambiguous plugin names by appending a symbol if 'name' in attrs and settings.CMSPLUGIN_CASCADE['plugin_prefix']: attrs['name'] = mark_safe_lazy(string_concat( settings.CMSPLUGIN_CASCADE['plugin_prefix'], " ", attrs['name'])) return super(CascadePluginBaseMetaclass, cls).__new__(cls, name, bases, attrs)
def check_sekizai(output): with output.section("Sekizai") as section: if is_installed('sekizai'): section.success("Sekizai is installed") else: section.error( "Sekizai is not installed, could not find 'sekizai' in INSTALLED_APPS" ) if 'sekizai.context_processors.sekizai' in settings.TEMPLATE_CONTEXT_PROCESSORS: section.success("Sekizai template context processor is installed") else: section.error( "Sekizai template context processor is not installed, could not find 'sekizai.context_processors.sekizai' in TEMPLATE_CONTEXT_PROCESSORS" ) for template, _ in get_cms_setting('TEMPLATES'): if template == constants.TEMPLATE_INHERITANCE_MAGIC: continue if validate_template(template, ['js', 'css']): section.success( "Sekizai namespaces 'js' and 'css' found in %r" % template) else: section.error( "Sekizai namespaces 'js' and 'css' not found in %r" % template) if section.successful: section.finish_success("Sekizai configuration okay") else: section.finish_error("Sekizai configuration has errors")
def reversion_register(model_class, fields=None, follow=(), format="json", exclude_fields=None): """CMS interface to reversion api - helper function. Registers model for reversion only if reversion is available. Auto excludes publisher fields. """ # reversion's merely recommended, not required if not is_installed('reversion'): return if fields and exclude_fields: raise ValueError( "Just one of fields, exclude_fields arguments can be passed.") opts = model_class._meta local_fields = opts.local_fields + opts.local_many_to_many if fields is None: fields = [field.name for field in local_fields] exclude_fields = exclude_fields or [] fields = filter(lambda name: not name in exclude_fields, fields) from cms.utils import reversion_hacks reversion_hacks.register_draft_only(model_class, fields, follow, format)
def __new__(cls, name, bases, attrs): model_mixins = attrs.pop('model_mixins', ()) if name in cls.plugins_with_extra_fields: ExtraFieldsMixin.media = media_property(ExtraFieldsMixin) bases = (ExtraFieldsMixin,) + bases if name in cls.plugins_with_bookmark: bases = (SectionMixin,) + bases model_mixins = (SectionModelMixin,) + model_mixins if name in cls.plugins_with_sharables: SharableGlossaryMixin.media = media_property(SharableGlossaryMixin) bases = (SharableGlossaryMixin,) + bases attrs['fields'] += (('save_shared_glossary', 'save_as_identifier'), 'shared_glossary',) attrs['sharable_fields'] = cls.plugins_with_sharables[name] base_model = SharableCascadeElement else: base_model = CascadeElement if name in cls.plugins_with_extra_render_templates: RenderTemplateMixin.media = media_property(RenderTemplateMixin) bases = (RenderTemplateMixin,) + bases if name == 'SegmentPlugin': # SegmentPlugin shall additionally inherit from configured mixin classes model_mixins += tuple(import_string(mc[0]) for mc in settings.CMSPLUGIN_CASCADE['segmentation_mixins']) module = attrs.get('__module__') attrs['model'] = create_proxy_model(name, model_mixins, base_model, module=module) if is_installed('reversion'): import reversion.revisions if not reversion.revisions.is_registered(base_model): reversion.revisions.register(base_model) # handle ambiguous plugin names by appending a symbol if 'name' in attrs and settings.CMSPLUGIN_CASCADE['plugin_prefix']: attrs['name'] = mark_safe_lazy(string_concat( settings.CMSPLUGIN_CASCADE['plugin_prefix'], " ", attrs['name'])) return super(CascadePluginBaseMetaclass, cls).__new__(cls, name, bases, attrs)
def add_history_menu(self): if self.toolbar.edit_mode and self.page: refresh = self.toolbar.REFRESH_PAGE history_menu = self.toolbar.get_or_create_menu(HISTORY_MENU_IDENTIFIER, _('History'), position=2) if is_installed('reversion'): import reversion from reversion.models import Revision versions = reversion.get_for_object(self.page) if self.page.revision_id: current_revision = Revision.objects.get(pk=self.page.revision_id) has_undo = versions.filter(revision__pk__lt=current_revision.pk).exists() has_redo = versions.filter(revision__pk__gt=current_revision.pk).exists() else: has_redo = False has_undo = versions.count() > 1 undo_action = admin_reverse('cms_page_undo', args=(self.page.pk,)) redo_action = admin_reverse('cms_page_redo', args=(self.page.pk,)) history_menu.add_ajax_item(_('Undo'), action=undo_action, disabled=not has_undo, on_success=refresh) history_menu.add_ajax_item(_('Redo'), action=redo_action, disabled=not has_redo, on_success=refresh) history_menu.add_break(HISTORY_MENU_BREAK) revert_action = admin_reverse('cms_page_revert_page', args=(self.page.pk, self.current_lang)) revert_question = _('Are you sure you want to revert to live?') history_menu.add_ajax_item(_('Revert to live'), action=revert_action, question=revert_question, disabled=not self.page.is_dirty(self.current_lang), on_success=refresh) history_menu.add_modal_item(_('View history'), url=admin_reverse('cms_page_history', args=(self.page.pk,)))
def reversion_register(model_class, fields=None, follow=(), format="json", exclude_fields=None): """CMS interface to reversion api - helper function. Registers model for reversion only if reversion is available. Auto excludes publisher fields. """ # reversion's merely recommended, not required if not is_installed('reversion'): return if fields and exclude_fields: raise ValueError("Just one of fields, exclude_fields arguments can be passed.") opts = model_class._meta local_fields = opts.local_fields + opts.local_many_to_many if fields is None: fields = [field.name for field in local_fields] exclude_fields = exclude_fields or [] fields = filter(lambda name: not name in exclude_fields, fields) from cms.utils import reversion_hacks reversion_hacks.register_draft_only(model_class, fields, follow, format)
def register_plugin(self, plugin): """ Registers the given plugin(s). Static sanity checks is also performed. If a plugin is already registered, this will raise PluginAlreadyRegistered. """ if not issubclass(plugin, CMSPluginBase): raise ImproperlyConfigured( "CMS Plugins must be subclasses of CMSPluginBase, %r is not." % plugin) plugin_name = plugin.__name__ if plugin_name in self.plugins: raise PluginAlreadyRegistered( "Cannot register %r, a plugin with this name (%r) is already " "registered." % (plugin, plugin_name)) plugin.value = plugin_name self.plugins[plugin_name] = plugin from cms.signals import pre_save_plugins signals.pre_save.connect(pre_save_plugins, sender=plugin.model, dispatch_uid='cms_pre_save_plugin_%s' % plugin_name) if is_installed('reversion'): from cms.utils.reversion_hacks import RegistrationError try: reversion_register(plugin.model) except RegistrationError: pass return plugin
def __new__(cls, name, bases, attrs): if name in cls.plugins_with_extrafields: ExtraFieldsMixin.media = media_property(ExtraFieldsMixin) bases = (ExtraFieldsMixin, ) + bases if name in cls.plugins_with_sharables: SharableGlossaryMixin.media = media_property(SharableGlossaryMixin) bases = (SharableGlossaryMixin, ) + bases attrs['fields'] += ( ('save_shared_glossary', 'save_as_identifier'), 'shared_glossary', ) attrs['sharable_fields'] = cls.plugins_with_sharables[name] base_model = SharableCascadeElement else: base_model = CascadeElement if name in getattr( settings, 'CASCADE_PLUGINS_WITH_EXTRA_RENDER_TEMPLATES').keys(): RenderTemplateMixin.media = media_property(RenderTemplateMixin) bases = (RenderTemplateMixin, ) + bases model_mixins = attrs.pop('model_mixins', ()) if name == 'SegmentPlugin': # SegmentPlugin shall additionally inherit from configured mixin classes model_mixins += tuple( import_by_path(mc[0]) for mc in settings.CASCADE_SEGMENTATION_MIXINS) attrs['model'] = create_proxy_model(name, model_mixins, base_model) if is_installed('reversion'): import reversion reversion.register(attrs['model']) return super(CascadePluginBaseMetaclass, cls).__new__(cls, name, bases, attrs)
def validate_dependencies(): # check for right version of reversions if is_installed('reversion'): from reversion.admin import VersionAdmin if not hasattr(VersionAdmin, 'get_urls'): raise ImproperlyConfigured( 'django-cms requires never version of reversion (VersionAdmin must contain get_urls method)' )
def __new__(cls, name, bases, attrs): model_mixins = attrs.pop('model_mixins', ()) if (cls.allow_plugin_hiding and name not in cls.exclude_hiding_plugin and 'name' in attrs and not attrs.get('text_enabled')): bases = (HidePluginMixin, ) + bases if name in cls.plugins_with_extra_fields: bases = (ExtraFieldsMixin, ) + bases if name in cls.plugins_with_extra_mixins: bases = (cls.plugins_with_extra_mixins[name], ) + bases if name in cls.plugins_with_bookmark: bases = (SectionMixin, ) + bases model_mixins = (SectionModelMixin, ) + model_mixins if name in cls.plugins_with_sharables: bases = (SharableGlossaryMixin, ) + bases attrs['fields'] = list(attrs.get('fields', ['glossary'])) attrs['fields'].extend([('save_shared_glossary', 'save_as_identifier'), 'shared_glossary']) attrs['sharable_fields'] = cls.plugins_with_sharables[name] base_model = SharableCascadeElement else: attrs['exclude'] = list(attrs.get('exclude', [])) attrs['exclude'].append('shared_glossary') base_model = CascadeElement if name in cls.plugins_with_extra_render_templates: bases = (RenderTemplateMixin, ) + bases if name == 'SegmentPlugin': # SegmentPlugin shall additionally inherit from configured mixin classes model_mixins += tuple( import_string(mc[0]) for mc in app_settings.CMSPLUGIN_CASCADE['segmentation_mixins']) if 'model' in attrs: # the plugin overrides the CascadeModel if not issubclass(attrs['model'], CascadeModelBase): msg = "Cascade Plugins, overriding the model, must inherit from `CascadeModelBase`." raise ImproperlyConfigured(msg) else: attrs['model'] = create_proxy_model(name, model_mixins, base_model, module=attrs.get('__module__')) if is_installed('reversion'): import reversion.revisions if not reversion.revisions.is_registered(base_model): reversion.revisions.register(base_model) # handle ambiguous plugin names by appending a symbol if 'name' in attrs and app_settings.CMSPLUGIN_CASCADE['plugin_prefix']: attrs['name'] = mark_safe_lazy( string_concat(app_settings.CMSPLUGIN_CASCADE['plugin_prefix'], " ", attrs['name'])) register_stride(name, bases, attrs, model_mixins) if name == 'CascadePluginBase': bases += ( CascadePluginMixin, CMSPluginBase, ) return super(CascadePluginBaseMetaclass, cls).__new__(cls, name, bases, attrs)
def get_page_from_request(request, use_path=None): """ Gets the current page from a request object. URLs can be of the following form (this should help understand the code): http://server.whatever.com/<some_path>/"pages-root"/some/page/slug <some_path>: This can be anything, and should be stripped when resolving pages names. This means the CMS is not installed at the root of the server's URLs. "pages-root" This is the root of Django urls for the CMS. It is, in essence an empty page slug (slug == '') The page slug can then be resolved to a Page model object """ # The following is used by cms.middleware.page.CurrentPageMiddleware if hasattr(request, '_current_page_cache'): return request._current_page_cache draft = use_draft(request) preview = 'preview' in request.GET # If use_path is given, someone already did the path cleaning if use_path is not None: path = use_path else: path = request.path_info pages_root = unquote(reverse("pages-root")) # otherwise strip off the non-cms part of the URL if is_installed('django.contrib.admin'): admin_base = admin_reverse('index') else: admin_base = None if path.startswith(pages_root) and (not admin_base or not path.startswith(admin_base)): path = path[len(pages_root):] # and strip any final slash if path.endswith("/"): path = path[:-1] page = get_page_from_path(path, preview, draft) if draft and page and not user_can_change_page(request.user, page): page = get_page_from_path(path, preview, draft=False) # For public pages we check if any parent is hidden due to published dates # In this case the selected page is not reachable if page and not draft: ancestors = page.get_ancestors().filter( Q(publication_date__gt=timezone.now()) | Q(publication_end_date__lt=timezone.now()), ) if ancestors.exists(): page = None request._current_page_cache = page return page
def validate_settings(): if "django.core.context_processors.request" not in d_settings.TEMPLATE_CONTEXT_PROCESSORS: raise ImproperlyConfigured( 'django-cms needs django.core.context_processors.request in settings.TEMPLATE_CONTEXT_PROCESSORS to work correctly.' ) if not is_installed('mptt'): raise ImproperlyConfigured('django-cms needs django-mptt installed.') if 'cms.middleware.multilingual.MultilingualURLMiddleware' in d_settings.MIDDLEWARE_CLASSES and 'django.middleware.locale.LocaleMiddleware' in d_settings.MIDDLEWARE_CLASSES: raise ImproperlyConfigured( 'django-cms MultilingualURLMiddleware replaces django.middleware.locale.LocaleMiddleware! Please remove django.middleware.locale.LocaleMiddleware from your MIDDLEWARE_CLASSES settings.' )
def __init__(self, *args, **kwargs): try: initial = dict(kwargs['instance'].glossary) except (KeyError, AttributeError): initial = {} initial.update(kwargs.pop('initial', {})) try: self.base_fields['product'].initial = initial['product']['pk'] except KeyError: self.base_fields['product'].initial = None if not is_installed('adminsortable2'): self.base_fields['order'].widget = widgets.HiddenInput() self.base_fields['order'].initial = 0 super(ProductGalleryForm, self).__init__(*args, **kwargs)
def __new__(cls, name, bases, attrs): model_mixins = attrs.pop('model_mixins', ()) if (cls.allow_plugin_hiding and name not in cls.exclude_hiding_plugin and 'name' in attrs and not attrs.get('text_enabled')): bases = (HidePluginMixin,) + bases if name in cls.plugins_with_extra_fields: bases = (ExtraFieldsMixin,) + bases if name in cls.plugins_with_extra_mixins: bases = (cls.plugins_with_extra_mixins[name],) + bases if name in cls.plugins_with_bookmark: bases = (SectionMixin,) + bases model_mixins = (SectionModelMixin,) + model_mixins if name in cls.plugins_with_sharables: bases = (SharableGlossaryMixin,) + bases attrs['fields'] = list(attrs.get('fields', ['glossary'])) attrs['fields'].extend([('save_shared_glossary', 'save_as_identifier'), 'shared_glossary']) attrs['sharable_fields'] = cls.plugins_with_sharables[name] base_model = SharableCascadeElement else: attrs['exclude'] = list(attrs.get('exclude', [])) attrs['exclude'].append('shared_glossary') base_model = CascadeElement if name in cls.plugins_with_extra_render_templates: bases = (RenderTemplateMixin,) + bases if name == 'SegmentPlugin': # SegmentPlugin shall additionally inherit from configured mixin classes model_mixins += tuple(import_string(mc[0]) for mc in app_settings.CMSPLUGIN_CASCADE['segmentation_mixins']) if 'model' in attrs: # the plugin overrides the CascadeModel if not issubclass(attrs['model'], CascadeModelBase): msg = "Cascade Plugins, overriding the model, must inherit from `CascadeModelBase`." raise ImproperlyConfigured(msg) else: attrs['model'] = create_proxy_model(name, model_mixins, base_model, module=attrs.get('__module__')) if is_installed('reversion'): import reversion.revisions if not reversion.revisions.is_registered(base_model): reversion.revisions.register(base_model) # handle ambiguous plugin names by appending a symbol if 'name' in attrs and app_settings.CMSPLUGIN_CASCADE['plugin_prefix']: attrs['name'] = mark_safe_lazy(string_concat( app_settings.CMSPLUGIN_CASCADE['plugin_prefix'], " ", attrs['name'])) register_stride(name, bases, attrs, model_mixins) if name == 'CascadePluginBase': bases += (CascadePluginMixin, CMSPluginBase,) return super(CascadePluginBaseMetaclass, cls).__new__(cls, name, bases, attrs)
def __init__(self, *args, **kwargs): try: initial = dict(kwargs['instance'].glossary) except (KeyError, AttributeError): initial = {} initial.update(kwargs.pop('initial', {})) for key in self.glossary_field_order: self.base_fields[key].initial = initial.get(key) try: self.base_fields['image_file'].initial = initial['image']['pk'] except KeyError: self.base_fields['image_file'].initial = None self.base_fields['image_file'].widget = AdminFileWidget(ManyToOneRel(FilerImageField, Image, 'file_ptr'), site) if not is_installed('adminsortable2'): self.base_fields['order'].widget = widgets.HiddenInput() self.base_fields['order'].initial = 0 super(GalleryImageForm, self).__init__(*args, **kwargs)
def __init__(self, *args, **kwargs): try: initial = dict(kwargs['instance'].glossary) except (KeyError, AttributeError): initial = {} initial.update(kwargs.pop('initial', {})) for key in self.glossary_fields: self.base_fields[key].initial = initial.get(key) try: self.base_fields['image_file'].initial = initial['image']['pk'] except KeyError: self.base_fields['image_file'].initial = None self.base_fields['image_file'].widget = AdminFileWidget(ManyToOneRel(FilerImageField, Image, 'file_ptr'), site) if not is_installed('adminsortable2'): self.base_fields['order'].widget = widgets.HiddenInput() self.base_fields['order'].initial = 0 super(GalleryImageForm, self).__init__(*args, **kwargs)
def get_page_from_request(request, use_path=None): """ Gets the current page from a request object. URLs can be of the following form (this should help understand the code): http://server.whatever.com/<some_path>/"pages-root"/some/page/slug <some_path>: This can be anything, and should be stripped when resolving pages names. This means the CMS is not installed at the root of the server's URLs. "pages-root" This is the root of Django urls for the CMS. It is, in essence an empty page slug (slug == '') The page slug can then be resolved to a Page model object """ # The following is used by cms.middleware.page.CurrentPageMiddleware if hasattr(request, '_current_page_cache'): return request._current_page_cache draft = use_draft(request) preview = 'preview' in request.GET # If use_path is given, someone already did the path cleaning if use_path is not None: path = use_path else: path = request.path pages_root = unquote(reverse("pages-root")) # otherwise strip off the non-cms part of the URL if is_installed('django.contrib.admin'): admin_base = reverse('admin:index') else: admin_base = None if path.startswith(pages_root) and (not admin_base or not path.startswith(admin_base)): path = path[len(pages_root):] # and strip any final slash if path.endswith("/"): path = path[:-1] page = get_page_from_path(path, preview, draft) if draft and page and not page.has_change_permission(request): page = get_page_from_path(path, preview, draft=False) request._current_page_cache = page return page
def get_page_from_request(request, use_path=None): """ Gets the current page from a request object. URLs can be of the following form (this should help understand the code): http://server.whatever.com/<some_path>/"pages-root"/some/page/slug <some_path>: This can be anything, and should be stripped when resolving pages names. This means the CMS is not installed at the root of the server's URLs. "pages-root" This is the root of Django urls for the CMS. It is, in essence an empty page slug (slug == '') The page slug can then be resolved to a Page model object """ # The following is used by cms.middleware.page.CurrentPageMiddleware if hasattr(request, "_current_page_cache"): return request._current_page_cache draft = use_draft(request) preview = "preview" in request.GET # If use_path is given, someone already did the path cleaning if use_path is not None: path = use_path else: path = request.path pages_root = unquote(reverse("pages-root")) # otherwise strip off the non-cms part of the URL if is_installed("django.contrib.admin"): admin_base = reverse("admin:index") else: admin_base = None if path.startswith(pages_root) and (not admin_base or not path.startswith(admin_base)): path = path[len(pages_root) :] # and strip any final slash if path.endswith("/"): path = path[:-1] page = get_page_from_path(path, preview, draft) if draft and page and not page.has_change_permission(request): page = get_page_from_path(path, preview, draft=False) request._current_page_cache = page return page
def register_plugin(self, plugin): """ Registers the given plugin(s). Static sanity checks is also performed. If a plugin is already registered, this will raise PluginAlreadyRegistered. """ if not issubclass(plugin, CMSPluginBase): raise ImproperlyConfigured( "CMS Plugins must be subclasses of CMSPluginBase, %r is not." % plugin ) plugin_name = plugin.__name__ if plugin_name in self.plugins: raise PluginAlreadyRegistered( "Cannot register %r, a plugin with this name (%r) is already " "registered." % (plugin, plugin_name) ) plugin.value = plugin_name self.plugins[plugin_name] = plugin from cms.signals import pre_save_plugins, post_delete_plugins, pre_delete_plugins signals.pre_save.connect(pre_save_plugins, sender=plugin.model, dispatch_uid='cms_pre_save_plugin_%s' % plugin_name) signals.post_delete.connect(post_delete_plugins, sender=CMSPlugin, dispatch_uid='cms_post_delete_plugin_%s' % plugin_name) signals.pre_delete.connect(pre_delete_plugins, sender=CMSPlugin, dispatch_uid='cms_pre_delete_plugin_%s' % plugin_name) if is_installed('reversion'): from cms.utils.reversion_hacks import RegistrationError try: reversion_register(plugin.model) except RegistrationError: pass return plugin
def get_page_queryset_from_path(path, preview=False, draft=False, site=None): """ Returns a queryset of pages corresponding to the path given """ if is_installed('django.contrib.admin'): admin_base = admin_reverse('index') # Check if this is called from an admin request if path.startswith(admin_base): # if so, get the page ID to request it directly match = ADMIN_PAGE_RE.search(path) if match: return Page.objects.filter(pk=match.group(1)) else: return Page.objects.none() if not site: site = Site.objects.get_current() # PageQuerySet.published filter on page site. # We have to explicitly filter on site only in preview mode if draft: pages = Page.objects.drafts().filter(site=site) elif preview: pages = Page.objects.public().filter(site=site) else: pages = Page.objects.public().published(site=site) if not path: # if there is no path (slashes stripped) and we found a home, this is the # home page. # PageQuerySet.published() introduces a join to title_set which can return # multiple rows. Get only the first match. return pages.filter(is_home=True, site=site)[:1] # title_set__path=path should be clear, get the pages where the path of the # title object is equal to our path. return pages.filter(title_set__path=path).distinct()
def save(self, **kwargs): from cms.api import create_page, add_plugin from cms.utils.permissions import has_page_add_permission # Check to see if this user has permissions to make this page. We've # already checked this when producing a list of wizard entries, but this # is to prevent people from possible form-hacking. if 'sub_page' in self.cleaned_data: sub_page = self.cleaned_data['sub_page'] else: sub_page = False if self.page: if sub_page: parent = self.page position = "last-child" else: parent = self.page.parent position = "right" else: parent = None position = "last-child" # Before we do this, verify this user has perms to do so. if not (self.user.is_superuser or has_page_add_permission(self.user, self.page, position=position, site=self.page.site)): raise NoPermissionsException( _(u"User does not have permission to add page.")) page = create_page( title=self.cleaned_data['title'], slug=self.cleaned_data['slug'], template=get_cms_setting('PAGE_WIZARD_DEFAULT_TEMPLATE'), language=self.language_code, created_by=smart_text(self.user), parent=parent, in_navigation=True, published=False ) page_type = self.cleaned_data.get("page_type") if page_type: copy_target = Page.objects.filter(pk=page_type).first() else: copy_target = None if copy_target: # If the user selected a page type, copy that. if not user_has_view_permission(self.user, copy_target): raise PermissionDenied() # Copy page attributes copy_target._copy_attributes(page, clean=True) page.save() # Copy contents (for each language) for lang in copy_target.get_languages(): copy_target._copy_contents(page, lang) # Copy extensions from cms.extensions import extension_pool extension_pool.copy_extensions(copy_target, page) else: # If the user provided content, then use that instead. content = self.cleaned_data.get('content') plugin_type = get_cms_setting('PAGE_WIZARD_CONTENT_PLUGIN') plugin_body = get_cms_setting('PAGE_WIZARD_CONTENT_PLUGIN_BODY') slot = get_cms_setting('PAGE_WIZARD_CONTENT_PLACEHOLDER') if plugin_type in plugin_pool.plugins and plugin_body: if content and permissions.has_plugin_permission( self.user, plugin_type, "add"): placeholder = self.get_placeholder(page, slot=slot) if placeholder: opts = { 'placeholder': placeholder, 'plugin_type': plugin_type, 'language': self.language_code, plugin_body: content, } add_plugin(**opts) # is it home? publish it right away if not self.page and page.is_home: page.publish(self.language_code) if is_installed('reversion'): from cms.utils.helpers import make_revision_with_plugins from cms.constants import REVISION_INITIAL_COMMENT from cms.utils.reversion_hacks import create_revision with create_revision(): make_revision_with_plugins( obj=page, user=self.user, message=ugettext(REVISION_INITIAL_COMMENT), ) return page
admin.autodiscover() urlpatterns = [ url(r'^admin/', include(admin.site.urls)), url(r'^media/(?P<path>.*)$', serve, { 'document_root': settings.MEDIA_ROOT, 'show_indexes': True }), url(r'^media/cms/(?P<path>.*)$', serve, { 'document_root': get_cms_setting('MEDIA_ROOT'), 'show_indexes': True }), url(r'^jsi18n/(?P<packages>\S+?)/$', javascript_catalog), ] urlpatterns += i18n_patterns( url(r'^detail/(?P<id>[0-9]+)/$', detail_view, name="detail"), url(r'^detail/(?P<pk>[0-9]+)/$', detail_view, name="example_detail"), url(r'^detail_multi/(?P<id>[0-9]+)/$', detail_view_multi, name="detail_multi"), url(r'^', include('cms.urls')), ) if settings.DEBUG and is_installed('debug_toolbar'): import debug_toolbar urlpatterns += [ url(r'^__debug__/', include(debug_toolbar.urls)), ]
def save(self, **kwargs): from cms.api import create_page, add_plugin from cms.utils.permissions import has_page_add_permission # Check to see if this user has permissions to make this page. We've # already checked this when producing a list of wizard entries, but this # is to prevent people from possible form-hacking. if 'sub_page' in self.cleaned_data: sub_page = self.cleaned_data['sub_page'] else: sub_page = False if self.page: if sub_page: parent = self.page position = "last-child" else: parent = self.page.parent position = "right" else: parent = None position = "last-child" # Before we do this, verify this user has perms to do so. if not (self.user.is_superuser or has_page_add_permission( self.user, self.page, position=position, site=self.page.site)): raise NoPermissionsException( _(u"User does not have permission to add page.")) page = create_page( title=self.cleaned_data['title'], slug=self.cleaned_data['slug'], template=get_cms_setting('PAGE_WIZARD_DEFAULT_TEMPLATE'), language=self.language_code, created_by=smart_text(self.user), parent=parent, in_navigation=True, published=False) page_type = self.cleaned_data.get("page_type") if page_type: copy_target = Page.objects.filter(pk=page_type).first() else: copy_target = None if copy_target: # If the user selected a page type, copy that. if not user_has_view_permission(self.user, copy_target): raise PermissionDenied() # Copy page attributes copy_target._copy_attributes(page, clean=True) page.save() # Copy contents (for each language) for lang in copy_target.get_languages(): copy_target._copy_contents(page, lang) # Copy extensions from cms.extensions import extension_pool extension_pool.copy_extensions(copy_target, page) else: # If the user provided content, then use that instead. content = self.cleaned_data.get('content') plugin_type = get_cms_setting('PAGE_WIZARD_CONTENT_PLUGIN') plugin_body = get_cms_setting('PAGE_WIZARD_CONTENT_PLUGIN_BODY') slot = get_cms_setting('PAGE_WIZARD_CONTENT_PLACEHOLDER') if plugin_type in plugin_pool.plugins and plugin_body: if content and permissions.has_plugin_permission( self.user, plugin_type, "add"): placeholder = self.get_placeholder(page, slot=slot) if placeholder: opts = { 'placeholder': placeholder, 'plugin_type': plugin_type, 'language': self.language_code, plugin_body: content, } add_plugin(**opts) # is it home? publish it right away if not self.page and page.is_home: page.publish(self.language_code) if is_installed('reversion'): from cms.utils.helpers import make_revision_with_plugins from cms.constants import REVISION_INITIAL_COMMENT from cms.utils.reversion_hacks import create_revision with create_revision(): make_revision_with_plugins( obj=page, user=self.user, message=ugettext(REVISION_INITIAL_COMMENT), ) return page
from cms.test_utils.project.placeholderapp.views import example_view from cms.utils.compat.dj import is_installed from cms.utils.conf import get_cms_setting from django.conf import settings from django.conf.urls import include, url from django.contrib import admin from django.contrib.staticfiles.urls import staticfiles_urlpatterns from django.views.i18n import javascript_catalog from django.views.static import serve admin.autodiscover() urlpatterns = [ url(r"^media/(?P<path>.*)$", serve, {"document_root": settings.MEDIA_ROOT, "show_indexes": True}), url(r"^media/cms/(?P<path>.*)$", serve, {"document_root": get_cms_setting("MEDIA_ROOT"), "show_indexes": True}), url(r"^jsi18n/(?P<packages>\S+?)/$", javascript_catalog), ] urlpatterns += staticfiles_urlpatterns() urlpatterns += [ url(r"^admin/", include(admin.site.urls)), url(r"^example/$", example_view), url(r"^", include("cms.urls")), ] if settings.DEBUG and is_installed("debug_toolbar"): import debug_toolbar urlpatterns += [url(r"^__debug__/", include(debug_toolbar.urls))]
def register_plugin(self, plugin): """ Registers the given plugin(s). If a plugin is already registered, this will raise PluginAlreadyRegistered. """ if not issubclass(plugin, CMSPluginBase): raise ImproperlyConfigured( "CMS Plugins must be subclasses of CMSPluginBase, %r is not." % plugin) if plugin.render_plugin and not type( plugin.render_plugin) == property or hasattr( plugin.model, 'render_template'): if plugin.render_template is None and not hasattr( plugin.model, 'render_template'): raise ImproperlyConfigured( "CMS Plugins must define a render template or set render_plugin=False: %s" % plugin) else: from django.template import loader template = hasattr( plugin.model, 'render_template' ) and plugin.model.render_template or plugin.render_template if isinstance(template, six.string_types) and template: try: loader.get_template(template) except TemplateDoesNotExist as e: # Note that the template loader will throw # TemplateDoesNotExist if the plugin's render_template # does in fact exist, but it includes a template that # doesn't. if six.text_type(e) == template: raise ImproperlyConfigured( "CMS Plugins must define a render template (%s) that exists: %s" % (plugin, template)) else: pass except TemplateSyntaxError: pass else: if plugin.allow_children: raise ImproperlyConfigured( "CMS Plugins can not define render_plugin=False and allow_children=True: %s" % plugin) plugin_name = plugin.__name__ if plugin_name in self.plugins: raise PluginAlreadyRegistered( "Cannot register %r, a plugin with this name (%r) is already " "registered." % (plugin, plugin_name)) plugin.value = plugin_name self.plugins[plugin_name] = plugin from cms.signals import pre_save_plugins, post_delete_plugins, pre_delete_plugins signals.pre_save.connect(pre_save_plugins, sender=plugin.model, dispatch_uid='cms_pre_save_plugin_%s' % plugin_name) signals.post_delete.connect(post_delete_plugins, sender=CMSPlugin, dispatch_uid='cms_post_delete_plugin_%s' % plugin_name) signals.pre_delete.connect(pre_delete_plugins, sender=CMSPlugin, dispatch_uid='cms_pre_delete_plugin_%s' % plugin_name) if is_installed('reversion'): try: from reversion.registration import RegistrationError except ImportError: from reversion.revisions import RegistrationError try: reversion_register(plugin.model) except RegistrationError: pass
def test_with_reversion(self): self.assertTrue(is_installed('reversion')) self._create_and_configure_a_container_plugin()
from django.forms import widgets from django.forms.models import ModelForm from django.template.loader import select_template from django.utils.translation import ugettext_lazy as _, ugettext from cms.plugin_pool import plugin_pool from cms.utils.compat.dj import is_installed from cmsplugin_cascade.mixins import WithSortableInlineElementsMixin from cmsplugin_cascade.models import SortableInlineCascadeElement from cmsplugin_cascade.fields import GlossaryField from shop.conf import app_settings from shop.models.product import ProductModel from .plugin_base import ShopPluginBase, ProductSelectField if is_installed('adminsortable2'): from adminsortable2.admin import SortableInlineAdminMixin else: SortableInlineAdminMixin = type(str('SortableInlineAdminMixin'), (object, ), {}) class ShopCatalogPlugin(ShopPluginBase): name = _("Catalog List View") require_parent = True parent_classes = ( 'BootstrapColumnPlugin', 'SimpleWrapperPlugin', ) cache = False
def validate_dependencies(): # check for right version of reversions if is_installed('reversion'): from reversion.admin import VersionAdmin if not hasattr(VersionAdmin, 'get_urls'): raise ImproperlyConfigured('django-cms requires never version of reversion (VersionAdmin must contain get_urls method)')
# only if permissions are in use signals.pre_save.connect(pre_save_user, sender=User, dispatch_uid='cms_pre_save_user') signals.post_save.connect(post_save_user, sender=User, dispatch_uid='cms_post_save_user') signals.pre_delete.connect(pre_delete_user, sender=User, dispatch_uid='cms_pre_delete_user') signals.pre_save.connect(pre_save_user, sender=PageUser, dispatch_uid='cms_pre_save_pageuser') signals.pre_delete.connect(pre_delete_user, sender=PageUser, dispatch_uid='cms_pre_delete_pageuser') signals.pre_save.connect(pre_save_group, sender=Group, dispatch_uid='cms_pre_save_group') signals.post_save.connect(post_save_user_group, sender=Group, dispatch_uid='cms_post_save_group') signals.pre_delete.connect(pre_delete_group, sender=Group, dispatch_uid='cms_post_save_group') signals.pre_save.connect(pre_save_group, sender=PageUserGroup, dispatch_uid='cms_pre_save_pageusergroup') signals.pre_delete.connect(pre_delete_group, sender=PageUserGroup, dispatch_uid='cms_pre_delete_pageusergroup') signals.pre_save.connect(pre_save_pagepermission, sender=PagePermission, dispatch_uid='cms_pre_save_pagepermission') signals.pre_delete.connect(pre_delete_pagepermission, sender=PagePermission, dispatch_uid='cms_pre_delete_pagepermission') signals.pre_save.connect(pre_save_globalpagepermission, sender=GlobalPagePermission, dispatch_uid='cms_pre_save_globalpagepermission') signals.pre_delete.connect(pre_delete_globalpagepermission, sender=GlobalPagePermission, dispatch_uid='cms_pre_delete_globalpagepermission') ###################### reversion ######################### if is_installed('reversion'): from cms.utils.reversion_hacks import post_revision_commit post_revision_commit.connect(post_revision, dispatch_uid='cms_post_revision')
signals.pre_save.connect(pre_save_group, sender=PageUserGroup, dispatch_uid='cms_pre_save_pageusergroup') signals.pre_delete.connect(pre_delete_group, sender=PageUserGroup, dispatch_uid='cms_pre_delete_pageusergroup') signals.pre_save.connect(pre_save_pagepermission, sender=PagePermission, dispatch_uid='cms_pre_save_pagepermission') signals.pre_delete.connect(pre_delete_pagepermission, sender=PagePermission, dispatch_uid='cms_pre_delete_pagepermission') signals.pre_save.connect(pre_save_globalpagepermission, sender=GlobalPagePermission, dispatch_uid='cms_pre_save_globalpagepermission') signals.pre_delete.connect( pre_delete_globalpagepermission, sender=GlobalPagePermission, dispatch_uid='cms_pre_delete_globalpagepermission') ###################### reversion ######################### if is_installed('reversion'): from cms.utils.reversion_hacks import post_revision_commit post_revision_commit.connect(post_revision, dispatch_uid='cms_post_revision')
def register_plugin(self, plugin): """ Registers the given plugin(s). If a plugin is already registered, this will raise PluginAlreadyRegistered. """ if not issubclass(plugin, CMSPluginBase): raise ImproperlyConfigured( "CMS Plugins must be subclasses of CMSPluginBase, %r is not." % plugin ) if plugin.render_plugin and not type(plugin.render_plugin) == property or hasattr(plugin.model, 'render_template'): if plugin.render_template is None and not hasattr(plugin.model, 'render_template'): raise ImproperlyConfigured( "CMS Plugins must define a render template or set render_plugin=False: %s" % plugin ) else: from django.template import loader template = hasattr(plugin.model, 'render_template') and plugin.model.render_template or plugin.render_template if isinstance(template, string_types) and template: try: loader.get_template(template) except TemplateDoesNotExist: raise ImproperlyConfigured( "CMS Plugins must define a render template (%s) that exist: %s" % (plugin, template) ) except TemplateSyntaxError: pass else: if plugin.allow_children: raise ImproperlyConfigured( "CMS Plugins can not define render_plugin=False and allow_children=True: %s" % plugin ) plugin_name = plugin.__name__ if plugin_name in self.plugins: raise PluginAlreadyRegistered( "Cannot register %r, a plugin with this name (%r) is already " "registered." % (plugin, plugin_name) ) plugin.value = plugin_name self.plugins[plugin_name] = plugin from cms.signals import pre_save_plugins, post_delete_plugins, pre_delete_plugins signals.pre_save.connect(pre_save_plugins, sender=plugin.model, dispatch_uid='cms_pre_save_plugin_%s' % plugin_name) signals.post_delete.connect(post_delete_plugins, sender=CMSPlugin, dispatch_uid='cms_post_delete_plugin_%s' % plugin_name) signals.pre_delete.connect(pre_delete_plugins, sender=CMSPlugin, dispatch_uid='cms_pre_delete_plugin_%s' % plugin_name) if is_installed('reversion'): try: from reversion.registration import RegistrationError except ImportError: from reversion.revisions import RegistrationError try: reversion_register(plugin.model) except RegistrationError: pass
def _verify_revision_support(): if not is_installed('reversion'): raise ImproperlyConfigured( "You have requested to create a revision " "but the reversion app is not in settings.INSTALLED_APPS" )
import logging from json import dumps from xml.etree.ElementTree import ElementTree from cms.utils.compat.dj import is_installed from dateutil.parser import parse from django.utils.timezone import make_aware from ..conf import settings if is_installed('django.contrib.redirects'): from django.contrib.redirects.models import Redirect try: from urllib.parse import urlparse except ImportError: from urlparse import urlparse def create_redirect(old_url, new_url): old_path = urlparse(old_url).path new_path = urlparse(new_url).path if old_path != '/' and new_path != old_path: redirect = Redirect.objects.get_or_create( site_id=settings.SITE_ID, old_path=urlparse(old_path).path, )[0] redirect.new_path = new_path redirect.save() return redirect else: def create_redirect(old_url, new_url): pass
def register_plugin(self, plugin): """ Registers the given plugin(s). If a plugin is already registered, this will raise PluginAlreadyRegistered. """ if not issubclass(plugin, CMSPluginBase): raise ImproperlyConfigured( "CMS Plugins must be subclasses of CMSPluginBase, %r is not." % plugin ) if (plugin.render_plugin and not type(plugin.render_plugin) == property or hasattr(plugin.model, 'render_template') or hasattr(plugin, 'get_render_template')): if (plugin.render_template is None and not hasattr(plugin.model, 'render_template') and not hasattr(plugin, 'get_render_template')): raise ImproperlyConfigured( "CMS Plugins must define a render template, " "a get_render_template method or " "set render_plugin=False: %s" % plugin ) # If plugin class defines get_render_template we cannot # statically check for valid template file as it depends # on plugin configuration and context. # We cannot prevent developer to shoot in the users' feet elif not hasattr(plugin, 'get_render_template'): from django.template import loader template = ((hasattr(plugin.model, 'render_template') and plugin.model.render_template) or plugin.render_template) if isinstance(template, six.string_types) and template: try: loader.get_template(template) except TemplateDoesNotExist as e: # Note that the template loader will throw # TemplateDoesNotExist if the plugin's render_template # does in fact exist, but it includes a template that # doesn't. if six.text_type(e) == template: raise ImproperlyConfigured( "CMS Plugins must define a render template (%s) that exists: %s" % (plugin, template) ) else: pass except TemplateSyntaxError: pass else: if plugin.allow_children: raise ImproperlyConfigured( "CMS Plugins can not define render_plugin=False and allow_children=True: %s" % plugin ) plugin_name = plugin.__name__ if plugin_name in self.plugins: raise PluginAlreadyRegistered( "Cannot register %r, a plugin with this name (%r) is already " "registered." % (plugin, plugin_name) ) plugin.value = plugin_name self.plugins[plugin_name] = plugin from cms.signals import pre_save_plugins, post_delete_plugins, pre_delete_plugins signals.pre_save.connect(pre_save_plugins, sender=plugin.model, dispatch_uid='cms_pre_save_plugin_%s' % plugin_name) signals.post_delete.connect(post_delete_plugins, sender=CMSPlugin, dispatch_uid='cms_post_delete_plugin_%s' % plugin_name) signals.pre_delete.connect(pre_delete_plugins, sender=CMSPlugin, dispatch_uid='cms_pre_delete_plugin_%s' % plugin_name) if is_installed('reversion'): from reversion.revisions import RegistrationError try: reversion_register(plugin.model) except RegistrationError: pass return plugin
from cms.utils import get_cms_setting from cms.utils.compat.dj import is_installed from django.conf import settings from django.conf.urls import include, url from django.conf.urls.i18n import i18n_patterns from django.contrib import admin admin.autodiscover() urlpatterns = [ url(r'^jsi18n/(?P<packages>\S+?)/$', 'django.views.i18n.javascript_catalog'), url(r'^media/cms/(?P<path>.*)$', 'django.views.static.serve', {'document_root': get_cms_setting('MEDIA_ROOT'), 'show_indexes': True}), url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}), ] urlpatterns += i18n_patterns('', url(r'^admin/', include(admin.site.urls)), url(r'^content/', include('cms.urls')), ) if settings.DEBUG and is_installed('debug_toolbar'): import debug_toolbar urlpatterns += [ url(r'^__debug__/', include(debug_toolbar.urls)), ]
def test_without_reversion(self): self.assertFalse(is_installed("reversion")) self._create_and_configure_a_container_plugin()
def add_page_menu(self): if self.page and self.has_page_change_permission(): edit_mode = self.toolbar.edit_mode refresh = self.toolbar.REFRESH_PAGE # menu for current page # NOTE: disabled if the current path is "deeper" into the # application's url patterns than its root. This is because # when the Content Manager is at the root of the app-hook, # some of the page options still make sense. current_page_menu = self.toolbar.get_or_create_menu( PAGE_MENU_IDENTIFIER, _('Page'), position=1, disabled=self.in_apphook() and not self.in_apphook_root()) # page operations menu add_page_menu = current_page_menu.get_or_create_menu(PAGE_MENU_ADD_IDENTIFIER, _('Create Page')) app_page_url = admin_reverse('cms_page_add') new_page_params = {'edit': 1, 'position': 'last-child'} if self.page.parent_id: new_page_params['target'] = self.page.parent_id add_page_menu_modal_items = ( (_('New Page'), new_page_params), (_('New Sub Page'), {'edit': 1, 'position': 'last-child', 'target': self.page.pk}), (_('Duplicate this Page'), {'copy_target': self.page.pk}) ) for title, params in add_page_menu_modal_items: params.update(language=self.toolbar.language) add_page_menu.add_modal_item(title, url=add_url_parameters(app_page_url, params)) # first break current_page_menu.add_break(PAGE_MENU_FIRST_BREAK) # page edit page_edit_url = '?%s' % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON') current_page_menu.add_link_item(_('Edit this Page'), disabled=edit_mode, url=page_edit_url) # page settings page_settings_url = admin_reverse('cms_page_change', args=(self.page.pk,)) page_settings_url = add_url_parameters(page_settings_url, language=self.toolbar.language) current_page_menu.add_modal_item(_('Page settings'), url=page_settings_url, disabled=not edit_mode, on_close=refresh) # advanced settings advanced_url = admin_reverse('cms_page_advanced', args=(self.page.pk,)) advanced_url = add_url_parameters(advanced_url, language=self.toolbar.language) advanced_disabled = not self.page.has_advanced_settings_permission(self.request) or not edit_mode current_page_menu.add_modal_item(_('Advanced settings'), url=advanced_url, disabled=advanced_disabled) # templates menu if self.toolbar.build_mode or edit_mode: templates_menu = current_page_menu.get_or_create_menu('templates', _('Templates')) action = admin_reverse('cms_page_change_template', args=(self.page.pk,)) for path, name in get_cms_setting('TEMPLATES'): active = self.page.template == path if path == TEMPLATE_INHERITANCE_MAGIC: templates_menu.add_break(TEMPLATE_MENU_BREAK) templates_menu.add_ajax_item(name, action=action, data={'template': path}, active=active, on_success=refresh) # page type page_type_url = admin_reverse('cms_page_add_page_type') page_type_url = add_url_parameters(page_type_url, copy_target=self.page.pk, language=self.toolbar.language) current_page_menu.add_modal_item(_('Save as Page Type'), page_type_url, disabled=not edit_mode) # second break current_page_menu.add_break(PAGE_MENU_SECOND_BREAK) # permissions if self.permissions_activated: permissions_url = admin_reverse('cms_page_permissions', args=(self.page.pk,)) permission_disabled = not edit_mode or not self.page.has_change_permissions_permission(self.request) current_page_menu.add_modal_item(_('Permissions'), url=permissions_url, disabled=permission_disabled) # dates settings dates_url = admin_reverse('cms_page_dates', args=(self.page.pk,)) current_page_menu.add_modal_item(_('Publishing dates'), url=dates_url, disabled=not edit_mode) # third break current_page_menu.add_break(PAGE_MENU_THIRD_BREAK) # navigation toggle nav_title = _('Hide in navigation') if self.page.in_navigation else _('Display in navigation') nav_action = admin_reverse('cms_page_change_innavigation', args=(self.page.pk,)) current_page_menu.add_ajax_item(nav_title, action=nav_action, disabled=not edit_mode, on_success=refresh) # publisher if self.title: if self.title.published: publish_title = _('Unpublish page') publish_url = admin_reverse('cms_page_unpublish', args=(self.page.pk, self.current_lang)) else: publish_title = _('Publish page') publish_url = admin_reverse('cms_page_publish_page', args=(self.page.pk, self.current_lang)) current_page_menu.add_ajax_item(publish_title, action=publish_url, disabled=not edit_mode, on_success=refresh) # fourth break current_page_menu.add_break(PAGE_MENU_FOURTH_BREAK) history_menu = current_page_menu.get_or_create_menu(HISTORY_MENU_IDENTIFIER, _('History')) if is_installed('reversion'): from cms.utils.reversion_hacks import reversion, Revision versions = reversion.get_for_object(self.page) if self.page.revision_id: current_revision = Revision.objects.get(pk=self.page.revision_id) has_undo = versions.filter(revision__pk__lt=current_revision.pk).exists() has_redo = versions.filter(revision__pk__gt=current_revision.pk).exists() else: has_redo = False has_undo = versions.count() > 1 undo_action = admin_reverse('cms_page_undo', args=(self.page.pk,)) redo_action = admin_reverse('cms_page_redo', args=(self.page.pk,)) history_menu.add_ajax_item(_('Undo'), action=undo_action, disabled=not has_undo, on_success=refresh) history_menu.add_ajax_item(_('Redo'), action=redo_action, disabled=not has_redo, on_success=refresh) history_menu.add_break(HISTORY_MENU_BREAK) revert_action = admin_reverse('cms_page_revert_page', args=(self.page.pk, self.current_lang)) revert_question = _('Are you sure you want to revert to live?') is_enabled = self.page.is_dirty(self.current_lang) and self.page.publisher_public history_menu.add_ajax_item(_('Revert to live'), action=revert_action, question=revert_question, disabled=not is_enabled, on_success=refresh, extra_classes=('cms-toolbar-revert',)) history_menu.add_modal_item(_('View history'), url=admin_reverse('cms_page_history', args=(self.page.pk,))) # last break current_page_menu.add_break(PAGE_MENU_LAST_BREAK) # delete delete_url = admin_reverse('cms_page_delete', args=(self.page.pk,)) on_delete_redirect_url = self.get_on_delete_redirect_url() current_page_menu.add_modal_item(_('Delete page'), url=delete_url, on_close=on_delete_redirect_url, disabled=not edit_mode)
from django.contrib.admin.sites import site from django.utils.html import format_html from django.utils.translation import ungettext_lazy, ugettext_lazy as _ from filer.fields.image import AdminFileWidget, FilerImageField from filer.models.imagemodels import Image from cms.plugin_pool import plugin_pool from cms.utils.compat.dj import is_installed from cmsplugin_cascade.fields import PartialFormField from cmsplugin_cascade.models import SortableInlineCascadeElement from cmsplugin_cascade.mixins import ImagePropertyMixin from cmsplugin_cascade.utils import resolve_dependencies from cmsplugin_cascade.plugin_base import CascadePluginBase, create_proxy_model from cmsplugin_cascade.widgets import CascadingSizeWidget from . import utils if is_installed('adminsortable2'): from adminsortable2.admin import SortableInlineAdminMixin else: SortableInlineAdminMixin = type(str('SortableInlineAdminMixin'), (object,), {}) class GalleryImageForm(ModelForm): image_file = ModelChoiceField(queryset=Image.objects.all(), label=_("Image"), required=False) image_title = CharField(label=_("Image Title"), required=False, widget=widgets.TextInput(attrs={'size': 60}), help_text=_("Caption text added to the 'title' attribute of the <img> element.")) alt_tag = CharField(label=_("Alternative Description"), required=False, widget=widgets.TextInput(attrs={'size': 60}), help_text=_("Textual description of the image added to the 'alt' tag of the <img> element.")) glossary_fields = ('image_title', 'alt_tag',)