Ejemplo n.º 1
0
    def test_result_order_when_multiple_sites_share_the_same_root_page(self):
        result = Site.get_site_root_paths()

        # An entry for the default site should come first
        self.assertEqual(result[0][0], self.default_site.id)

        # Followed by entries for others in 'host' alphabetical order
        self.assertEqual(result[1][0], self.abc_site.id)
        self.assertEqual(result[2][0], self.def_site.id)
Ejemplo n.º 2
0
def external_link(request):
    initial_data = {
        "url": request.GET.get("link_url", ""),
        "link_text": request.GET.get("link_text", ""),
    }

    if request.method == "POST":
        form = ExternalLinkChooserForm(request.POST,
                                       initial=initial_data,
                                       prefix="external-link-chooser")

        if form.is_valid():
            submitted_url = form.cleaned_data["url"]
            result = {
                "url":
                submitted_url,
                "title":
                form.cleaned_data["link_text"].strip()
                or form.cleaned_data["url"],
                # If the user has explicitly entered / edited something in the link_text field,
                # always use that text. If not, we should favour keeping the existing link/selection
                # text, where applicable.
                # (Normally this will match the link_text passed in the URL here anyhow,
                # but that won't account for non-text content such as images.)
                "prefer_this_title_as_link_text": ("link_text"
                                                   in form.changed_data),
            }

            link_conversion = getattr(settings,
                                      "WAGTAILADMIN_EXTERNAL_LINK_CONVERSION",
                                      LINK_CONVERSION_ALL).lower()

            if link_conversion not in [
                    LINK_CONVERSION_ALL,
                    LINK_CONVERSION_EXACT,
                    LINK_CONVERSION_CONFIRM,
            ]:
                # We should not attempt to convert external urls to page links
                return render_modal_workflow(
                    request,
                    None,
                    None,
                    None,
                    json_data={
                        "step": "external_link_chosen",
                        "result": result
                    },
                )

            # Next, we should check if the url matches an internal page
            # Strip the url of its query/fragment link parameters - these won't match a page
            url_without_query = re.split(r"\?|#", submitted_url)[0]

            # Start by finding any sites the url could potentially match
            sites = getattr(request, "_wagtail_cached_site_root_paths", None)
            if sites is None:
                sites = Site.get_site_root_paths()

            match_relative_paths = submitted_url.startswith("/") and len(
                sites) == 1
            # We should only match relative urls if there's only a single site
            # Otherwise this could get very annoying accidentally matching coincidentally
            # named pages on different sites

            if match_relative_paths:
                possible_sites = [(pk, url_without_query)
                                  for pk, path, url, language_code in sites]
            else:
                possible_sites = [(pk, url_without_query[len(url):])
                                  for pk, path, url, language_code in sites
                                  if submitted_url.startswith(url)]

            # Loop over possible sites to identify a page match
            for pk, url in possible_sites:
                try:
                    route = Site.objects.get(pk=pk).root_page.specific.route(
                        request,
                        [
                            component
                            for component in url.split("/") if component
                        ],
                    )

                    matched_page = route.page.specific

                    internal_data = {
                        "id":
                        matched_page.pk,
                        "parentId":
                        matched_page.get_parent().pk,
                        "adminTitle":
                        matched_page.draft_title,
                        "editUrl":
                        reverse("wagtailadmin_pages:edit",
                                args=(matched_page.pk, )),
                        "url":
                        matched_page.url,
                    }

                    # Let's check what this page's normal url would be
                    normal_url = (matched_page.get_url_parts(
                        request=request)[-1] if match_relative_paths else
                                  matched_page.get_full_url(request=request))

                    # If that's what the user provided, great. Let's just convert the external
                    # url to an internal link automatically unless we're set up tp manually check
                    # all conversions
                    if (normal_url == submitted_url
                            and link_conversion != LINK_CONVERSION_CONFIRM):
                        return render_modal_workflow(
                            request,
                            None,
                            None,
                            None,
                            json_data={
                                "step": "external_link_chosen",
                                "result": internal_data,
                            },
                        )
                    # If not, they might lose query parameters or routable page information

                    if link_conversion == LINK_CONVERSION_EXACT:
                        # We should only convert exact matches
                        continue

                    # Let's confirm the conversion with them explicitly
                    else:
                        return render_modal_workflow(
                            request,
                            "wagtailadmin/chooser/confirm_external_to_internal.html",
                            None,
                            {
                                "submitted_url": submitted_url,
                                "internal_url": normal_url,
                                "page": matched_page.draft_title,
                            },
                            json_data={
                                "step": "confirm_external_to_internal",
                                "external": result,
                                "internal": internal_data,
                            },
                        )

                except Http404:
                    continue

            # Otherwise, with no internal matches, fall back to an external url
            return render_modal_workflow(
                request,
                None,
                None,
                None,
                json_data={
                    "step": "external_link_chosen",
                    "result": result
                },
            )
    else:
        form = ExternalLinkChooserForm(initial=initial_data,
                                       prefix="external-link-chooser")

    return render_modal_workflow(
        request,
        "wagtailadmin/chooser/external_link.html",
        None,
        shared_context(
            request,
            {
                "form": form,
            },
        ),
        json_data={"step": "external_link"},
    )
Ejemplo n.º 3
0
    def post(self, request):
        self.form = self.form_class(
            request.POST,
            initial=self.get_initial_data(),
            prefix=self.form_prefix,
        )

        if self.form.is_valid():
            result = self.get_result_data()
            submitted_url = result["url"]

            link_conversion = getattr(
                settings,
                "WAGTAILADMIN_EXTERNAL_LINK_CONVERSION",
                LINK_CONVERSION_ALL,
            ).lower()

            if link_conversion not in [
                    LINK_CONVERSION_ALL,
                    LINK_CONVERSION_EXACT,
                    LINK_CONVERSION_CONFIRM,
            ]:
                # We should not attempt to convert external urls to page links
                return self.render_chosen_response(result)

            # Next, we should check if the url matches an internal page
            # Strip the url of its query/fragment link parameters - these won't match a page
            url_without_query = re.split(r"\?|#", submitted_url)[0]

            # Start by finding any sites the url could potentially match
            sites = getattr(request, "_wagtail_cached_site_root_paths", None)
            if sites is None:
                sites = Site.get_site_root_paths()

            match_relative_paths = submitted_url.startswith("/") and len(
                sites) == 1
            # We should only match relative urls if there's only a single site
            # Otherwise this could get very annoying accidentally matching coincidentally
            # named pages on different sites

            if match_relative_paths:
                possible_sites = [(pk, url_without_query)
                                  for pk, path, url, language_code in sites]
            else:
                possible_sites = [(pk, url_without_query[len(url):])
                                  for pk, path, url, language_code in sites
                                  if submitted_url.startswith(url)]

            # Loop over possible sites to identify a page match
            for pk, url in possible_sites:
                try:
                    route = Site.objects.get(pk=pk).root_page.specific.route(
                        request,
                        [
                            component
                            for component in url.split("/") if component
                        ],
                    )

                    matched_page = route.page.specific

                    internal_data = {
                        "id":
                        matched_page.pk,
                        "parentId":
                        matched_page.get_parent().pk,
                        "adminTitle":
                        matched_page.draft_title,
                        "editUrl":
                        reverse("wagtailadmin_pages:edit",
                                args=(matched_page.pk, )),
                        "url":
                        matched_page.url,
                    }

                    # Let's check what this page's normal url would be
                    normal_url = (matched_page.get_url_parts(
                        request=request)[-1] if match_relative_paths else
                                  matched_page.get_full_url(request=request))

                    # If that's what the user provided, great. Let's just convert the external
                    # url to an internal link automatically unless we're set up tp manually check
                    # all conversions
                    if (normal_url == submitted_url
                            and link_conversion != LINK_CONVERSION_CONFIRM):
                        return self.render_chosen_response(internal_data)
                    # If not, they might lose query parameters or routable page information

                    if link_conversion == LINK_CONVERSION_EXACT:
                        # We should only convert exact matches
                        continue

                    # Let's confirm the conversion with them explicitly
                    else:
                        return render_modal_workflow(
                            request,
                            "wagtailadmin/chooser/confirm_external_to_internal.html",
                            None,
                            {
                                "submitted_url": submitted_url,
                                "internal_url": normal_url,
                                "page": matched_page.draft_title,
                            },
                            json_data={
                                "step": "confirm_external_to_internal",
                                "external": result,
                                "internal": internal_data,
                            },
                        )

                except Http404:
                    continue

            # Otherwise, with no internal matches, fall back to an external url
            return self.render_chosen_response(result)
        else:  # form invalid
            return self.render_form_response()