diff --git a/CHANGELOG.txt b/CHANGELOG.txt index fe408683cf..bb5fe97661 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -8,6 +8,7 @@ Changelog * Added `ancestor_of` API filter (Jaap Roes) * Added support for customising group management views (Jan Seifert) * Added `full_url` property to image renditions (Shreyash Srivastava) + * Added locale selector when choosing translatable snippets (Karl Hobley) * Fix: Invalid filter values for foreign key fields in the API now give an error instead of crashing (Tidjani Dia) * Fix: Ordering specified in `construct_explorer_page_queryset` hook is now taken into account again by the page explorer API (Andre Fonseca) * Fix: Deleting a page from its listing view no longer results in a 404 error (Tidjani Dia) diff --git a/client/src/entrypoints/snippets/snippet-chooser.js b/client/src/entrypoints/snippets/snippet-chooser.js index f3923ce32e..6a8ed5f50b 100644 --- a/client/src/entrypoints/snippets/snippet-chooser.js +++ b/client/src/entrypoints/snippets/snippet-chooser.js @@ -1,5 +1,7 @@ import $ from 'jquery'; +/* global wagtailConfig */ + function createSnippetChooser(id, modelString) { const chooserElement = $('#' + id + '-chooser'); const docTitle = chooserElement.find('.title'); @@ -53,9 +55,18 @@ function createSnippetChooser(id, modelString) { $('.action-choose', chooserElement).focus(); }, openChooserModal: () => { + let urlQuery = ''; + if (wagtailConfig.ACTIVE_CONTENT_LOCALE) { + // The user is editing a piece of translated content. + // Pass the locale along as a request parameter. If this + // snippet is also translatable, the results will be + // pre-filtered by this locale. + urlQuery = '?locale=' + wagtailConfig.ACTIVE_CONTENT_LOCALE; + } + // eslint-disable-next-line no-undef, new-cap ModalWorkflow({ - url: chooserBaseUrl, + url: chooserBaseUrl + urlQuery, // eslint-disable-next-line no-undef onload: SNIPPET_CHOOSER_MODAL_ONLOAD_HANDLERS, responses: { diff --git a/docs/releases/2.14.rst b/docs/releases/2.14.rst index baf168f354..53973de91d 100644 --- a/docs/releases/2.14.rst +++ b/docs/releases/2.14.rst @@ -16,6 +16,7 @@ Other features * Added ``ancestor_of`` API filter. See :ref:`apiv2_filter_by_tree_position`. (Jaap Roes) * Added support for customising group management views. See :ref:`customising_group_views`. (Jan Seifert) * Added ``full_url`` property to image renditions (Shreyash Srivastava) + * Added locale selector when choosing translatable snippets (Karl Hobley) Bug fixes ~~~~~~~~~ diff --git a/wagtail/admin/templates/wagtailadmin/pages/create.html b/wagtail/admin/templates/wagtailadmin/pages/create.html index 0790a5cc03..1b64a34bee 100644 --- a/wagtail/admin/templates/wagtailadmin/pages/create.html +++ b/wagtail/admin/templates/wagtailadmin/pages/create.html @@ -103,6 +103,13 @@ {{ edit_handler.html_declarations }} + + + + {% endif %}
diff --git a/wagtail/snippets/templates/wagtailsnippets/snippets/create.html b/wagtail/snippets/templates/wagtailsnippets/snippets/create.html index 223f3fc62f..faed75e87f 100644 --- a/wagtail/snippets/templates/wagtailsnippets/snippets/create.html +++ b/wagtail/snippets/templates/wagtailsnippets/snippets/create.html @@ -34,4 +34,13 @@ {% include "wagtailadmin/pages/_editor_js.html" %} {{ edit_handler.form.media.js }} {{ edit_handler.html_declarations }} + + {% endblock %} diff --git a/wagtail/snippets/templates/wagtailsnippets/snippets/edit.html b/wagtail/snippets/templates/wagtailsnippets/snippets/edit.html index e7a132979b..74deb9bc07 100644 --- a/wagtail/snippets/templates/wagtailsnippets/snippets/edit.html +++ b/wagtail/snippets/templates/wagtailsnippets/snippets/edit.html @@ -51,4 +51,13 @@ {% include "wagtailadmin/pages/_editor_js.html" %} {{ edit_handler.form.media.js }} {{ edit_handler.html_declarations }} + + {% endblock %} diff --git a/wagtail/snippets/tests.py b/wagtail/snippets/tests.py index 15fa053c95..fdb3d4cf59 100644 --- a/wagtail/snippets/tests.py +++ b/wagtail/snippets/tests.py @@ -1051,16 +1051,20 @@ class TestSnippetChoose(TestCase, WagtailTestUtils): def setUp(self): self.login() + self.url_args = ['tests', 'advert'] def get(self, params=None): return self.client.get(reverse('wagtailsnippets:choose', - args=('tests', 'advert')), + args=self.url_args), params or {}) def test_simple(self): response = self.get() self.assertTemplateUsed(response, 'wagtailsnippets/chooser/choose.html') + # Check locale filter doesn't exist normally + self.assertNotIn('', response.json()['html']) + + # Check both snippets are shown + self.assertEqual(len(response.context['items']), 2) + self.assertEqual(response.context['items'][0].text, "English snippet") + self.assertEqual(response.context['items'][1].text, "French snippet") + + # Now test with a locale selected + response = self.get({'locale': 'en'}) + + self.assertEqual(len(response.context['items']), 1) + self.assertEqual(response.context['items'][0].text, "English snippet") + class TestSnippetChooseWithSearchableSnippet(TestCase, WagtailTestUtils): def setUp(self): diff --git a/wagtail/snippets/views/chooser.py b/wagtail/snippets/views/chooser.py index 7c93eddb1a..ad5923a281 100644 --- a/wagtail/snippets/views/chooser.py +++ b/wagtail/snippets/views/chooser.py @@ -7,6 +7,7 @@ from django.utils.translation import gettext as _ from wagtail.admin.forms.search import SearchForm from wagtail.admin.modal_workflow import render_modal_workflow +from wagtail.core.models import Locale, TranslatableMixin from wagtail.search.backends import get_search_backend from wagtail.search.index import class_is_indexed from wagtail.snippets.views.snippets import get_snippet_model_from_url_params @@ -22,6 +23,24 @@ def choose(request, app_label, model_name): if not items.ordered: items = items.order_by('pk') + # Filter by locale + locale = None + locale_filter = None + selected_locale = None + if issubclass(model, TranslatableMixin): + # 'locale' is the Locale of the object that this snippet is being chosen for + if request.GET.get('locale'): + locale = get_object_or_404(Locale, language_code=request.GET['locale']) + + # 'locale_filter' is the current value of the "Locale" selector in the UI + if request.GET.get('locale_filter'): + locale_filter = get_object_or_404(Locale, language_code=request.GET['locale_filter']) + + selected_locale = locale_filter or locale + + if selected_locale: + items = items.filter(locale=selected_locale) + # Search is_searchable = class_is_indexed(model) is_searching = False @@ -54,6 +73,9 @@ def choose(request, app_label, model_name): 'items': paginated_items, 'query_string': search_query, 'is_searching': is_searching, + 'locale': locale, + 'locale_filter': locale_filter, + 'selected_locale': selected_locale, }) return render_modal_workflow( @@ -66,6 +88,10 @@ def choose(request, app_label, model_name): 'search_form': search_form, 'query_string': search_query, 'is_searching': is_searching, + 'locale': locale, + 'locale_filter': locale_filter, + 'selected_locale': selected_locale, + 'locale_options': Locale.objects.all() if issubclass(model, TranslatableMixin) else [], }, json_data={'step': 'choose'} )