Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
    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__()))
Ejemplo n.º 4
0
 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
Ejemplo n.º 6
0
    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
Ejemplo n.º 7
0
    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 '/'
Ejemplo n.º 8
0
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)
Ejemplo n.º 9
0
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)
Ejemplo n.º 10
0
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
Ejemplo n.º 11
0
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)
Ejemplo n.º 12
0
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