def _copy_contents(self, target): """ Copy all the plugins to a new page. :param target: The page where the new content should be stored """ # TODO: Make this into a "graceful" copy instead of deleting and overwriting # copy the placeholders (and plugins on those placeholders!) CMSPlugin.objects.filter(placeholder__page=target).delete() for ph in self.placeholders.all(): plugins = ph.get_plugins_list() try: ph = target.placeholders.get(slot=ph.slot) except Placeholder.DoesNotExist: ph.pk = None # make a new instance ph.save() target.placeholders.add(ph) # update the page copy except Placeholder.MultipleObjectsReturned: pass # print "TARGET:", target.__class__, target.id # print "PLACEHOLDER:", ph # print "SLOT:", ph.slot # for plach in target.placeholders.filter(slot=ph.slot): # print # print "PLACH:", plach.id, plach, repr(plach), dir(plach) # raise if plugins: copy_plugins_to(plugins, ph)
def _copy_contents(self, target, language): """ Copy all the plugins to a new article. :param target: The page where the new content should be stored """ # TODO: Make this into a "graceful" copy instead of deleting and # overwriting copy the placeholders # (and plugins on those placeholders!) plugins = CMSPlugin.objects.filter( placeholder=target.content, language=language).order_by('-depth') for plugin in plugins: instance, cls = plugin.get_plugin_instance() if instance and getattr(instance, 'cmsplugin_ptr_id', False): instance.cmsplugin_ptr = plugin instance.cmsplugin_ptr._no_reorder = True instance.delete(no_mp=True) else: plugin._no_reorder = True plugin.delete(no_mp=True) plugins = self.content.get_plugins_list(language) # update the page copy if plugins: copy_plugins_to(plugins, target.content)
def handle(self, verbosity, filename, *args, **options): activate(settings.LANGUAGE_CODE) path = self.find_fixture(filename) if self.verbosity >= 2: self.stdout.write("Importing products from: {}".format(path)) with open(path, 'r') as fh: data = json.load(fh) for number, product in enumerate(data, 1): product_model = product.pop('product_model') ProductModel = ContentType.objects.get(app_label='myshop', model=product_model) class_name = 'myshop.management.serializers.' + ProductModel.model_class( ).__name__ + 'Serializer' serializer_class = import_string(class_name) serializer = serializer_class(data=product) assert serializer.is_valid(), serializer.errors instance = serializer.save() self.stdout.write("{}. {}".format(number, instance)) if product_model == 'commodity': languages = get_public_languages() try: clipboard = CascadeClipboard.objects.get( identifier=instance.slug) except CascadeClipboard.DoesNotExist: pass else: deserialize_to_placeholder(instance.placeholder, clipboard.data, languages[0]) plugins = list( instance.placeholder.get_plugins( language=languages[0]).order_by('path')) for language in languages[1:]: copy_plugins_to(plugins, instance.placeholder, language)
def _copy_placeholder_to_clipboard(self, request, source_placeholder, target_placeholder): source_language = request.POST['source_language'] target_language = request.POST['target_language'] # User is copying the whole placeholder to the clipboard. old_plugins = source_placeholder.get_plugins_list(language=source_language) if not self.has_copy_plugins_permission(request, old_plugins): message = _('You do not have permission to copy this placeholder.') raise PermissionDenied(force_text(message)) # Empty the clipboard target_placeholder.clear() # Create a PlaceholderReference plugin which in turn # creates a blank placeholder called "clipboard" # the real clipboard has the reference placeholder inside but the plugins # are inside of the newly created blank clipboard. # This allows us to wrap all plugins in the clipboard under one plugin reference = PlaceholderReference.objects.create( name=source_placeholder.get_label(), plugin_type='PlaceholderPlugin', language=target_language, placeholder=target_placeholder, ) copy_plugins.copy_plugins_to( old_plugins, to_placeholder=reference.placeholder_ref, to_language=target_language, ) return reference
def copy_language(self, request, obj_id): obj = self.get_object(request, object_id=obj_id) source_language = request.POST.get('source_language') target_language = request.POST.get('target_language') if not self.has_change_permission(request, obj=obj): raise PermissionDenied if obj is None: raise Http404 if not target_language or not target_language in get_language_list( site_id=self.get_site(request).pk): return HttpResponseBadRequest( force_text(_("Language must be set to a supported language!"))) for placeholder in obj.get_placeholders(): plugins = list( placeholder.get_plugins( language=source_language).order_by('path')) if not placeholder.has_add_plugins_permission( request.user, plugins): return HttpResponseForbidden( force_text( _('You do not have permission to copy these plugins.')) ) copy_plugins.copy_plugins_to(plugins, placeholder, target_language) return HttpResponse("ok")
def publish(self, request, language, force=False): if force or self.has_publish_permission(request): self.public.clear(language=language) plugins = self.draft.get_plugins_list(language=language) copy_plugins_to(plugins, self.public, no_signals=True) self.dirty = False self.save() return True return False
def test_copy_plugin_author(self): post1 = self._get_post(self.data['en'][0]) post2 = self._get_post(self.data['en'][1]) plugin = add_plugin(post1.content, 'BlogAuthorPostsPlugin', language='en') plugin.authors.add(self.user) plugins = list(post1.content.cmsplugin_set.filter(language='en').order_by('tree_id', 'level', 'position')) copy_plugins_to(plugins, post2.content) new = downcast_plugins(post2.content.cmsplugin_set.all()) self.assertEqual(set(new[0].authors.all()), set([self.user]))
def handle(self, *args, **options): verbose = options.get('verbosity') > 1 only_empty = options.get('only_empty') copy_content = options.get('copy_content') from_lang = options.get('from_lang') to_lang = options.get('to_lang') try: site = int(options.get('site', None)) except Exception: site = settings.SITE_ID try: assert from_lang in get_language_list(site) assert to_lang in get_language_list(site) except AssertionError: raise CommandError('Both languages have to be present in settings.LANGUAGES and settings.CMS_LANGUAGES') for page in Page.objects.on_site(site).drafts(): # copy title if from_lang in page.get_languages(): title = page.get_title_obj(to_lang, fallback=False) if isinstance(title, EmptyTitle): title = page.get_title_obj(from_lang) if verbose: self.stdout.write('copying title %s from language %s\n' % (title.title, from_lang)) title.id = None title.publisher_public_id = None title.publisher_state = 0 title.language = to_lang title.save() if copy_content: # copy plugins using API if verbose: self.stdout.write('copying plugins for %s from %s\n' % (page.get_page_title(from_lang), from_lang)) copy_plugins_to_language(page, from_lang, to_lang, only_empty) else: if verbose: self.stdout.write('Skipping page %s, language %s not defined\n' % (page.get_page_title(page.get_languages()[0]), from_lang)) if copy_content: for static_placeholder in StaticPlaceholder.objects.all(): plugin_list = [] for plugin in static_placeholder.draft.get_plugins(): if plugin.language == from_lang: plugin_list.append(plugin) if plugin_list: if verbose: self.stdout.write( 'copying plugins from static_placeholder "%s" in "%s" to "%s"\n' % ( static_placeholder.name, from_lang, to_lang) ) copy_plugins_to(plugin_list, static_placeholder.draft, to_lang) self.stdout.write('all done')
def test_copy_plugins(self): """ Test that copying plugins works as expected. """ # create some objects page_en = create_page("CopyPluginTestPage (EN)", "nav_playground.html", "en") page_de = create_page("CopyPluginTestPage (DE)", "nav_playground.html", "de") ph_en = page_en.placeholders.get(slot="body") ph_de = page_de.placeholders.get(slot="body") # add the text plugin text_plugin_en = add_plugin(ph_en, "TextPlugin", "en", body="Hello World") self.assertEquals(text_plugin_en.pk, CMSPlugin.objects.all()[0].pk) # add a *nested* link plugin link_plugin_en = add_plugin(ph_en, "LinkPlugin", "en", target=text_plugin_en, name="A Link", url="https://www.django-cms.org") # the call above to add a child makes a plugin reload required here. text_plugin_en = self.reload(text_plugin_en) # check the relations self.assertEquals(text_plugin_en.get_children().count(), 1) self.assertEqual(link_plugin_en.parent.pk, text_plugin_en.pk) # just sanity check that so far everything went well self.assertEqual(CMSPlugin.objects.count(), 2) # copy the plugins to the german placeholder copy_plugins_to(ph_en.cmsplugin_set.all(), ph_de, 'de') self.assertEqual(ph_de.cmsplugin_set.filter(parent=None).count(), 1) text_plugin_de = ph_de.cmsplugin_set.get(parent=None).get_plugin_instance()[0] self.assertEqual(text_plugin_de.get_children().count(), 1) link_plugin_de = text_plugin_de.get_children().get().get_plugin_instance()[0] # check we have twice as many plugins as before self.assertEqual(CMSPlugin.objects.count(), 4) # check language plugins self.assertEqual(CMSPlugin.objects.filter(language='de').count(), 2) self.assertEqual(CMSPlugin.objects.filter(language='en').count(), 2) text_plugin_en = self.reload(text_plugin_en) link_plugin_en = self.reload(link_plugin_en) # check the relations in english didn't change self.assertEquals(text_plugin_en.get_children().count(), 1) self.assertEqual(link_plugin_en.parent.pk, text_plugin_en.pk) self.assertEqual(link_plugin_de.name, link_plugin_en.name) self.assertEqual(link_plugin_de.url, link_plugin_en.url) self.assertEqual(text_plugin_de.body, text_plugin_en.body)
def test_copy_plugin_latest(self): post1 = self._get_post(self.data['en'][0]) post2 = self._get_post(self.data['en'][1]) tag = Tag.objects.create(name='tag 1') plugin = add_plugin(post1.content, 'BlogLatestEntriesPlugin', language='en') plugin.tags.add(tag) plugins = list(post1.content.cmsplugin_set.filter(language='en').order_by('tree_id', 'level', 'position')) copy_plugins_to(plugins, post2.content) new = downcast_plugins(post2.content.cmsplugin_set.all()) self.assertEqual(set(new[0].tags.all()), set([tag]))
def test_copy_plugin_author(self): post1 = self._get_post(self._post_data[0]['en']) post2 = self._get_post(self._post_data[1]['en']) plugin = add_plugin(post1.content, 'BlogAuthorPostsPlugin', language='en', app_config=self.app_config_1) plugin.authors.add(self.user) if CMS_30: plugins = list(post1.content.cmsplugin_set.filter(language='en').order_by('tree_id', 'level', 'position')) else: plugins = list(post1.content.cmsplugin_set.filter(language='en').order_by('path', 'depth', 'position')) copy_plugins_to(plugins, post2.content) new = downcast_plugins(post2.content.cmsplugin_set.all()) self.assertEqual(set(new[0].authors.all()), set([self.user]))
def copy_content_from(self,name): init_str=name if init_str is not None: default_event=None from cms.utils.copy_plugins import copy_plugins_to ev_objects = Event.objects.filter(title__exact = '[Default]') if len(ev_objects) > 0: self.save() default_event = ev_objects[0] plugin_list = list(default_event.content.cmsplugin_set.all().order_by('tree_id', '-rght')) # self.content = Placeholder() copy_plugins_to(plugin_list,self.content) self.content.save()
def copy_content(self, from_instance): # add any tags from the 'from_instance' self.tags.add(*list(from_instance.tags.names())) # clear any existing plugins self.content.clear() # get the list of plugins in the 'from_instance's intro plugins = from_instance.content.get_plugins_list() # copy 'from_instance's intro plugins to this object's intro copy_plugins_to(plugins, self.content, no_signals=True)
def test_copy_plugin_latest(self): post1 = self._get_post(self.data['en'][0]) post2 = self._get_post(self.data['en'][1]) tag = Tag.objects.create(name='tag 1') plugin = add_plugin(post1.content, 'BlogLatestEntriesPlugin', language='en') plugin.tags.add(tag) plugins = list( post1.content.cmsplugin_set.filter(language='en').order_by( 'tree_id', 'level', 'position')) copy_plugins_to(plugins, post2.content) new = downcast_plugins(post2.content.cmsplugin_set.all()) self.assertEqual(set(new[0].tags.all()), set([tag]))
def create_stack(self, request, placeholder_id, plugin_id=None): if request.method == "POST": form = StackCreationForm(data=request.POST) if form.is_valid(): if plugin_id: plugin = get_object_or_404(CMSPlugin, pk=plugin_id) plugin_list = list(plugin.get_descendants(include_self=True)) else: placeholder = get_object_or_404(Placeholder, pk=placeholder_id) plugin_list = list(placeholder.get_plugins()) stack = form.save() copy_plugins_to(plugin_list, stack.content) stack.save() return HttpResponse("OK") # TODO: close the window return self.add_view(request)
def test_copy_plugin_latest(self): post1 = self._get_post(self._post_data[0]['en']) post2 = self._get_post(self._post_data[1]['en']) tag1 = Tag.objects.create(name='tag 1') tag2 = Tag.objects.create(name='tag 2') plugin = add_plugin(post1.content, 'BlogLatestEntriesPlugin', language='en', app_config=self.app_config_1) plugin.tags.add(tag1) plugin.tags.add(tag2) if CMS_30: plugins = list(post1.content.cmsplugin_set.filter(language='en').order_by('tree_id', 'level', 'position')) else: plugins = list(post1.content.cmsplugin_set.filter(language='en').order_by('path', 'depth', 'position')) copy_plugins_to(plugins, post2.content) new = downcast_plugins(post2.content.cmsplugin_set.all()) self.assertEqual(set(new[0].tags.all()), set([tag1, tag2])) self.assertEqual(set(new[0].tags.all()), set(plugin.tags.all()))
def publish(self, request, language, force=False): if force or self.has_publish_permission(request): for plugin in CMSPlugin.objects.filter(placeholder=self.public, language=language).order_by('-level'): inst, cls = plugin.get_plugin_instance() if inst and getattr(inst, 'cmsplugin_ptr', False): inst.cmsplugin_ptr._no_reorder = True inst.delete() else: plugin._no_reorder = True plugin.delete() plugins = self.draft.get_plugins_list(language=language) copy_plugins_to(plugins, self.public, no_signals=True) self.dirty = False self.save() return True return False
def copy_plugins_to_language(page, source_language, target_language, only_empty=True): """ Copy the plugins to another language in the same page for all the page placeholders. By default plugins are copied only if placeholder has no plugin for the target language; use ``only_empty=False`` to change this. .. warning: This function skips permissions checks :param page: the page to copy :type page: :class:`cms.models.pagemodel.Page` instance :param string source_language: The source language code, must be in :setting:`django:LANGUAGES` :param string target_language: The source language code, must be in :setting:`django:LANGUAGES` :param bool only_empty: if False, plugin are copied even if plugins exists in the target language (on a placeholder basis). :return int: number of copied plugins """ copied = 0 placeholders = page.placeholders.all() for placeholder in placeholders: # only_empty is True we check if the placeholder already has plugins and # we skip it if has some if not only_empty or not placeholder.cmsplugin_set.filter(language=target_language).exists(): plugins = list( placeholder.cmsplugin_set.filter(language=source_language).order_by('tree_id', 'level', 'position')) copied_plugins = copy_plugins.copy_plugins_to(plugins, placeholder, target_language) copied += len(copied_plugins) return copied
def _copy_plugin_to_clipboard(self, request, source_placeholder, target_placeholder): source_language = request.POST['source_language'] source_plugin_id = request.POST.get('source_plugin_id') target_language = request.POST['target_language'] source_plugin = get_object_or_404( CMSPlugin, pk=source_plugin_id, language=source_language, ) old_plugins = ( CMSPlugin .get_tree(parent=source_plugin) .filter(placeholder=source_placeholder) .order_by('path') ) if not self.has_copy_plugins_permission(request, old_plugins): message = _('You do not have permission to copy these plugins.') raise PermissionDenied(force_text(message)) # Empty the clipboard target_placeholder.clear() plugin_pairs = copy_plugins.copy_plugins_to( old_plugins, to_placeholder=target_placeholder, to_language=target_language, ) return plugin_pairs[0][0]
def copy_plugins_to_language(page, source_language, target_language, only_empty=True): """ Copy the plugins to another language in the same page for all the page placeholders. By default plugins are copied only if placeholder has no plugin for the target language; use ``only_empty=False`` to change this. .. warning: This function skips permissions checks :param page: the page to copy :type page: :class:`cms.models.pagemodel.Page` instance :param string source_language: The source language code, must be in :setting:`django:LANGUAGES` :param string target_language: The source language code, must be in :setting:`django:LANGUAGES` :param bool only_empty: if False, plugin are copied even if plugins exists in the target language (on a placeholder basis). :return int: number of copied plugins """ copied = 0 placeholders = page.get_placeholders() for placeholder in placeholders: # only_empty is True we check if the placeholder already has plugins and # we skip it if has some if not only_empty or not placeholder.get_plugins(language=target_language).exists(): plugins = list( placeholder.get_plugins(language=source_language).order_by('path')) copied_plugins = copy_plugins.copy_plugins_to(plugins, placeholder, target_language) copied += len(copied_plugins) return copied
def insert_stack(self, request, placeholder_id): placeholder = get_object_or_404(Placeholder, pk=placeholder_id) form = StackInsertionForm(initial={"language_code": request.GET.get("language_code", "")}) if request.method == "POST": form = StackInsertionForm(data=request.POST) if form.is_valid(): context = {"CMS_MEDIA_URL": get_cms_setting("MEDIA_URL"), "is_popup": True, "cancel": False} if form.cleaned_data["insertion_type"] == StackInsertionForm.INSERT_LINK: cms_plugin = add_plugin( placeholder, StackPlugin, form.cleaned_data["language_code"], stack=form.cleaned_data["stack"] ) context.update( { "plugin": cms_plugin, "type": cms_plugin.get_plugin_name(), "plugin_id": cms_plugin.pk, "icon": force_escape(escapejs(cms_plugin.get_instance_icon_src())), "alt": force_escape(escapejs(cms_plugin.get_instance_icon_alt())), } ) else: plugin_ziplist = copy_plugins_to( list(form.cleaned_data["stack"].content.get_plugins()), placeholder ) # TODO: once we actually use the plugin context in the frontend, we have to support multiple plugins return TemplateResponse(request, "admin/cms/page/plugin/confirm_form.html", context) return TemplateResponse(request, "admin/stacks/insert_stack.html", {"form": form})
def _duplicate_page(source, destination, publish=None, user=None): placeholders = source.get_placeholders() source = source.get_public_object() destination = destination.get_draft_object() destination_placeholders = dict([(a.slot, a) for a in destination.get_placeholders()]) for k, v in settings.LANGUAGES: available = [a.language for a in destination.title_set.all()] title = source.get_title_obj(language=k) if not k in available: cms.api.create_title(k, title.title, destination, menu_title=title.menu_title, slug=title.slug) for placeholder in placeholders: destination_placeholders[placeholder.slot].clear() for k, v in settings.LANGUAGES: plugins = list( placeholder.cmsplugin_set.filter(language=k).order_by('path') ) copied_plugins = copy_plugins.copy_plugins_to(plugins, destination_placeholders[placeholder.slot], k) if publish: try: for k, v in settings.LANGUAGES: cms.api.publish_page(destination, user, k) except Exception as e: pass
def create_stack(self, request, placeholder_id, plugin_id=None): if request.method == 'POST': form = StackCreationForm(data=request.POST) if form.is_valid(): if plugin_id: plugin = get_object_or_404(CMSPlugin, pk=plugin_id) plugin_list = list( plugin.get_descendants(include_self=True)) else: placeholder = get_object_or_404(Placeholder, pk=placeholder_id) plugin_list = list(placeholder.get_plugins()) stack = form.save() copy_plugins_to(plugin_list, stack.content) stack.save() return HttpResponse('OK') # TODO: close the window return self.add_view(request)
def publish(self, request, language, force=False): if force or self.has_publish_permission(request): for plugin in CMSPlugin.objects.filter( placeholder=self.public, language=language).order_by('-level'): inst, cls = plugin.get_plugin_instance() if inst and getattr(inst, 'cmsplugin_ptr', False): inst.cmsplugin_ptr._no_reorder = True inst.delete() else: plugin._no_reorder = True plugin.delete() plugins = self.draft.get_plugins_list(language=language) copy_plugins_to(plugins, self.public, no_signals=True) self.dirty = False self.save() return True return False
def clone_placeholder(self, src_obj, dst_obj): if not django_cms_exists: return for field in self.get_placeholder_fields(src_obj): src_placeholder = getattr(src_obj, field) dst_placeholder = getattr(dst_obj, field) dst_placeholder.pk = None dst_placeholder.save() setattr(dst_obj, field, dst_placeholder) dst_obj.save() src_plugins = src_placeholder.get_plugins_list() # CMS automatically generates a new Placeholder ID copy_plugins_to(src_plugins, dst_placeholder)
def copy_plugins(self, request): """ POST request should have the following data: - source_language - source_placeholder_id - source_plugin_id (optional) - target_language - target_placeholder_id - target_plugin_id (optional, new parent) """ source_language = request.POST['source_language'] source_placeholder_id = request.POST['source_placeholder_id'] source_plugin_id = request.POST.get('source_plugin_id', None) target_language = request.POST['target_language'] target_placeholder_id = request.POST['target_placeholder_id'] target_plugin_id = request.POST.get('target_plugin_id', None) source_placeholder = get_object_or_404(Placeholder, pk=source_placeholder_id) target_placeholder = get_object_or_404(Placeholder, pk=target_placeholder_id) if not target_language or not target_language in get_language_list(): return HttpResponseBadRequest(_("Language must be set to a supported language!")) if source_plugin_id: source_plugin = get_object_or_404(CMSPlugin, pk=source_plugin_id) reload_required = requires_reload(PLUGIN_COPY_ACTION, [source_plugin]) plugins = list( source_placeholder.cmsplugin_set.filter(tree_id=source_plugin.tree_id, lft__gte=source_plugin.lft, rght__lte=source_plugin.rght).order_by('tree_id', 'level', 'position')) else: plugins = list( source_placeholder.cmsplugin_set.filter(language=source_language).order_by('tree_id', 'level', 'position')) reload_required = requires_reload(PLUGIN_COPY_ACTION, plugins) if not self.has_copy_plugin_permission(request, source_placeholder, target_placeholder, plugins): return HttpResponseForbidden(_('You do not have permission to copy these plugins.')) copy_plugins.copy_plugins_to(plugins, target_placeholder, target_language, target_plugin_id) plugin_list = CMSPlugin.objects.filter(language=target_language, placeholder=target_placeholder).order_by( 'tree_id', 'level', 'position') reduced_list = [] for plugin in plugin_list: reduced_list.append( {'id': plugin.pk, 'type': plugin.plugin_type, 'parent': plugin.parent_id, 'position': plugin.position, 'desc': force_unicode(plugin.get_short_description())}) self.post_copy_plugins(request, source_placeholder, target_placeholder, plugins) json_response = {'plugin_list': reduced_list, 'reload': reload_required} return HttpResponse(simplejson.dumps(json_response), content_type='application/json')
def copy(self, target_placeholder, source_language, fieldname, model, target_language, **kwargs): from cms.utils.copy_plugins import copy_plugins_to trgt = model.objects.get(**{fieldname: target_placeholder}) src = model.objects.get(master=trgt.master, language_code=source_language) source_placeholder = getattr(src, fieldname, None) if not source_placeholder: return False return copy_plugins_to(source_placeholder.get_plugins_list(), target_placeholder, target_language)
def _copy_contents(self, target): """ Copy all the plugins to a new page. :param target: The page where the new content should be stored """ # TODO: Make this into a "graceful" copy instead of deleting and overwriting # copy the placeholders (and plugins on those placeholders!) CMSPlugin.objects.filter(placeholder__page=target).delete() for ph in self.placeholders.all(): plugins = ph.get_plugins_list() try: ph = target.placeholders.get(slot=ph.slot) except Placeholder.DoesNotExist: ph.pk = None # make a new instance ph.save() target.placeholders.add(ph) # update the page copy if plugins: copy_plugins_to(plugins, ph)
def copy_referenced_plugins(self): referenced_plugins = self.get_referenced_plugins() if referenced_plugins: plugins_pairs = list( copy_plugins_to(referenced_plugins, self.placeholder, to_language=self.language, parent_plugin_id=self.id)) self.add_existing_child_plugins_to_pairs(plugins_pairs) self.post_copy(self, plugins_pairs)
def copy_content(self, from_instance): ''' copy content including tags, and placeholder plugins to this instance from a passed Lesson :param from_instance: a Lesson object the content/tags are being copied from :return: None ''' # add any tags from the 'from_instance' self.tags.add(*list(from_instance.tags.names())) # clear any existing plugins self.summary.clear() # get the list of plugins in the 'from_instance's intro plugins = from_instance.summary.get_plugins_list() # copy 'from_instance's intro plugins to this object's intro copy_plugins_to(plugins, self.summary, no_signals=True)
def duplicate_from(self,event): self.start = event.start self.end = event.end self.title = "copy of - %s"%event.title self.description = event.description self.creator = event.creator self.created_on = datetime.datetime.now() self.rule = event.rule self.end_recurring_period = event.end_recurring_period self.calendar = event.calendar from cms.utils.copy_plugins import copy_plugins_to self.save() default_event = event plugin_list = list(default_event.content.cmsplugin_set.all().order_by('tree_id', '-rght')) # self.content = Placeholder() copy_plugins_to(plugin_list,self.content) self.content.save()
def clone_placeholder(self, src_obj, dst_obj): try: from cms.utils.copy_plugins import copy_plugins_to except ImportError: return for field in self.get_placeholder_fields(src_obj): src_placeholder = getattr(src_obj, field) dst_placeholder = getattr(dst_obj, field) dst_placeholder.pk = None dst_placeholder.save() setattr(dst_obj, field, dst_placeholder) dst_obj.save() src_plugins = src_placeholder.get_plugins_list() # CMS automatically generates a new Placeholder ID copy_plugins_to(src_plugins, dst_placeholder)
def _copy_contents(self, target, language): ''' Copy all the plugins to a new article. :param target: The article where the new content should be stored ''' # TODO: Make this into a 'graceful' copy instead of deleting and overwriting # copy the placeholders (and plugins on those placeholders!) from cms.models.pluginmodel import CMSPlugin for plugin in CMSPlugin.objects.filter( placeholder__cms_articles=target, language=language).order_by('-depth'): inst, cls = plugin.get_plugin_instance() if inst and getattr(inst, 'cmsplugin_ptr_id', False): inst.cmsplugin_ptr = plugin inst.cmsplugin_ptr._no_reorder = True inst.delete(no_mp=True) else: plugin._no_reorder = True plugin.delete(no_mp=True) new_phs = [] target_phs = target.placeholders.all() for ph in self.get_placeholders(): plugins = ph.get_plugins_list(language) found = False for target_ph in target_phs: if target_ph.slot == ph.slot: ph = target_ph found = True break if not found: ph.pk = None # make a new instance ph.save() new_phs.append(ph) # update the article copy if plugins: copy_plugins_to(plugins, ph) target.placeholders.add(*new_phs)
def copy_pages(from_lang, to_lang, pages): site = settings.SITE_ID #test both langs if from_lang == to_lang: raise Exception("from_lang must be different from to_lang!") try: assert from_lang in get_language_list(site) assert to_lang in get_language_list(site) except AssertionError: raise Exception("Could not languages from site") for page in pages.all(): # copy title if from_lang in page.get_languages(): try: title = page.get_title_obj(to_lang, fallback=False) except Title.DoesNotExist: title = page.get_title_obj(from_lang) title.id = None title.publisher_public_id = None title.publisher_state = 0 title.language = to_lang title.save() # copy plugins using API copy_plugins_to_language(page, from_lang, to_lang) for static_placeholder in StaticPlaceholder.objects.all(): plugin_list = [] for plugin in static_placeholder.draft.get_plugins(): if plugin.language == from_lang: plugin_list.append(plugin) if plugin_list: copy_plugins_to(plugin_list, static_placeholder.draft, to_lang)
def _copy_contents(self, target, language): ''' Copy all the plugins to a new article. :param target: The article where the new content should be stored ''' # TODO: Make this into a 'graceful' copy instead of deleting and overwriting # copy the placeholders (and plugins on those placeholders!) from cms.models.pluginmodel import CMSPlugin for plugin in CMSPlugin.objects.filter(placeholder__cms_articles=target, language=language).order_by('-depth'): inst, cls = plugin.get_plugin_instance() if inst and getattr(inst, 'cmsplugin_ptr_id', False): inst.cmsplugin_ptr = plugin inst.cmsplugin_ptr._no_reorder = True inst.delete(no_mp=True) else: plugin._no_reorder = True plugin.delete(no_mp=True) new_phs = [] target_phs = target.placeholders.all() for ph in self.get_placeholders(): plugins = ph.get_plugins_list(language) found = False for target_ph in target_phs: if target_ph.slot == ph.slot: ph = target_ph found = True break if not found: ph.pk = None # make a new instance ph.save() new_phs.append(ph) # update the article copy if plugins: copy_plugins_to(plugins, ph) target.placeholders.add(*new_phs)
def _duplicate_page(source, destination, publish=None, user=None): placeholders = source.get_placeholders() source = source.get_public_object() destination = destination.get_draft_object() en_title = source.get_title_obj(language='en') destination_placeholders = dict([(a.slot, a) for a in destination.get_placeholders()]) for k, v in settings.LANGUAGES: available = [a.language for a in destination.title_set.all()] title = source.get_title_obj(language=k) # Doing some cleanup while I am at it if en_title and title: title.title = en_title.title title.slug = en_title.slug if hasattr(title, 'save'): title.save() if not k in available: cms.api.create_title(k, title.title, destination, slug=title.slug) try: destination_title = destination.get_title_obj(language=k) if en_title and title and destination_title: destination_title.page_title = title.page_title destination_title.slug = en_title.slug if hasattr(destination_title, 'save'): destination_title.save() except Exception as e: print("Error updating title.") for placeholder in placeholders: destination_placeholders[placeholder.slot].clear() for k, v in settings.LANGUAGES: plugins = list( placeholder.cmsplugin_set.filter(language=k).order_by('path') ) copied_plugins = copy_plugins.copy_plugins_to(plugins, destination_placeholders[placeholder.slot], k) if publish: try: for k, v in settings.LANGUAGES: cms.api.publish_page(destination, user, k) except Exception as e: pass
def insert_stack(self, request, placeholder_id): placeholder = get_object_or_404(Placeholder, pk=placeholder_id) form = StackInsertionForm( initial={'language_code': request.GET.get('language_code', '')}) if request.method == 'POST': form = StackInsertionForm(data=request.POST) if form.is_valid(): context = { 'CMS_MEDIA_URL': get_cms_setting('MEDIA_URL'), 'is_popup': True, 'cancel': False, } if form.cleaned_data[ 'insertion_type'] == StackInsertionForm.INSERT_LINK: cms_plugin = add_plugin(placeholder, StackPlugin, form.cleaned_data['language_code'], stack=form.cleaned_data['stack']) context.update({ 'plugin': cms_plugin, "type": cms_plugin.get_plugin_name(), 'plugin_id': cms_plugin.pk, 'icon': force_escape( escapejs(cms_plugin.get_instance_icon_src())), 'alt': force_escape( escapejs(cms_plugin.get_instance_icon_alt())), }) else: plugin_ziplist = copy_plugins_to( list(form.cleaned_data['stack'].content.get_plugins()), placeholder) # TODO: once we actually use the plugin context in the frontend, we have to support multiple plugins return TemplateResponse( request, 'admin/cms/page/plugin/confirm_form.html', context) return TemplateResponse(request, 'admin/stacks/insert_stack.html', { 'form': form, })
def copy_to(self, placeholder, language): copy_plugins_to(self.placeholder_ref.get_plugins(), placeholder, to_language=language)
def handle(self, *args, **options): verbose = options.get('verbosity') > 1 only_empty = options.get('only_empty') copy_content = options.get('copy_content') from_lang = options.get('from_lang') to_lang = options.get('to_lang') try: site = int(options.get('site', None)) except Exception: site = settings.SITE_ID try: assert from_lang in get_language_list(site) assert to_lang in get_language_list(site) except AssertionError: raise CommandError( 'Both languages have to be present in settings.LANGUAGES and settings.CMS_LANGUAGES' ) for page in Page.objects.on_site(site).drafts(): # copy title if from_lang in page.get_languages(): title = page.get_title_obj(to_lang, fallback=False) if isinstance(title, EmptyTitle): title = page.get_title_obj(from_lang) if verbose: self.stdout.write( 'copying title %s from language %s\n' % (title.title, from_lang)) title.id = None title.publisher_public_id = None title.publisher_state = 0 title.language = to_lang title.save() if copy_content: # copy plugins using API if verbose: self.stdout.write( 'copying plugins for %s from %s\n' % (page.get_page_title(from_lang), from_lang)) copy_plugins_to_language(page, from_lang, to_lang, only_empty) else: if verbose: self.stdout.write( 'Skipping page %s, language %s not defined\n' % (page.get_page_title( page.get_languages()[0]), from_lang)) if copy_content: for static_placeholder in StaticPlaceholder.objects.all(): plugin_list = [] for plugin in static_placeholder.draft.get_plugins(): if plugin.language == from_lang: plugin_list.append(plugin) if plugin_list: if verbose: self.stdout.write( 'copying plugins from static_placeholder "%s" in "%s" to "%s"\n' % (static_placeholder.name, from_lang, to_lang)) copy_plugins_to(plugin_list, static_placeholder.draft, to_lang) self.stdout.write('all done')
def copy_placeholders_and_check_results(self, placeholders): """ This function is not itself a test; rather, it can be used by any test that has created placeholders. It will check that whatever the plugin structure in the placeholder, it will be copied accurately when they are copied. placeholders is a list of placeholders """ for original_placeholder in placeholders: # get the plugins original_plugins = original_placeholder.get_plugins() # copy them to a new placeholder copied_placeholder = Placeholder.objects.create(slot=original_placeholder.slot) copy_plugins_to( original_placeholder.get_plugins(), copied_placeholder ) copied_plugins = copied_placeholder.get_plugins() # we should find the same number of plugins in both placeholders self.assertEquals( original_plugins.count(), copied_plugins.count() ) # quick check: make sure the two querysets match: for original, copy in zip(original_plugins, copied_plugins): self.assertEquals( Text.objects.get(id=original.id).body, Text.objects.get(id=copy.id).body ) # Now build a *tree* of the plugins, and match those - it's not # enough just to compare querysets as above; we should *also* check # that when we build a tree, the various nodes are assembled as we # would expect. We will pump the trees into a pair of lists: original_plugins_list = [] copied_plugins_list = [] # This function builds the tree of plugins, starting from its roots. # In that respect it's like many of the plugin tree-building # routines elsewhere in the system. def plugin_list_from_tree(roots, plugin_list): for plugin in roots: plugin_list.append(plugin) # recurse over the set of nodes plugin_list_from_tree(plugin.get_children(), plugin_list) # build the tree for each set of plugins plugin_list_from_tree(original_plugins.filter(level=0), original_plugins_list) plugin_list_from_tree(copied_plugins.filter(level=0), copied_plugins_list) # Check that each pair of items in the two lists match, in lots of # different ways for original, copy in zip(original_plugins_list, copied_plugins_list): original_text_plugin = Text.objects.get(id=original.id) copied_text_plugin = Text.objects.get(id=copy.id) # This first one is a sanity test, just to prove that we aren't # simply comparing *exactly the same items* in all these tests. # It could happen... self.assertNotEquals(original.id, copy.id) self.assertEquals( original_text_plugin.body, copied_text_plugin.body ) self.assertEquals( original_text_plugin.level, copied_text_plugin.level ) self.assertEquals( original_text_plugin.position, copied_text_plugin.position ) self.assertEquals( original_text_plugin.rght, copied_text_plugin.rght ) self.assertEquals( original_text_plugin.lft, copied_text_plugin.lft ) self.assertEquals( original_text_plugin.get_descendant_count(), copied_text_plugin.get_descendant_count() ) self.assertEquals( original_text_plugin.get_ancestors().count(), copied_text_plugin.get_ancestors().count() ) # just in case the test method that called us wants it: return copied_placeholder
def copy_plugins(self, request): """ POST request should have the following data: - source_language - source_placeholder_id - source_plugin_id (optional) - target_language - target_placeholder_id - target_plugin_id (optional, new parent) """ source_language = request.POST['source_language'] source_placeholder_id = request.POST['source_placeholder_id'] source_plugin_id = request.POST.get('source_plugin_id', None) target_language = request.POST['target_language'] target_placeholder_id = request.POST['target_placeholder_id'] target_plugin_id = request.POST.get('target_plugin_id', None) source_placeholder = get_object_or_404(Placeholder, pk=source_placeholder_id) target_placeholder = get_object_or_404(Placeholder, pk=target_placeholder_id) if not target_language or not target_language in get_language_list(): return HttpResponseBadRequest(force_unicode(_("Language must be set to a supported language!"))) if source_plugin_id: source_plugin = get_object_or_404(CMSPlugin, pk=source_plugin_id) reload_required = requires_reload(PLUGIN_COPY_ACTION, [source_plugin]) if source_plugin.plugin_type == "PlaceholderPlugin": # if it is a PlaceholderReference plugin only copy the plugins it references inst, cls = source_plugin.get_plugin_instance(self) plugins = inst.placeholder_ref.get_plugins_list() else: plugins = list( source_placeholder.cmsplugin_set.filter( path__startswith=source_plugin.path, depth__gte=source_plugin.depth).order_by('path') ) else: plugins = list( source_placeholder.cmsplugin_set.filter(language=source_language).order_by('path')) reload_required = requires_reload(PLUGIN_COPY_ACTION, plugins) if not self.has_copy_plugin_permission(request, source_placeholder, target_placeholder, plugins): return HttpResponseForbidden(force_unicode(_('You do not have permission to copy these plugins.'))) if target_placeholder.pk == request.toolbar.clipboard.pk and not source_plugin_id and not target_plugin_id: # if we copy a whole placeholder to the clipboard create PlaceholderReference plugin instead and fill it # the content of the source_placeholder. ref = PlaceholderReference() ref.name = source_placeholder.get_label() ref.plugin_type = "PlaceholderPlugin" ref.language = target_language ref.placeholder = target_placeholder ref.save() ref.copy_from(source_placeholder, source_language) else: copy_plugins.copy_plugins_to(plugins, target_placeholder, target_language, target_plugin_id) plugin_list = CMSPlugin.objects.filter(language=target_language, placeholder=target_placeholder).order_by( 'path') reduced_list = [] for plugin in plugin_list: reduced_list.append( { 'id': plugin.pk, 'type': plugin.plugin_type, 'parent': plugin.parent_id, 'position': plugin.position, 'desc': force_unicode(plugin.get_short_description()), 'language': plugin.language, 'placeholder_id': plugin.placeholder_id } ) self.post_copy_plugins(request, source_placeholder, target_placeholder, plugins) json_response = {'plugin_list': reduced_list, 'reload': reload_required} return HttpResponse(json.dumps(json_response), content_type='application/json')
def _paste_placeholder(self, request, plugin, target_language, target_placeholder, tree_order): plugins = plugin.placeholder_ref.get_plugins_list() if not self.has_copy_from_clipboard_permission(request, target_placeholder, plugins): message = force_text(_("You have no permission to paste this placeholder")) raise PermissionDenied(message) target_tree_order = [int(pk) for pk in tree_order if not pk == '__COPY__'] action_token = self._send_pre_placeholder_operation( request, operation=operations.PASTE_PLACEHOLDER, plugins=plugins, target_language=target_language, target_placeholder=target_placeholder, target_order=target_tree_order, ) new_plugins = copy_plugins.copy_plugins_to( plugins, to_placeholder=target_placeholder, to_language=target_language, ) new_plugin_ids = (new.pk for new, old in new_plugins) # Creates a list of PKs for the top-level plugins ordered by # their position. top_plugins = (pair for pair in new_plugins if not pair[0].parent_id) top_plugins_pks = [p[0].pk for p in sorted(top_plugins, key=lambda pair: pair[1].position)] # If an ordering was supplied, we should replace the item that has # been copied with the new plugins target_tree_order[tree_order.index('__COPY__'):0] = top_plugins_pks reorder_plugins( target_placeholder, parent_id=None, language=target_language, order=target_tree_order, ) new_plugins = ( CMSPlugin .objects .filter(pk__in=new_plugin_ids) .order_by('path') .select_related('placeholder') ) new_plugins = list(new_plugins) self._send_post_placeholder_operation( request, operation=operations.PASTE_PLACEHOLDER, token=action_token, plugins=new_plugins, target_language=target_language, target_placeholder=target_placeholder, target_order=target_tree_order, ) return new_plugins
def _paste_plugin(self, request, plugin, target_language, target_placeholder, tree_order, target_parent=None): plugins = ( CMSPlugin .get_tree(parent=plugin) .filter(placeholder=plugin.placeholder_id) .order_by('path') ) plugins = list(plugins) if not self.has_copy_from_clipboard_permission(request, target_placeholder, plugins): message = force_text(_("You have no permission to paste this plugin")) raise PermissionDenied(message) if target_parent: target_parent_id = target_parent.pk else: target_parent_id = None target_tree_order = [int(pk) for pk in tree_order if not pk == '__COPY__'] action_token = self._send_pre_placeholder_operation( request, operation=operations.PASTE_PLUGIN, plugin=plugin, target_language=target_language, target_placeholder=target_placeholder, target_parent_id=target_parent_id, target_order=target_tree_order, ) plugin_pairs = copy_plugins.copy_plugins_to( plugins, to_placeholder=target_placeholder, to_language=target_language, parent_plugin_id=target_parent_id, ) root_plugin = plugin_pairs[0][0] # If an ordering was supplied, replace the item that has # been copied with the new copy target_tree_order.insert(tree_order.index('__COPY__'), root_plugin.pk) reorder_plugins( target_placeholder, parent_id=target_parent_id, language=target_language, order=target_tree_order, ) # Fetch from db to update position and other tree values root_plugin.refresh_from_db() self._send_post_placeholder_operation( request, operation=operations.PASTE_PLUGIN, plugin=root_plugin.get_bound_plugin(), token=action_token, target_language=target_language, target_placeholder=target_placeholder, target_parent_id=target_parent_id, target_order=target_tree_order, ) return root_plugin
def copy_from(self, placeholder, language): copy_plugins_to(placeholder.get_plugins(language), self.placeholder_ref, to_language=self.language)
def copy_from(self, placeholder, language): plugins = placeholder.get_plugins(language) return copy_plugins_to(plugins, self.placeholder_ref, to_language=self.language)
def copy_page(self, target, site, position='first-child', copy_permissions=True, copy_moderation=True, public_copy=False): """ copy a page [ and all its descendants to a new location ] Doesn't checks for add page permissions anymore, this is done in PageAdmin. Note: public_copy was added in order to enable the creation of a copy for creating the public page during the publish operation as it sets the publisher_is_draft=False. """ from cms.utils.moderator import update_moderation_message page_copy = None if public_copy: # create a copy of the draft page - existing code loops through pages so added it to a list pages = [copy.copy(self)] else: pages = [self] + list(self.get_descendants().order_by('-rght')) if not public_copy: site_reverse_ids = Page.objects.filter( site=site, reverse_id__isnull=False).values_list('reverse_id', flat=True) if target: target.old_pk = -1 if position == "first-child": tree = [target] elif target.parent_id: tree = [target.parent] else: tree = [] else: tree = [] if tree: tree[0].old_pk = tree[0].pk first = True # loop over all affected pages (self is included in descendants) for page in pages: titles = list(page.title_set.all()) # get all current placeholders (->plugins) placeholders = list(page.placeholders.all()) origin_id = page.id # create a copy of this page by setting pk = None (=new instance) page.old_pk = page.pk page.pk = None page.level = None page.rght = None page.lft = None page.tree_id = None page.published = False page.moderator_state = Page.MODERATOR_CHANGED page.publisher_public_id = None # only set reverse_id on standard copy if not public_copy: if page.reverse_id in site_reverse_ids: page.reverse_id = None if first: first = False if tree: page.parent = tree[0] else: page.parent = None page.insert_at(target, position) else: count = 1 found = False for prnt in tree: if prnt.old_pk == page.parent_id: page.parent = prnt tree = tree[0:count] found = True break count += 1 if not found: page.parent = None tree.append(page) page.site = site # override default page settings specific for public copy if public_copy: page.published = True page.publisher_is_draft = False page.moderator_state = Page.MODERATOR_APPROVED # we need to set relate this new public copy to its draft page (self) page.publisher_public = self # code taken from Publisher publish() overridden here as we need to save the page # before we are able to use the page object for titles, placeholders etc.. below # the method has been modified to return the object after saving the instance variable page = self._publisher_save_public(page) page_copy = page # create a copy used in the return else: # only need to save the page if it isn't public since it is saved above otherwise page.save() # copy moderation, permissions if necessary if settings.CMS_PERMISSION and copy_permissions: from cms.models.permissionmodels import PagePermission for permission in PagePermission.objects.filter( page__id=origin_id): permission.pk = None permission.page = page permission.save() if settings.CMS_MODERATOR and copy_moderation: from cms.models.moderatormodels import PageModerator for moderator in PageModerator.objects.filter( page__id=origin_id): moderator.pk = None moderator.page = page moderator.save() # update moderation message for standard copy if not public_copy: update_moderation_message(page, unicode(_('Page was copied.'))) # copy titles of this page for title in titles: title.pk = None # setting pk = None creates a new instance title.publisher_public_id = None title.published = False title.page = page # create slug-copy for standard copy if not public_copy: title.slug = page_utils.get_available_slug(title) title.save() # copy the placeholders (and plugins on those placeholders!) for ph in placeholders: plugins = list(ph.cmsplugin_set.all().order_by( 'tree_id', '-rght')) try: ph = page.placeholders.get(slot=ph.slot) except Placeholder.DoesNotExist: ph.pk = None # make a new instance ph.save() page.placeholders.add(ph) if plugins: copy_plugins_to(plugins, ph) # invalidate the menu for this site menu_pool.clear(site_id=site.pk) return page_copy # return the page_copy or None
def copy_plugins(self, request): """ POST request should have the following data: - source_language - source_placeholder_id - source_plugin_id (optional) - target_language - target_placeholder_id - target_plugin_id (optional, new parent) """ source_language = request.POST['source_language'] source_placeholder_id = request.POST['source_placeholder_id'] source_plugin_id = request.POST.get('source_plugin_id', None) target_language = request.POST['target_language'] target_placeholder_id = request.POST['target_placeholder_id'] target_plugin_id = request.POST.get('target_plugin_id', None) source_placeholder = get_object_or_404(Placeholder, pk=source_placeholder_id) target_placeholder = get_object_or_404(Placeholder, pk=target_placeholder_id) if not target_language or not target_language in get_language_list(): return HttpResponseBadRequest(force_text(_("Language must be set to a supported language!"))) if source_plugin_id: source_plugin = get_object_or_404(CMSPlugin, pk=source_plugin_id) reload_required = requires_reload(PLUGIN_COPY_ACTION, [source_plugin]) if source_plugin.plugin_type == "PlaceholderPlugin": # if it is a PlaceholderReference plugin only copy the plugins it references inst, cls = source_plugin.get_plugin_instance(self) plugins = inst.placeholder_ref.get_plugins_list() else: plugins = list( source_placeholder.cmsplugin_set.filter( path__startswith=source_plugin.path, depth__gte=source_plugin.depth).order_by('path') ) else: plugins = list( source_placeholder.cmsplugin_set.filter( language=source_language).order_by('path')) reload_required = requires_reload(PLUGIN_COPY_ACTION, plugins) if not self.has_copy_plugin_permission( request, source_placeholder, target_placeholder, plugins): return HttpResponseForbidden(force_text( _('You do not have permission to copy these plugins.'))) # Are we copying an entire placeholder? if (target_placeholder.pk == request.toolbar.clipboard.pk and not source_plugin_id and not target_plugin_id): # if we copy a whole placeholder to the clipboard create # PlaceholderReference plugin instead and fill it the content of the # source_placeholder. ref = PlaceholderReference() ref.name = source_placeholder.get_label() ref.plugin_type = "PlaceholderPlugin" ref.language = target_language ref.placeholder = target_placeholder ref.save() ref.copy_from(source_placeholder, source_language) else: copy_plugins.copy_plugins_to( plugins, target_placeholder, target_language, target_plugin_id) plugin_list = CMSPlugin.objects.filter( language=target_language, placeholder=target_placeholder ).order_by('path') reduced_list = [] for plugin in plugin_list: reduced_list.append( { 'id': plugin.pk, 'type': plugin.plugin_type, 'parent': plugin.parent_id, 'position': plugin.position, 'desc': force_text(plugin.get_short_description()), 'language': plugin.language, 'placeholder_id': plugin.placeholder_id } ) self.post_copy_plugins(request, source_placeholder, target_placeholder, plugins) # When this is executed we are in the admin class of the source placeholder # It can be a page or a model with a placeholder field. # Because of this we need to get the admin class instance of the # target placeholder and call post_copy_plugins() on it. # By doing this we make sure that both the source and target are # informed of the operation. target_placeholder_admin = self._get_attached_admin(target_placeholder) if (target_placeholder_admin and target_placeholder_admin.model != self.model): target_placeholder_admin.post_copy_plugins( request, source_placeholder=source_placeholder, target_placeholder=target_placeholder, plugins=plugins, ) json_response = {'plugin_list': reduced_list, 'reload': reload_required} return HttpResponse(json.dumps(json_response), content_type='application/json')
def move_plugin(self, request): """ Performs a move or a "paste" operation (when «move_a_copy» is set) POST request with following parameters: - plugin_id - placeholder_id - plugin_language (optional) - plugin_parent (optional) - plugin_order (array, optional) - move_a_copy (Boolean, optional) (anything supplied here except a case- insensitive "false" is True) NOTE: If move_a_copy is set, the plugin_order should contain an item '__COPY__' with the desired destination of the copied plugin. """ # plugin_id and placeholder_id are required, so, if nothing is supplied, # an ValueError exception will be raised by get_int(). try: plugin_id = get_int(request.POST.get('plugin_id')) except TypeError: raise RuntimeError("'plugin_id' is a required parameter.") plugin = CMSPlugin.objects.get(pk=plugin_id) try: placeholder_id = get_int(request.POST.get('placeholder_id')) except TypeError: raise RuntimeError("'placeholder_id' is a required parameter.") except ValueError: raise RuntimeError("'placeholder_id' must be an integer string.") placeholder = Placeholder.objects.get(pk=placeholder_id) # The rest are optional parent_id = get_int(request.POST.get('plugin_parent', ""), None) language = request.POST.get('plugin_language', None) move_a_copy = request.POST.get('move_a_copy', False) move_a_copy = (move_a_copy and move_a_copy != "0" and move_a_copy.lower() != "false") source_placeholder = plugin.placeholder if not language and plugin.language: language = plugin.language order = request.POST.getlist("plugin_order[]") if not self.has_move_plugin_permission(request, plugin, placeholder): return HttpResponseForbidden( force_text(_("You have no permission to move this plugin"))) if placeholder != source_placeholder: try: template = self.get_placeholder_template(request, placeholder) has_reached_plugin_limit(placeholder, plugin.plugin_type, plugin.language, template=template) except PluginLimitReached as er: return HttpResponseBadRequest(er) if move_a_copy: # "paste" if plugin.plugin_type == "PlaceholderPlugin": parent_id = None inst = plugin.get_plugin_instance()[0] plugins = inst.placeholder_ref.get_plugins() else: plugins = [plugin] + list(plugin.get_descendants()) new_plugins = copy_plugins.copy_plugins_to( plugins, placeholder, language, parent_plugin_id=parent_id, ) top_plugins = [] top_parent = new_plugins[0][0].parent_id for new_plugin, old_plugin in new_plugins: if new_plugin.parent_id == top_parent: # NOTE: There is no need to save() the plugins here. new_plugin.position = old_plugin.position top_plugins.append(new_plugin) # Creates a list of string PKs of the top-level plugins ordered by # their position. top_plugins_pks = [str(p.pk) for p in sorted( top_plugins, key=lambda x: x.position)] if parent_id: parent = CMSPlugin.objects.get(pk=parent_id) for plugin in top_plugins: plugin.parent = parent plugin.placeholder = placeholder plugin.language = language plugin.save() # If an ordering was supplied, we should replace the item that has # been copied with the new copy if order: if '__COPY__' in order: copy_idx = order.index('__COPY__') del order[copy_idx] order[copy_idx:0] = top_plugins_pks else: order.extend(top_plugins_pks) # Set the plugin variable to point to the newly created plugin. plugin = new_plugins[0][0] else: # Regular move if parent_id: if plugin.parent_id != parent_id: parent = CMSPlugin.objects.get(pk=parent_id) if parent.placeholder_id != placeholder.pk: return HttpResponseBadRequest(force_text( _('parent must be in the same placeholder'))) if parent.language != language: return HttpResponseBadRequest(force_text( _('parent must be in the same language as ' 'plugin_language'))) plugin.parent_id = parent.pk plugin.language = language plugin.save() plugin = plugin.move(parent, pos='last-child') else: sibling = CMSPlugin.get_last_root_node() plugin.parent = plugin.parent_id = None plugin.placeholder = placeholder plugin.save() plugin = plugin.move(sibling, pos='right') plugins = [plugin] + list(plugin.get_descendants()) # Don't neglect the children for child in plugins: child.placeholder = placeholder child.language = language child.save() reorder_plugins(placeholder, parent_id, language, order) # When this is executed we are in the admin class of the source placeholder # It can be a page or a model with a placeholder field. # Because of this we need to get the admin class instance of the # target placeholder and call post_move_plugin() on it. # By doing this we make sure that both the source and target are # informed of the operation. target_placeholder_admin = self._get_attached_admin(placeholder) if move_a_copy: # "paste" self.post_copy_plugins(request, source_placeholder, placeholder, plugins) if (target_placeholder_admin and target_placeholder_admin.model != self.model): target_placeholder_admin.post_copy_plugins( request, source_placeholder=source_placeholder, target_placeholder=placeholder, plugins=plugins, ) else: self.post_move_plugin(request, source_placeholder, placeholder, plugin) if (target_placeholder_admin and target_placeholder_admin.model != self.model): target_placeholder_admin.post_move_plugin( request, source_placeholder=source_placeholder, target_placeholder=placeholder, plugin=plugin, ) try: language = request.toolbar.toolbar_language except AttributeError: language = get_language_from_request(request) with force_language(language): plugin_urls = plugin.get_action_urls() json_response = { 'urls': plugin_urls, 'reload': move_a_copy or requires_reload( PLUGIN_MOVE_ACTION, [plugin]) } return HttpResponse( json.dumps(json_response), content_type='application/json')
def handle(self, *args, **kwargs): verbose = 'verbose' in args only_empty = 'force-copy' not in args site = [arg.split("=")[1] for arg in args if arg.startswith("site")] if site: site = site.pop() else: site = settings.SITE_ID #test both langs try: assert len(args) >= 2 from_lang = args[0] to_lang = args[1] assert from_lang != to_lang except AssertionError: raise CommandError("Error: bad arguments -- Usage: manage.py cms copy-lang <lang_from> <lang_to>") try: assert from_lang in get_language_list(site) assert to_lang in get_language_list(site) except AssertionError: raise CommandError("Both languages have to be present in settings.LANGUAGES and settings.CMS_LANGUAGES") for page in Page.objects.on_site(site).drafts(): # copy title if from_lang in page.get_languages(): title = page.get_title_obj(to_lang, fallback=False) if isinstance(title, EmptyTitle): title = page.get_title_obj(from_lang) if verbose: self.stdout.write('copying title %s from language %s\n' % (title.title, from_lang)) title.id = None title.publisher_public_id = None title.publisher_state = 0 title.language = to_lang title.save() # copy plugins using API if verbose: self.stdout.write('copying plugins for %s from %s\n' % (page.get_page_title(from_lang), from_lang)) copy_plugins_to_language(page, from_lang, to_lang, only_empty) else: if verbose: self.stdout.write('Skipping page %s, language %s not defined\n' % (page, from_lang)) for static_placeholder in StaticPlaceholder.objects.all(): plugin_list = [] for plugin in static_placeholder.draft.get_plugins(): if plugin.language == from_lang: plugin_list.append(plugin) if plugin_list: if verbose: self.stdout.write("copying plugins from static_placeholder '%s' in '%s' to '%s'\n" % (static_placeholder.name, from_lang, to_lang)) copy_plugins_to(plugin_list, static_placeholder.draft, to_lang) self.stdout.write(u"all done")
serializer = serializer_class(data=product) assert serializer.is_valid(), serializer.errors instance = serializer.save() self.assign_product_to_catalog(instance) self.stdout.write("{}. {}".format(number, instance)) if product_model == 'commodity': languages = get_public_languages() try: clipboard = CascadeClipboard.objects.get(identifier=instance.slug) except CascadeClipboard.DoesNotExist: pass else: deserialize_to_placeholder(instance.placeholder, clipboard.data, languages[0]) plugins = list(instance.placeholder.get_plugins(language=languages[0]).order_by('path')) for language in languages[1:]: copy_plugins_to(plugins, instance.placeholder, language) def find_fixture(self, filename): if os.path.isabs(filename): fixture_dirs = [os.path.dirname(filename)] fixture_name = os.path.basename(filename) else: fixture_dirs = settings.FIXTURE_DIRS if os.path.sep in os.path.normpath(filename): fixture_dirs = [os.path.join(dir_, os.path.dirname(filename)) for dir_ in fixture_dirs] fixture_name = os.path.basename(filename) else: fixture_name = filename for fixture_dir in fixture_dirs: path = os.path.join(fixture_dir, fixture_name)
def copy_page(self, target, site, position='first-child', copy_permissions=True): """ Copy a page [ and all its descendants to a new location ] Doesn't checks for add page permissions anymore, this is done in PageAdmin. Note: public_copy was added in order to enable the creation of a copy for creating the public page during the publish operation as it sets the publisher_is_draft=False. Note for issue #1166: when copying pages there is no need to check for conflicting URLs as pages are copied unpublished. """ from cms.utils.moderator import update_moderation_message page_copy = None pages = [self] + list(self.get_descendants().order_by('-rght')) site_reverse_ids = Page.objects.filter(site=site, reverse_id__isnull=False).values_list('reverse_id', flat=True) if target: target.old_pk = -1 if position == "first-child": tree = [target] elif target.parent_id: tree = [target.parent] else: tree = [] else: tree = [] if tree: tree[0].old_pk = tree[0].pk first = True # loop over all affected pages (self is included in descendants) for page in pages: titles = list(page.title_set.all()) # get all current placeholders (->plugins) placeholders = list(page.placeholders.all()) origin_id = page.id # create a copy of this page by setting pk = None (=new instance) page.old_pk = page.pk page.pk = None page.level = None page.rght = None page.lft = None page.tree_id = None page.published = False page.publisher_public_id = None # only set reverse_id on standard copy if page.reverse_id in site_reverse_ids: page.reverse_id = None if first: first = False if tree: page.parent = tree[0] else: page.parent = None page.insert_at(target, position) else: count = 1 found = False for prnt in tree: if prnt.old_pk == page.parent_id: page.parent = prnt tree = tree[0:count] found = True break count += 1 if not found: page.parent = None tree.append(page) page.site = site page.save() # copy permissions if necessary if get_cms_setting('PERMISSION') and copy_permissions: from cms.models.permissionmodels import PagePermission for permission in PagePermission.objects.filter(page__id=origin_id): permission.pk = None permission.page = page permission.save() update_moderation_message(page, unicode(_('Page was copied.'))) # copy titles of this page for title in titles: title.pk = None # setting pk = None creates a new instance title.page = page # create slug-copy for standard copy title.slug = page_utils.get_available_slug(title) title.save() # copy the placeholders (and plugins on those placeholders!) for ph in placeholders: plugins = ph.get_plugins_list() try: ph = page.placeholders.get(slot=ph.slot) except Placeholder.DoesNotExist: ph.pk = None # make a new instance ph.save() page.placeholders.add(ph) # update the page copy page_copy = page if plugins: copy_plugins_to(plugins, ph) # invalidate the menu for this site menu_pool.clear(site_id=site.pk) return page_copy # return the page_copy or None
def copy_page(self, target, site, position='first-child', copy_permissions=True, copy_moderation=True, public_copy=False): """ copy a page [ and all its descendants to a new location ] Doesn't checks for add page permissions anymore, this is done in PageAdmin. Note: public_copy was added in order to enable the creation of a copy for creating the public page during the publish operation as it sets the publisher_is_draft=False. """ from cms.utils.moderator import update_moderation_message page_copy = None if public_copy: # create a copy of the draft page - existing code loops through pages so added it to a list pages = [copy.copy(self)] else: pages = [self] + list(self.get_descendants().order_by('-rght')) if not public_copy: site_reverse_ids = Page.objects.filter(site=site, reverse_id__isnull=False).values_list('reverse_id', flat=True) if target: target.old_pk = -1 if position == "first-child": tree = [target] elif target.parent_id: tree = [target.parent] else: tree = [] else: tree = [] if tree: tree[0].old_pk = tree[0].pk first = True # loop over all affected pages (self is included in descendants) for page in pages: titles = list(page.title_set.all()) # get all current placeholders (->plugins) placeholders = list(page.placeholders.all()) origin_id = page.id # create a copy of this page by setting pk = None (=new instance) page.old_pk = page.pk page.pk = None page.level = None page.rght = None page.lft = None page.tree_id = None page.published = False page.moderator_state = Page.MODERATOR_CHANGED page.publisher_public_id = None # only set reverse_id on standard copy if not public_copy: if page.reverse_id in site_reverse_ids: page.reverse_id = None if first: first = False if tree: page.parent = tree[0] else: page.parent = None page.insert_at(target, position) else: count = 1 found = False for prnt in tree: if prnt.old_pk == page.parent_id: page.parent = prnt tree = tree[0:count] found = True break count += 1 if not found: page.parent = None tree.append(page) page.site = site # override default page settings specific for public copy if public_copy: page.published = True page.publisher_is_draft=False page.moderator_state = Page.MODERATOR_APPROVED # we need to set relate this new public copy to its draft page (self) page.publisher_public = self # code taken from Publisher publish() overridden here as we need to save the page # before we are able to use the page object for titles, placeholders etc.. below # the method has been modified to return the object after saving the instance variable page = self._publisher_save_public(page) page_copy = page # create a copy used in the return else: # only need to save the page if it isn't public since it is saved above otherwise page.save() # copy moderation, permissions if necessary if settings.CMS_PERMISSION and copy_permissions: from cms.models.permissionmodels import PagePermission for permission in PagePermission.objects.filter(page__id=origin_id): permission.pk = None permission.page = page permission.save() if settings.CMS_MODERATOR and copy_moderation: from cms.models.moderatormodels import PageModerator for moderator in PageModerator.objects.filter(page__id=origin_id): moderator.pk = None moderator.page = page moderator.save() # update moderation message for standard copy if not public_copy: update_moderation_message(page, unicode(_('Page was copied.'))) # copy titles of this page for title in titles: title.pk = None # setting pk = None creates a new instance title.publisher_public_id = None title.published = False title.page = page # create slug-copy for standard copy if not public_copy: title.slug = get_available_slug(title) title.save() # copy the placeholders (and plugins on those placeholders!) for ph in placeholders: plugins = list(ph.cmsplugin_set.all().order_by('tree_id', '-rght')) try: ph = page.placeholders.get(slot=ph.slot) except Placeholder.DoesNotExist: ph.pk = None # make a new instance ph.save() page.placeholders.add(ph) if plugins: copy_plugins_to(plugins, ph) # invalidate the menu for this site menu_pool.clear(site_id=site.pk) return page_copy # return the page_copy or None
def copy_plugins(self, request): """ POST request should have the following data: - source_language - source_placeholder_id - source_plugin_id (optional) - target_language - target_placeholder_id - target_plugin_id (optional, new parent) """ source_language = request.POST["source_language"] source_placeholder_id = request.POST["source_placeholder_id"] source_plugin_id = request.POST.get("source_plugin_id", None) target_language = request.POST["target_language"] target_placeholder_id = request.POST["target_placeholder_id"] target_plugin_id = request.POST.get("target_plugin_id", None) source_placeholder = get_object_or_404(Placeholder, pk=source_placeholder_id) target_placeholder = get_object_or_404(Placeholder, pk=target_placeholder_id) if not target_language or not target_language in get_language_list(): return HttpResponseBadRequest(force_unicode(_("Language must be set to a supported language!"))) if source_plugin_id: source_plugin = get_object_or_404(CMSPlugin, pk=source_plugin_id) reload_required = requires_reload(PLUGIN_COPY_ACTION, [source_plugin]) if source_plugin.plugin_type == "PlaceholderPlugin": # if it is a PlaceholderReference plugin only copy the plugins it references inst, cls = source_plugin.get_plugin_instance(self) plugins = inst.placeholder_ref.get_plugins_list() else: plugins = list( source_placeholder.cmsplugin_set.filter( tree_id=source_plugin.tree_id, lft__gte=source_plugin.lft, rght__lte=source_plugin.rght ).order_by("tree_id", "level", "position") ) else: plugins = list( source_placeholder.cmsplugin_set.filter(language=source_language).order_by( "tree_id", "level", "position" ) ) reload_required = requires_reload(PLUGIN_COPY_ACTION, plugins) if not self.has_copy_plugin_permission(request, source_placeholder, target_placeholder, plugins): return HttpResponseForbidden(force_unicode(_("You do not have permission to copy these plugins."))) if target_placeholder.pk == request.toolbar.clipboard.pk and not source_plugin_id and not target_plugin_id: # if we copy a whole placeholder to the clipboard create PlaceholderReference plugin instead and fill it # the content of the source_placeholder. ref = PlaceholderReference() ref.name = source_placeholder.get_label() ref.plugin_type = "PlaceholderPlugin" ref.language = target_language ref.placeholder = target_placeholder ref.save() ref.copy_from(source_placeholder, source_language) else: copy_plugins.copy_plugins_to(plugins, target_placeholder, target_language, target_plugin_id) plugin_list = CMSPlugin.objects.filter(language=target_language, placeholder=target_placeholder).order_by( "tree_id", "level", "position" ) reduced_list = [] for plugin in plugin_list: reduced_list.append( { "id": plugin.pk, "type": plugin.plugin_type, "parent": plugin.parent_id, "position": plugin.position, "desc": force_unicode(plugin.get_short_description()), "language": plugin.language, "placeholder_id": plugin.placeholder_id, } ) self.post_copy_plugins(request, source_placeholder, target_placeholder, plugins) json_response = {"plugin_list": reduced_list, "reload": reload_required} return HttpResponse(json.dumps(json_response), content_type="application/json")