def test_default_language_changer_with_public_page(self): """ The DefaultLanguageChanger should not try to resolve the url for unpublished languages. """ cms_page = create_page('en-page', 'nav_playground.html', 'en', published=True) for language in get_language_list(site_id=1): if language != 'en': create_title(language, '%s-page' % language, cms_page) cms_page.publish(language) else: cms_page.unpublish('pt-br') cms_page.unpublish('es-mx') request = self.get_request( path=cms_page.get_absolute_url(), language='en', page=cms_page.publisher_public, ) urls_expected = [ '/en/en-page/', '/de/de-page/', '/fr/fr-page/', '/en/en-page/', # the pt-br url is en because that's a fallback '/en/en-page/', # the es-mx url is en because that's a fallback ] urls_found = [ DefaultLanguageChanger(request)(code) for code in get_language_list(site_id=1) ] self.assertSequenceEqual(urls_expected, urls_found)
def get_language_from_request(request, current_page=None): """ Return the most obvious language according the request """ language = request.REQUEST.get('language', None) site_id = current_page.site_id if current_page else None if language: if not language in get_language_list(site_id): language = None if language is None: language = getattr(request, 'LANGUAGE_CODE', None) if language: if not language in get_language_list(site_id): language = None if language is None and current_page: # in last resort, get the first language available in the page languages = current_page.get_languages() if len(languages) > 0: language = languages[0] if language is None: # language must be defined in CMS_LANGUAGES, so check first if there # is any language with LANGUAGE_CODE, otherwise try to split it and find # best match language = get_default_language(site_id=site_id) return language
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(): try: title = page.get_title_obj(to_lang, fallback=False) except Title.DoesNotExist: 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.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)) self.stdout.write(u"all done")
def _create_blog(self, options): default_language = get_default_language() languages = get_language_list() activate(default_language) try: blog_page = Page.objects.get( application_namespace=APP_NAMESPACE, publisher_is_draft=True, site=self.site, ) except Page.DoesNotExist: self.stdout.write("Create new blog AppHook page.") blog_page = create_page( title=_("blog"), template=options["template"], language=settings.LANGUAGE_CODE, apphook=BLOG_APP_HOOK, apphook_namespace=APP_NAMESPACE, in_navigation=True, ) else: self.stdout.write("Use existing blog AppHook page.") placeholder, created = Placeholder.objects.get_or_create(slot=PLACEHOLDER_SLOT) if created: self.stdout.write("New placeholder for blog page created.") placeholder.save() else: self.stdout.write("Use existing placeholder for blog page.") for language in languages: activate(language) if language != default_language: if Title.objects.filter(language=language, page=blog_page).exists(): self.stdout.write("Use existing title in %r" % language) else: self.stdout.write("Create title in %r" % language) create_title(language=language, title=_("blog"), page=blog_page) for plugin_type in PLUGIN_TYPES: queryset = CMSPlugin.objects.filter( placeholder=placeholder, plugin_type=plugin_type, language=language ) if queryset.exists(): self.stdout.write("Use existing plugin %r in %r" % (plugin_type, language)) else: self.stdout.write("Create plugin %r in %r" % (plugin_type, language)) add_plugin(placeholder, plugin_type, language=language) # self.stdout.write("publish placeholder in language: %r" % language) # placeholder.publish(request=None, language=language, force=True) self.stdout.write("publish blog page in language: %r" % language) blog_page.publish(language)
def get_context(self, context, template, i18n_mode): if template in MARKERS: _tmp = template if i18n_mode not in MARKERS: template = i18n_mode else: template = NOT_PROVIDED i18n_mode = _tmp if template is NOT_PROVIDED: template = "menu/language_chooser.html" if not i18n_mode in MARKERS: i18n_mode = 'raw' if 'request' not in context: # If there's an exception (500), default context_processors may not be called. return {'template': 'cms/content.html'} marker = MARKERS[i18n_mode] current_lang = get_language() site = Site.objects.get_current() request = context['request'] if request.user.is_staff: languages = get_language_list(site_id=site.pk) else: languages = get_public_languages(site_id=site.pk) languages_info = [] for language in languages: obj = get_language_object(language, site_id=site.pk) languages_info.append((obj['code'], marker(obj['name'], obj['code']))) context['languages'] = languages_info context['current_language'] = current_lang context['template'] = template return context
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 applications_page_check(request, current_page=None, path=None): """Tries to find if given path was resolved over application. Applications have higher priority than other cms pages. """ if current_page: return current_page if path is None: # We should get in this branch only if an apphook is active on / # This removes the non-CMS part of the URL. path = request.path.replace(reverse('pages-root'), '', 1) # check if application resolver can resolve this for lang in get_language_list(): if path.startswith(lang + "/"): path = path[len(lang + "/"):] for resolver in APP_RESOLVERS: try: page_id = resolver.resolve_page_id(path) # yes, it is application page page = Page.objects.public().get(id=page_id) # If current page was matched, then we have some override for content # from cms, but keep current page. Otherwise return page to which was application assigned. return page except Resolver404: # Raised if the page is not managed by an apphook pass return None
class CMSRequestBasedMixin(object): languages = get_language_list() @classmethod def setUpClass(cls): super(CMSRequestBasedMixin, cls).setUpClass() cls.request_factory = RequestFactory() cls.site1 = Site.objects.get(pk=1) @staticmethod def get_request(language=None, url="/", post_data=None): """ Returns a Request instance populated with cms specific attributes. User is not set. """ request_factory = RequestFactory(HTTP_HOST=settings.ALLOWED_HOSTS[0]) if post_data is None: request = request_factory.get(url) else: request = request_factory.post(url, post_data) request.LANGUAGE_CODE = language or settings.LANGUAGE_CODE # Needed for plugin rendering. request.current_page = None # session and messages setattr(request, 'session', 'session') messages = FallbackStorage(request) setattr(request, '_messages', messages) return request def get_su_request(self, *args, **kwargs): request = self.get_request(*args, **kwargs) request.user = self.super_user return request
def copy_language(self, request, object_id): target_language = request.POST.get('target_language') # CAVEAT: Avoiding self.get_object because it sets the page cache, # We don't want a draft showing to a regular site visitor! # source_page_content = self.get_object(request, object_id=object_id) source_page_content = PageContent._original_manager.get(pk=object_id) if source_page_content is None: raise self._get_404_exception(object_id) page = source_page_content.page if not target_language or target_language not in get_language_list(site_id=page.node.site_id): return HttpResponseBadRequest(force_str(_("Language must be set to a supported language!"))) target_page_content = get_latest_admin_viewable_page_content(page, target_language) # First check that we are able to edit the target if not self.has_change_permission(request, obj=target_page_content): raise PermissionDenied for placeholder in source_page_content.get_placeholders(): # Try and get a matching placeholder, only if it exists try: target = target_page_content.get_placeholders().get(slot=placeholder.slot) except ObjectDoesNotExist: continue plugins = placeholder.get_plugins_list(source_page_content.language) if not target.has_add_plugins_permission(request.user, plugins): return HttpResponseForbidden(force_str(_('You do not have permission to copy these plugins.'))) copy_plugins_to_placeholder(plugins, target, language=target_language) return HttpResponse("ok")
def forwards(apps, schema_editor): BlogConfig = apps.get_model("djangocms_blog", "BlogConfig") BlogConfigTranslation = apps.get_model("djangocms_blog", "BlogConfigTranslation") Post = apps.get_model("djangocms_blog", "Post") BlogCategory = apps.get_model("djangocms_blog", "BlogCategory") GenericBlogPlugin = apps.get_model("djangocms_blog", "GenericBlogPlugin") LatestPostsPlugin = apps.get_model("djangocms_blog", "LatestPostsPlugin") AuthorEntriesPlugin = apps.get_model("djangocms_blog", "AuthorEntriesPlugin") config = None for page in Page.objects.drafts().filter(application_urls="BlogApp"): config, created = BlogConfig.objects.get_or_create( namespace=page.application_namespace) if not BlogConfigTranslation.objects.exists(): for lang in get_language_list(): title = page.get_title(lang) translation = BlogConfigTranslation.objects.create( language_code=lang, master_id=config.pk, app_title=title) if config: for model in (Post, BlogCategory, GenericBlogPlugin, LatestPostsPlugin, AuthorEntriesPlugin): for item in model.objects.filter(app_config__isnull=True): item.app_config = config item.save()
def applications_page_check(request, current_page=None, path=None): """Tries to find if given path was resolved over application. Applications have higher priority than other cms pages. """ if current_page: return current_page if path is None: # We should get in this branch only if an apphook is active on / # This removes the non-CMS part of the URL. path = request.path_info.replace(reverse('pages-root'), '', 1) # check if application resolver can resolve this for lang in get_language_list(): if path.startswith(lang + "/"): path = path[len(lang + "/"):] use_public = not use_draft(request) for resolver in APP_RESOLVERS: try: page_id = resolver.resolve_page_id(path) # yes, it is application page page = Page.objects.public().get(id=page_id) # If current page was matched, then we have some override for # content from cms, but keep current page. Otherwise return page # to which was application assigned. return page if use_public else page.publisher_public except Resolver404: # Raised if the page is not managed by an apphook pass except Page.DoesNotExist: pass return None
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(): try: title = page.get_title_obj(to_lang, fallback=False) except Title.DoesNotExist: 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.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)) self.stdout.write(u"all done")
class CMSRequestBasedTest(CleanUpMixin, TestCase): """Sets-up User(s) and CMS Pages for testing.""" languages = get_language_list() @classmethod def setUpClass(cls): cls.request_factory = RequestFactory() cls.user = create_user('normal', '*****@*****.**', 'normal') cls.site1 = Site.objects.get(pk=1) @classmethod def tearDownClass(cls): User.objects.all().delete() def get_or_create_page(self, base_title=None, languages=None): """Creates a page with a given title, or, if it already exists, just retrieves and returns it.""" from cms.api import create_page, create_title if not base_title: # No title? Create one. base_title = self.rand_str(prefix="page", length=8) if not languages: # If no langs supplied, use'em all languages = self.languages # If there is already a page with this title, just return it. try: page_title = Title.objects.get(title=base_title) return page_title.page.get_draft_object() except: pass # No? Okay, create one. page = create_page(base_title, 'fullwidth.html', language=languages[0]) # If there are multiple languages, create the translations if len(languages) > 1: for lang in languages[1:]: title_lang = "{0}-{1}".format(base_title, lang) create_title(language=lang, title=title_lang, page=page) page.publish(lang) return page.get_draft_object() def get_page_request( self, page, user, path=None, edit=False, lang_code='en'): from cms.middleware.toolbar import ToolbarMiddleware path = path or page and page.get_absolute_url() if edit: path += '?edit' request = RequestFactory().get(path) request.session = {} request.user = user request.LANGUAGE_CODE = lang_code if edit: request.GET = {'edit': None} else: request.GET = {'edit_off': None} request.current_page = page mid = ToolbarMiddleware() mid.process_request(request) return request
def lookups(self, request, model_admin): """ Returns a list of tuples. The first element in each tuple is the coded value for the option that will appear in the URL query. The second element is the human-readable name for the option that will appear in the right sidebar. """ return ((item, item) for item in get_language_list())
def create_title(article, language, title, slug=None, description=None, page_title=None, menu_title=None, meta_description=None, creation_date=None, image=None): """ Create an article title. """ # validate article assert isinstance(article, Article) # validate language: assert language in get_language_list(article.tree.node.site_id) # validate creation date if creation_date: assert isinstance(creation_date, datetime.date) # set default slug: if not slug: slug = settings.CMS_ARTICLES_SLUG_FORMAT.format( now=creation_date or now(), slug=slugify(title), ) # find unused slug: base_slug = slug qs = Title.objects.filter(language=language) used_slugs = list(s for s in qs.values_list('slug', flat=True) if s.startswith(base_slug)) i = 1 while slug in used_slugs: slug = '%s-%s' % (base_slug, i) i += 1 # create title title = Title.objects.create( article=article, language=language, title=title, slug=slug, description=description, page_title=page_title, menu_title=menu_title, meta_description=meta_description, image=image, ) return title
def create_title(language, title, page, menu_title=None, slug=None, redirect=None, meta_description=None, parent=None, overwrite_url=None, page_title=None, path=None): """ Create a title. Parent is only used if slug=None. See docs/extending_cms/api_reference.rst for more info """ # validate page assert isinstance(page, Page) # validate language: assert language in get_language_list(page.node.site_id) # set default slug: if not slug: base = page.get_path_for_slug(slugify(title), language) slug = get_available_slug(page.node.site, base, language) if overwrite_url: path = overwrite_url.strip('/') elif path is None: path = page.get_path_for_slug(slug, language) title = Title.objects.create( language=language, title=title, menu_title=menu_title, page_title=page_title, slug=slug, path=path, redirect=redirect, meta_description=meta_description, page=page, has_url_overwrite=bool(overwrite_url), ) page_languages = page.get_languages() if language not in page_languages: page.update_languages(page_languages + [language]) return title
def create_title(language, title, page, menu_title=None, slug=None, apphook=None, redirect=None, meta_description=None, meta_keywords=None, parent=None, overwrite_url=None): """ Create a title. Parent is only used if slug=None. See docs/extending_cms/api_reference.rst for more info """ # validate page assert isinstance(page, Page) # validate language: assert language in get_language_list(page.site_id) # set default slug: if not slug: slug = _generate_valid_slug(title, parent, language) # validate and normalize apphook if apphook: application_urls = _verify_apphook(apphook) else: application_urls = None title = Title.objects.create(language=language, title=title, menu_title=menu_title, slug=slug, application_urls=application_urls, redirect=redirect, meta_description=meta_description, meta_keywords=meta_keywords, page=page) if overwrite_url: title.has_url_overwrite = True title.path = overwrite_url title.save() return title
def copy_plugins(self, request): """ POST request should have the following data: - cms_path - source_language - source_placeholder_id - source_plugin_id (optional) - target_language - target_placeholder_id - target_plugin_id (deprecated/unused) """ source_placeholder_id = request.POST['source_placeholder_id'] target_language = request.POST['target_language'] target_placeholder_id = request.POST['target_placeholder_id'] 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!"))) copy_to_clipboard = target_placeholder.pk == request.toolbar.clipboard.pk source_plugin_id = request.POST.get('source_plugin_id', None) if copy_to_clipboard and source_plugin_id: new_plugin = self._copy_plugin_to_clipboard( request, source_placeholder, target_placeholder, ) new_plugins = [new_plugin] elif copy_to_clipboard: new_plugin = self._copy_placeholder_to_clipboard( request, source_placeholder, target_placeholder, ) new_plugins = [new_plugin] else: new_plugins = self._add_plugins_from_placeholder( request, source_placeholder, target_placeholder, ) data = get_plugin_tree_as_json(request, new_plugins) return HttpResponse(data, content_type='application/json')
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 create_title(language, title, page, menu_title=None, slug=None, redirect=None, meta_description=None, parent=None, overwrite_url=None, with_revision=False): """ Create a title. Parent is only used if slug=None. See docs/extending_cms/api_reference.rst for more info """ # validate page assert isinstance(page, Page) # validate language: assert language in get_language_list(page.site_id) if with_revision: # fail fast if revision is requested # but not enabled on the project. _verify_revision_support() # set default slug: if not slug: slug = generate_valid_slug(title, parent, language) title = Title.objects.create(language=language, title=title, menu_title=menu_title, slug=slug, redirect=redirect, meta_description=meta_description, page=page) if overwrite_url: title.has_url_overwrite = True title.path = overwrite_url title.save() if with_revision: _create_revision(obj=page) return title
def create_title(language, title, page, menu_title=None, slug=None, apphook=None, redirect=None, meta_description=None, meta_keywords=None, parent=None, overwrite_url=None): """ Create a title. Parent is only used if slug=None. See docs/extending_cms/api_reference.rst for more info """ # validate page assert isinstance(page, Page) # validate language: assert language in get_language_list(page.site_id) # set default slug: if not slug: slug = _generate_valid_slug(title, parent, language) # validate and normalize apphook if apphook: application_urls = _verify_apphook(apphook) else: application_urls = None title = Title.objects.create( language=language, title=title, menu_title=menu_title, slug=slug, application_urls=application_urls, redirect=redirect, meta_description=meta_description, meta_keywords=meta_keywords, page=page ) if overwrite_url: title.has_url_overwrite = True title.path = overwrite_url title.save() return title
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 create_title(language, title, page, menu_title=None, slug=None, redirect=None, meta_description=None, parent=None, overwrite_url=None, with_revision=None): """ Create a title. Parent is only used if slug=None. See docs/extending_cms/api_reference.rst for more info """ # validate page assert isinstance(page, Page) # validate language: assert language in get_language_list(page.site_id) if with_revision in (True, False): _raise_revision_warning() # set default slug: if not slug: slug = generate_valid_slug(title, parent, language) title = Title.objects.create(language=language, title=title, menu_title=menu_title, slug=slug, redirect=redirect, meta_description=meta_description, page=page) if overwrite_url: title.has_url_overwrite = True title.path = overwrite_url title.save() return title
def create_title(language, title, page, menu_title=None, slug=None, redirect=None, meta_description=None, parent=None, overwrite_url=None, with_revision=False): """ Create a title. Parent is only used if slug=None. See docs/extending_cms/api_reference.rst for more info """ # validate page assert isinstance(page, Page) # validate language: assert language in get_language_list(page.site_id) if with_revision: # fail fast if revision is requested # but not enabled on the project. _verify_revision_support() # set default slug: if not slug: slug = generate_valid_slug(title, parent, language) title = Title.objects.create( language=language, title=title, menu_title=menu_title, slug=slug, redirect=redirect, meta_description=meta_description, page=page ) if overwrite_url: title.has_url_overwrite = True title.path = overwrite_url title.save() if with_revision: _create_revision(obj=page) return title
def forwards(self, orm): BlogConfig = orm['djangocms_blog.BlogConfig'] BlogConfigTranslation = orm['djangocms_blog.BlogConfigTranslation'] Post = orm['djangocms_blog.Post'] BlogCategory = orm['djangocms_blog.BlogCategory'] GenericBlogPlugin = orm['djangocms_blog.GenericBlogPlugin'] LatestPostsPlugin = orm['djangocms_blog.LatestPostsPlugin'] AuthorEntriesPlugin = orm['djangocms_blog.AuthorEntriesPlugin'] config = None for page in Page.objects.drafts().filter(application_urls='BlogApp'): config = BlogConfig.objects.create(namespace=page.application_namespace) for lang in get_language_list(): title = page.get_title(lang) translation = BlogConfigTranslation.objects.create(language_code=lang, master_id=config.pk, app_title=title) if config: for model in (Post, BlogCategory, GenericBlogPlugin, LatestPostsPlugin, AuthorEntriesPlugin): for item in model.objects.all(): item.app_config = config item.save()
def forwards(apps, schema_editor): BlogConfig = apps.get_model('djangocms_blog', 'BlogConfig') BlogConfigTranslation = apps.get_model('djangocms_blog', 'BlogConfigTranslation') Post = apps.get_model('djangocms_blog', 'Post') BlogCategory = apps.get_model('djangocms_blog', 'BlogCategory') GenericBlogPlugin = apps.get_model('djangocms_blog', 'GenericBlogPlugin') LatestPostsPlugin = apps.get_model('djangocms_blog', 'LatestPostsPlugin') AuthorEntriesPlugin = apps.get_model('djangocms_blog', 'AuthorEntriesPlugin') config = None for page in Page.objects.drafts().filter(application_urls='BlogApp'): config = BlogConfig.objects.create(namespace=page.application_namespace) for lang in get_language_list(): title = page.get_title(lang) translation = BlogConfigTranslation.objects.create(language_code=lang, master_id=config.pk, app_title=title) if config: for model in (Post, BlogCategory, GenericBlogPlugin, LatestPostsPlugin, AuthorEntriesPlugin): for item in model.objects.all(): item.app_config = config item.save()
def clean(self): from cms.utils.plugins import has_reached_plugin_limit data = self.cleaned_data if self.errors: return data language = data['plugin_language'] placeholder = data['placeholder_id'] parent_plugin = data.get('plugin_parent') if language not in get_language_list(): message = ugettext("Language must be set to a supported language!") self.add_error('plugin_language', message) return self.cleaned_data if parent_plugin: if parent_plugin.language != language: message = ugettext("Parent plugin language must be same as language!") self.add_error('plugin_language', message) return self.cleaned_data if parent_plugin.placeholder_id != placeholder.pk: message = ugettext("Parent plugin placeholder must be same as placeholder!") self.add_error('placeholder_id', message) return self.cleaned_data if placeholder.page: template = placeholder.page.get_template() else: template = None try: has_reached_plugin_limit( placeholder, self.plugin_type, language, template=template ) except PluginLimitReached as error: self.add_error(None, force_text(error)) return self.cleaned_data
def clean(self): from cms.utils.plugins import has_reached_plugin_limit data = self.cleaned_data if self.errors: return data language = data['plugin_language'] placeholder = data['placeholder_id'] parent_plugin = data.get('plugin_parent') if language not in get_language_list(): message = ugettext("Language must be set to a supported language!") self.add_error('plugin_language', message) return self.cleaned_data if parent_plugin: if parent_plugin.language != language: message = ugettext( "Parent plugin language must be same as language!") self.add_error('plugin_language', message) return self.cleaned_data if parent_plugin.placeholder_id != placeholder.pk: message = ugettext( "Parent plugin placeholder must be same as placeholder!") self.add_error('placeholder_id', message) return self.cleaned_data if placeholder.page: template = placeholder.page.get_template() else: template = None try: has_reached_plugin_limit(placeholder, data['plugin_type'], language, template=template) except PluginLimitReached as error: self.add_error(None, force_text(error)) return self.cleaned_data
def create_title(language, title, page, menu_title=None, slug=None, redirect=None, meta_description=None, parent=None, overwrite_url=None, with_revision=None): """ Create a title. Parent is only used if slug=None. See docs/extending_cms/api_reference.rst for more info """ # validate page assert isinstance(page, Page) # validate language: assert language in get_language_list(page.site_id) if with_revision in (True, False): _raise_revision_warning() # set default slug: if not slug: slug = generate_valid_slug(title, parent, language) title = Title.objects.create( language=language, title=title, menu_title=menu_title, slug=slug, redirect=redirect, meta_description=meta_description, page=page ) if overwrite_url: title.has_url_overwrite = True title.path = overwrite_url title.save() return title
def forwards(apps, schema_editor): BlogConfig = apps.get_model('djangocms_blog', 'BlogConfig') BlogConfigTranslation = apps.get_model('djangocms_blog', 'BlogConfigTranslation') Post = apps.get_model('djangocms_blog', 'Post') BlogCategory = apps.get_model('djangocms_blog', 'BlogCategory') GenericBlogPlugin = apps.get_model('djangocms_blog', 'GenericBlogPlugin') LatestPostsPlugin = apps.get_model('djangocms_blog', 'LatestPostsPlugin') AuthorEntriesPlugin = apps.get_model('djangocms_blog', 'AuthorEntriesPlugin') config = None for page in Page.objects.drafts().filter(application_urls='BlogApp'): config = BlogConfig.objects.create( namespace=page.application_namespace) for lang in get_language_list(): title = page.get_title(lang) translation = BlogConfigTranslation.objects.create( language_code=lang, master_id=config.pk, app_title=title) if config: for model in (Post, BlogCategory, GenericBlogPlugin, LatestPostsPlugin, AuthorEntriesPlugin): for item in model.objects.all(): item.app_config = config item.save()
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")
def clean_language(self): language = self.cleaned_data['language'] if not language in get_language_list(): raise ValidationError("Given language does not match language settings.") return language
def populate(self): # always use draft if we have a page self.page = get_page_draft(self.request.current_page) if not self.page: # Nothing to do return # check global permissions if CMS_PERMISSIONS is active if get_cms_setting('PERMISSION'): if not has_page_change_permission: has_global_current_page_change_permission = has_page_permission( self.request.user, self.request.current_page, 'change') else: has_global_current_page_change_permission = has_page_change_permission( self.request) else: has_global_current_page_change_permission = False # check if user has page edit permission if not has_page_change_permission: can_change = (self.request.current_page and self.request.current_page.has_change_permission( self.request.user)) else: can_change = (self.request.current_page and self.request.current_page.has_change_permission( self.request)) if has_global_current_page_change_permission or can_change: not_edit_mode = not self.toolbar.edit_mode current_page_menu = self.toolbar.get_or_create_menu('page') super_item = current_page_menu.find_first( Break, identifier=PAGE_MENU_SECOND_BREAK) + 1 meta_menu = current_page_menu.get_or_create_menu( 'pagemeta', PAGE_META_MENU_TITLE, position=super_item) position = 0 # Page tags try: page_extension = PageMeta.objects.get( extended_object_id=self.page.pk) except PageMeta.DoesNotExist: page_extension = None try: if page_extension: url = reverse('admin:djangocms_page_meta_pagemeta_change', args=(page_extension.pk, )) else: url = '%s?extended_object=%s' % ( reverse('admin:djangocms_page_meta_pagemeta_add'), self.page.pk) except NoReverseMatch: # not in urls pass else: meta_menu.add_modal_item(PAGE_META_ITEM_TITLE, url=url, disabled=not_edit_mode, position=position) # Title tags for title in self.page.title_set.filter( language__in=get_language_list(self.page.site_id)): try: title_extension = TitleMeta.objects.get( extended_object_id=title.pk) except TitleMeta.DoesNotExist: title_extension = None try: if title_extension: url = reverse( 'admin:djangocms_page_meta_titlemeta_change', args=(title_extension.pk, )) else: url = '%s?extended_object=%s' % ( reverse('admin:djangocms_page_meta_titlemeta_add'), title.pk) except NoReverseMatch: # not in urls pass else: position += 1 language = get_language_object(title.language) meta_menu.add_modal_item(language['name'], url=url, disabled=not_edit_mode, position=position)
class BaseTest(TestCase): """ Base class with utility function """ request_factory = None user = None languages = get_language_list() category_1 = None thumb_1 = None thumb_2 = None data = { 'it': [ { 'title': u'Primo post', 'abstract': u'<p>prima riga</p>', 'description': u'Questa è la descrizione', 'keywords': u'keyword1, keyword2', 'text': u'Testo del post', }, { 'title': u'Secondo post', 'abstract': u'<p>prima riga del secondo post</p>', 'description': u'Descrizione del secondo post', 'keywords': u'keyword3, keyword4', 'text': u'Testo del secondo post' }, ], 'en': [{ 'title': u'First post', 'abstract': u'<p>first line</p>', 'description': u'This is the description', 'keywords': u'keyword1, keyword2', 'text': u'Post text' }, { 'title': u'Second post', 'abstract': u'<p>second post first line</p>', 'description': u'Second post description', 'keywords': u'keyword3, keyword4', 'text': u'Second post text' }] } @classmethod def setUpClass(cls): cls.request_factory = RequestFactory() cls.user = create_user('admin', '*****@*****.**', 'admin', is_staff=True, is_superuser=True) cls.user_staff = create_user('staff', '*****@*****.**', 'staff', is_staff=True) cls.user_normal = create_user('normal', '*****@*****.**', 'normal') def setUp(self): activate('en') super(BaseTest, self).setUp() self.category_1 = BlogCategory.objects.create() self.category_1.name = u'category 1' self.category_1.save() self.category_1.set_current_language('it') self.category_1.name = u'categoria 1' self.category_1.save() self.category_1.set_current_language('en') self.thumb_1 = ThumbnailOption.objects.create(name='base', width=100, height=100, crop=True, upscale=False) self.thumb_2 = ThumbnailOption.objects.create(name='main', width=200, height=200, crop=False, upscale=False) img = create_image() self.image_name = 'test_file.jpg' self.filename = os.path.join(settings.FILE_UPLOAD_TEMP_DIR, self.image_name) img.save(self.filename, 'JPEG') file_obj = DjangoFile(open(self.filename, 'rb'), name=self.image_name) self.img = Image.objects.create(owner=self.user, original_filename=self.image_name, file=file_obj) def _get_post(self, data, post=None, lang='en'): if not post: post = Post() post.set_current_language(lang) post.author = self.user post.title = data['title'] post.abstract = data['abstract'] post.meta_description = data['description'] post.meta_keywords = data['keywords'] post.save() post.categories.add(self.category_1) post.save() return post @classmethod def tearDownClass(cls): User.objects.all().delete() def tearDown(self): os.remove(self.filename) for f in File.objects.all(): f.delete() def get_pages(self): from cms.api import create_page, create_title page = create_page(u'page one', 'fullwidth.html', language='en') page_2 = create_page(u'page two', 'fullwidth.html', language='en') create_title(language='fr', title=u'page un', page=page) create_title(language='it', title=u'pagina uno', page=page) for lang in self.languages: page.publish(lang) page_2.publish('en') return page.get_draft_object(), page_2.get_draft_object() def get_request(self, page, lang): request = self.request_factory.get(page.get_path(lang)) request.current_page = page request.user = self.user request.session = {} request.cookies = SimpleCookie() request.errors = StringIO() return request def get_page_request(self, page, user, path=None, edit=False, lang_code='en'): from cms.middleware.toolbar import ToolbarMiddleware path = path or page and page.get_absolute_url() if edit: path += '?edit' request = RequestFactory().get(path) request.session = {} request.user = user request.LANGUAGE_CODE = lang_code if edit: request.GET = {'edit': None} else: request.GET = {'edit_off': None} request.current_page = page mid = ToolbarMiddleware() mid.process_request(request) return request def get_posts(self): post1 = self._get_post(self.data['en'][0]) post1 = self._get_post(self.data['it'][0], post1, 'it') post1.publish = True post1.main_image = self.img post1.save() post1.set_current_language('en') post2 = self._get_post(self.data['en'][1]) post2 = self._get_post(self.data['it'][1], post2, 'it') post2.set_current_language('en') post2.main_image = self.img return post1, post2
def create_page(title, template, language, menu_title=None, slug=None, apphook=None, apphook_namespace=None, redirect=None, meta_description=None, created_by='python-api', parent=None, publication_date=None, publication_end_date=None, in_navigation=False, soft_root=False, reverse_id=None, navigation_extenders=None, published=False, site=None, login_required=False, limit_visibility_in_menu=constants.VISIBILITY_ALL, position="last-child", overwrite_url=None, xframe_options=Page.X_FRAME_OPTIONS_INHERIT): """ Create a CMS Page and it's title for the given language See docs/extending_cms/api_reference.rst for more info """ # validate template if not template == TEMPLATE_INHERITANCE_MAGIC: assert template in [tpl[0] for tpl in get_cms_setting('TEMPLATES')] get_template(template) # validate site if not site: site = get_current_site() else: assert isinstance(site, Site) # validate language: assert language in get_language_list(site), get_cms_setting('LANGUAGES').get(site.pk) # validate parent if parent: assert isinstance(parent, Page) assert parent.publisher_is_draft # validate publication date if publication_date: assert isinstance(publication_date, datetime.date) # validate publication end date if publication_end_date: assert isinstance(publication_end_date, datetime.date) if navigation_extenders: raw_menus = menu_pool.get_menus_by_attribute("cms_enabled", True) menus = [menu[0] for menu in raw_menus] assert navigation_extenders in menus # validate menu visibility accepted_limitations = (constants.VISIBILITY_ALL, constants.VISIBILITY_USERS, constants.VISIBILITY_ANONYMOUS) assert limit_visibility_in_menu in accepted_limitations # validate position assert position in ('last-child', 'first-child', 'left', 'right') target_node = parent.node if parent else None # validate and normalize apphook if apphook: application_urls = _verify_apphook(apphook, apphook_namespace) else: application_urls = None # ugly permissions hack if created_by and isinstance(created_by, get_user_model()): _thread_locals.user = created_by created_by = getattr(created_by, get_user_model().USERNAME_FIELD) else: _thread_locals.user = None if reverse_id: if Page.objects.drafts().filter(reverse_id=reverse_id, node__site=site).exists(): raise FieldError('A page with the reverse_id="%s" already exist.' % reverse_id) page = Page( created_by=created_by, changed_by=created_by, publication_date=publication_date, publication_end_date=publication_end_date, in_navigation=in_navigation, soft_root=soft_root, reverse_id=reverse_id, navigation_extenders=navigation_extenders, template=template, application_urls=application_urls, application_namespace=apphook_namespace, login_required=login_required, limit_visibility_in_menu=limit_visibility_in_menu, xframe_options=xframe_options, ) page.set_tree_node(site=site, target=target_node, position=position) page.save() page.rescan_placeholders() create_title( language=language, title=title, menu_title=menu_title, slug=slug, redirect=redirect, meta_description=meta_description, page=page, overwrite_url=overwrite_url, ) if published: page.publish(language) if parent and position in ('last-child', 'first-child'): parent._clear_node_cache() del _thread_locals.user return page
class CMSRequestBasedTest(TestUtilityMixin, TransactionTestCase): """Sets-up User(s) and CMS Pages for testing.""" languages = get_language_list() @classmethod def setUpClass(cls): cls.request_factory = RequestFactory() if not User.objects.filter(username='******').count(): cls.user = create_user('normal', '*****@*****.**', 'normal') cls.site1 = Site.objects.get(pk=1) @classmethod def tearDownClass(cls): User.objects.all().delete() def setUp(self): super(CMSRequestBasedTest, self).setUp() 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 = ThingsConfig.objects.create(namespace='things', app_title='Things') self.page = api.create_page( 'Things', self.template, self.language, published=True, parent=self.root_page, apphook='ThingsApp', apphook_namespace=self.app_config.namespace) self.placeholder = self.page.placeholders.all()[0] self.request = self.get_request('en') 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) @staticmethod def get_request(language=None, url="/"): """ Returns a Request instance populated with cms specific attributes. """ request_factory = RequestFactory(HTTP_HOST=settings.ALLOWED_HOSTS[0]) request = request_factory.get(url) request.session = {} request.LANGUAGE_CODE = language or settings.LANGUAGE_CODE # Needed for plugin rendering. request.current_page = None request.user = AnonymousUser() return request def get_or_create_page(self, base_title=None, languages=None): """Creates a page with a given title, or, if it already exists, just retrieves and returns it.""" from cms.api import create_page, create_title if not base_title: # No title? Create one. base_title = self.rand_str(prefix="page", length=8) if not languages: # If no langs supplied, use'em all languages = self.languages # If there is already a page with this title, just return it. try: page_title = Title.objects.get(title=base_title) return page_title.page.get_draft_object() except: pass # No? Okay, create one. page = create_page(base_title, 'fullwidth.html', language=languages[0]) # If there are multiple languages, create the translations if len(languages) > 1: for lang in languages[1:]: title_lang = "{0}-{1}".format(base_title, lang) create_title(language=lang, title=title_lang, page=page) page.publish(lang) return page.get_draft_object() def get_page_request(self, page, user, path=None, edit=False, lang_code='en'): from cms.middleware.toolbar import ToolbarMiddleware path = path or page and page.get_absolute_url() if edit: path += '?edit' request = RequestFactory().get(path) request.session = {} request.user = user request.LANGUAGE_CODE = lang_code if edit: request.GET = {'edit': None} else: request.GET = {'edit_off': None} request.current_page = page mid = ToolbarMiddleware() mid.process_request(request) return request
def populate(self): # always use draft if we have a page self.page = get_page_draft(self.request.current_page) if not self.page: # Nothing to do return # check global permissions if CMS_PERMISSIONS is active if get_cms_setting("PERMISSION"): if not has_page_change_permission: has_global_current_page_change_permission = has_page_permission( self.request.user, self.request.current_page, "change" ) else: has_global_current_page_change_permission = has_page_change_permission(self.request) else: has_global_current_page_change_permission = False # check if user has page edit permission if not has_page_change_permission: can_change = self.request.current_page and self.request.current_page.has_change_permission( self.request.user ) else: can_change = self.request.current_page and self.request.current_page.has_change_permission(self.request) if has_global_current_page_change_permission or can_change: not_edit_mode = not self.toolbar.edit_mode current_page_menu = self.toolbar.get_or_create_menu("page") super_item = current_page_menu.find_first(Break, identifier=PAGE_MENU_SECOND_BREAK) + 1 meta_menu = current_page_menu.get_or_create_menu("pagemeta", PAGE_META_MENU_TITLE, position=super_item) position = 0 # Page tags try: page_extension = PageMeta.objects.get(extended_object_id=self.page.pk) except PageMeta.DoesNotExist: page_extension = None try: if page_extension: url = reverse("admin:djangocms_page_meta_pagemeta_change", args=(page_extension.pk,)) else: url = "%s?extended_object=%s" % (reverse("admin:djangocms_page_meta_pagemeta_add"), self.page.pk) except NoReverseMatch: # not in urls pass else: meta_menu.add_modal_item(PAGE_META_ITEM_TITLE, url=url, disabled=not_edit_mode, position=position) # Title tags for title in self.page.title_set.filter(language__in=get_language_list(self.page.site_id)): try: title_extension = TitleMeta.objects.get(extended_object_id=title.pk) except TitleMeta.DoesNotExist: title_extension = None try: if title_extension: url = reverse("admin:djangocms_page_meta_titlemeta_change", args=(title_extension.pk,)) else: url = "%s?extended_object=%s" % (reverse("admin:djangocms_page_meta_titlemeta_add"), title.pk) except NoReverseMatch: # not in urls pass else: position += 1 language = get_language_object(title.language) meta_menu.add_modal_item(language["name"], url=url, disabled=not_edit_mode, position=position)
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 populate(self): # always use draft if we have a page self.page = get_page_draft(self.request.current_page) if not self.page: # Nothing to do return # check global permissions if CMS_PERMISSIONS is active if get_cms_setting('PERMISSION'): has_global_current_page_change_permission = has_page_permission( self.request.user, self.request.current_page, 'change' ) else: has_global_current_page_change_permission = False # check if user has page edit permission has_change_permission = self.request.current_page.has_change_permission(self.request.user) can_change = (self.request.current_page and has_change_permission) if has_global_current_page_change_permission or can_change: try: not_edit_mode = not self.toolbar.edit_mode except AttributeError: not_edit_mode = not self.toolbar.edit_mode_active tags_menu = self.toolbar.get_or_create_menu('page') super_item = tags_menu.find_first(Break, identifier=PAGE_MENU_SECOND_BREAK) + 1 tags_menu = tags_menu.get_or_create_menu( 'pagetags', PAGE_TAGS_MENU_TITLE, position=super_item ) position = 0 # Page tags try: page_extension = PageTags.objects.get(extended_object_id=self.page.pk) except PageTags.DoesNotExist: page_extension = None try: if page_extension: url = reverse('admin:djangocms_page_tags_pagetags_change', args=(page_extension.pk,)) else: url = '%s?extended_object=%s' % ( reverse('admin:djangocms_page_tags_pagetags_add'), self.page.pk ) except NoReverseMatch: # pragma: no cover # not in urls pass else: tags_menu.add_modal_item(PAGE_TAGS_ITEM_TITLE, url=url, disabled=not_edit_mode, position=position) # Title tags try: site_id = self.page.node.site_id except AttributeError: # CMS_3_4 site_id = self.page.site_id for title in self.page.title_set.filter( language__in=get_language_list(site_id) ): try: title_extension = TitleTags.objects.get(extended_object_id=title.pk) except TitleTags.DoesNotExist: title_extension = None try: if title_extension: url = reverse('admin:djangocms_page_tags_titletags_change', args=(title_extension.pk,)) else: url = '%s?extended_object=%s' % ( reverse('admin:djangocms_page_tags_titletags_add'), title.pk) except NoReverseMatch: # pragma: no cover # not in urls pass else: position += 1 language = get_language_object(title.language) tags_menu.add_modal_item(language['name'], url=url, disabled=not_edit_mode, position=position)
def details(request, slug): """ The main view of the Django-CMS! Takes a request and a slug, renders the page. """ response_timestamp = now() if get_cms_setting("PAGE_CACHE") and ( not hasattr(request, 'toolbar') or ( not request.toolbar.edit_mode and not request.toolbar.show_toolbar and not request.user.is_authenticated() ) ): cache_content = get_page_cache(request) if cache_content is not None: content, headers, expires_datetime = cache_content response = HttpResponse(content) response._headers = headers # Recalculate the max-age header for this cached response max_age = int( (expires_datetime - response_timestamp).total_seconds() + 0.5) patch_cache_control(response, max_age=max_age) return response # Get a Page model object from the request page = get_page_from_request(request, use_path=slug) if not page: return _handle_no_page(request, slug) current_language = request.GET.get('language', None) if not current_language: current_language = request.POST.get('language', None) if current_language: current_language = get_language_code(current_language) if current_language not in get_language_list(page.site_id): current_language = None if current_language is None: current_language = get_language_code(getattr(request, 'LANGUAGE_CODE', None)) if current_language: current_language = get_language_code(current_language) if current_language not in get_language_list(page.site_id): current_language = None if current_language is None: current_language = get_language_code(get_language()) # Check that the current page is available in the desired (current) language available_languages = [] # this will return all languages in draft mode, and published only in live mode page_languages = list(page.get_published_languages()) if hasattr(request, 'user') and request.user.is_staff: user_languages = get_language_list() else: user_languages = get_public_languages() for frontend_lang in user_languages: if frontend_lang in page_languages: available_languages.append(frontend_lang) # Check that the language is in FRONTEND_LANGUAGES: own_urls = [ 'http%s://%s%s' % ('s' if request.is_secure() else '', request.get_host(), request.path), '/%s' % request.path, request.path, ] if current_language not in user_languages: #are we on root? if not slug: #redirect to supported language languages = [] for language in available_languages: languages.append((language, language)) if languages: # get supported language new_language = get_language_from_request(request) if new_language in get_public_languages(): with force_language(new_language): pages_root = reverse('pages-root') if (hasattr(request, 'toolbar') and request.user.is_staff and request.toolbar.edit_mode): request.toolbar.redirect_url = pages_root elif pages_root not in own_urls: return HttpResponseRedirect(pages_root) elif not hasattr(request, 'toolbar') or not request.toolbar.redirect_url: _handle_no_page(request, slug) else: return _handle_no_page(request, slug) if current_language not in available_languages: # If we didn't find the required page in the requested (current) # language, let's try to find a fallback found = False for alt_lang in get_fallback_languages(current_language): if alt_lang in available_languages: if get_redirect_on_fallback(current_language) or slug == "": with force_language(alt_lang): path = page.get_absolute_url(language=alt_lang, fallback=True) # In the case where the page is not available in the # preferred language, *redirect* to the fallback page. This # is a design decision (instead of rendering in place)). if (hasattr(request, 'toolbar') and request.user.is_staff and request.toolbar.edit_mode): request.toolbar.redirect_url = path elif path not in own_urls: return HttpResponseRedirect(path) else: found = True if not found and (not hasattr(request, 'toolbar') or not request.toolbar.redirect_url): # There is a page object we can't find a proper language to render it _handle_no_page(request, slug) if apphook_pool.get_apphooks(): # There are apphooks in the pool. Let's see if there is one for the # current page # since we always have a page at this point, applications_page_check is # pointless # page = applications_page_check(request, page, slug) # Check for apphooks! This time for real! app_urls = page.get_application_urls(current_language, False) skip_app = False if (not page.is_published(current_language) and hasattr(request, 'toolbar') and request.toolbar.edit_mode): skip_app = True if app_urls and not skip_app: app = apphook_pool.get_apphook(app_urls) pattern_list = [] if app: for urlpatterns in get_app_urls(app.get_urls(page, current_language)): pattern_list += urlpatterns try: view, args, kwargs = resolve('/', tuple(pattern_list)) return view(request, *args, **kwargs) except Resolver404: pass # Check if the page has a redirect url defined for this language. redirect_url = page.get_redirect(language=current_language) if redirect_url: if (is_language_prefix_patterns_used() and redirect_url[0] == "/" and not redirect_url.startswith('/%s/' % current_language)): # add language prefix to url redirect_url = "/%s/%s" % (current_language, redirect_url.lstrip("/")) # prevent redirect to self if hasattr(request, 'toolbar') and request.user.is_staff and request.toolbar.edit_mode: request.toolbar.redirect_url = redirect_url elif redirect_url not in own_urls: return HttpResponseRedirect(redirect_url) # permission checks if page.login_required and not request.user.is_authenticated(): return redirect_to_login(urlquote(request.get_full_path()), settings.LOGIN_URL) if hasattr(request, 'toolbar'): request.toolbar.set_object(page) response = render_page(request, page, current_language=current_language, slug=slug) return response
def article(request, slug): """ The main view of the Django-CMS Articles! Takes a request and a slug, renders the article. """ # Get current CMS Page as article tree tree = request.current_page # Check whether it really is a tree. # It could also be one of its sub-pages. if tree.application_urls != 'CMSArticlesApp': # In such case show regular CMS Page return page(request, slug) # Get an Article object from the request draft = use_draft(request) and request.user.has_perm( 'cms_articles.change_article') preview = 'preview' in request.GET and request.user.has_perm( 'cms_articles.change_article') site = tree.node.site article = get_article_from_slug(tree, slug, preview, draft) if not article: # raise 404 _handle_no_page(request) request.current_article = article if hasattr(request, 'user') and request.user.is_staff: user_languages = get_language_list(site_id=site.pk) else: user_languages = get_public_languages(site_id=site.pk) request_language = get_language_from_request(request, check_path=True) # get_published_languages will return all languages in draft mode # and published only in live mode. # These languages are then filtered out by the user allowed languages available_languages = [ language for language in user_languages if language in list(article.get_published_languages()) ] own_urls = [ request.build_absolute_uri(request.path), '/%s' % request.path, request.path, ] try: redirect_on_fallback = get_redirect_on_fallback(request_language, site_id=site.pk) except LanguageError: redirect_on_fallback = False if request_language not in user_languages: # Language is not allowed # Use the default site language default_language = get_default_language_for_site(site.pk) fallbacks = get_fallback_languages(default_language, site_id=site.pk) fallbacks = [default_language] + fallbacks else: fallbacks = get_fallback_languages(request_language, site_id=site.pk) # Only fallback to languages the user is allowed to see fallback_languages = [ language for language in fallbacks if language != request_language and language in available_languages ] language_is_unavailable = request_language not in available_languages if language_is_unavailable and not fallback_languages: # There is no page with the requested language # and there's no configured fallbacks return _handle_no_page(request) elif language_is_unavailable and redirect_on_fallback: # There is no page with the requested language and # the user has explicitly requested to redirect on fallbacks, # so redirect to the first configured / available fallback language fallback = fallback_languages[0] redirect_url = article.get_absolute_url(fallback, fallback=False) else: redirect_url = False if redirect_url: if request.user.is_staff and hasattr( request, 'toolbar') and request.toolbar.edit_mode_active: request.toolbar.redirect_url = redirect_url elif redirect_url not in own_urls: # prevent redirect to self return HttpResponseRedirect(redirect_url) # permission checks if article.login_required and not request.user.is_authenticated(): return redirect_to_login(urlquote(request.get_full_path()), settings.LOGIN_URL) if hasattr(request, 'toolbar'): request.toolbar.obj = article structure_requested = get_cms_setting( 'CMS_TOOLBAR_URL__BUILD') in request.GET if article.has_change_permission(request) and structure_requested: return render_object_structure(request, article) return render_article(request, article, current_language=request_language, slug=slug)
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.'))) 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) json_response = {'plugin_list': reduced_list, 'reload': reload_required} return HttpResponse(json.dumps(json_response), content_type='application/json')
def create_page(title, template, language, menu_title=None, slug=None, apphook=None, redirect=None, meta_description=None, meta_keywords=None, created_by='python-api', parent=None, publication_date=None, publication_end_date=None, in_navigation=False, soft_root=False, reverse_id=None, navigation_extenders=None, published=False, site=None, login_required=False, limit_visibility_in_menu=VISIBILITY_ALL, position="last-child", overwrite_url=None): """ Create a CMS Page and it's title for the given language See docs/extending_cms/api_reference.rst for more info """ # ugly permissions hack if created_by and isinstance(created_by, auth.get_user_model()): _thread_locals.user = created_by created_by = created_by.username else: _thread_locals.user = None # validate template assert template in [tpl[0] for tpl in get_cms_setting('TEMPLATES')] # validate site if not site: site = Site.objects.get_current() else: assert isinstance(site, Site) # validate language: assert language in get_language_list(site), get_cms_setting('LANGUAGES').get(site.pk) # set default slug: if not slug: slug = _generate_valid_slug(title, parent, language) # validate and normalize apphook if apphook: application_urls = _verify_apphook(apphook) else: application_urls = None # validate parent if parent: assert isinstance(parent, Page) parent = Page.objects.get(pk=parent.pk) # validate publication date if publication_date: assert isinstance(publication_date, datetime.date) # validate publication end date if publication_end_date: assert isinstance(publication_end_date, datetime.date) # validate softroot assert get_cms_setting('SOFTROOT') or not soft_root if navigation_extenders: raw_menus = menu_pool.get_menus_by_attribute("cms_enabled", True) menus = [menu[0] for menu in raw_menus] assert navigation_extenders in menus # validate menu visibility accepted_limitations = (VISIBILITY_ALL, VISIBILITY_USERS, VISIBILITY_STAFF) assert limit_visibility_in_menu in accepted_limitations # validate position assert position in ('last-child', 'first-child', 'left', 'right') page = Page( created_by=created_by, changed_by=created_by, parent=parent, publication_date=publication_date, publication_end_date=publication_end_date, in_navigation=in_navigation, soft_root=soft_root, reverse_id=reverse_id, navigation_extenders=navigation_extenders, published=False, # will be published later template=template, site=site, login_required=login_required, limit_visibility_in_menu=limit_visibility_in_menu, ) page.insert_at(parent, position) page.save() create_title( language=language, title=title, menu_title=menu_title, slug=slug, apphook=application_urls, redirect=redirect, meta_description=meta_description, meta_keywords=meta_keywords, page=page, overwrite_url=overwrite_url ) if published: page.publish() del _thread_locals.user return page.reload()
def details(request, slug): """ The main view of the Django-CMS! Takes a request and a slug, renders the page. """ # get the right model context = RequestContext(request) subdomain=request.META['HTTP_HOST'] if subdomain[:4]=='www.': subdomain=subdomain[4:] if (subdomain[-6:]=='com.ua' and subdomain.count('.')>=3) or (subdomain[-6:]!='com.ua' and subdomain.count('.')>=2): subdomain=subdomain[:subdomain.find('.')] else: subdomain='' main_domain=request.META['HTTP_HOST'] if subdomain!='': main_domain=main_domain[len(subdomain)+1:] if subdomain and subdomain!='etalon' and not subdomain.endswith('dev'): try: obl=Site.objects.get_current().obl.get(subdomain=subdomain) except: return HttpResponseRedirect('http://'+main_domain+request.get_full_path()) else: if request.location and request.location.custom_region: try: obl=Site.objects.get_current().obl.get(slug=request.location.custom_region.slug) return HttpResponseRedirect('http://'+request.location.custom_region.subdomain+'.'+main_domain+request.get_full_path()) except: pass # import logging # logging.info('dm='+request.META['HTTP_HOST']) # logging.info('sbd='+subdomain) # logging.info('mdm='+main_domain) # logging.info('loc='+location(request)['loc']) # # Get a Page model object from the request page = get_page_from_request(request, use_path=slug) if not page: return _handle_no_page(request, slug) current_language = get_language_from_request(request) # Check that the current page is available in the desired (current) language available_languages = [] page_languages = page.get_languages() user_languages = get_public_languages() if hasattr(request, 'user') and request.user.is_staff: user_languages = get_language_list() for frontend_lang in user_languages: if frontend_lang in page_languages: available_languages.append(frontend_lang) attrs = '' if 'edit' in request.GET: attrs = '?edit=1' elif 'preview' in request.GET: attrs = '?preview=1' if 'draft' in request.GET: attrs += '&draft=1' # Check that the language is in FRONTEND_LANGUAGES: if not current_language in user_languages: #are we on root? if not slug: #redirect to supported language languages = [] for language in available_languages: languages.append((language, language)) if languages: with SettingsOverride(LANGUAGES=languages, LANGUAGE_CODE=languages[0][0]): #get supported language new_language = get_language_from_request(request) if new_language in get_public_languages(): with force_language(new_language): pages_root = reverse('pages-root') return HttpResponseRedirect(pages_root + attrs) else: _handle_no_page(request, slug) else: return _handle_no_page(request, slug) if current_language not in available_languages: # If we didn't find the required page in the requested (current) # language, let's try to find a fallback found = False for alt_lang in get_fallback_languages(current_language): if alt_lang in available_languages: if get_redirect_on_fallback(current_language): with force_language(alt_lang): path = page.get_absolute_url(language=alt_lang, fallback=True) # In the case where the page is not available in the # preferred language, *redirect* to the fallback page. This # is a design decision (instead of rendering in place)). return HttpResponseRedirect(path + attrs) else: found = True if not found: # There is a page object we can't find a proper language to render it _handle_no_page(request, slug) if apphook_pool.get_apphooks(): # There are apphooks in the pool. Let's see if there is one for the # current page # since we always have a page at this point, applications_page_check is # pointless # page = applications_page_check(request, page, slug) # Check for apphooks! This time for real! try: app_urls = page.get_application_urls(current_language, False) except Title.DoesNotExist: app_urls = [] if app_urls: app = apphook_pool.get_apphook(app_urls) pattern_list = [] for urlpatterns in get_app_urls(app.urls): pattern_list += urlpatterns urlpatterns = patterns('', *pattern_list) try: context.current_app = page.reverse_id if page.reverse_id else app.app_name view, args, kwargs = resolve('/', tuple(urlpatterns)) return view(request, *args, **kwargs) except Resolver404: pass # Check if the page has a redirect url defined for this language. redirect_url = page.get_redirect(language=current_language) if redirect_url: if redirect_url.startswith('reverse_id:'): slug=cms_tags._get_page_by_untyped_arg(redirect_url.split(':')[1], request, Site.objects.get_current().id).get_absolute_url() return HttpResponsePermanentRedirect(slug) else: if (is_language_prefix_patterns_used() and redirect_url[0] == "/" and not redirect_url.startswith('/%s/' % current_language)): # add language prefix to url redirect_url = "/%s/%s" % (current_language, redirect_url.lstrip("/")) # prevent redirect to self own_urls = [ 'http%s://%s%s' % ('s' if request.is_secure() else '', request.get_host(), request.path), '/%s' % request.path, request.path, ] if redirect_url not in own_urls: return HttpResponsePermanentRedirect(redirect_url + attrs) # permission checks if page.login_required and not request.user.is_authenticated(): path = urlquote(request.get_full_path()) tup = settings.LOGIN_URL, "next", path return HttpResponseRedirect('%s?%s=%s' % tup) template_name = get_template_from_request(request, page, no_current_page=True) # fill the context context['lang'] = current_language context['current_page'] = page context['has_change_permissions'] = page.has_change_permission(request) context['has_view_permissions'] = page.has_view_permission(request) if not context['has_view_permissions']: return _handle_no_page(request, slug) return render_to_response(template_name, context_instance=context)
def create_page(title, template, language, menu_title=None, slug=None, apphook=None, redirect=None, meta_description=None, meta_keywords=None, created_by='python-api', parent=None, publication_date=None, publication_end_date=None, in_navigation=False, soft_root=False, reverse_id=None, navigation_extenders=None, published=False, site=None, login_required=False, limit_visibility_in_menu=VISIBILITY_ALL, position="last-child", overwrite_url=None): """ Create a CMS Page and it's title for the given language See docs/extending_cms/api_reference.rst for more info """ # ugly permissions hack if created_by and isinstance(created_by, User): _thread_locals.user = created_by created_by = created_by.username else: _thread_locals.user = None # validate template assert template in [tpl[0] for tpl in get_cms_setting('TEMPLATES')] # validate site if not site: site = Site.objects.get_current() else: assert isinstance(site, Site) # validate language: assert language in get_language_list(site), get_cms_setting( 'LANGUAGES').get(site.pk) # set default slug: if not slug: slug = _generate_valid_slug(title, parent, language) # validate and normalize apphook if apphook: application_urls = _verify_apphook(apphook) else: application_urls = None # validate parent if parent: assert isinstance(parent, Page) parent = Page.objects.get(pk=parent.pk) # validate publication date if publication_date: assert isinstance(publication_date, datetime.date) # validate publication end date if publication_end_date: assert isinstance(publication_end_date, datetime.date) # validate softroot assert get_cms_setting('SOFTROOT') or not soft_root if navigation_extenders: raw_menus = menu_pool.get_menus_by_attribute("cms_enabled", True) menus = [menu[0] for menu in raw_menus] assert navigation_extenders in menus # validate menu visibility accepted_limitations = (VISIBILITY_ALL, VISIBILITY_USERS, VISIBILITY_STAFF) assert limit_visibility_in_menu in accepted_limitations # validate position assert position in ('last-child', 'first-child', 'left', 'right') page = Page( created_by=created_by, changed_by=created_by, parent=parent, publication_date=publication_date, publication_end_date=publication_end_date, in_navigation=in_navigation, soft_root=soft_root, reverse_id=reverse_id, navigation_extenders=navigation_extenders, published=False, # will be published later template=template, site=site, login_required=login_required, limit_visibility_in_menu=limit_visibility_in_menu, ) page.insert_at(parent, position) page.save() create_title(language=language, title=title, menu_title=menu_title, slug=slug, apphook=application_urls, redirect=redirect, meta_description=meta_description, meta_keywords=meta_keywords, page=page, overwrite_url=overwrite_url) if published: page.publish() del _thread_locals.user return page.reload()
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 article(request, slug): """ The main view of the Django-CMS Articles! Takes a request and a slug, renders the article. """ # Get current CMS Page as article tree tree = request.current_page.get_public_object() # Check whether it really is a tree. # It could also be one of its sub-pages. if tree.application_urls != 'CMSArticlesApp': # In such case show regular CMS Page return page(request, slug) # Get an Article object from the request draft = use_draft(request) and request.user.has_perm('cms_articles.change_article') preview = 'preview' in request.GET and request.user.has_perm('cms_articles.change_article') site = tree.node.site article = get_article_from_slug(tree, slug, preview, draft) if not article: # raise 404 _handle_no_page(request) request.current_article = article if hasattr(request, 'user') and request.user.is_staff: user_languages = get_language_list(site_id=site.pk) else: user_languages = get_public_languages(site_id=site.pk) request_language = get_language_from_request(request, check_path=True) # get_published_languages will return all languages in draft mode # and published only in live mode. # These languages are then filtered out by the user allowed languages available_languages = [ language for language in user_languages if language in list(article.get_published_languages()) ] own_urls = [ request.build_absolute_uri(request.path), '/%s' % request.path, request.path, ] try: redirect_on_fallback = get_redirect_on_fallback(request_language, site_id=site.pk) except LanguageError: redirect_on_fallback = False if request_language not in user_languages: # Language is not allowed # Use the default site language default_language = get_default_language_for_site(site.pk) fallbacks = get_fallback_languages(default_language, site_id=site.pk) fallbacks = [default_language] + fallbacks else: fallbacks = get_fallback_languages(request_language, site_id=site.pk) # Only fallback to languages the user is allowed to see fallback_languages = [ language for language in fallbacks if language != request_language and language in available_languages ] language_is_unavailable = request_language not in available_languages if language_is_unavailable and not fallback_languages: # There is no page with the requested language # and there's no configured fallbacks return _handle_no_page(request) elif language_is_unavailable and redirect_on_fallback: # There is no page with the requested language and # the user has explicitly requested to redirect on fallbacks, # so redirect to the first configured / available fallback language fallback = fallback_languages[0] redirect_url = article.get_absolute_url(fallback, fallback=False) else: redirect_url = False if redirect_url: if request.user.is_staff and hasattr(request, 'toolbar') and request.toolbar.edit_mode_active: request.toolbar.redirect_url = redirect_url elif redirect_url not in own_urls: # prevent redirect to self return HttpResponseRedirect(redirect_url) # permission checks if article.login_required and not request.user.is_authenticated(): return redirect_to_login(urlquote(request.get_full_path()), settings.LOGIN_URL) if hasattr(request, 'toolbar'): request.toolbar.obj = article structure_requested = get_cms_setting('CMS_TOOLBAR_URL__BUILD') in request.GET if article.has_change_permission(request) and structure_requested: return render_object_structure(request, article) return render_article(request, article, current_language=request_language, slug=slug)
def details(request, slug): """ The main view of the Django-CMS! Takes a request and a slug, renders the page. """ response_timestamp = now() if get_cms_setting("PAGE_CACHE") and ( not hasattr(request, 'toolbar') or (not request.toolbar.edit_mode and not request.toolbar.show_toolbar and not request.user.is_authenticated())): cache_content = get_page_cache(request) if cache_content is not None: content, headers, expires_datetime = cache_content response = HttpResponse(content) response._headers = headers # Recalculate the max-age header for this cached response max_age = int((expires_datetime - response_timestamp).total_seconds() + 0.5) patch_cache_control(response, max_age=max_age) return response # Get a Page model object from the request page = get_page_from_request(request, use_path=slug) if not page: return _handle_no_page(request, slug) current_language = request.GET.get('language', None) if not current_language: current_language = request.POST.get('language', None) if current_language: current_language = get_language_code(current_language) if current_language not in get_language_list(page.site_id): current_language = None if current_language is None: current_language = get_language_code( getattr(request, 'LANGUAGE_CODE', None)) if current_language: current_language = get_language_code(current_language) if current_language not in get_language_list(page.site_id): current_language = None if current_language is None: current_language = get_language_code(get_language()) # Check that the current page is available in the desired (current) language available_languages = [] # this will return all languages in draft mode, and published only in live mode page_languages = list(page.get_published_languages()) if hasattr(request, 'user') and request.user.is_staff: user_languages = get_language_list() else: user_languages = get_public_languages() for frontend_lang in user_languages: if frontend_lang in page_languages: available_languages.append(frontend_lang) # Check that the language is in FRONTEND_LANGUAGES: own_urls = [ 'http%s://%s%s' % ('s' if request.is_secure() else '', request.get_host(), request.path), '/%s' % request.path, request.path, ] if current_language not in user_languages: #are we on root? if not slug: #redirect to supported language languages = [] for language in available_languages: languages.append((language, language)) if languages: # get supported language new_language = get_language_from_request(request) if new_language in get_public_languages(): with force_language(new_language): pages_root = reverse('pages-root') if (hasattr(request, 'toolbar') and request.user.is_staff and request.toolbar.edit_mode): request.toolbar.redirect_url = pages_root elif pages_root not in own_urls: return HttpResponseRedirect(pages_root) elif not hasattr(request, 'toolbar') or not request.toolbar.redirect_url: _handle_no_page(request, slug) else: return _handle_no_page(request, slug) if current_language not in available_languages: # If we didn't find the required page in the requested (current) # language, let's try to find a fallback found = False for alt_lang in get_fallback_languages(current_language): if alt_lang in available_languages: if get_redirect_on_fallback(current_language) or slug == "": with force_language(alt_lang): path = page.get_absolute_url(language=alt_lang, fallback=True) # In the case where the page is not available in the # preferred language, *redirect* to the fallback page. This # is a design decision (instead of rendering in place)). if (hasattr(request, 'toolbar') and request.user.is_staff and request.toolbar.edit_mode): request.toolbar.redirect_url = path elif path not in own_urls: return HttpResponseRedirect(path) else: found = True if not found and (not hasattr(request, 'toolbar') or not request.toolbar.redirect_url): # There is a page object we can't find a proper language to render it _handle_no_page(request, slug) else: page_path = page.get_absolute_url(language=current_language) page_slug = page.get_path(language=current_language) or page.get_slug( language=current_language) if slug and slug != page_slug and request.path[:len(page_path )] != page_path: # The current language does not match it's slug. # Redirect to the current language. if hasattr( request, 'toolbar' ) and request.user.is_staff and request.toolbar.edit_mode: request.toolbar.redirect_url = page_path else: return HttpResponseRedirect(page_path) if apphook_pool.get_apphooks(): # There are apphooks in the pool. Let's see if there is one for the # current page # since we always have a page at this point, applications_page_check is # pointless # page = applications_page_check(request, page, slug) # Check for apphooks! This time for real! app_urls = page.get_application_urls(current_language, False) skip_app = False if (not page.is_published(current_language) and hasattr(request, 'toolbar') and request.toolbar.edit_mode): skip_app = True if app_urls and not skip_app: app = apphook_pool.get_apphook(app_urls) pattern_list = [] if app: for urlpatterns in get_app_urls( app.get_urls(page, current_language)): pattern_list += urlpatterns try: view, args, kwargs = resolve('/', tuple(pattern_list)) return view(request, *args, **kwargs) except Resolver404: pass # Check if the page has a redirect url defined for this language. redirect_url = page.get_redirect(language=current_language) if redirect_url: if (is_language_prefix_patterns_used() and redirect_url[0] == "/" and not redirect_url.startswith('/%s/' % current_language)): # add language prefix to url redirect_url = "/%s/%s" % (current_language, redirect_url.lstrip("/")) # prevent redirect to self if hasattr(request, 'toolbar' ) and request.user.is_staff and request.toolbar.edit_mode: request.toolbar.redirect_url = redirect_url elif redirect_url not in own_urls: return HttpResponseRedirect(redirect_url) # permission checks if page.login_required and not request.user.is_authenticated(): return redirect_to_login(urlquote(request.get_full_path()), settings.LOGIN_URL) if hasattr(request, 'toolbar'): request.toolbar.set_object(page) response = render_page(request, page, current_language=current_language, slug=slug) return response
def details(request, slug): """ The main view of the Django-CMS! Takes a request and a slug, renders the page. """ from django.core.cache import cache if get_cms_setting("PAGE_CACHE") and ( not hasattr(request, 'toolbar') or ( not request.toolbar.edit_mode and not request.toolbar.show_toolbar and not request.user.is_authenticated() ) ): cache_content = cache.get( _get_cache_key(request), version=_get_cache_version() ) if not cache_content is None: content, headers = cache_content response = HttpResponse(content) response._headers = headers return response # Get a Page model object from the request page = get_page_from_request(request, use_path=slug) if not page: return _handle_no_page(request, slug) current_language = request.REQUEST.get('language', None) if current_language: current_language = get_language_code(current_language) if not current_language in get_language_list(page.site_id): current_language = None if current_language is None: current_language = get_language_code(getattr(request, 'LANGUAGE_CODE', None)) if current_language: current_language = get_language_code(current_language) if not current_language in get_language_list(page.site_id): current_language = None if current_language is None: current_language = get_language_code(get_language()) # Check that the current page is available in the desired (current) language available_languages = [] page_languages = list(page.get_languages()) if hasattr(request, 'user') and request.user.is_staff: user_languages = get_language_list() else: user_languages = get_public_languages() for frontend_lang in user_languages: if frontend_lang in page_languages: available_languages.append(frontend_lang) # Check that the language is in FRONTEND_LANGUAGES: own_urls = [ 'http%s://%s%s' % ('s' if request.is_secure() else '', request.get_host(), request.path), '/%s' % request.path, request.path, ] if not current_language in user_languages: #are we on root? if not slug: #redirect to supported language languages = [] for language in available_languages: languages.append((language, language)) if languages: with SettingsOverride(LANGUAGES=languages, LANGUAGE_CODE=languages[0][0]): #get supported language new_language = get_language_from_request(request) if new_language in get_public_languages(): with force_language(new_language): pages_root = reverse('pages-root') if hasattr(request, 'toolbar') and request.user.is_staff and request.toolbar.edit_mode: request.toolbar.redirect_url = pages_root elif pages_root not in own_urls: return HttpResponseRedirect(pages_root) elif not hasattr(request, 'toolbar') or not request.toolbar.redirect_url: _handle_no_page(request, slug) else: return _handle_no_page(request, slug) if current_language not in available_languages: # If we didn't find the required page in the requested (current) # language, let's try to find a fallback found = False for alt_lang in get_fallback_languages(current_language): if alt_lang in available_languages: if get_redirect_on_fallback(current_language) or slug == "": with force_language(alt_lang): path = page.get_absolute_url(language=alt_lang, fallback=True) # In the case where the page is not available in the # preferred language, *redirect* to the fallback page. This # is a design decision (instead of rendering in place)). if hasattr(request, 'toolbar') and request.user.is_staff and request.toolbar.edit_mode: request.toolbar.redirect_url = path elif path not in own_urls: return HttpResponseRedirect(path) else: found = True if not found and (not hasattr(request, 'toolbar') or not request.toolbar.redirect_url): # There is a page object we can't find a proper language to render it _handle_no_page(request, slug) if apphook_pool.get_apphooks(): # There are apphooks in the pool. Let's see if there is one for the # current page # since we always have a page at this point, applications_page_check is # pointless # page = applications_page_check(request, page, slug) # Check for apphooks! This time for real! app_urls = page.get_application_urls(current_language, False) skip_app = False if not page.is_published(current_language) and hasattr(request, 'toolbar') and request.toolbar.edit_mode: skip_app = True if app_urls and not skip_app: app = apphook_pool.get_apphook(app_urls) pattern_list = [] for urlpatterns in get_app_urls(app.urls): pattern_list += urlpatterns urlpatterns = patterns('', *pattern_list) try: view, args, kwargs = resolve('/', tuple(urlpatterns)) return view(request, *args, **kwargs) except Resolver404: pass # Check if the page has a redirect url defined for this language. redirect_url = page.get_redirect(language=current_language) if redirect_url: if (is_language_prefix_patterns_used() and redirect_url[0] == "/" and not redirect_url.startswith( '/%s/' % current_language)): # add language prefix to url redirect_url = "/%s/%s" % (current_language, redirect_url.lstrip("/")) # prevent redirect to self if hasattr(request, 'toolbar') and request.user.is_staff and request.toolbar.edit_mode: request.toolbar.redirect_url = redirect_url elif redirect_url not in own_urls: return HttpResponseRedirect(redirect_url) # permission checks if page.login_required and not request.user.is_authenticated(): return redirect_to_login(urlquote(request.get_full_path()), settings.LOGIN_URL) if hasattr(request, 'toolbar'): request.toolbar.set_object(page) template_name = get_template_from_request(request, page, no_current_page=True) # fill the context context = RequestContext(request) context['lang'] = current_language context['current_page'] = page context['has_change_permissions'] = page.has_change_permission(request) context['has_view_permissions'] = page.has_view_permission(request) if not context['has_view_permissions']: return _handle_no_page(request, slug) response = TemplateResponse(request, template_name, context) response.add_post_render_callback(_cache_page) # Add headers for X Frame Options - this really should be changed upon moving to class based views xframe_options = page.get_xframe_options() if xframe_options == Page.X_FRAME_OPTIONS_INHERIT: # This is when we defer to django's own clickjacking handling return response # We want to prevent django setting this in their middlewear response.xframe_options_exempt = True if xframe_options == Page.X_FRAME_OPTIONS_ALLOW: # Do nothing, allowed is no header. return response elif xframe_options == Page.X_FRAME_OPTIONS_SAMEORIGIN: response['X-Frame-Options'] = 'SAMEORIGIN' elif xframe_options == Page.X_FRAME_OPTIONS_DENY: response['X-Frame-Options'] = 'DENY' return response
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")
def create_article(tree, template, title, language, slug=None, description=None, page_title=None, menu_title=None, meta_description=None, created_by=None, image=None, publication_date=None, publication_end_date=None, published=False, login_required=False, creation_date=None, categories=[]): """ Create a CMS Article and it's title for the given language """ # validate tree tree = tree.get_public_object() assert tree.application_urls == 'CMSArticlesApp' # validate template assert template in [tpl[0] for tpl in settings.CMS_ARTICLES_TEMPLATES] get_template(template) # validate language: assert language in get_language_list(tree.node.site_id), settings.CMS_LANGUAGES.get(tree.node.site_id) # validate publication date if publication_date: assert isinstance(publication_date, datetime.date) # validate publication end date if publication_end_date: assert isinstance(publication_end_date, datetime.date) # validate creation date if not creation_date: creation_date = publication_date if creation_date: assert isinstance(creation_date, datetime.date) # get username if created_by: try: username = created_by.get_username() except Exception: username = force_text(created_by) else: username = '******' with current_user(username): # create article article = Article.objects.create( tree=tree, template=template, login_required=login_required, creation_date=creation_date, publication_date=publication_date, publication_end_date=publication_end_date, languages=language, ) for category in categories: article.categories.add(category) # create title create_title( article=article, language=language, title=title, slug=slug, description=description, page_title=page_title, menu_title=menu_title, meta_description=meta_description, creation_date=creation_date, image=image, ) # publish article if published: article.publish(language) return article.reload()
class BaseTest(TestCase): """ Base class with utility function """ request_factory = None user = None languages = get_language_list() page_data = { } title_data = { 'keywords': 'keyword1, keyword2, keyword3', 'description': 'lorem ipsum - english', 'og_description': 'opengraph - lorem ipsum - english', 'twitter_description': 'twitter - lorem ipsum - english', 'gplus_description': 'gplus - lorem ipsum - english', } title_data_it = { 'keywords': 'parola1, parola2, parola3', 'description': 'lorem ipsum - italian', 'og_description': 'opengraph - lorem ipsum - italian', 'twitter_description': 'twitter - lorem ipsum - italian', 'gplus_description': 'gplus - lorem ipsum - italian', } og_data = { 'og_type': 'article', 'og_author_url': 'https://facebook.com/FakeUser', 'og_author_fbid': u'123456789', 'og_publisher': 'https://facebook.com/FakeUser', 'og_app_id': u'123456789', } twitter_data = { 'twitter_author': 'fake_user', 'twitter_site': 'fake_site', 'twitter_type': 'summary', } gplus_data = { 'gplus_author': '+FakeUser', 'gplus_type': 'Article', } @classmethod def setUpClass(cls): cls.request_factory = RequestFactory() cls.user = User.objects.create(username='******', is_staff=True, is_superuser=True) cls.user_staff = User.objects.create(username='******', is_staff=True) cls.user_normal = User.objects.create(username='******') def get_pages(self): from cms.api import create_page, create_title page = create_page(u'page one', 'page.html', language='en') page_2 = create_page(u'page two', 'page.html', language='en') create_title(language='fr_FR', title=u'page un', page=page) create_title(language='it', title=u'pagina uno', page=page) for lang in self.languages: page.publish(lang) page_2.publish('en') return page.get_draft_object(), page_2.get_draft_object() def get_request(self, page, lang): request = self.request_factory.get(page.get_path(lang)) request.current_page = page request.user = self.user request.session = {} request.cookies = SimpleCookie() request.errors = StringIO() request.LANGUAGE_CODE = lang return request def get_page_request(self, page, user, path=None, edit=False, lang_code='en'): from cms.middleware.toolbar import ToolbarMiddleware path = path or page and page.get_absolute_url(lang_code) if edit: path += '?edit' request = RequestFactory().get(path) request.session = {} request.user = user request.LANGUAGE_CODE = lang_code if edit: request.GET = {'edit': None} else: request.GET = {'edit_off': None} request.current_page = page mid = ToolbarMiddleware() mid.process_request(request) return request def tearDown(self): Page.objects.all().delete() PageMeta.objects.all().delete() TitleMeta.objects.all().delete() @classmethod def tearDownClass(cls): User.objects.all().delete()
def create_page(title, template, language, menu_title=None, slug=None, apphook=None, apphook_namespace=None, redirect=None, meta_description=None, created_by='python-api', parent=None, publication_date=None, publication_end_date=None, in_navigation=False, soft_root=False, reverse_id=None, navigation_extenders=None, published=False, site=None, login_required=False, limit_visibility_in_menu=VISIBILITY_ALL, position="last-child", overwrite_url=None, xframe_options=Page.X_FRAME_OPTIONS_INHERIT): """ Create a CMS Page and it's title for the given language See docs/extending_cms/api_reference.rst for more info """ # ugly permissions hack if created_by and isinstance(created_by, get_user_model()): _thread_locals.user = created_by created_by = getattr(created_by, get_user_model().USERNAME_FIELD) else: _thread_locals.user = None # validate template if not template == TEMPLATE_INHERITANCE_MAGIC: assert template in [tpl[0] for tpl in get_cms_setting('TEMPLATES')] get_template(template) # validate site if not site: site = Site.objects.get_current() else: assert isinstance(site, Site) # validate language: assert language in get_language_list(site), get_cms_setting('LANGUAGES').get(site.pk) # set default slug: if not slug: slug = _generate_valid_slug(title, parent, language) # validate parent if parent: assert isinstance(parent, Page) parent = Page.objects.get(pk=parent.pk) # validate publication date if publication_date: assert isinstance(publication_date, datetime.date) # validate publication end date if publication_end_date: assert isinstance(publication_end_date, datetime.date) if navigation_extenders: raw_menus = menu_pool.get_menus_by_attribute("cms_enabled", True) menus = [menu[0] for menu in raw_menus] assert navigation_extenders in menus # validate menu visibility accepted_limitations = (VISIBILITY_ALL, VISIBILITY_USERS, VISIBILITY_STAFF) assert limit_visibility_in_menu in accepted_limitations # validate position assert position in ('last-child', 'first-child', 'left', 'right') # validate and normalize apphook if apphook: application_urls = _verify_apphook(apphook, apphook_namespace) else: application_urls = None if reverse_id: if Page.objects.drafts().filter(reverse_id=reverse_id).count(): raise FieldError('A page with the reverse_id="%s" already exist.' % reverse_id) page = Page( created_by=created_by, changed_by=created_by, parent=parent, publication_date=publication_date, publication_end_date=publication_end_date, in_navigation=in_navigation, soft_root=soft_root, reverse_id=reverse_id, navigation_extenders=navigation_extenders, template=template, application_urls=application_urls, application_namespace=apphook_namespace, site=site, login_required=login_required, limit_visibility_in_menu=limit_visibility_in_menu, xframe_options=xframe_options, ) page.insert_at(parent, position) page.save() create_title( language=language, title=title, menu_title=menu_title, slug=slug, redirect=redirect, meta_description=meta_description, page=page, overwrite_url=overwrite_url, ) if published: page.publish(language) del _thread_locals.user return page.reload()
def details(request, slug): """ The main view of the Django-CMS! Takes a request and a slug, renders the page. """ # get the right model context = RequestContext(request) # Get a Page model object from the request page = get_page_from_request(request, use_path=slug) if not page: return _handle_no_page(request, slug) current_language = get_language_from_request(request) # Check that the current page is available in the desired (current) language available_languages = [] page_languages = list(page.get_languages()) if hasattr(request, 'user') and request.user.is_staff: user_languages = get_language_list() else: user_languages = get_public_languages() for frontend_lang in user_languages: if frontend_lang in page_languages: available_languages.append(frontend_lang) attrs = '' if 'edit' in request.GET: attrs = '?edit=1' elif 'preview' in request.GET: attrs = '?preview=1' if 'draft' in request.GET: attrs += '&draft=1' # Check that the language is in FRONTEND_LANGUAGES: if not current_language in user_languages: #are we on root? if not slug: #redirect to supported language languages = [] for language in available_languages: languages.append((language, language)) if languages: with SettingsOverride(LANGUAGES=languages, LANGUAGE_CODE=languages[0][0]): #get supported language new_language = get_language_from_request(request) if new_language in get_public_languages(): with force_language(new_language): pages_root = reverse('pages-root') return HttpResponseRedirect(pages_root + attrs) else: _handle_no_page(request, slug) else: return _handle_no_page(request, slug) if current_language not in available_languages: # If we didn't find the required page in the requested (current) # language, let's try to find a fallback found = False for alt_lang in get_fallback_languages(current_language): if alt_lang in available_languages: if get_redirect_on_fallback(current_language): with force_language(alt_lang): path = page.get_absolute_url(language=alt_lang, fallback=True) # In the case where the page is not available in the # preferred language, *redirect* to the fallback page. This # is a design decision (instead of rendering in place)). return HttpResponseRedirect(path + attrs) else: found = True if not found: # There is a page object we can't find a proper language to render it _handle_no_page(request, slug) if apphook_pool.get_apphooks(): # There are apphooks in the pool. Let's see if there is one for the # current page # since we always have a page at this point, applications_page_check is # pointless # page = applications_page_check(request, page, slug) # Check for apphooks! This time for real! try: app_urls = page.get_application_urls(current_language, False) except Title.DoesNotExist: app_urls = [] if app_urls: app = apphook_pool.get_apphook(app_urls) pattern_list = [] for urlpatterns in get_app_urls(app.urls): pattern_list += urlpatterns urlpatterns = patterns('', *pattern_list) try: view, args, kwargs = resolve('/', tuple(urlpatterns)) return view(request, *args, **kwargs) except Resolver404: pass # Check if the page has a redirect url defined for this language. redirect_url = page.get_redirect(language=current_language) if redirect_url: if (is_language_prefix_patterns_used() and redirect_url[0] == "/" and not redirect_url.startswith('/%s/' % current_language)): # add language prefix to url redirect_url = "/%s/%s" % (current_language, redirect_url.lstrip("/")) # prevent redirect to self own_urls = [ 'http%s://%s%s' % ('s' if request.is_secure() else '', request.get_host(), request.path), '/%s' % request.path, request.path, ] if redirect_url not in own_urls: return HttpResponseRedirect(redirect_url + attrs) # permission checks if page.login_required and not request.user.is_authenticated(): return redirect_to_login(urlquote(request.get_full_path()), settings.LOGIN_URL) template_name = get_template_from_request(request, page, no_current_page=True) # fill the context context['lang'] = current_language context['current_page'] = page context['has_change_permissions'] = page.has_change_permission(request) context['has_view_permissions'] = page.has_view_permission(request) if not context['has_view_permissions']: return _handle_no_page(request, slug) return TemplateResponse(request, template_name, context)