kopia lustrzana https://github.com/wagtail/wagtail
Add page synchronization to simple_translation
rodzic
f533726de3
commit
d026632894
|
@ -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/".
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
|
|
Ładowanie…
Reference in New Issue