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)
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)
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
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()
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)
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"] }, )
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)
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
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
def test_get_active_overridden(self): with translation.override("fr"): self.assertEqual(Locale.get_active().language_code, "fr")
def test_get_active_default(self): self.assertEqual(Locale.get_active().language_code, "en")
def test_default_doesnt_have_to_be_english(self): locale = Locale.get_default() self.assertEqual(locale.language_code, "fr")
def test_default(self): locale = Locale.get_default() self.assertEqual(locale.language_code, "en")
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"] }, )