mirror of
https://github.com/Hopiu/wagtail-modeltranslation.git
synced 2026-03-16 22:10:30 +00:00
Merge pull request #142 from dmarcelino/original_slug
#141: Ensure original slug field is always saved in the same language
This commit is contained in:
commit
37eec32f7a
5 changed files with 156 additions and 6 deletions
|
|
@ -23,8 +23,36 @@ If, for example, you're using wagtail-embedvideos the EmbedVideoChooserPanel is
|
|||
|
||||
Default: ``[]`` (empty list)
|
||||
|
||||
This settings behaves as the above but should be used for panels that are composed by other panels (MultiFieldPanel or FieldRowPanel for example).
|
||||
This setting behaves as the above but should be used for panels that are composed by other panels (MultiFieldPanel or FieldRowPanel for example).
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
WAGTAILMODELTRANSLATION_CUSTOM_COMPOSED_PANELS = ['app_x.module_y.PanelZ']
|
||||
|
||||
|
||||
``WAGTAILMODELTRANSLATION_ORIGINAL_SLUG_LANGUAGE``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. versionadded:: 0.6.0
|
||||
|
||||
Default: ``None``
|
||||
|
||||
This setting enables consistency for the original (not translated) 'slug' value that is saved to the ``Page`` model table (wagtailcore_page). The value saved to the DB will be independent of user's current language and instead will rely on this setting's language.
|
||||
This is specially useful when Wagtail pages are edited by users of different languages and the site makes use of `slugurl <http://docs.wagtail.io/en/latest/topics/writing_templates.html#slugurl>`_.
|
||||
|
||||
``None``
|
||||
[set by default]
|
||||
|
||||
Setting turned off. Behaviour is the same as django-modeltranslation, meaning the value of the original slug field is undetermined (check `The State of the Original Field <http://django-modeltranslation.readthedocs.io/en/latest/usage.html#the-state-of-the-original-field>`_).
|
||||
|
||||
``'default'``
|
||||
Original slug field saved to the DB is in django-modeltranslation's default language.
|
||||
|
||||
``'xx'`` (language code)
|
||||
Use a language code to ensure the value saved to the original slug field is in the chosen language. For example: ``'en'``.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
WAGTAILMODELTRANSLATION_ORIGINAL_SLUG_LANGUAGE = 'default'
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ def runtests():
|
|||
('en', 'English'),
|
||||
),
|
||||
MIDDLEWARE_CLASSES=(),
|
||||
WAGTAILMODELTRANSLATION_ORIGINAL_SLUG_LANGUAGE='default',
|
||||
)
|
||||
|
||||
if django.VERSION >= (1, 7):
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import copy
|
||||
import logging
|
||||
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.core.exceptions import ValidationError, FieldDoesNotExist
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.db import transaction
|
||||
from django.http import Http404
|
||||
|
|
@ -23,7 +23,7 @@ from wagtail.wagtailsearch.index import SearchField
|
|||
from wagtail.wagtailsnippets.models import get_snippet_models
|
||||
from wagtail.wagtailsnippets.views.snippets import SNIPPET_EDIT_HANDLERS
|
||||
|
||||
from wagtail_modeltranslation.settings import CUSTOM_SIMPLE_PANELS, CUSTOM_COMPOSED_PANELS
|
||||
from wagtail_modeltranslation.settings import CUSTOM_SIMPLE_PANELS, CUSTOM_COMPOSED_PANELS, ORIGINAL_SLUG_LANGUAGE
|
||||
from wagtail_modeltranslation.utils import compare_class_tree_depth
|
||||
|
||||
logger = logging.getLogger('wagtail.core')
|
||||
|
|
@ -88,8 +88,15 @@ class WagtailTranslator(object):
|
|||
translated_field.field_name = build_localized_fieldname(field.field_name, language)
|
||||
model.search_fields = list(model.search_fields) + [translated_field]
|
||||
|
||||
# OVERRIDE PAGE METHODS
|
||||
# SLUG FIELD PATCHING
|
||||
|
||||
try:
|
||||
slug_field = model._meta.get_field('slug')
|
||||
_patch_pre_save(slug_field)
|
||||
except FieldDoesNotExist:
|
||||
pass
|
||||
|
||||
# OVERRIDE PAGE METHODS
|
||||
model.move = _new_move
|
||||
model.set_url_path = _new_set_url_path
|
||||
model.route = _new_route
|
||||
|
|
@ -201,7 +208,6 @@ class WagtailTranslator(object):
|
|||
# patched, leaving the original untouched
|
||||
return panel
|
||||
|
||||
|
||||
# Overridden Page methods adapted to the translated fields
|
||||
|
||||
@transaction.atomic # only commit when all descendants are properly updated
|
||||
|
|
@ -403,6 +409,30 @@ def _patch_clean(model):
|
|||
model.clean = clean
|
||||
|
||||
|
||||
def _patch_pre_save(field):
|
||||
if not ORIGINAL_SLUG_LANGUAGE:
|
||||
return
|
||||
|
||||
if ORIGINAL_SLUG_LANGUAGE == 'default':
|
||||
reference_slug_language = mt_settings.DEFAULT_LANGUAGE
|
||||
else:
|
||||
reference_slug_language = ORIGINAL_SLUG_LANGUAGE
|
||||
|
||||
def pre_save(self, model_instance, add):
|
||||
"""
|
||||
Returns slug field's value using the language set by `WAGTAILMODELTRANSLATION_ORIGINAL_SLUG_LANGUAGE`
|
||||
just before saving.
|
||||
"""
|
||||
current_language = get_language()
|
||||
# using ORIGINAL_SLUG_LANGUAGE makes Page's slug value consistent
|
||||
trans_real.activate(reference_slug_language)
|
||||
value = getattr(model_instance, self.attname)
|
||||
trans_real.activate(current_language)
|
||||
return value
|
||||
|
||||
field.pre_save = pre_save.__get__(field)
|
||||
|
||||
|
||||
def patch_wagtail_models():
|
||||
# After all models being registered the Page or BaseSetting subclasses and snippets are patched
|
||||
registered_models = translator.get_registered_models()
|
||||
|
|
|
|||
|
|
@ -10,3 +10,5 @@ CUSTOM_SIMPLE_PANELS = [import_from_string(panel_class) for panel_class in
|
|||
getattr(settings, 'WAGTAILMODELTRANSLATION_CUSTOM_SIMPLE_PANELS', [])]
|
||||
CUSTOM_COMPOSED_PANELS = [import_from_string(panel_class) for panel_class in
|
||||
getattr(settings, 'WAGTAILMODELTRANSLATION_CUSTOM_COMPOSED_PANELS', [])]
|
||||
|
||||
ORIGINAL_SLUG_LANGUAGE = getattr(settings, 'WAGTAILMODELTRANSLATION_ORIGINAL_SLUG_LANGUAGE', None)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import django
|
|||
from django.apps import apps as django_apps
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.core.management import call_command
|
||||
from django.test import TestCase, TransactionTestCase
|
||||
from django.test import TestCase, TransactionTestCase, RequestFactory
|
||||
from django.test.utils import override_settings
|
||||
from django.utils.translation import get_language, trans_real
|
||||
from modeltranslation import settings as mt_settings, translator
|
||||
|
|
@ -336,6 +336,95 @@ class WagtailModeltranslationTest(WagtailModeltranslationTestBase):
|
|||
|
||||
self.assertRaises(ValidationError, child2.clean)
|
||||
|
||||
def test_original_slug_update(self):
|
||||
from wagtail.wagtailcore.models import Page
|
||||
# save the page in the default language
|
||||
root = models.TestRootPage(title='original slug', title_de='originalschnecke', depth=1, path='0002',
|
||||
slug_en='test-slug-en', slug_de='test-slug-de')
|
||||
root.save()
|
||||
|
||||
# some control checks, we don't expect any surprises here
|
||||
self.assertEqual(root.slug, 'test-slug-de', 'slug has the wrong value.')
|
||||
self.assertEqual(root.slug_de, 'test-slug-de', 'slug_de has the wrong value.')
|
||||
self.assertEqual(root.slug_en, 'test-slug-en', 'slug_en has the wrong value.')
|
||||
|
||||
# fetches the correct Page using slug
|
||||
page = Page.objects.filter(slug='test-slug-de').first()
|
||||
self.assertEqual(page.specific, root, 'The wrong page was retrieved from DB.')
|
||||
|
||||
trans_real.activate('en')
|
||||
|
||||
# fetches the correct Page using slug using non-default language
|
||||
page = Page.objects.filter(slug='test-slug-de').first()
|
||||
self.assertEqual(page.specific, root, 'The wrong page was retrieved from DB.')
|
||||
|
||||
# save the page 2 in the non-default language
|
||||
root2 = models.TestRootPage(title='original slug 2', title_de='originalschnecke 2', depth=1, path='0003',
|
||||
slug_en='test-slug2-en', slug_de='test-slug2-de')
|
||||
root2.save()
|
||||
|
||||
# sanity checks
|
||||
self.assertEqual(root2.slug, 'test-slug2-en', 'slug has the wrong value.')
|
||||
self.assertEqual(root2.slug_de, 'test-slug2-de', 'slug_de has the wrong value.')
|
||||
self.assertEqual(root2.slug_en, 'test-slug2-en', 'slug_en has the wrong value.')
|
||||
|
||||
# fetches the correct Page using slug using non-default language
|
||||
page = Page.objects.filter(slug='test-slug2-de').first()
|
||||
self.assertEqual(page.specific, root2, 'The wrong page was retrieved from DB.')
|
||||
|
||||
trans_real.activate('de')
|
||||
|
||||
# fetches the correct Page using slug using default language
|
||||
page = Page.objects.filter(slug='test-slug2-de').first()
|
||||
self.assertEqual(page.specific, root2, 'The wrong page was retrieved from DB.')
|
||||
|
||||
|
||||
|
||||
def test_relative_url(self):
|
||||
from wagtail.wagtailcore.models import Site
|
||||
# Create a test Site with a root page
|
||||
root = models.TestRootPage(title='title slugurl', depth=1, path='0004',
|
||||
slug_en='title_slugurl_en', slug_de='title_slugurl_de')
|
||||
root.save()
|
||||
site = Site(root_page=root)
|
||||
site.save()
|
||||
|
||||
# Add children to the root
|
||||
child = root.add_child(
|
||||
instance=models.TestSlugPage1(title='child1 slugurl',
|
||||
slug_en='child-slugurl-en', slug_de='child-slugurl-de',
|
||||
depth=2, path='00040001')
|
||||
)
|
||||
child.save_revision().publish()
|
||||
|
||||
url_1_de = child.relative_url(site)
|
||||
self.assertEqual(url_1_de, '/de/child-slugurl-de/',
|
||||
'When using the default language, slugurl produces the wrong url.')
|
||||
|
||||
trans_real.activate('en')
|
||||
|
||||
url_1_en = child.relative_url(site)
|
||||
self.assertEqual(url_1_en, '/en/child-slugurl-en/',
|
||||
'When using non-default language, slugurl produces the wrong url.')
|
||||
|
||||
# Add children using non-default language
|
||||
child2 = root.add_child(
|
||||
instance=models.TestSlugPage2(title='child2 slugurl', title_de='child2 slugurl DE',
|
||||
slug_de='child2-slugurl-de', slug_en='child2-slugurl-en',
|
||||
depth=2, path='00040002')
|
||||
)
|
||||
child2.save_revision().publish()
|
||||
|
||||
url_2_en = child2.relative_url(site)
|
||||
self.assertEqual(url_2_en, '/en/child2-slugurl-en/',
|
||||
'When using non-default language, slugurl produces the wrong url.')
|
||||
|
||||
trans_real.activate('de')
|
||||
|
||||
url_2_de = child2.relative_url(site)
|
||||
self.assertEqual(url_2_de, '/de/child2-slugurl-de/',
|
||||
'When using non-default language, slugurl produces the wrong url.')
|
||||
|
||||
def test_searchfield_patching(self):
|
||||
# Check if the search fields have the original field plus the translated ones
|
||||
expected_fields = ['title', 'title_de', 'title_en', 'description', 'description_de', 'description_en']
|
||||
|
|
|
|||
Loading…
Reference in a new issue