diff --git a/docs/template tags.rst b/docs/template tags.rst index 0f12ead..a9ee8b3 100644 --- a/docs/template tags.rst +++ b/docs/template tags.rst @@ -11,4 +11,17 @@ Use this template tag to get the url of the current page in another language. Th .. code-block:: django + {% load wagtail_modeltranslation %} {% change_lang 'pt' %} + +slugurl_trans +=========== + +Use this template tag as a replacement for `slugurl`. + +.. code-block:: django + + {% load wagtail_modeltranslation %} + {% slugurl_trans 'default_lang_slug' %} + {# or #} + {% slugurl_trans 'pt_lang_slug' 'pt' %} diff --git a/wagtail_modeltranslation/apps.py b/wagtail_modeltranslation/apps.py index 8154142..f77efc0 100644 --- a/wagtail_modeltranslation/apps.py +++ b/wagtail_modeltranslation/apps.py @@ -19,6 +19,3 @@ class ModeltranslationConfig(AppConfig): from .patch_wagtailadmin import patch_wagtail_models patch_wagtail_models() - - from .patch_wagtailcore import patch_wagtail_tags - patch_wagtail_tags() diff --git a/wagtail_modeltranslation/contextlib.py b/wagtail_modeltranslation/contextlib.py index 2f6d207..72218d3 100644 --- a/wagtail_modeltranslation/contextlib.py +++ b/wagtail_modeltranslation/contextlib.py @@ -2,12 +2,12 @@ from django.utils.translation import activate from modeltranslation.utils import get_language -class set_language: +class use_language: """ Context manager to safely change language momentarily Usage: - with set_language('en'): + with use_language('en'): en_url = obj.get_absolute_url() """ def __init__(self, lang): diff --git a/wagtail_modeltranslation/patch_wagtailcore.py b/wagtail_modeltranslation/patch_wagtailcore.py deleted file mode 100644 index 249a89d..0000000 --- a/wagtail_modeltranslation/patch_wagtailcore.py +++ /dev/null @@ -1,26 +0,0 @@ -from wagtail.wagtailcore.models import Page -from wagtail.wagtailcore.templatetags import wagtailcore_tags - -from modeltranslation.settings import DEFAULT_LANGUAGE - -from .contextlib import set_language - - -# decorate MigrationAutodetector.changes so we can silently remove wagtailcore changes -def slugurl_decorator(func): - def wrapper(context, slug): - with set_language(DEFAULT_LANGUAGE): - page = Page.objects.filter(slug=slug).first() - - if page: - return page.relative_url(context['request'].site) - else: - # default to original function - return func(context, slug) - - return wrapper - - -def patch_wagtail_tags(): - # decorate slugurl tag so `{% slugurl 'default_lang_slug' %}` always works with original slug - wagtailcore_tags.slugurl = slugurl_decorator(wagtailcore_tags.slugurl) diff --git a/wagtail_modeltranslation/templatetags/wagtail_modeltranslation.py b/wagtail_modeltranslation/templatetags/wagtail_modeltranslation.py index ff45021..492fbb2 100644 --- a/wagtail_modeltranslation/templatetags/wagtail_modeltranslation.py +++ b/wagtail_modeltranslation/templatetags/wagtail_modeltranslation.py @@ -5,8 +5,15 @@ import re from django import template from django.core.urlresolvers import resolve from django.utils.translation import activate, get_language + from six import iteritems +from wagtail.wagtailcore.models import Page + +from modeltranslation.settings import DEFAULT_LANGUAGE + +from wagtail_modeltranslation.contextlib import use_language + register = template.Library() @@ -43,3 +50,24 @@ def change_lang(context, lang=None, *args, **kwargs): return translated_url return '' + + +# Alternative to slugurl which uses chosen or default language for language +@register.simple_tag(takes_context=True) +def slugurl_trans(context, slug, language=None): + """ + Examples: + {% slugurl_trans 'default_lang_slug' %} + {% slugurl_trans 'de_lang_slug' 'de' %} + + Returns the URL for the page that has the given slug. + """ + language = language or DEFAULT_LANGUAGE + + with use_language(language): + page = Page.objects.filter(slug=slug).first() + + if page: + return page.relative_url(context['request'].site) + else: + return None diff --git a/wagtail_modeltranslation/tests/tests.py b/wagtail_modeltranslation/tests/tests.py index a6f43cb..0a9adb2 100755 --- a/wagtail_modeltranslation/tests/tests.py +++ b/wagtail_modeltranslation/tests/tests.py @@ -70,9 +70,8 @@ class WagtailModeltranslationTransactionTestBase(TransactionTestCase): # Reload the patching class to update the imported translator # in order to include the newly registered models - from wagtail_modeltranslation import patch_wagtailadmin, patch_wagtailcore + from wagtail_modeltranslation import patch_wagtailadmin imp.reload(patch_wagtailadmin) - imp.reload(patch_wagtailcore) # 3. Reset test models (because autodiscover have already run, those models # have translation fields, but for languages previously defined. We want @@ -355,8 +354,11 @@ class WagtailModeltranslationTest(WagtailModeltranslationTestBase): self.assertRaises(ValidationError, child2.clean) - def test_slugurl(self): - from wagtail.wagtailcore.templatetags.wagtailcore_tags import slugurl + def test_slugurl_trans(self): + """ + Assert tag slugurl_trans is immune to user's current language + """ + from wagtail_modeltranslation.templatetags.wagtail_modeltranslation import slugurl_trans site_pages = { 'model': models.TestRootPage, 'kwargs': {'title': 'root slugurl', }, @@ -374,13 +376,15 @@ class WagtailModeltranslationTest(WagtailModeltranslationTestBase): setattr(request_mock, 'site', site) context = {'request': request_mock} - self.assertEqual(slugurl(context, 'root-slugurl'), '/de/') - self.assertEqual(slugurl(context, 'child-slugurl'), '/de/child-slugurl/') + self.assertEqual(slugurl_trans(context, 'root-slugurl'), '/de/') + self.assertEqual(slugurl_trans(context, 'child-slugurl'), '/de/child-slugurl/') + self.assertEqual(slugurl_trans(context, 'child-slugurl-en', 'en'), '/de/child-slugurl/') trans_real.activate('en') - self.assertEqual(slugurl(context, 'root-slugurl'), '/en/') - self.assertEqual(slugurl(context, 'child-slugurl'), '/en/child-slugurl-en/') + self.assertEqual(slugurl_trans(context, 'root-slugurl'), '/en/') + self.assertEqual(slugurl_trans(context, 'child-slugurl'), '/en/child-slugurl-en/') + self.assertEqual(slugurl_trans(context, 'child-slugurl-en', 'en'), '/en/child-slugurl-en/') def test_original_slug_update(self): from wagtail.wagtailcore.models import Page