Esempio n. 1
0
    def get_success_url(self):
        urlquery = ""
        if self.locale and self.object.locale is not Locale.get_default():
            urlquery = "?locale=" + self.object.locale.language_code

        return (reverse("wagtailsnippets:list",
                        args=[self.app_label, self.model_name]) + urlquery)
Esempio n. 2
0
    def get(self, request, *args, **kwargs):
        if getattr(settings, "WAGTAIL_I18N_ENABLED", False):
            if request.GET.get("locale"):
                self.locale = get_object_or_404(
                    Locale, language_code=request.GET["locale"])
            else:
                self.locale = Locale.get_default()

        return super().get(request, *args, **kwargs)
Esempio n. 3
0
    def _get_locale(self):
        if getattr(settings, "WAGTAIL_I18N_ENABLED", False) and issubclass(
                self.model, TranslatableMixin):
            selected_locale = self.request.GET.get("locale")
            if selected_locale:
                return get_object_or_404(Locale, language_code=selected_locale)
            return Locale.get_default()

        return None
Esempio n. 4
0
    def get_locale(self):
        i18n_enabled = getattr(settings, "WAGTAIL_I18N_ENABLED", False)
        if hasattr(self, "model") and self.model:
            i18n_enabled = i18n_enabled and issubclass(self.model,
                                                       TranslatableMixin)

        if not i18n_enabled:
            return None

        if hasattr(self, "object") and self.object:
            return self.object.locale

        selected_locale = self.request.GET.get("locale")
        if selected_locale:
            return get_object_or_404(Locale, language_code=selected_locale)
        return Locale.get_default()
Esempio n. 5
0
    def dispatch(self, request, *args, **kwargs):
        if self.is_pagemodel:
            user = request.user
            parents = self.permission_helper.get_valid_parent_pages(user)
            parent_count = parents.count()

            # There's only one available parent for this page type for this
            # user, so we send them along with that as the chosen parent page
            if parent_count == 1:
                parent = parents.get()
                parent_pk = quote(parent.pk)
                return redirect(
                    self.url_helper.get_action_url("add", self.app_label,
                                                   self.model_name, parent_pk))

            # The page can be added in multiple places, so redirect to the
            # choose_parent view so that the parent can be specified
            return redirect(self.url_helper.get_action_url("choose_parent"))

        if getattr(settings, "WAGTAIL_I18N_ENABLED", False) and issubclass(
                self.model, TranslatableMixin):
            selected_locale = self.request.GET.get("locale")
            if selected_locale:
                locale = get_object_or_404(Locale,
                                           language_code=selected_locale)
            else:
                locale = Locale.get_default()

            kwargs.update({
                "locale":
                locale,
                "translations": [{
                    "locale":
                    locale,
                    "url":
                    self.create_url + "?locale=" + locale.language_code,
                } for locale in Locale.objects.all().exclude(id=locale.id)],
            })

        return super().dispatch(request, *args, **kwargs)
Esempio n. 6
0
def browse(request, parent_page_id=None):
    # A missing or empty page_type parameter indicates 'all page types'
    # (i.e. descendants of wagtailcore.page)
    page_type_string = request.GET.get("page_type") or "wagtailcore.page"
    user_perm = request.GET.get("user_perms", False)

    try:
        desired_classes = page_models_from_string(page_type_string)
    except (ValueError, LookupError):
        raise Http404

    # Find parent page
    if parent_page_id:
        parent_page = get_object_or_404(Page, id=parent_page_id)
    elif desired_classes == (Page, ):
        # Just use the root page
        parent_page = Page.get_first_root_node()
    else:
        # Find the highest common ancestor for the specific classes passed in
        # In many cases, such as selecting an EventPage under an EventIndex,
        # this will help the administrator find their page quicker.
        all_desired_pages = Page.objects.all().type(*desired_classes)
        parent_page = all_desired_pages.first_common_ancestor()

    parent_page = parent_page.specific

    # Get children of parent page (without streamfields)
    pages = parent_page.get_children().defer_streamfields().specific()

    # allow hooks to modify the queryset
    for hook in hooks.get_hooks("construct_page_chooser_queryset"):
        pages = hook(pages, request)

    # Filter them by page type
    if desired_classes != (Page, ):
        # restrict the page listing to just those pages that:
        # - are of the given content type (taking into account class inheritance)
        # - or can be navigated into (i.e. have children)
        choosable_pages = pages.type(*desired_classes)
        descendable_pages = pages.filter(numchild__gt=0)
        pages = choosable_pages | descendable_pages

    can_choose_root = request.GET.get("can_choose_root", False)
    target_pages = Page.objects.filter(pk__in=[
        int(pk) for pk in request.GET.getlist("target_pages[]", []) if pk
    ])

    match_subclass = request.GET.get("match_subclass", True)

    # Do permission lookups for this user now, instead of for every page.
    permission_proxy = UserPagePermissionsProxy(request.user)

    # Parent page can be chosen if it is a instance of desired_classes
    parent_page.can_choose = can_choose_page(
        parent_page,
        permission_proxy,
        desired_classes,
        can_choose_root,
        user_perm,
        target_pages=target_pages,
        match_subclass=match_subclass,
    )
    parent_page.is_parent_page = True
    parent_page.can_descend = False

    selected_locale = None
    locale_options = []
    show_locale_labels = getattr(settings, "WAGTAIL_I18N_ENABLED", False)
    if show_locale_labels:
        pages = pages.select_related("locale")

        if parent_page.is_root():
            # 'locale' is the current value of the "Locale" selector in the UI
            if request.GET.get("locale"):
                selected_locale = get_object_or_404(
                    Locale, language_code=request.GET["locale"])
                active_locale_id = selected_locale.pk
            else:
                active_locale_id = Locale.get_active().pk

            # we are at the Root level, so get the locales from the current pages
            choose_url = reverse("wagtailadmin_choose_page")
            locale_options = [{
                "locale":
                locale,
                "url":
                choose_url + "?" + urlencode({
                    "page_type": page_type_string,
                    "locale": locale.language_code
                }),
            } for locale in Locale.objects.filter(
                pk__in=pages.values_list("locale_id")).exclude(
                    pk=active_locale_id)]
        else:
            # We have a parent page (that is not the root page). Use its locale as the selected localer
            selected_locale = parent_page.locale
            # and get the locales based on its available translations
            locales_and_parent_pages = {
                item["locale"]: item["pk"]
                for item in Page.objects.translation_of(parent_page).values(
                    "locale", "pk")
            }
            locales_and_parent_pages[selected_locale.pk] = parent_page.pk
            for locale in Locale.objects.filter(
                    pk__in=list(locales_and_parent_pages.keys())).exclude(
                        pk=selected_locale.pk):
                choose_child_url = reverse(
                    "wagtailadmin_choose_page_child",
                    args=[locales_and_parent_pages[locale.pk]],
                )

                locale_options.append({
                    "locale":
                    locale,
                    "url":
                    choose_child_url + "?" +
                    urlencode({"page_type": page_type_string}),
                })

        # finally, filter the browseable pages on the selected locale
        if selected_locale:
            pages = pages.filter(locale=selected_locale)

    # Pagination
    # We apply pagination first so we don't need to walk the entire list
    # in the block below
    paginator = Paginator(pages, per_page=25)
    pages = paginator.get_page(request.GET.get("p"))

    # Annotate each page with can_choose/can_decend flags
    for page in pages:
        page.can_choose = can_choose_page(
            page,
            permission_proxy,
            desired_classes,
            can_choose_root,
            user_perm,
            target_pages=target_pages,
            match_subclass=match_subclass,
        )
        page.can_descend = page.get_children_count()
        page.is_parent_page = False

    table = PageChooserTable(
        [
            PageTitleColumn("title", label=_("Title")),
            DateColumn(
                "updated",
                label=_("Updated"),
                width="12%",
                accessor="latest_revision_created_at",
            ),
            Column("type",
                   label=_("Type"),
                   width="12%",
                   accessor="page_type_display_name"),
            PageStatusColumn("status", label=_("Status"), width="12%"),
            PageNavigateToChildrenColumn("children", label="", width="10%"),
        ],
        [parent_page] + list(pages),
    )

    # Render
    context = shared_context(
        request,
        {
            "parent_page":
            parent_page,
            "parent_page_id":
            parent_page.pk,
            "table":
            table,
            "pagination_page":
            pages,
            "search_form":
            SearchForm(),
            "page_type_string":
            page_type_string,
            "page_type_names": [
                desired_class.get_verbose_name()
                for desired_class in desired_classes
            ],
            "page_types_restricted": (page_type_string != "wagtailcore.page"),
            "show_locale_labels":
            show_locale_labels,
            "locale_options":
            locale_options,
            "selected_locale":
            selected_locale,
        },
    )

    return render_modal_workflow(
        request,
        "wagtailadmin/chooser/browse.html",
        None,
        context,
        json_data={
            "step": "browse",
            "parent_page_id": context["parent_page_id"]
        },
    )
Esempio n. 7
0
def create(request, app_label, model_name):
    model = get_snippet_model_from_url_params(app_label, model_name)

    permission = get_permission_name("add", model)
    if not request.user.has_perm(permission):
        raise PermissionDenied

    for fn in hooks.get_hooks("before_create_snippet"):
        result = fn(request, model)
        if hasattr(result, "status_code"):
            return result

    instance = model()

    # Set locale of the new instance
    if issubclass(model, TranslatableMixin):
        selected_locale = request.GET.get("locale")
        if selected_locale:
            instance.locale = get_object_or_404(Locale,
                                                language_code=selected_locale)
        else:
            instance.locale = Locale.get_default()

    # Make edit handler
    edit_handler = get_snippet_edit_handler(model)
    form_class = edit_handler.get_form_class()

    if request.method == "POST":
        form = form_class(request.POST,
                          request.FILES,
                          instance=instance,
                          for_user=request.user)

        if form.is_valid():
            with transaction.atomic():
                form.save()
                log(instance=instance, action="wagtail.create")

            messages.success(
                request,
                _("%(snippet_type)s '%(instance)s' created.") % {
                    "snippet_type": capfirst(model._meta.verbose_name),
                    "instance": instance,
                },
                buttons=[
                    messages.button(
                        reverse(
                            "wagtailsnippets:edit",
                            args=(app_label, model_name, quote(instance.pk)),
                        ),
                        _("Edit"),
                    )
                ],
            )

            for fn in hooks.get_hooks("after_create_snippet"):
                result = fn(request, instance)
                if hasattr(result, "status_code"):
                    return result

            urlquery = ""
            if (isinstance(instance, TranslatableMixin)
                    and instance.locale is not Locale.get_default()):
                urlquery = "?locale=" + instance.locale.language_code

            return redirect(
                reverse("wagtailsnippets:list", args=[app_label, model_name]) +
                urlquery)
        else:
            messages.validation_error(
                request, _("The snippet could not be created due to errors."),
                form)
    else:
        form = form_class(instance=instance, for_user=request.user)

    edit_handler = edit_handler.get_bound_panel(request=request,
                                                instance=instance,
                                                form=form)

    action_menu = SnippetActionMenu(request, view="create", model=model)

    context = {
        "model_opts": model._meta,
        "edit_handler": edit_handler,
        "form": form,
        "action_menu": action_menu,
        "locale": None,
        "translations": [],
        "media": edit_handler.media + form.media + action_menu.media,
    }

    if getattr(settings, "WAGTAIL_I18N_ENABLED", False) and issubclass(
            model, TranslatableMixin):
        context.update({
            "locale":
            instance.locale,
            "translations": [{
                "locale":
                locale,
                "url":
                reverse("wagtailsnippets:add", args=[app_label, model_name]) +
                "?locale=" + locale.language_code,
            } for locale in Locale.objects.all().exclude(id=instance.locale.id)
                             ],
        })

    return TemplateResponse(request, "wagtailsnippets/snippets/create.html",
                            context)
Esempio n. 8
0
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        items = self.model.objects.all()
        enable_locale_filter = getattr(settings, "WAGTAIL_I18N_ENABLED",
                                       False) and issubclass(
                                           self.model, TranslatableMixin)

        if enable_locale_filter:
            if "locale" in self.request.GET:
                try:
                    locale = Locale.objects.get(
                        language_code=self.request.GET["locale"])
                except Locale.DoesNotExist:
                    # Redirect to snippet without locale
                    return redirect("wagtailsnippets:list", self.app_label,
                                    self.model_name)
            else:
                # Default to active locale (this will take into account the user's chosen admin language)
                locale = Locale.get_active()

            items = items.filter(locale=locale)

        else:
            locale = None

        # Preserve the snippet's model-level ordering if specified, but fall back on PK if not
        # (to ensure pagination is consistent)
        if not items.ordered:
            items = items.order_by("pk")

        # Search
        is_searchable = class_is_indexed(self.model)
        is_searching = False
        search_query = None
        if is_searchable and "q" in self.request.GET:
            search_form = SearchForm(
                self.request.GET,
                placeholder=_("Search %(snippet_type_name)s") %
                {"snippet_type_name": self.model._meta.verbose_name_plural},
            )

            if search_form.is_valid():
                search_query = search_form.cleaned_data["q"]

                search_backend = get_search_backend()
                items = search_backend.search(search_query, items)
                is_searching = True

        else:
            search_form = SearchForm(
                placeholder=_("Search %(snippet_type_name)s") %
                {"snippet_type_name": self.model._meta.verbose_name_plural})

        paginator = Paginator(items, per_page=20)
        paginated_items = paginator.get_page(self.request.GET.get("p"))

        context.update({
            "model_opts":
            self.model._meta,
            "items":
            paginated_items,
            "can_add_snippet":
            self.request.user.has_perm(get_permission_name("add", self.model)),
            "can_delete_snippets":
            self.request.user.has_perm(
                get_permission_name("delete", self.model)),
            "is_searchable":
            is_searchable,
            "search_form":
            search_form,
            "is_searching":
            is_searching,
            "query_string":
            search_query,
            "locale":
            None,
            "translations": [],
        })

        if enable_locale_filter:
            context.update({
                "locale":
                locale,
                "translations": [{
                    "locale":
                    locale,
                    "url":
                    reverse(
                        "wagtailsnippets:list",
                        args=[self.app_label, self.model_name],
                    ) + "?locale=" + locale.language_code,
                } for locale in Locale.objects.all().exclude(id=locale.id)],
            })

        return context
Esempio n. 9
0
    def get_success_url(self):
        urlquery = ""
        if self.locale and self.object.locale is not Locale.get_default():
            urlquery = "?locale=" + self.object.locale.language_code

        return reverse(self.index_url_name) + urlquery
Esempio n. 10
0
 def test_get_active_overridden(self):
     with translation.override("fr"):
         self.assertEqual(Locale.get_active().language_code, "fr")
Esempio n. 11
0
 def test_get_active_default(self):
     self.assertEqual(Locale.get_active().language_code, "en")
Esempio n. 12
0
 def test_default_doesnt_have_to_be_english(self):
     locale = Locale.get_default()
     self.assertEqual(locale.language_code, "fr")
Esempio n. 13
0
 def test_default(self):
     locale = Locale.get_default()
     self.assertEqual(locale.language_code, "en")
Esempio n. 14
0
    def get(self, request, parent_page_id=None):
        self.i18n_enabled = getattr(settings, "WAGTAIL_I18N_ENABLED", False)

        # A missing or empty page_type parameter indicates 'all page types'
        # (i.e. descendants of wagtailcore.page)
        page_type_string = request.GET.get("page_type") or "wagtailcore.page"
        user_perm = request.GET.get("user_perms", False)

        try:
            self.desired_classes = page_models_from_string(page_type_string)
        except (ValueError, LookupError):
            raise Http404

        # Find parent page
        if parent_page_id:
            self.parent_page = get_object_or_404(Page, id=parent_page_id)
        elif self.desired_classes == (Page, ):
            # Just use the root page
            self.parent_page = Page.get_first_root_node()
        else:
            # Find the highest common ancestor for the specific classes passed in
            # In many cases, such as selecting an EventPage under an EventIndex,
            # this will help the administrator find their page quicker.
            all_desired_pages = Page.objects.all().type(*self.desired_classes)
            self.parent_page = all_desired_pages.first_common_ancestor()

        self.parent_page = self.parent_page.specific

        pages = self.get_object_list()
        pages = self.filter_object_list(pages)

        can_choose_root = request.GET.get("can_choose_root", False)
        target_pages = Page.objects.filter(pk__in=[
            int(pk) for pk in request.GET.getlist("target_pages[]", []) if pk
        ])

        match_subclass = request.GET.get("match_subclass", True)

        # Do permission lookups for this user now, instead of for every page.
        permission_proxy = UserPagePermissionsProxy(request.user)

        # Parent page can be chosen if it is a instance of desired_classes
        self.parent_page.can_choose = can_choose_page(
            self.parent_page,
            permission_proxy,
            self.desired_classes,
            can_choose_root,
            user_perm,
            target_pages=target_pages,
            match_subclass=match_subclass,
        )
        self.parent_page.is_parent_page = True
        self.parent_page.can_descend = False

        selected_locale = None
        locale_options = []
        if self.i18n_enabled:
            if self.parent_page.is_root():
                # 'locale' is the current value of the "Locale" selector in the UI
                if request.GET.get("locale"):
                    selected_locale = get_object_or_404(
                        Locale, language_code=request.GET["locale"])
                    active_locale_id = selected_locale.pk
                else:
                    active_locale_id = Locale.get_active().pk

                # we are at the Root level, so get the locales from the current pages
                choose_url = reverse("wagtailadmin_choose_page")
                locale_options = [{
                    "locale":
                    locale,
                    "url":
                    choose_url + "?" +
                    urlencode({
                        "page_type": page_type_string,
                        "locale": locale.language_code,
                    }),
                } for locale in Locale.objects.filter(
                    pk__in=pages.values_list("locale_id")).exclude(
                        pk=active_locale_id)]
            else:
                # We have a parent page (that is not the root page). Use its locale as the selected localer
                selected_locale = self.parent_page.locale
                # and get the locales based on its available translations
                locales_and_parent_pages = {
                    item["locale"]: item["pk"]
                    for item in Page.objects.translation_of(
                        self.parent_page).values("locale", "pk")
                }
                locales_and_parent_pages[
                    selected_locale.pk] = self.parent_page.pk
                for locale in Locale.objects.filter(
                        pk__in=list(locales_and_parent_pages.keys())).exclude(
                            pk=selected_locale.pk):
                    choose_child_url = reverse(
                        "wagtailadmin_choose_page_child",
                        args=[locales_and_parent_pages[locale.pk]],
                    )

                    locale_options.append({
                        "locale":
                        locale,
                        "url":
                        choose_child_url + "?" +
                        urlencode({"page_type": page_type_string}),
                    })

            # finally, filter the browseable pages on the selected locale
            if selected_locale:
                pages = pages.filter(locale=selected_locale)

        # Pagination
        # We apply pagination first so we don't need to walk the entire list
        # in the block below
        paginator = Paginator(pages, per_page=25)
        pages = paginator.get_page(request.GET.get("p"))

        # Annotate each page with can_choose/can_decend flags
        for page in pages:
            page.can_choose = can_choose_page(
                page,
                permission_proxy,
                self.desired_classes,
                can_choose_root,
                user_perm,
                target_pages=target_pages,
                match_subclass=match_subclass,
            )
            page.can_descend = page.get_children_count()
            page.is_parent_page = False

        table = PageChooserTable(
            self.columns,
            [self.parent_page] + list(pages),
        )

        # Render
        context = shared_context(
            request,
            {
                "parent_page":
                self.parent_page,
                "parent_page_id":
                self.parent_page.pk,
                "table":
                table,
                "pagination_page":
                pages,
                "search_form":
                SearchForm(),
                "page_type_string":
                page_type_string,
                "page_type_names": [
                    desired_class.get_verbose_name()
                    for desired_class in self.desired_classes
                ],
                "page_types_restricted":
                (page_type_string != "wagtailcore.page"),
                "show_locale_labels":
                self.i18n_enabled,
                "locale_options":
                locale_options,
                "selected_locale":
                selected_locale,
            },
        )

        return render_modal_workflow(
            request,
            "wagtailadmin/chooser/browse.html",
            None,
            context,
            json_data={
                "step": "browse",
                "parent_page_id": context["parent_page_id"]
            },
        )