Add locale filter into snippet chooser (#6699)

pull/7193/head
Karl Hobley 2020-10-09 11:27:54 +01:00 zatwierdzone przez Matt Westcott
rodzic 08be45dbd9
commit 4daeed1bf5
11 zmienionych plików z 139 dodań i 4 usunięć

Wyświetl plik

@ -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)

Wyświetl plik

@ -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: {

Wyświetl plik

@ -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
~~~~~~~~~

Wyświetl plik

@ -103,6 +103,13 @@
{{ edit_handler.html_declarations }}
<script>
// Set wagtailConfig.ACTIVE_CONTENT_LOCALE if this is a translated page
// This value may be used by JS widgets on the form
{% if locale %}
window.wagtailConfig = window.wagtailConfig || {};
window.wagtailConfig.ACTIVE_CONTENT_LOCALE = '{{ locale.language_code|escapejs }}';
{% endif %}
$(function(){
$('#page-edit-form .tab-content section.active input').first().trigger('focus');

Wyświetl plik

@ -121,6 +121,13 @@
{{ edit_handler.html_declarations }}
<script>
// Set wagtailConfig.ACTIVE_CONTENT_LOCALE if this is a translated page
// This value may be used by JS widgets on the form
{% if locale %}
window.wagtailConfig = window.wagtailConfig || {};
window.wagtailConfig.ACTIVE_CONTENT_LOCALE = '{{ locale.language_code|escapejs }}';
{% endif %}
$(function() {
{% if publishing_will_cancel_workflow %}
/* Make user confirm before publishing the page if it will cancel an ongoing workflow */

Wyświetl plik

@ -13,13 +13,24 @@ SNIPPET_CHOOSER_MODAL_ONLOAD_HANDLERS = {
});
}
var searchUrl = $('form.snippet-search', modal.body).attr('action');
var searchForm$ = $('form.snippet-search', modal.body);
var searchUrl = searchForm$.attr('action');
var request;
function search() {
var data = {q: $('#id_q').val(), results: 'true'};
if (searchForm$.has('input[name="locale"]')) {
data['locale'] = $('input[name="locale"]', searchForm$).val();
}
if (searchForm$.has('#snippet-chooser-locale')) {
data['locale_filter'] = $('#snippet-chooser-locale', searchForm$).val();
}
request = $.ajax({
url: searchUrl,
data: {q: $('#id_q').val(), results: 'true'},
data: data,
success: function(data, status) {
request = null;
$('#search-results').html(data);

Wyświetl plik

@ -6,6 +6,10 @@
{# Need to keep the form in the HTML, even if the snippet is not searchable #}
{# This is to allow pagination links to be generated from the form action URL #}
<form class="snippet-search search-bar" action="{% url 'wagtailsnippets:choose' model_opts.app_label model_opts.model_name %}" method="GET" novalidate>
{% if locale %}
<input type="hidden" name="locale" value="{{ locale.language_code }}">
{% endif %}
{% if is_searchable %}
<ul class="fields">
{% for field in search_form %}
@ -14,6 +18,27 @@
<li class="submit"><input type="submit" value="{% trans 'Search' %}" class="button" /></li>
</ul>
{% endif %}
{% if locale_options %}
<ul class="fields">
<li class="col">
<div class="field field-small">
<select id="snippet-chooser-locale" name="lang">
{% for locale_option in locale_options %}
<option value="{{ locale_option.language_code }}"{% if locale_option == selected_locale %} selected{% endif %}>{{ locale_option.get_display_name }}</option>
{% endfor %}
</select>
<script type="text/javascript">
$(function() {
$('#snippet-chooser-locale').change(function() {
$('form.snippet-search').submit();
});
});
</script>
</div>
</li>
</ul>
{% endif %}
</form>
<div id="search-results" class="listing snippets">

Wyświetl plik

@ -34,4 +34,13 @@
{% include "wagtailadmin/pages/_editor_js.html" %}
{{ edit_handler.form.media.js }}
{{ edit_handler.html_declarations }}
<script>
// Set wagtailConfig.ACTIVE_CONTENT_LOCALE if this is a translated page
// This value may be used by JS widgets on the form
{% if locale %}
window.wagtailConfig = window.wagtailConfig || {};
window.wagtailConfig.ACTIVE_CONTENT_LOCALE = '{{ locale.language_code|escapejs }}';
{% endif %}
</script>
{% endblock %}

Wyświetl plik

@ -51,4 +51,13 @@
{% include "wagtailadmin/pages/_editor_js.html" %}
{{ edit_handler.form.media.js }}
{{ edit_handler.html_declarations }}
<script>
// Set wagtailConfig.ACTIVE_CONTENT_LOCALE if this is a translated page
// This value may be used by JS widgets on the form
{% if locale %}
window.wagtailConfig = window.wagtailConfig || {};
window.wagtailConfig.ACTIVE_CONTENT_LOCALE = '{{ locale.language_code|escapejs }}';
{% endif %}
</script>
{% endblock %}

Wyświetl plik

@ -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('<select id="snippet-chooser-locale" name="lang">', response.json()['html'])
def test_ordering(self):
"""
Listing should be ordered by PK if no ordering has been set on the model
@ -1083,6 +1087,30 @@ class TestSnippetChoose(TestCase, WagtailTestUtils):
def test_not_searchable(self):
self.assertFalse(self.get().context['is_searchable'])
@override_settings(WAGTAIL_I18N_ENABLED=True)
def test_filter_by_locale(self):
self.url_args = ['snippetstests', 'translatablesnippet']
fr_locale = Locale.objects.create(language_code="fr")
TranslatableSnippet.objects.create(text="English snippet")
TranslatableSnippet.objects.create(text="French snippet", locale=fr_locale)
response = self.get()
# Check the filter is added
self.assertIn('<select id="snippet-chooser-locale" name="lang">', 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):

Wyświetl plik

@ -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'}
)