kopia lustrzana https://github.com/wagtail/wagtail
Add locale filter into snippet chooser (#6699)
rodzic
08be45dbd9
commit
4daeed1bf5
|
@ -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)
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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
|
||||
~~~~~~~~~
|
||||
|
|
|
@ -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');
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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'}
|
||||
)
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue