def __init__(self, request): super(CMSToolbar, self).__init__() self._cached_templates = {} self.right_items = [] self.left_items = [] self.last_left_items = [] self.last_right_items = [] self.populated = False self.post_template_populated = False self.menus = {} self.obj = None self.redirect_url = None self.request = None self.is_staff = None self.edit_mode = None self.edit_mode_url_on = get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON') self.edit_mode_url_off = get_cms_setting('CMS_TOOLBAR_URL__EDIT_OFF') self.disable_url = get_cms_setting('CMS_TOOLBAR_URL__DISABLE') self.build_mode = None self.use_draft = None self.show_toolbar = None self.login_form = None self.clipboard = None self.language = None self.toolbar_language = None self.show_toolbar = True self.init_toolbar(request) with force_language(self.language): try: decorator = resolve(self.request.path_info).func try: # If the original view is decorated we try to extract the real function # module instead of the decorator's one if decorator and getattr(decorator, 'func_closure', False): # python 2 self.app_name = decorator.func_closure[0].cell_contents.__module__ elif decorator and getattr(decorator, '__closure__', False): # python 3 self.app_name = decorator.__closure__[0].cell_contents.__module__ else: raise AttributeError() except (TypeError, AttributeError): # no decorator self.app_name = decorator.__module__ except (Resolver404, AttributeError): self.app_name = "" toolbars = toolbar_pool.get_toolbars() parts = self.app_name.split('.') while parts: path = '.'.join(parts) if path in installed_apps(): self.app_name = path break parts.pop() self.toolbars = OrderedDict() for key in toolbars: toolbar = toolbars[key](self.request, self, toolbars[key].check_current_app(key, self.app_name), self.app_name) self.toolbars[key] = toolbar
def get_template_from_request(request, obj=None, no_current_page=False): """ Gets a valid template from different sources or falls back to the default template. """ template = None if len(get_cms_setting('TEMPLATES')) == 1: return get_cms_setting('TEMPLATES')[0][0] if hasattr(request, 'POST') and "template" in request.POST: template = request.POST['template'] elif hasattr(request, 'GET') and "template" in request.GET: template = request.GET['template'] if not template and obj is not None: template = obj.get_template() if not template and not no_current_page and hasattr(request, "current_page"): current_page = request.current_page if hasattr(current_page, "get_template"): template = current_page.get_template() if template is not None and template in dict(get_cms_setting('TEMPLATES')).keys(): if template == constants.TEMPLATE_INHERITANCE_MAGIC and obj: # Happens on admin's request when changing the template for a page # to "inherit". return obj.get_template() return template return get_cms_setting('TEMPLATES')[0][0]
def save(self, commit=True): job_opening = super(CreateJobOpeningForm, self).save(commit=False) # If 'content' field has value, create a TextPlugin with same and add # it to the PlaceholderField content = clean_html(self.cleaned_data.get('content', ''), False) content_plugin = get_cms_setting('WIZARD_CONTENT_PLUGIN') if content and permissions.has_plugin_permission( self.user, 'TextPlugin', 'add'): # If the job_opening has not been saved, then there will be no # Placeholder set-up for this question yet, so, ensure we have saved # first. if not job_opening.pk: job_opening.save() if job_opening and job_opening.content: plugin_kwargs = { 'placeholder': job_opening.content, 'plugin_type': content_plugin, 'language': self.language_code, get_cms_setting('WIZARD_CONTENT_PLUGIN_BODY'): content, } add_plugin(**plugin_kwargs) with transaction.atomic(): with revision_context_manager.create_revision(): job_opening.save() if self.user: revision_context_manager.set_user(self.user) revision_context_manager.set_comment( ugettext("Initial version.")) return job_opening
def save(self, commit=True): job_opening = super(CreateJobOpeningForm, self).save(commit=False) # If 'job_opening_content' field has value, create a TextPlugin with same and add # it to the PlaceholderField job_opening_content = clean_html(self.cleaned_data.get('job_opening_content', ''), False) content_plugin = get_cms_setting('PAGE_WIZARD_CONTENT_PLUGIN') content_field = get_cms_setting('PAGE_WIZARD_CONTENT_PLUGIN_BODY') if job_opening_content and permissions.has_plugin_permission( self.user, content_plugin, 'add'): # If the job_opening has not been saved, then there will be no # Placeholder set-up for this question yet, so, ensure we have saved # first. if not job_opening.pk: job_opening.save() if job_opening and job_opening.content: plugin_kwargs = { 'placeholder': job_opening.content, 'plugin_type': content_plugin, 'language': self.language_code, content_field: job_opening_content, } add_plugin(**plugin_kwargs) job_opening.save() return job_opening
def save(self, commit=True): event = super(CreateEventForm, self).save(commit=False) # If 'content' field has value, create a TextPlugin with same and add # it to the PlaceholderField description = self.cleaned_data.get('description', '') content_plugin = get_cms_setting('WIZARD_CONTENT_PLUGIN') if description and permissions.has_plugin_permission( self.user, content_plugin, 'add'): # If the event has not been saved, then there will be no # Placeholder set-up for this event yet, so, ensure we have saved # first. if not event.pk: event.save() if event and event.description: # we have to use kwargs because we don't know in advance what # is the 'body' field for configured plugin plugin_kwargs = { 'placeholder': event.description, 'plugin_type': content_plugin, 'language': self.language_code, get_cms_setting('WIZARD_CONTENT_PLUGIN_BODY'): description, } add_plugin(**plugin_kwargs) if commit: event.save() return event
def test_undo_slug_collision(self): data1 = self.get_new_page_data() data2 = self.get_new_page_data() data1['slug'] = 'page1' data2['slug'] = 'page2' with self.login_user_context(self.get_superuser()): response = self.client.post(URL_CMS_PAGE_ADD, data1) self.assertEqual(response.status_code, 302) response = self.client.post(URL_CMS_PAGE_ADD, data2) self.assertEqual(response.status_code, 302) page1 = Page.objects.get(title_set__slug='page1') page2 = Page.objects.get(title_set__slug='page2') data1['slug'] = 'page3' response = self.client.post(URL_CMS_PAGE_CHANGE % page1.pk, data1) self.assertEqual(response.status_code, 302) data2['slug'] = 'page1' response = self.client.post(URL_CMS_PAGE_CHANGE % page2.pk, data2) self.assertEqual(response.status_code, 302) undo_url = reverse("admin:cms_page_undo", args=[page1.pk]) response = self.client.post(undo_url) self.assertEqual(response.status_code, 200) self.assertEqual(Title.objects.get(page=page1).slug, 'page3') response = self.client.get(reverse("admin:cms_page_changelist")) self.assertEqual(response.status_code, 200) response = self.client.get('/en/?%s' % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON')) self.assertEqual(response.status_code, 200) response = self.client.get('/en/page1/?%s' % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON')) self.assertEqual(response.status_code, 200)
def process_request(self, request): """ If we should show the toolbar for this request, put it on request.toolbar. Then call the request_hook on the toolbar. """ edit_on = get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON') edit_off = get_cms_setting('CMS_TOOLBAR_URL__EDIT_OFF') build = get_cms_setting('CMS_TOOLBAR_URL__BUILD') if edit_on in request.GET and not request.session.get('cms_edit', False): if not request.session.get('cms_edit', False): menu_pool.clear() request.session['cms_edit'] = True if request.session.get('cms_build', False): request.session['cms_build'] = False if edit_off in request.GET and request.session.get('cms_edit', True): if request.session.get('cms_edit', True): menu_pool.clear() request.session['cms_edit'] = False if request.session.get('cms_build', False): request.session['cms_build'] = False if build in request.GET and not request.session.get('cms_build', False): request.session['cms_build'] = True if request.user.is_staff: try: request.cms_latest_entry = LogEntry.objects.filter( user=request.user, action_flag__in=(ADDITION, CHANGE) ).only('pk').order_by('-pk')[0].pk except IndexError: request.cms_latest_entry = -1 request.toolbar = CMSToolbar(request)
def save(self, commit=True): question = super(CreateFaqQuestionForm, self).save(commit=False) # If 'content' field has value, create a TextPlugin with same and add # it to the PlaceholderField answer = self.cleaned_data.get('answer', '') content_plugin = get_cms_setting('WIZARD_CONTENT_PLUGIN') if answer and permissions.has_plugin_permission( self.user, content_plugin, 'add'): # If the question has not been saved, then there will be no # Placeholder set-up for this question yet, so, ensure we have saved # first. if not question.pk: question.save() if question and question.answer: plugin_kwarg = { 'placeholder': question.answer, 'plugin_type': content_plugin, 'language': self.language_code, get_cms_setting('WIZARD_CONTENT_PLUGIN_BODY'): answer, } add_plugin(**plugin_kwarg) if commit: question.save() return question
def test_static_placeholders_permissions(self): # login url = '%s/?%s' % (self.live_server_url, get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON')) self.driver.get(url) self.assertRaises(NoSuchElementException, self.driver.find_element_by_class_name, 'cms_toolbar-item_logout') username_input = self.driver.find_element_by_id("id_cms-username") username_input.send_keys(getattr(self.user, get_user_model().USERNAME_FIELD)) password_input = self.driver.find_element_by_id("id_cms-password") password_input.send_keys(getattr(self.user, get_user_model().USERNAME_FIELD)) password_input.submit() self.wait_page_loaded() self.assertTrue(self.driver.find_element_by_class_name('cms_toolbar-item-navigation')) pk = Placeholder.objects.filter(slot='logo').order_by('id')[0].pk placeholder_name = 'cms_placeholder-%s' % pk # test static placeholder permission (content of static placeholders is NOT editable) self.driver.get('%s/en/?%s' % (self.live_server_url, get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON'))) self.assertRaises(NoSuchElementException, self.driver.find_element_by_class_name, placeholder_name) # update userpermission edit_permission = Permission.objects.get(codename="edit_static_placeholder") self.user.user_permissions.add( edit_permission ) # test static placeholder permission (content of static placeholders is editable) self.driver.get('%s/en/?%s' % (self.live_server_url, get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON'))) self.assertTrue(self.driver.find_element_by_class_name(placeholder_name))
def test_get_page_for_apphook_on_preview_or_edit(self): if get_user_model().USERNAME_FIELD == 'email': superuser = get_user_model().objects.create_superuser('admin', '*****@*****.**', '*****@*****.**') else: superuser = get_user_model().objects.create_superuser('admin', '*****@*****.**', 'admin') page = create_page("home", "nav_playground.html", "en", created_by=superuser, published=True, apphook=APP_NAME) create_title('de', page.get_title(), page) page.publish('en') page.publish('de') page.save() public_page = page.get_public_object() with self.login_user_context(superuser): with force_language("en"): path = reverse('sample-settings') request = self.get_request(path + '?%s' % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON')) request.LANGUAGE_CODE = 'en' attached_to_page = applications_page_check(request, path=path[1:]) # strip leading slash response = self.client.get(path+"?edit") self.assertContains(response, '?redirect=') with force_language("de"): path = reverse('sample-settings') request = self.get_request(path + '?%s' % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON')) request.LANGUAGE_CODE = 'de' attached_to_page = applications_page_check(request, path=path[1:]) # strip leading slash self.assertEqual(attached_to_page.pk, public_page.pk)
def test_undo_slug_collision(self): data1 = self.get_new_page_data() data2 = self.get_new_page_data() data1["slug"] = "page1" data2["slug"] = "page2" with self.login_user_context(self.get_superuser()): response = self.client.post(URL_CMS_PAGE_ADD, data1) self.assertEqual(response.status_code, 302) response = self.client.post(URL_CMS_PAGE_ADD, data2) self.assertEqual(response.status_code, 302) page1 = Page.objects.get(title_set__slug="page1") page2 = Page.objects.get(title_set__slug="page2") data1["slug"] = "page3" response = self.client.post(URL_CMS_PAGE_CHANGE % page1.pk, data1) self.assertEqual(response.status_code, 302) data2["slug"] = "page1" response = self.client.post(URL_CMS_PAGE_CHANGE % page2.pk, data2) self.assertEqual(response.status_code, 302) undo_url = admin_reverse("cms_page_undo", args=[page1.pk]) response = self.client.post(undo_url) self.assertEqual(response.status_code, 200) self.assertEqual(Title.objects.get(page=page1).slug, "page3") response = self.client.get(admin_reverse("cms_page_changelist")) self.assertEqual(response.status_code, 200) response = self.client.get("/en/?%s" % get_cms_setting("CMS_TOOLBAR_URL__EDIT_ON")) self.assertEqual(response.status_code, 200) response = self.client.get("/en/page1/?%s" % get_cms_setting("CMS_TOOLBAR_URL__EDIT_ON")) self.assertEqual(response.status_code, 200)
def __init__(self, request): super(CMSToolbar, self).__init__() self.right_items = [] self.left_items = [] self.populated = False self.post_template_populated = False self.menus = {} self.request = request self.login_form = CMSToolbarLoginForm(request=request) self.is_staff = self.request.user.is_staff self.edit_mode = self.is_staff and self.request.session.get("cms_edit", False) self.edit_mode_url_on = get_cms_setting("CMS_TOOLBAR_URL__EDIT_ON") self.edit_mode_url_off = get_cms_setting("CMS_TOOLBAR_URL__EDIT_OFF") self.build_mode = self.is_staff and self.request.session.get("cms_build", False) self.use_draft = self.is_staff and self.edit_mode or self.build_mode self.show_toolbar = self.is_staff or self.request.session.get("cms_edit", False) self.obj = None self.redirect_url = None if settings.USE_I18N: self.language = get_language_from_request(request) else: self.language = settings.LANGUAGE_CODE # We need to store the current language in case the user's preferred language is different. self.toolbar_language = self.language if self.is_staff: try: user_settings = UserSettings.objects.select_related("clipboard").get(user=self.request.user) except UserSettings.DoesNotExist: user_settings = UserSettings(language=self.language, user=self.request.user) placeholder = Placeholder(slot="clipboard") placeholder.save() user_settings.clipboard = placeholder user_settings.save() if (settings.USE_I18N and user_settings.language in dict(settings.LANGUAGES)) or ( not settings.USE_I18N and user_settings.language == settings.LANGUAGE_CODE ): self.toolbar_language = user_settings.language else: user_settings.language = self.language user_settings.save() self.clipboard = user_settings.clipboard with force_language(self.language): try: self.app_name = resolve(self.request.path).app_name except Resolver404: self.app_name = "" toolbars = toolbar_pool.get_toolbars() self.toolbars = SortedDict() app_key = "" for key in toolbars: app_name = ".".join(key.split(".")[:-2]) if app_name == self.app_name and len(key) > len(app_key): app_key = key for key in toolbars: toolbar = toolbars[key](self.request, self, key == app_key, app_key) self.toolbars[key] = toolbar
def get_visible_page_objects(request, pages, site=None): """ This code is basically a many-pages-at-once version of Page.has_view_permission. pages contains all published pages check if there is ANY restriction that needs a permission page visibility calculation """ public_for = get_cms_setting('PUBLIC_FOR') can_see_unrestricted = public_for == 'all' or ( public_for == 'staff' and request.user.is_staff) is_auth_user = request.user.is_authenticated() restricted_pages = load_view_restrictions(request, pages) if not restricted_pages: if can_see_unrestricted: return pages elif not is_auth_user: return [] # Unauth user can't acquire global or user perm to see pages if get_cms_setting('PERMISSION') and not site: site = current_site(request) # avoid one extra query when possible if has_global_page_permission(request, site, can_view=True): return pages has_global_perm = SimpleLazyObject(lambda: request.user.has_perm('cms.view_page')) user_groups = SimpleLazyObject(lambda: set(request.user.groups.values_list('pk', flat=True))) def has_permission_membership(page_id): """ PagePermission user group membership tests """ user_pk = request.user.pk for perm in restricted_pages[page_id]: if perm.user_id == user_pk or perm.group_id in user_groups: return True return False visible_pages = [] for page in pages: to_add = False page_id = page.pk is_restricted = page_id in restricted_pages # restricted_pages contains as key any page.pk that is # affected by a permission grant_on if not is_restricted and can_see_unrestricted: to_add = True elif is_auth_user: # setting based handling of unrestricted pages # check group and user memberships to restricted pages if is_restricted and has_permission_membership(page_id) or has_global_perm: to_add = True if to_add: visible_pages.append(page) return visible_pages
def get_languages(site_id=None): site_id = get_site(site_id) result = get_cms_setting('LANGUAGES').get(site_id) if not result: result = [] defaults = get_cms_setting('LANGUAGES').get('default', {}) for code, name in settings.LANGUAGES: lang = {'code': code, 'name': _(name)} lang.update(defaults) result.append(lang) get_cms_setting('LANGUAGES')[site_id] = result return result
def save(self, commit=True): event = super(CreateEventForm, self).save(commit=False) if not commit: return event # If 'content' field has value, create a TextPlugin with same and add # it to the PlaceholderField description = clean_html( self.cleaned_data.get('description', ''), False) try: # CMS >= 3.3.x content_plugin = get_cms_setting('PAGE_WIZARD_CONTENT_PLUGIN') except KeyError: # CMS <= 3.2.x content_plugin = get_cms_setting('WIZARD_CONTENT_PLUGIN') try: # CMS >= 3.3.x content_field = get_cms_setting('PAGE_WIZARD_CONTENT_PLUGIN_BODY') except KeyError: # CMS <= 3.2.x content_field = get_cms_setting('WIZARD_CONTENT_PLUGIN_BODY') if description and permissions.has_plugin_permission( self.user, content_plugin, 'add'): # If the event has not been saved, then there will be no # Placeholder set-up for this event yet, so, ensure we have saved # first. if not event.pk: event.save() if event and event.description: # we have to use kwargs because we don't know in advance what # is the 'body' field for configured plugin plugin_kwargs = { 'placeholder': event.description, 'plugin_type': content_plugin, 'language': self.language_code, content_field: description, } add_plugin(**plugin_kwargs) with transaction.atomic(): with revision_context_manager.create_revision(): event.save() if self.user: revision_context_manager.set_user(self.user) revision_context_manager.set_comment( ugettext("Initial version.")) return event
def is_cms_request(self,request): cms_app_name = get_cms_setting('APP_NAME') toolbar_hide = get_cms_setting('TOOLBAR_HIDE') if not toolbar_hide or not cms_app_name: return True try: match = resolve(request.path_info) except: return False return match.app_name == cms_app_name
def process_request(self, request): """ If we should show the toolbar for this request, put it on request.toolbar. Then call the request_hook on the toolbar. """ if not self.is_cms_request(request): return edit_on = get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON') edit_off = get_cms_setting('CMS_TOOLBAR_URL__EDIT_OFF') build = get_cms_setting('CMS_TOOLBAR_URL__BUILD') disable = get_cms_setting('CMS_TOOLBAR_URL__DISABLE') anonymous_on = get_cms_setting('TOOLBAR_ANONYMOUS_ON') if disable in request.GET: request.session['cms_toolbar_disabled'] = True if edit_on in request.GET: # If we actively enter edit mode, we should show the toolbar in any case request.session['cms_toolbar_disabled'] = False if not request.session.get('cms_toolbar_disabled', False) and ( request.user.is_staff or (anonymous_on and request.user.is_anonymous()) ): if edit_on in request.GET and not request.session.get('cms_edit', False): if not request.session.get('cms_edit', False): menu_pool.clear() request.session['cms_edit'] = True if request.session.get('cms_build', False): request.session['cms_build'] = False if edit_off in request.GET and request.session.get('cms_edit', True): if request.session.get('cms_edit', True): menu_pool.clear() request.session['cms_edit'] = False if request.session.get('cms_build', False): request.session['cms_build'] = False if build in request.GET and not request.session.get('cms_build', False): request.session['cms_build'] = True else: if request.session.get('cms_build'): request.session['cms_build'] = False if request.session.get('cms_edit'): request.session['cms_edit'] = False if request.user.is_staff: try: request.cms_latest_entry = LogEntry.objects.filter( user=request.user, action_flag__in=(ADDITION, CHANGE) ).only('pk').order_by('-pk')[0].pk except IndexError: request.cms_latest_entry = -1 request.toolbar = CMSToolbar(request)
def has_view_permission(self, request): from cms.models.permissionmodels import PagePermission, GlobalPagePermission from cms.utils.plugins import current_site if not self.publisher_is_draft: return self.publisher_draft.has_view_permission(request) # does any restriction exist? # inherited and direct is_restricted = PagePermission.objects.for_page(page=self).filter(can_view=True).exists() if request.user.is_authenticated(): site = current_site(request) global_perms_q = Q(can_view=True) & Q( Q(sites__in=[site]) | Q(sites__isnull=True) ) global_view_perms = GlobalPagePermission.objects.with_user( request.user).filter(global_perms_q).exists() # a global permission was given to the request's user if global_view_perms: return True elif not is_restricted: if ((get_cms_setting('PUBLIC_FOR') == 'all') or (get_cms_setting('PUBLIC_FOR') == 'staff' and request.user.is_staff)): return True # a restricted page and an authenticated user elif is_restricted: opts = self._meta codename = '%s.view_%s' % (opts.app_label, opts.object_name.lower()) user_perm = request.user.has_perm(codename) generic_perm = self.has_generic_permission(request, "view") return (user_perm or generic_perm) else: #anonymous user if is_restricted or not get_cms_setting('PUBLIC_FOR') == 'all': # anyonymous user, page has restriction and global access is permitted return False else: # anonymous user, no restriction saved in database return True # Authenticated user # Django wide auth perms "can_view" or cms auth perms "can_view" opts = self._meta codename = '%s.view_%s' % (opts.app_label, opts.object_name.lower()) return (request.user.has_perm(codename) or self.has_generic_permission(request, "view"))
def get_unihandecode_context(self, language): if language[:2] in get_cms_setting('UNIHANDECODE_DECODERS'): uhd_lang = language[:2] else: uhd_lang = get_cms_setting('UNIHANDECODE_DEFAULT_DECODER') uhd_host = get_cms_setting('UNIHANDECODE_HOST') uhd_version = get_cms_setting('UNIHANDECODE_VERSION') if uhd_lang and uhd_host and uhd_version: uhd_urls = [ '%sunihandecode-%s.core.min.js' % (uhd_host, uhd_version), '%sunihandecode-%s.%s.min.js' % (uhd_host, uhd_version, uhd_lang), ] else: uhd_urls = [] return {'unihandecode_lang': uhd_lang, 'unihandecode_urls': uhd_urls}
def test_redirect_with_toolbar(self): create_page("one", "nav_playground.html", "en", published=True, redirect='/en/page2') superuser = self.get_superuser() with self.login_user_context(superuser): response = self.client.get('/en/?%s' % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON')) self.assertEqual(response.status_code, 200)
def _fastlogin(self, **credentials): session = import_module(settings.SESSION_ENGINE).SessionStore() session.save() request = AttributeObject(session=session, META={}) user = authenticate(**credentials) login(request, user) session.save() # We need to "warm up" the webdriver as we can only set cookies on the # current domain self.driver.get(self.live_server_url) # While we don't care about the page fully loading, Django will freak # out if we 'abort' this request, so we wait patiently for it to finish self.wait_page_loaded() self.driver.add_cookie({ 'name': settings.SESSION_COOKIE_NAME, 'value': session.session_key, 'path': '/', 'domain': urlparse(self.live_server_url).hostname }) self.driver.get('{0}/?{1}'.format( self.live_server_url, get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON') )) self.wait_page_loaded()
def test_copy_from_language(self): self._login() self.driver.get('%s/it/?%s' % (self.live_server_url, get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON'))) # check if there are no plugins in italian version of the page italian_plugins = self.page.placeholders.all()[0].get_plugins_list('it') self.assertEqual(len(italian_plugins), 0) build_button = self.driver.find_element_by_css_selector('.cms-toolbar-item-cms-mode-switcher a[href="?%s"]' % get_cms_setting('CMS_TOOLBAR_URL__BUILD')) build_button.click() submenu = self.driver.find_element_by_css_selector('.cms-dragbar .cms-submenu') hov = ActionChains(self.driver).move_to_element(submenu) hov.perform() submenu_link_selector = '.cms-submenu-item a[data-rel="copy-lang"][data-language="en"]' WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, submenu_link_selector))) copy_from_english = self.driver.find_element_by_css_selector(submenu_link_selector) copy_from_english.click() # Done, check if the text plugin was copied and it is only one WebDriverWait(self.driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, '.cms-draggable:nth-child(1)'))) italian_plugins = self.page.placeholders.all()[0].get_plugins_list('it') self.assertEqual(len(italian_plugins), 1) plugin_instance = italian_plugins[0].get_plugin_instance()[0] self.assertEqual(plugin_instance.body, 'test')
def test_toolbar_login_view(self): User = get_user_model() create_page('Home', 'simple.html', 'en', published=True) ex1 = Example1.objects.create( char_1='char_1', char_2='char_1', char_3='char_3', char_4='char_4', date_field=datetime.datetime.now() ) try: apphook_pool.register(Example1App) except AppAlreadyRegistered: pass self.reload_urls() create_page('apphook', 'simple.html', 'en', published=True, apphook=Example1App) url = '%s/%s/?%s' % (self.live_server_url, 'apphook/detail/%s' % ex1.pk, get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON')) self.driver.get(url) username_input = self.driver.find_element_by_id("id_cms-username") username_input.send_keys(getattr(self.user, User.USERNAME_FIELD)) password_input = self.driver.find_element_by_id("id_cms-password") password_input.send_keys("what") password_input.submit() self.wait_page_loaded() self.assertTrue(self.driver.find_element_by_class_name('cms-error'))
def get_placeholder_content(context, request, current_page, name, inherit, default): edit_mode = getattr(request, 'toolbar', None) and getattr(request.toolbar, 'edit_mode') pages = [current_page] # don't display inherited plugins in edit mode, so that the user doesn't # mistakenly edit/delete them. This is a fix for issue #1303. See the discussion # there for possible enhancements if inherit and not edit_mode: pages = chain([current_page], list(reversed(current_page.get_cached_ancestors()))) for page in pages: placeholder = _get_placeholder(current_page, page, context, name) if placeholder is None: continue if not edit_mode and get_cms_setting('PLACEHOLDER_CACHE'): if hasattr(placeholder, 'content_cache'): return mark_safe(placeholder.content_cache) if not hasattr(placeholder, 'cache_checked'): cached_value = get_placeholder_cache(placeholder, get_language()) if cached_value is not None: restore_sekizai_context(context, cached_value['sekizai']) return mark_safe(cached_value['content']) if not get_plugins(request, placeholder, page.get_template()): continue content = render_placeholder(placeholder, context, name) if content: return content # if we reach this point, we have an empty or non-existant placeholder # call _get_placeholder again to get the placeholder properly rendered # in frontend editing placeholder = _get_placeholder(current_page, current_page, context, name) return render_placeholder(placeholder, context, name, default=default)
def test_placeholder_pk_thousands_format(self): page = create_page("page", "nav_playground.html", "en", published=True) for placeholder in page.placeholders.all(): page.placeholders.remove(placeholder) placeholder.pk += 1000 placeholder.save() page.placeholders.add(placeholder) page.reload() for placeholder in page.placeholders.all(): add_plugin(placeholder, "TextPlugin", "en", body="body", id=placeholder.pk) with SettingsOverride(USE_THOUSAND_SEPARATOR=True, USE_L10N=True): # Superuser user = self.get_superuser() self.client.login(username=getattr(user, get_user_model().USERNAME_FIELD), password=getattr(user, get_user_model().USERNAME_FIELD)) response = self.client.get("/en/?%s" % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON')) for placeholder in page.placeholders.all(): self.assertContains( response, "'placeholder_id': '%s'" % placeholder.pk) self.assertNotContains( response, "'placeholder_id': '%s'" % format( placeholder.pk, ".", grouping=3, thousand_sep=",")) self.assertNotContains( response, "'plugin_id': '%s'" % format( placeholder.pk, ".", grouping=3, thousand_sep=",")) self.assertNotContains( response, "'clipboard': '%s'" % format( response.context['request'].toolbar.clipboard.pk, ".", grouping=3, thousand_sep=","))
def _get_cache_key(name, page_lookup, lang, site_id): if isinstance(page_lookup, Page): page_key = str(page_lookup.pk) else: page_key = str(page_lookup) page_key = _clean_key(page_key) return get_cms_setting('CACHE_PREFIX') + name + '__page_lookup:' + page_key + '_site:' + str(site_id) + '_lang:' + str(lang)
def get_value(self, context, page_lookup, lang, site): from django.core.cache import cache site_id = get_site_id(site) request = context.get('request', False) if not request: return '' if lang is None: lang = get_language_from_request(request) cache_key = _get_cache_key('page_url', page_lookup, lang, site_id) + \ '_type:absolute_url' url = cache.get(cache_key) if not url: page = _get_page_by_untyped_arg(page_lookup, request, site_id) if page: url = page.get_absolute_url(language=lang) cache.set(cache_key, url, get_cms_setting('CACHE_DURATIONS')['content']) if url: return url return ''
def __init__(self, *args, **kwargs): super(PageAddForm, self).__init__(*args, **kwargs) self.fields['parent'].widget = HiddenInput() self.fields['site'].widget = HiddenInput() if not self.fields['site'].initial: self.fields['site'].initial = Site.objects.get_current().pk site_id = self.fields['site'].initial languages = get_language_tuple(site_id) self.fields['language'].choices = languages if not self.fields['language'].initial: self.fields['language'].initial = get_language() if (self.fields['parent'].initial and get_cms_setting('TEMPLATE_INHERITANCE') in [name for name, value in get_cms_setting('TEMPLATES')]): # non-root pages default to inheriting their template self.fields['template'].initial = constants.TEMPLATE_INHERITANCE_MAGIC
def _get_placeholder(current_page, page, context, name): placeholder_cache = getattr(current_page, '_tmp_placeholders_cache', {}) if page.pk in placeholder_cache: placeholder = placeholder_cache[page.pk].get(name, None) if placeholder: return placeholder placeholder_cache[page.pk] = {} placeholders = page.rescan_placeholders().values() fetch_placeholders = [] request = context['request'] if not get_cms_setting('PLACEHOLDER_CACHE') or (hasattr(request, 'toolbar') and request.toolbar.edit_mode): fetch_placeholders = placeholders else: for placeholder in placeholders: cached_value = get_placeholder_cache(placeholder, get_language()) if cached_value is not None: restore_sekizai_context(context, cached_value['sekizai']) placeholder.content_cache = cached_value['content'] else: fetch_placeholders.append(placeholder) placeholder.cache_checked = True if fetch_placeholders: assign_plugins(context['request'], fetch_placeholders, page.get_template(), get_language()) for placeholder in placeholders: placeholder_cache[page.pk][placeholder.slot] = placeholder placeholder.page = page current_page._tmp_placeholders_cache = placeholder_cache placeholder = placeholder_cache[page.pk].get(name, None) if page.application_urls and not placeholder: raise PlaceholderNotFound( '"%s" placeholder not found in an apphook application. Please use a static placeholder instead.' % name) return placeholder
def modify(self, request, nodes, namespace, root_id, post_cut, breadcrumb): # only apply this modifier if we're pre-cut (since what we do is cut) if post_cut or not get_cms_setting('SOFTROOT'): return nodes selected = None root_nodes = [] # find the selected node as well as all the root nodes for node in nodes: if node.selected: selected = node if not node.parent: root_nodes.append(node) # if we found a selected ... if selected: # and the selected is a softroot if selected.attr.get("soft_root", False): # get it's descendants nodes = selected.get_descendants() # remove the link to parent selected.parent = None # make the selected page the root in the menu nodes = [selected] + nodes else: # if it's not a soft root, walk ancestors (upwards!) nodes = self.find_ancestors_and_remove_children(selected, nodes) return nodes
def get_request_ip_resolver(): """ This is the recommended method for obtaining the specified CMS_REQUEST_IP_RESOLVER as it also does some basic import validation. Returns the resolver or raises an ImproperlyConfigured exception. """ module, attribute = get_cms_setting('REQUEST_IP_RESOLVER').rsplit('.', 1) try: ip_resolver_module = importlib.import_module(module) ip_resolver = getattr(ip_resolver_module, attribute) except ImportError: raise ImproperlyConfigured( _('Unable to find the specified CMS_REQUEST_IP_RESOLVER module: ' '"{0}".').format(module)) except AttributeError: raise ImproperlyConfigured( _('Unable to find the specified CMS_REQUEST_IP_RESOLVER function: ' '"{0}" in module "{1}".').format(attribute, module)) return ip_resolver
def _has_global_permission(user, site, action): if not user.is_authenticated: return False if user.is_superuser: return True codename = get_model_permission_codename(GlobalPagePermission, action=action) if not user.has_perm(codename): return False if not get_cms_setting('PERMISSION'): return True has_perm = GlobalPagePermission.objects.get_with_change_permissions( user, site.pk).exists() return has_perm
def _send_email(request, action, recipients, subject, template): page = request.page edit_on = get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON') page_url = page.get_absolute_url(request.language) + '?' + edit_on author_name = request.get_first_action().get_by_user_name() if action.to_user_id: moderator_name = action.get_to_user_name() elif action.to_role_id: moderator_name = action.to_role.name else: moderator_name = '' site = page.node.site admin_url = reverse( 'admin:djangocms_moderation_pagemoderationrequest_change', args=(request.pk, )) context = { 'page': page, 'page_url': get_absolute_url(page_url, site), 'author_name': author_name, 'by_user_name': action.get_by_user_name(), 'moderator_name': moderator_name, 'job_id': request.pk, 'comment': request.get_last_action().message, 'admin_url': get_absolute_url(admin_url, site), } template = 'djangocms_moderation/emails/moderation-request/{}'.format( template) with force_language(request.language): subject = force_text(subject) content = render_to_string(template, context) message = EmailMessage( subject=subject, body=content, from_email=settings.DEFAULT_FROM_EMAIL, to=recipients, ) return message.send()
def user_can_view_page(user, page): if user.is_superuser: return True public_for = get_cms_setting('PUBLIC_FOR') can_see_unrestricted = public_for == 'all' or (public_for == 'staff' and user.is_staff) page = get_page_draft(page) # inherited and direct view permissions is_restricted = page.has_view_restrictions() if not is_restricted and can_see_unrestricted: # Page has no restrictions and project is configured # to allow everyone to see unrestricted pages. return True elif not user.is_authenticated(): # Page has restrictions or project is configured # to require staff user status to see pages. return False if user_can_view_all_pages(user, site=page.site): return True if not is_restricted: # Page has no restrictions but user can't see unrestricted pages return False if user_can_change_page(user, page): # If user has change permissions on a page # then he can automatically view it. return True has_perm = has_generic_permission( page=page, user=user, action='view_page', check_global=False, ) return has_perm
def set_placeholder_cache(placeholder, lang, site_id, content, request): """ Sets the (correct) placeholder cache with the rendered placeholder. """ from django.core.cache import cache key = _get_placeholder_cache_key(placeholder, lang, site_id, request) duration = min( get_cms_setting('CACHE_DURATIONS')['content'], placeholder.get_cache_expiration(request, now())) cache.set(key, content, duration) # "touch" the cache-version, so that it stays as fresh as this content. version, vary_on_list = _get_placeholder_cache_version( placeholder, lang, site_id) _set_placeholder_cache_version(placeholder, lang, site_id, version, vary_on_list, duration=duration)
def get_template(self): """ get the template of this page if defined or if closer parent if defined or DEFAULT_PAGE_TEMPLATE otherwise """ if hasattr(self, '_template_cache'): return self._template_cache template = None if self.template: if self.template != constants.TEMPLATE_INHERITANCE_MAGIC: template = self.template else: try: template = self.get_ancestors(ascending=True).exclude( template=constants.TEMPLATE_INHERITANCE_MAGIC).values_list('template', flat=True)[0] except IndexError: pass if not template: template = get_cms_setting('TEMPLATES')[0][0] self._template_cache = template return template
def register(self, toolbar): import warnings if toolbar.__module__.split('.')[-1] == 'cms_toolbar': warnings.warn( 'cms_toolbar.py filename is deprecated, ' 'and it will be removed in version 3.4; ' 'please rename it to cms_toolbars.py', DeprecationWarning) if not self.force_register and get_cms_setting('TOOLBARS'): return toolbar from cms.toolbar_base import CMSToolbar # validate the app if not issubclass(toolbar, CMSToolbar): raise ImproperlyConfigured( 'CMS Toolbar must inherit ' 'cms.toolbar_base.CMSToolbar, %r does not' % toolbar) name = "%s.%s" % (toolbar.__module__, toolbar.__name__) if name in self.toolbars.keys(): raise ToolbarAlreadyRegistered( "[%s] a toolbar with this name is already registered" % name) self.toolbars[name] = toolbar return toolbar
def render_plugin(context, instance, placeholder, template, processors=None, current_app=None): """ Renders a single plugin and applies the post processors to it's rendered content. """ if not processors: processors = [] if isinstance(template, basestring): content = render_to_string(template, context_instance=context) elif isinstance(template, Template): content = template.render(context) else: content = '' for processor in iterload_objects(get_cms_setting('PLUGIN_PROCESSORS')): content = processor(instance, placeholder, content, context) for processor in processors: content = processor(instance, placeholder, content, context) for processor in DEFAULT_PLUGIN_PROCESSORS: content = processor(instance, placeholder, content, context) return content
def load_view_restrictions(request, pages): """ Load all view restrictions for the pages and update the cache in the request The request cache will receive values for all the pages, but the returned dict will only have keys where restrictions actually exist """ restricted_pages = defaultdict(list) if get_cms_setting('PERMISSION'): if hasattr(request, '_cms_view_perms'): cache = request._cms_view_perms # TODO: Check if we have anything that requires checking else: cache = request._cms_view_perms = {} pages_list = load_ancestors(pages) pages_by_id = {} for page in pages_list: page_id = page.pk if page.publisher_is_draft else page.publisher_public_id pages_by_id[page_id] = page cache[page_id] = [] page_permissions = PagePermission.objects.filter( page__in=pages_by_id, can_view=True).select_related('group__pageusergroup') for perm in page_permissions: perm_page = pages_by_id[perm.page_id] # add the page itself if perm.grant_on & MASK_PAGE: restricted_pages[perm_page.pk].append(perm) # add children if perm.grant_on & MASK_CHILDREN: children = perm_page.get_children() for child in children: restricted_pages[child.pk].append(perm) # add descendants elif perm.grant_on & MASK_DESCENDANTS: descendants = perm_page.get_cached_descendants() for child in descendants: restricted_pages[child.pk].append(perm) # Overwrite cache where we found restrictions cache.update(restricted_pages) return restricted_pages
def render_plugin(context, instance, placeholder, template, processors=None, current_app=None): """ Renders a single plugin and applies the post processors to it's rendered content. """ request = context.get('request') if request: toolbar = getattr(request, 'toolbar', None) if current_app: request.current_app = current_app else: toolbar = None if toolbar and isinstance(template, six.string_types): template = toolbar.get_cached_template(template) if not processors: processors = [] if isinstance(template, six.string_types): content = render_to_string(template, flatten_context(context)) elif (isinstance(template, Template) or (hasattr(template, 'template') and hasattr(template, 'render') and isinstance(template.template, Template))): content = template.render(context) else: content = '' for processor in iterload_objects(get_cms_setting('PLUGIN_PROCESSORS')): content = processor(instance, placeholder, content, context) for processor in processors: content = processor(instance, placeholder, content, context) for processor in DEFAULT_PLUGIN_PROCESSORS: content = processor(instance, placeholder, content, context) return content
def get_view_restrictions(pages): """ Load all view restrictions for the pages """ restricted_pages = defaultdict(list) if not get_cms_setting('PERMISSION'): # Permissions are off. There's no concept of page restrictions. return restricted_pages if not pages: return restricted_pages nodes = [page.node for page in pages] pages_by_id = {} for page in pages: if page.node.is_root(): page.node._set_hierarchy(nodes) page.node.__dict__['item'] = page pages_by_id[page.pk] = page page_permissions = PagePermission.objects.filter( page__in=pages_by_id, can_view=True, ) for perm in page_permissions: # set internal fk cache to our page with loaded ancestors and descendants if DJANGO_1_11: perm._page_cache = pages_by_id[perm.page_id] else: # for django >= 2.0 PagePermission.page.field.set_cached_value( perm, pages_by_id[perm.page_id]) for page_id in perm.get_page_ids(): restricted_pages[page_id].append(perm) return restricted_pages
def test_cms_page_toolbar_pages_link_doesnt_filter_the_page_list_by_page_id(self): """ The PageToolbar "Pages" link sends a parameter "page_id=X" which filters the page admin changelist. This is not desired behaviour for this package, the page_id for the standard cms is designed to allow the page tree to show a tree from a page i.e. expand any children below it. The page admin for this package does not use a page tree so this functionality breaks the admin changelist by only showing the page with the matching id. The PageAdmin page list should not be affected by the page_id parameter. """ template_1 = get_cms_setting('TEMPLATES')[0][0] pages = PageContentWithVersionFactory.create_batch(6, template=template_1, language="en") base_url = self.get_admin_url(PageContent, "changelist") simulated_toolbar_pages_link = "/en/admin/cms/pagecontent/?language=en&page_id=1" with self.login_user_context(self.get_superuser()): # Default changelist link response = self.client.get(base_url) # Toolbar pages link simulation response_with_page_id = self.client.get(simulated_toolbar_pages_link) self.assertSetEqual(set(response.context["cl"].queryset), set(pages)) self.assertSetEqual(set(response_with_page_id.context["cl"].queryset), set(pages))
def _get_placeholder_cache_version_key(placeholder, lang, site_id): """ Returns the version key for the given «placeholder», «lang» and «site_id». Invalidating this (via clear_placeholder_cache by replacing the stored value with a new value) will effectively make all "sub-caches" relating to this (placeholder x lang) inaccessible. Sub-caches include caches per TZ and per VARY header. """ prefix = get_cms_setting('CACHE_PREFIX') key = '{prefix}|placeholder_cache_version|id:{id}|lang:{lang}|site:{site}'.format( prefix=prefix, id=placeholder.pk, lang=str(lang), site=site_id, ) if len(key) > 250: key = '{prefix}|{hash}'.format( prefix=prefix, hash=hashlib.sha1(key.encode('utf-8')).hexdigest(), ) return key
def check_i18n(output): with output.section("Internationalization") as section: if isinstance(getattr(settings, 'CMS_LANGUAGES', {}), dict): section.success("New style CMS_LANGUAGES") else: section.warn("Old style (tuple based) CMS_LANGUAGES, please switch to the new (dictionary based) style") if getattr(settings, 'LANGUAGE_CODE', '').find('_') > -1: section.warn("LANGUAGE_CODE must contain a valid language code, not a locale (e.g.: 'en-us' instead of " "'en_US'): '%s' provided" % getattr(settings, 'LANGUAGE_CODE', '')) for lang in getattr(settings, 'LANGUAGES', ()): if lang[0].find('_') > -1: section.warn("LANGUAGES must contain valid language codes, not locales (e.g.: 'en-us' instead of " "'en_US'): '%s' provided" % lang[0]) if settings.SITE_ID == hash(settings.SITE_ID): for site, items in get_cms_setting('LANGUAGES').items(): if type(site) == int: for lang in items: if lang['code'].find('_') > -1: section.warn("CMS_LANGUAGES entries must contain valid language codes, not locales (e.g.: " "'en-us' instead of 'en_US'): '%s' provided" % lang['code']) else: section.error("SITE_ID must be an integer, not %r" % settings.SITE_ID)
def render_plugin(self, instance, context, placeholder=None, editable=False): if not placeholder: placeholder = instance.placeholder instance, plugin = instance.get_plugin_instance() if not instance or not plugin.render_plugin: return '' # we'd better pass a flat dict to template.render # as plugin.render can return pretty much any kind of context / dictionary # we'd better flatten it and force to a Context object # flattening the context means that template must be an engine-specific template object # which is guaranteed by get_cached_template if the template returned by # plugin._get_render_template is either a string or an engine-specific template object context = PluginContext(context, instance, placeholder) context = plugin.render(context, instance, placeholder.slot) context = flatten_context(context) template = plugin._get_render_template(context, instance, placeholder) template = self.templates.get_cached_template(template) content = template.render(context) for processor in iterload_objects( get_cms_setting('PLUGIN_PROCESSORS')): content = processor(instance, placeholder, content, context) if editable: content = self.plugin_edit_template.format(pk=instance.pk, content=content) placeholder_cache = self._rendered_plugins_by_placeholder.setdefault( placeholder.pk, {}) placeholder_cache.setdefault('plugins', []).append(instance) return mark_safe(content)
def get_user_permission_level(user, site): """ Returns highest user level from the page/permission hierarchy on which user haves can_change_permission. Also takes look into user groups. Higher level equals to lower number. Users on top of hierarchy have level 0. Level is the same like page.depth attribute. Example: A,W level 0 / \ user B,GroupE level 1 / \ C,X D,Y,W level 2 Users A, W have user level 0. GroupE and all his users have user level 1 If user D is a member of GroupE, his user level will be 1, otherwise is 2. """ if not user.is_authenticated: raise NoPermissionsException if user.is_superuser or not get_cms_setting('PERMISSION'): return ROOT_USER_LEVEL has_global_perms = ( GlobalPagePermission.objects.get_with_change_permissions( user, site.pk).exists()) if has_global_perms: return ROOT_USER_LEVEL try: permission = (PagePermission.objects.get_with_change_permissions( user, site).select_related('page').order_by('page__node__path'))[0] except IndexError: # user isn't assigned to any node raise NoPermissionsException return permission.page.node.depth
def _login(self): url = '%s/?%s' % (self.live_server_url, get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON')) self.driver.get(url) self.assertRaises(NoSuchElementException, self.driver.find_element_by_class_name, 'cms_toolbar-item_logout') username_input = self.driver.find_element_by_id("id_cms-username") username_input.send_keys( getattr(self.user, get_user_model().USERNAME_FIELD)) password_input = self.driver.find_element_by_id("id_cms-password") password_input.send_keys( getattr(self.user, get_user_model().USERNAME_FIELD)) password_input.submit() self.wait_page_loaded() self.assertTrue( self.driver.find_element_by_class_name( 'cms_toolbar-item-navigation'))
def test_redirect_with_toolbar(self): create_page("one", "nav_playground.html", "en", published=True, redirect='/en/page2') superuser = self.get_superuser() with self.login_user_context(superuser): response = self.client.get('/en/?%s' % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON')) self.assertEqual(response.status_code, 200) self.assertContains(response, 'This page has no preview') self.client.get('/en/?%s' % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON')) response = self.client.get('/en/?%s' % get_cms_setting('CMS_TOOLBAR_URL__EDIT_OFF')) self.assertEqual(response.status_code, 302) self.client.get('/en/?%s' % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON')) response = self.client.get('/en/?%s' % get_cms_setting('TOOLBAR_URL__BUILD')) self.assertEqual(response.status_code, 200) self.assertContains(response, 'This page has no preview') self.client.get('/en/?%s' % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON')) response = self.client.get('/en/?%s' % get_cms_setting('TOOLBAR_URL__DISABLE')) self.assertEqual(response.status_code, 302)
def setUp(self): super(CmsPluginsFilerBaseTestCase, self).setUp() # cms related self.template = get_cms_setting('TEMPLATES')[0][0] self.language = settings.LANGUAGES[0][0] self.root_page = self.create_root_page() page = api.create_page( title='Plugins test en', template=self.template, language='en', published=True, parent=self.root_page, ) page.publish('en') self.page = page.reload() self.placeholder = self.page.placeholders.all()[0] # filer related, taken from django- test cases setUp logic self.image = self.create_test_image() self.image_name = 'test_file.jpg' self.filename = os.path.join(settings.FILE_UPLOAD_TEMP_DIR, self.image_name) self.image.save(self.filename, 'JPEG')
def render_plugin(context, instance, placeholder, template, processors=None, current_app=None): """ Renders a single plugin and applies the post processors to it's rendered content. """ if current_app: context['request'].current_app = current_app if not processors: processors = [] if isinstance(template, six.string_types): content = render_to_string(template, context) elif (isinstance(template, Template) or (hasattr(template, 'template') and hasattr(template, 'render') and isinstance(template.template, Template))): content = template.render(context) else: content = '' for processor in iterload_objects(get_cms_setting('PLUGIN_PROCESSORS')): content = processor(instance, placeholder, content, context) for processor in processors: content = processor(instance, placeholder, content, context) for processor in DEFAULT_PLUGIN_PROCESSORS: content = processor(instance, placeholder, content, context) return content
def setUp(self): self.template = get_cms_setting('TEMPLATES')[0][0] self.language = settings.LANGUAGES[0][0] self.root_page = api.create_page( 'root page', self.template, self.language, published=True) self.app_config = NewsBlogConfig.objects.create( namespace='NBNS', paginate_by=15) self.page = api.create_page( 'page', self.template, self.language, published=True, parent=self.root_page, apphook='NewsBlogApp', apphook_namespace=self.app_config.namespace) self.plugin_page = api.create_page( title="plugin_page", template=self.template, language=self.language, parent=self.root_page, published=True) self.placeholder = self.page.placeholders.all()[0] self.setup_categories() for page in self.root_page, self.page: for language, _ in settings.LANGUAGES[1:]: api.create_title(language, page.get_slug(), page) page.publish(language)
def cms_settings(request): """ Adds cms-related variables to the context. """ from menus.menu_pool import MenuRenderer @lru_cache(maxsize=None) def _get_menu_renderer(): # We use lru_cache to avoid getting the manager # every time this function is called. from menus.menu_pool import menu_pool return menu_pool.get_renderer(request) # Now use lazy() to avoid getting the menu renderer # up until the point is needed. # lazy() does not memoize results, is why lru_cache is needed. _get_menu_renderer = lazy(_get_menu_renderer, MenuRenderer) return { 'cms_menu_renderer': _get_menu_renderer(), 'CMS_MEDIA_URL': get_cms_setting('MEDIA_URL'), 'CMS_TEMPLATE': lambda: get_page_template_from_request(request), }
def _get_placeholder(current_page, page, context, name): from django.core.cache import cache placeholder_cache = getattr(current_page, '_tmp_placeholders_cache', {}) if page.pk in placeholder_cache: placeholder = placeholder_cache[page.pk].get(name, None) if placeholder: return placeholder placeholder_cache[page.pk] = {} placeholders = page.rescan_placeholders().values() fetch_placeholders = [] request = context['request'] if not get_cms_setting('PLACEHOLDER_CACHE') or (hasattr( request, 'toolbar') and request.toolbar.edit_mode): fetch_placeholders = placeholders else: for placeholder in placeholders: cache_key = placeholder.get_cache_key(get_language()) cached_value = cache.get(cache_key) if not cached_value is None: restore_sekizai_context(context, cached_value['sekizai']) placeholder.content_cache = cached_value['content'] else: fetch_placeholders.append(placeholder) placeholder.cache_checked = True if fetch_placeholders: assign_plugins(context['request'], fetch_placeholders, page.get_template(), get_language()) for placeholder in placeholders: placeholder_cache[page.pk][placeholder.slot] = placeholder placeholder.page = page current_page._tmp_placeholders_cache = placeholder_cache placeholder = placeholder_cache[page.pk].get(name, None) if page.application_urls and not placeholder: raise PlaceholderNotFound( '"%s" placeholder not found in an apphook application. Please use a static placeholder instead.' % name) return placeholder
def test_cache_invalidation(self): # Ensure that we're testing in an environment WITHOUT the MW cache... exclude = [ 'django.middleware.cache.UpdateCacheMiddleware', 'django.middleware.cache.FetchFromCacheMiddleware' ] overrides = dict() if getattr(settings, 'MIDDLEWARE', None): overrides['MIDDLEWARE'] = [ mw for mw in settings.MIDDLEWARE if mw not in exclude ] else: overrides['MIDDLEWARE_CLASSES'] = [ mw for mw in settings.MIDDLEWARE_CLASSES if mw not in exclude ] with self.settings(**overrides): # Silly to do these tests if this setting isn't True page_cache_setting = get_cms_setting('PAGE_CACHE') self.assertTrue(page_cache_setting) page1 = create_page('test page 1', 'nav_playground.html', 'en', published=True) page1_url = page1.get_absolute_url() placeholder = page1.placeholders.get(slot="body") add_plugin(placeholder, "TextPlugin", 'en', body="First content") page1.publish('en') response = self.client.get(page1_url) self.assertContains(response, 'First content') response = self.client.get(page1_url) self.assertContains(response, 'First content') add_plugin(placeholder, "TextPlugin", 'en', body="Second content") page1.publish('en') response = self.client.get(page1_url) self.assertContains(response, 'Second content')
def get_page_request(self, page, user, path=None, edit=False, lang='en', use_middlewares=False, secure=False): """ Create a GET request for the given page suitable for use the django CMS toolbar This method requires django CMS installed to work. It will raise an ImportError otherwise; not a big deal as this method makes sense only in a django CMS environment :param page: current page object :param user: current user :param path: path (if different from the current page path) :param edit: whether enabling editing mode :param lang: request language :param use_middlewares: pass the request through configured middlewares. :param secure: create HTTPS request :return: request """ from cms.utils.conf import get_cms_setting edit_on = get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON') path = path or page and page.get_absolute_url(lang) if edit: path = '{0}?{1}'.format(path, edit_on) request = self.request_factory.get(path, secure=secure) return self._prepare_request(request, page, user, lang, use_middlewares, use_toolbar=True, secure=secure)
def test_hide_untranslated(self): TESTLANG = get_primary_language() TESTLANG2 = get_secondary_language() page = create_page("mlpage-%s" % TESTLANG, "nav_playground.html", TESTLANG) create_title(TESTLANG2, "mlpage-%s" % TESTLANG2, page, slug=page.get_slug()) page.publish(TESTLANG) page.publish(TESTLANG2) page2 = create_page("mlpage-2-%s" % TESTLANG, "nav_playground.html", TESTLANG, parent=page) page2.publish(TESTLANG) lang_settings = copy.deepcopy(get_cms_setting('LANGUAGES')) request_1 = self.get_request('/%s/' % TESTLANG, TESTLANG) request_2 = self.get_request('/%s/' % TESTLANG2, TESTLANG2) request_1_menu_renderer = menu_pool.get_renderer(request_1) request_2_menu_renderer = menu_pool.get_renderer(request_2) lang_settings[1][1]['hide_untranslated'] = False with self.settings(CMS_LANGUAGES=lang_settings): request_1_nodes = request_1_menu_renderer.get_menu('CMSMenu').get_nodes(request_1) request_2_nodes = request_2_menu_renderer.get_menu('CMSMenu').get_nodes(request_2) list_1 = [node.id for node in request_1_nodes] list_2 = [node.id for node in request_2_nodes] self.assertEqual(list_1, list_2) self.assertEqual(len(list_1), 2) lang_settings[1][1]['hide_untranslated'] = True with self.settings(CMS_LANGUAGES=lang_settings): request_1_nodes = request_1_menu_renderer.get_menu('CMSMenu').get_nodes(request_1) request_2_nodes = request_2_menu_renderer.get_menu('CMSMenu').get_nodes(request_2) list_1 = [node.id for node in request_1_nodes] list_2 = [node.id for node in request_2_nodes] self.assertNotEqual(list_1, list_2) self.assertEqual(len(list_2), 1) self.assertEqual(len(list_1), 2)
def test_placeholder_pk_thousands_format(self): page = create_page("page", "nav_playground.html", "en", published=True) for placeholder in page.placeholders.all(): page.placeholders.remove(placeholder) placeholder.pk += 1000 placeholder.save() page.placeholders.add(placeholder) page.reload() for placeholder in page.placeholders.all(): add_plugin(placeholder, "TextPlugin", "en", body="body") with self.settings(USE_THOUSAND_SEPARATOR=True, USE_L10N=True): # Superuser user = self.get_superuser() self.client.login( username=getattr(user, get_user_model().USERNAME_FIELD), password=getattr(user, get_user_model().USERNAME_FIELD)) endpoint = page.get_absolute_url() + '?' + get_cms_setting( 'CMS_TOOLBAR_URL__EDIT_ON') response = self.client.get(endpoint) for placeholder in page.placeholders.all(): self.assertContains(response, '"placeholder_id": "%s"' % placeholder.pk) self.assertNotContains( response, '"placeholder_id": "%s"' % format(placeholder.pk, ".", grouping=3, thousand_sep=",")) self.assertNotContains( response, '"plugin_id": "%s"' % format(placeholder.pk, ".", grouping=3, thousand_sep=",")) self.assertNotContains( response, '"clipboard": "%s"' % format(response.context['request'].toolbar.clipboard.pk, ".", grouping=3, thousand_sep=","))
def _get_page_ids_for_action(user, site, action, check_global=True, use_cache=True): if user.is_superuser or not get_cms_setting('PERMISSION'): # got superuser, or permissions aren't enabled? # just return grant all mark return GRANT_ALL_PERMISSIONS if check_global and has_global_permission(user, site, action=action, use_cache=use_cache): return GRANT_ALL_PERMISSIONS if use_cache: # read from cache if possible cached = get_permission_cache(user, action) get_page_actions = get_page_actions_for_user else: cached = None get_page_actions = get_page_actions_for_user.without_cache if cached is not None: return cached page_actions = get_page_actions(user, site) page_ids = list(page_actions[action]) set_permission_cache(user, action, page_ids) return page_ids
def get_placeholder_content(context, request, current_page, name, inherit, default): edit_mode = getattr(request, 'toolbar', None) and getattr( request.toolbar, 'edit_mode') pages = [current_page] # don't display inherited plugins in edit mode, so that the user doesn't # mistakenly edit/delete them. This is a fix for issue #1303. See the discussion # there for possible enhancements if inherit and not edit_mode: pages = chain([current_page], list(reversed(current_page.get_cached_ancestors()))) for page in pages: placeholder = _get_placeholder(current_page, page, context, name) if placeholder is None: continue if not edit_mode and get_cms_setting('PLACEHOLDER_CACHE'): if hasattr(placeholder, 'content_cache'): return mark_safe(placeholder.content_cache) if not hasattr(placeholder, 'cache_checked'): site_id = get_site_id(getattr(page, 'site_id', None)) cached_value = get_placeholder_cache(placeholder, get_language(), site_id, request) if cached_value is not None: restore_sekizai_context(context, cached_value['sekizai']) return mark_safe(cached_value['content']) if not get_plugins(request, placeholder, page.get_template()): continue content = render_placeholder(placeholder, context, name) if content: return content # if we reach this point, we have an empty or non-existant placeholder # call _get_placeholder again to get the placeholder properly rendered # in frontend editing placeholder = _get_placeholder(current_page, current_page, context, name) return render_placeholder(placeholder, context, name, default=default)
def render_placeholder(placeholder, context_to_copy, name_fallback="Placeholder", lang=None, default=None): """ Renders plugins for a placeholder on the given page using shallow copies of the given context, and returns a string containing the rendered output. """ if not placeholder: return from cms.utils.plugins import get_plugins context = context_to_copy context.push() request = context['request'] if not hasattr(request, 'placeholder'): request.placeholders = [] request.placeholders.append(placeholder) if hasattr(placeholder, 'content_cache'): return mark_safe(placeholder.content_cache) page = placeholder.page if placeholder else None # It's kind of duplicate of the similar call in `get_plugins`, but it's required # to have a valid language in this function for `get_fallback_languages` to work if lang: save_language = lang else: lang = get_language_from_request(request) save_language = lang # Prepend frontedit toolbar output if applicable edit = False toolbar = getattr(request, 'toolbar', None) if getattr(toolbar, 'edit_mode', False): edit = True if edit: from cms.middleware.toolbar import toolbar_plugin_processor processors = (toolbar_plugin_processor, ) else: processors = None from django.core.cache import cache if get_cms_setting('PLACEHOLDER_CACHE'): cache_key = placeholder.get_cache_key(lang) if not edit and placeholder and not hasattr(placeholder, 'cache_checked'): cached_value = cache.get(cache_key) if not cached_value is None: restore_sekizai_context(context, cached_value['sekizai']) return mark_safe(cached_value['content']) if page: template = page.template else: template = None plugins = [ plugin for plugin in get_plugins(request, placeholder, template, lang=lang) ] # Add extra context as defined in settings, but do not overwrite existing context variables, # since settings are general and database/template are specific # TODO this should actually happen as a plugin context processor, but these currently overwrite # existing context -- maybe change this order? slot = getattr(placeholder, 'slot', None) extra_context = {} if slot: extra_context = get_placeholder_conf("extra_context", slot, template, {}) for key, value in extra_context.items(): if key not in context: context[key] = value content = [] watcher = Watcher(context) content.extend(render_plugins(plugins, context, placeholder, processors)) toolbar_content = '' if edit: if not hasattr(request.toolbar, 'placeholders'): request.toolbar.placeholders = {} if placeholder.pk not in request.toolbar.placeholders: request.toolbar.placeholders[placeholder.pk] = placeholder if edit: toolbar_content = mark_safe( render_placeholder_toolbar(placeholder, context, name_fallback, save_language)) if content: content = mark_safe("".join(content)) elif default: #should be nodelist from a template content = mark_safe(default.render(context_to_copy)) else: content = '' context['content'] = content context['placeholder'] = toolbar_content context['edit'] = edit result = render_to_string("cms/toolbar/content.html", context) changes = watcher.get_changes() if placeholder and not edit and placeholder.cache_placeholder and get_cms_setting( 'PLACEHOLDER_CACHE'): cache.set(cache_key, { 'content': result, 'sekizai': changes }, get_cms_setting('CACHE_DURATIONS')['content']) context.pop() return result