Add page synchronization to simple_translation

pull/7552/head
Mitchel Cabuloy 2021-09-29 18:43:45 +08:00 zatwierdzone przez GitHub
rodzic f533726de3
commit d026632894
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
3 zmienionych plików z 104 dodań i 31 usunięć

Wyświetl plik

@ -29,3 +29,19 @@ Add ``"wagtail.contrib.simple_translation"`` to INSTALLED_APPS in your settings
Run ``python manage.py migrate`` to create the necessary permissions.
In the Wagtail admin, go to settings and give some users or groups the "Can submit translations" permission.
Page tree synchronisation
~~~~~~~~~~~~~~~~~~~~~~~~~
Depending on your use case, it may be useful to keep the page trees in sync between different locales.
You can enable this feature by setting `WAGTAILSIMPLETRANSLATION_SYNC_PAGE_TREE` to `True`.
.. code-block:: python
WAGTAILSIMPLETRANSLATION_SYNC_PAGE_TREE = True
When this feature is turned on, every time an editor creates a page, Wagtail creates an alias for that page under the page trees of all the other locales.
For example, when an editor creates the page "/en/blog/my-blog-post/", Wagtail creates an alias of that page at "/fr/blog/my-blog-post/" and "/de/blog/my-blog-post/".

Wyświetl plik

@ -1,5 +1,9 @@
from django.conf import settings
from django.db.models import Model
from wagtail.core import hooks
from wagtail.core.models import Locale
class SimpleTranslation(Model):
"""
@ -9,8 +13,28 @@ class SimpleTranslation(Model):
- `remove_stale_contenttypes`, will drop the perm
- `dump_data`, will complain about the missing table
"""
class Meta:
default_permissions = []
permissions = [
('submit_translation', "Can submit translations"),
("submit_translation", "Can submit translations"),
]
@hooks.register("after_create_page")
def after_create_page(request, page):
"""Creates page aliases in other locales when a page is created.
Whenever a page is created under a specific locale, this signal handler
creates an alias page for that page under the other locales.
e.g. When an editor creates the page "blog/my-blog-post" under the English
tree, this signal handler creates an alias of that page called
"blog/my-blog-post" under the other locales' trees.
"""
if getattr(settings, "WAGTAILSIMPLETRANSLATION_SYNC_PAGE_TREE", False):
# Check if the source tree needs to be synchronised into any other trees
# Create aliases in all those locales
for locale in Locale.objects.exclude(pk=page.locale_id):
if not page.has_translation(locale):
page.copy_for_translation(locale, copy_parents=True, alias=True)

Wyświetl plik

@ -6,8 +6,10 @@ from django.urls import reverse
from django.utils.translation import gettext_lazy
from wagtail.contrib.simple_translation.forms import SubmitTranslationForm
from wagtail.contrib.simple_translation.models import after_create_page
from wagtail.contrib.simple_translation.views import (
SubmitPageTranslationView, SubmitSnippetTranslationView, SubmitTranslationView)
from wagtail.core import hooks
from wagtail.core.models import Locale, Page, ParentNotTranslatedError
from wagtail.tests.i18n.models import TestPage
from wagtail.tests.snippets.models import TranslatableSnippet
@ -71,17 +73,13 @@ class TestSubmitTranslationView(WagtailTestUtils, TestCase):
self.assertIsInstance(context["form"], SubmitTranslationForm)
def test_dispatch_as_anon(self):
url = reverse(
"simple_translation:submit_page_translation", args=(self.en_homepage.id,)
)
url = reverse("simple_translation:submit_page_translation", args=(self.en_homepage.id,))
response = self.client.get(url)
self.assertEqual(response.status_code, 302)
self.assertEqual(response.url, f"/admin/login/?next={url}")
def test_dispatch_as_moderator(self):
url = reverse(
"simple_translation:submit_page_translation", args=(self.en_homepage.id,)
)
url = reverse("simple_translation:submit_page_translation", args=(self.en_homepage.id,))
user = self.login()
group = Group.objects.get(name="Moderators")
user.groups.add(group)
@ -89,9 +87,7 @@ class TestSubmitTranslationView(WagtailTestUtils, TestCase):
self.assertEqual(response.status_code, 200)
def test_dispatch_as_user_with_perm(self):
url = reverse(
"simple_translation:submit_page_translation", args=(self.en_homepage.id,)
)
url = reverse("simple_translation:submit_page_translation", args=(self.en_homepage.id,))
user = self.login()
permission = Permission.objects.get(codename="submit_translation")
user.user_permissions.add(permission)
@ -136,28 +132,20 @@ class TestSubmitPageTranslationView(WagtailTestUtils, TestCase):
self.assertEqual(view.get_subtitle(), "Welcome to your new Wagtail site!")
def test_submit_page_translation_view_test_get(self):
url = reverse(
"simple_translation:submit_page_translation", args=(self.en_blog_index.id,)
)
url = reverse("simple_translation:submit_page_translation", args=(self.en_blog_index.id,))
self.login()
response = self.client.get(url)
assert isinstance(response.context["form"], SubmitTranslationForm)
def test_submit_page_translation_view_test_post_invalid(self):
url = reverse(
"simple_translation:submit_page_translation", args=(self.en_blog_index.id,)
)
url = reverse("simple_translation:submit_page_translation", args=(self.en_blog_index.id,))
self.login()
response = self.client.post(url, {})
assert response.status_code == 200
assert response.context["form"].errors == {
"locales": ["This field is required."]
}
assert response.context["form"].errors == {"locales": ["This field is required."]}
def test_submit_page_translation_view_test_post_single_locale(self):
url = reverse(
"simple_translation:submit_page_translation", args=(self.en_blog_index.id,)
)
url = reverse("simple_translation:submit_page_translation", args=(self.en_blog_index.id,))
de = Locale.objects.get(language_code="de").id
data = {"locales": [de], "include_subtree": True}
self.login()
@ -176,9 +164,7 @@ class TestSubmitPageTranslationView(WagtailTestUtils, TestCase):
en_blog_post_sub = Page(title="Blog post sub", slug="blog-post-sub")
self.en_blog_post.add_child(instance=en_blog_post_sub)
url = reverse(
"simple_translation:submit_page_translation", args=(self.en_blog_post.id,)
)
url = reverse("simple_translation:submit_page_translation", args=(self.en_blog_post.id,))
de = Locale.objects.get(language_code="de").id
fr = Locale.objects.get(language_code="fr").id
data = {"locales": [de, fr], "include_subtree": True}
@ -187,9 +173,7 @@ class TestSubmitPageTranslationView(WagtailTestUtils, TestCase):
with self.assertRaisesMessage(ParentNotTranslatedError, ""):
self.client.post(url, data)
url = reverse(
"simple_translation:submit_page_translation", args=(self.en_blog_index.id,)
)
url = reverse("simple_translation:submit_page_translation", args=(self.en_blog_index.id,))
response = self.client.post(url, data)
assert response.status_code == 302
@ -252,9 +236,7 @@ class TestSubmitSnippetTranslationView(WagtailTestUtils, TestCase):
"model_name": "some_model",
"pk": 99,
}
self.assertEqual(
view.get_success_url(), "/admin/snippets/some_app/some_model/edit/99/"
)
self.assertEqual(view.get_success_url(), "/admin/snippets/some_app/some_model/edit/99/")
def test_get_success_message(self):
view = SubmitSnippetTranslationView()
@ -263,3 +245,54 @@ class TestSubmitSnippetTranslationView(WagtailTestUtils, TestCase):
view.get_success_message(self.fr_locale),
f"Successfully created French for translatable snippet 'TranslatableSnippet object ({self.en_snippet.id})'",
)
@override_settings(
LANGUAGES=[
("en", "English"),
("fr", "French"),
("de", "German"),
],
WAGTAIL_CONTENT_LANGUAGES=[
("en", "English"),
("fr", "French"),
("de", "German"),
],
WAGTAILSIMPLETRANSLATION_SYNC_PAGE_TREE=True
)
class TestPageTreeSync(WagtailTestUtils, TestCase):
def setUp(self):
self.en_locale = Locale.objects.first()
self.fr_locale = Locale.objects.create(language_code="fr")
self.de_locale = Locale.objects.create(language_code="de")
self.en_homepage = Page.objects.get(depth=2)
self.fr_homepage = self.en_homepage.copy_for_translation(self.fr_locale)
self.de_homepage = self.en_homepage.copy_for_translation(self.de_locale)
def test_hook_function_registered(self):
fns = hooks.get_hooks("after_create_page")
self.assertIn(after_create_page, fns)
def test_alias_created_after_page_saved(self):
en_blog_index = TestPage(title="Blog", slug="blog")
self.en_homepage.add_child(instance=en_blog_index)
after_create_page(None, en_blog_index)
fr_blog_index = en_blog_index.get_translation(self.fr_locale)
de_blog_index = en_blog_index.get_translation(self.de_locale)
self.assertEqual(fr_blog_index.alias_of.specific, en_blog_index)
self.assertEqual(de_blog_index.alias_of.specific, en_blog_index)
@override_settings(WAGTAILSIMPLETRANSLATION_SYNC_PAGE_TREE=False)
def test_page_sync_disabled(self):
en_blog_index = TestPage(title="Blog", slug="blog")
self.en_homepage.add_child(instance=en_blog_index)
after_create_page(None, en_blog_index)
self.assertFalse(en_blog_index.has_translation(self.fr_locale))
self.assertFalse(en_blog_index.has_translation(self.de_locale))