def get_url(self, site): """ All fields in basic_types and supported_models should be exclusive or's, otherwise the value will be returned based on the order of the below method rather than the intended value. """ obj = self._get_url_obj(site) language = get_default_language_for_site(obj.site) if obj.content_object: try: absolute_url = obj.content_object.get_absolute_url( language=language) except BaseException: absolute_url = obj.content_object.get_absolute_url() url = "//{}{}".format(obj.site.domain, absolute_url) elif obj.manual_url: url = obj.manual_url elif obj.relative_path: url = obj.relative_path elif obj.phone: url = "tel:{}".format(obj.phone.replace(" ", "")) elif obj.mailto: url = "mailto:{}".format(obj.mailto) else: url = "" if (not obj.phone and not obj.mailto) and obj.anchor: url += "#{}".format(obj.anchor) return url
def get_url(self, site): """ The implementation of this seems to have been based on the assumption that the model was... populated using the forms.py save and clean logic. All fields in basic_types and supported_models should be exclusive or's, otherwise the value will be returned based on the order of the below method rather than the intended value. """ logger.warning(""" URL.get_model method should only be called on models populated via forms that implement a XOR on fields within supported_models and basic_types! """) obj = self._get_url_obj(site) language = get_default_language_for_site(obj.site) if obj.content_object: try: absolute_url = obj.content_object.get_absolute_url( language=language) except BaseException: absolute_url = obj.content_object.get_absolute_url() url = "//{}{}".format(obj.site.domain, absolute_url) elif obj.manual_url: url = obj.manual_url elif obj.relative_path: url = obj.relative_path elif obj.phone: url = "tel:{}".format(obj.phone.replace(" ", "")) elif obj.mailto: url = "mailto:{}".format(obj.mailto) else: url = "" if (not obj.phone and not obj.mailto) and obj.anchor: url += "#{}".format(obj.anchor) return url
def add_navigation_languages(apps, schema_editor): db_alias = schema_editor.connection.alias MenuContent = apps.get_model("djangocms_navigation", "MenuContent") navigation_queryset = MenuContent.objects.using(db_alias).filter( language__exact="") for model in navigation_queryset: model.language = get_default_language_for_site(model.menu.site) model.save() logger.info("Added default language {} to model {}".format( model.language, model.__str__()))
def __init__(self, pool, request): self.pool = pool # It's important this happens on init # because we need to make sure that a menu renderer # points to the same registered menus as long as the # instance lives. self.menus = pool.get_registered_menus(for_rendering=True) self.request = request if is_language_prefix_patterns_used(): self.request_language = get_language_from_request(request, check_path=True) else: self.request_language = get_default_language_for_site( get_current_site().pk) self.site = Site.objects.get_current(request)
def _get_alias(self, request, static_code, extra_bits): alias_filter_kwargs = { 'static_code': static_code, } # Site current_site = get_current_site() if 'site' in extra_bits: alias_filter_kwargs['site'] = current_site else: alias_filter_kwargs['site_id__isnull'] = True # Try and find an Alias to render alias = Alias.objects.filter(**alias_filter_kwargs).first() # If there is no alias found we need to create one if not alias: # If versioning is enabled we can only create the records with a logged in user / staff member if is_versioning_enabled() and not request.user.is_authenticated: return None language = get_default_language_for_site(current_site) # Parlers get_or_create doesn't work well with translations, so we must perform our own get or create default_category = Category.objects.filter(translations__name=DEFAULT_STATIC_ALIAS_CATEGORY_NAME).first() if not default_category: default_category = Category.objects.create(name=DEFAULT_STATIC_ALIAS_CATEGORY_NAME) alias_creation_kwargs = { 'static_code': static_code, 'creation_method': Alias.CREATION_BY_TEMPLATE } # Site if 'site' in extra_bits: alias_creation_kwargs['site'] = current_site alias = Alias.objects.create(category=default_category, **alias_creation_kwargs) alias_content = AliasContent.objects.create( alias=alias, name=static_code, language=language, ) if is_versioning_enabled(): from djangocms_versioning.models import Version Version.objects.create(content=alias_content, created_by=request.user) return alias
def get_url(self, site): obj = self._get_url_obj(site) language = get_default_language_for_site(obj.site) if obj.content_object: url = "//{}{}".format( obj.site.domain, obj.content_object.get_absolute_url(language=language)) elif obj.manual_url: url = obj.manual_url elif obj.phone: url = "tel:{}".format(obj.phone.replace(" ", "")) elif obj.mailto: url = "mailto:{}".format(obj.mailto) else: url = "" if (not obj.phone and not obj.mailto) and obj.anchor: url += "#{}".format(obj.anchor) return url
def get_page_path(self, lang): page = getattr(self.request, 'current_page', None) if not page: return '/%s/' % lang if settings.USE_I18N else '/' page_languages = page.get_published_languages() if lang in page_languages: return page.get_absolute_url(lang, fallback=False) site = get_current_site() if is_valid_site_language(lang, site_id=site.pk): _valid_language = True _hide_untranslated = hide_untranslated(lang, site.pk) else: _valid_language = False _hide_untranslated = False if _hide_untranslated and settings.USE_I18N: return '/%s/' % lang default_language = get_default_language_for_site(site.pk) if not _valid_language and default_language in page_languages: # The request language is not configured for the current site. # Fallback to the default language configured for the current site. return page.get_absolute_url(default_language, fallback=False) if _valid_language: fallbacks = get_fallback_languages(lang, site_id=site.pk) or [] fallbacks = [ _lang for _lang in fallbacks if _lang in page_languages ] else: fallbacks = [] if fallbacks: return page.get_absolute_url(fallbacks[0], fallback=False) return '/%s/' % lang if settings.USE_I18N else '/'
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 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_active 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 site = get_current_site() page = get_page_from_request(request, use_path=slug) toolbar = get_toolbar_from_request(request) tree_nodes = TreeNode.objects.get_for_site(site) if not page and not slug and not tree_nodes.exists(): # render the welcome page if the requested path is root "/" # and there's no pages return _render_welcome_page(request) if not page: # raise 404 _handle_no_page(request) request.current_page = page 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) if not page.is_home and request_language not in user_languages: # The homepage is treated differently because # when a request goes to the root of the site (/) # without a language, Django will redirect to the user's # browser language which might not be a valid cms language, # this means we need to correctly redirect that request. return _handle_no_page(request) # 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(page.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 or page.is_home): # 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 = page.get_absolute_url(fallback, fallback=False) else: page_path = page.get_absolute_url(request_language) page_slug = page.get_path(request_language) or page.get_slug( request_language) if slug and slug != page_slug and request.path[:len(page_path )] != page_path: # The current language does not match its slug. # Redirect to the current language. return HttpResponseRedirect(page_path) # Check if the page has a redirect url defined for this language. redirect_url = page.get_redirect(request_language, fallback=False) or '' redirect_url = _clean_redirect_url(redirect_url, request_language) if redirect_url: if request.user.is_staff and toolbar.edit_mode_active: toolbar.redirect_url = redirect_url elif redirect_url not in own_urls: # prevent redirect to self 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) structure_requested = get_cms_setting( 'CMS_TOOLBAR_URL__BUILD') in request.GET if user_can_change_page(request.user, page) and structure_requested: return render_object_structure(request, page) return render_page(request, page, current_language=request_language, slug=slug)
def get_public_page_with_fallbacks(page, request): """ the plugin should show the published page whenever it exists or the draft page otherwise. On a public content, the draft page should not be shown at all but this is left to the caller. This is inspired by what DjangoCMS does in its main view: https://github.com/django-cms/django-cms/blob/3.8.0/cms/views.py#L37 """ page = page.get_public_object() request_language = translation.get_language_from_request(request, check_path=True) if not page: return None # Check permissions site = get_current_site() if not page_permissions.user_can_view_page(request.user, page, site): return None if request.user.is_staff: user_languages = i18n.get_language_list(site_id=site.pk) else: user_languages = i18n.get_public_languages(site_id=site.pk) # These languages are then filtered out by the user allowed languages available_languages = [ language for language in user_languages if language in list(page.get_published_languages()) ] if request_language not in user_languages: # Language is not allowed # Use the default site language default_language = i18n.get_default_language_for_site(site.pk) fallbacks = i18n.get_fallback_languages(default_language, site_id=site.pk) fallbacks = [default_language] + fallbacks else: fallbacks = i18n.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 ] if request_language not in available_languages: if not fallback_languages: # There is no page with the requested language # and there's no configured fallbacks return None if request_language in page.get_languages(): # The page was already published and later unpublished in the current # language. In this case we must not fallback to another language. return None return page
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 get_relevant_page_with_fallbacks(context, instance): """ The plugin should show the published page whenever it exists or the draft page otherwise but only in edit mode. This is inspired by what DjangoCMS does in its main view: https://github.com/django-cms/django-cms/blob/3.8.0/cms/views.py#L37 """ request = context["request"] site = get_current_site() # Check permissions if not page_permissions.user_can_view_page(request.user, instance.page, site): return None relevant_page = instance.page.get_public_object() if not relevant_page: if context.get( "current_page") and context["current_page"].publisher_is_draft: return instance.page return None if request.user.is_staff: user_languages = i18n.get_language_list(site_id=site.pk) else: user_languages = i18n.get_public_languages(site_id=site.pk) # These languages are then filtered out by the user allowed languages available_languages = [ language for language in user_languages if language in list(relevant_page.get_published_languages()) ] request_language = translation.get_language_from_request(request, check_path=True) if request_language not in user_languages: # Language is not allowed # Use the default site language default_language = i18n.get_default_language_for_site(site.pk) fallbacks = i18n.get_fallback_languages(default_language, site_id=site.pk) fallbacks = [default_language] + fallbacks else: fallbacks = i18n.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 ] if request_language not in available_languages: if not fallback_languages: # There is no page with the requested language # and there's no configured fallbacks return None if request_language in relevant_page.get_languages(): # The page was already published and later unpublished in the current # language. In this case we must not fallback to another language. return None return relevant_page