mirror of
https://github.com/Hopiu/wagtail-modeltranslation.git
synced 2026-05-12 09:13:15 +00:00
Patch slugurl to accept original language slug
no matter what is the user's current language
This commit is contained in:
parent
d22fc4c89c
commit
4bcd6086e0
5 changed files with 53 additions and 74 deletions
|
|
@ -19,3 +19,6 @@ class ModeltranslationConfig(AppConfig):
|
|||
|
||||
from .patch_wagtailadmin import patch_wagtail_models
|
||||
patch_wagtail_models()
|
||||
|
||||
from .patch_wagtailcore import patch_wagtail_tags
|
||||
patch_wagtail_tags()
|
||||
|
|
|
|||
21
wagtail_modeltranslation/contextlib.py
Normal file
21
wagtail_modeltranslation/contextlib.py
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
from django.utils.translation import activate
|
||||
from modeltranslation.utils import get_language
|
||||
|
||||
|
||||
class set_language:
|
||||
"""
|
||||
Context manager to safely change language momentarily
|
||||
|
||||
Usage:
|
||||
with set_language('en'):
|
||||
en_url = obj.get_absolute_url()
|
||||
"""
|
||||
def __init__(self, lang):
|
||||
self.language = lang
|
||||
self.current_language = get_language()
|
||||
|
||||
def __enter__(self):
|
||||
activate(self.language)
|
||||
|
||||
def __exit__(self, exctype, excinst, exctb):
|
||||
activate(self.current_language)
|
||||
|
|
@ -1,77 +1,7 @@
|
|||
# coding: utf-8
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.db import connection
|
||||
from django.db.models import F, Q
|
||||
from modeltranslation.settings import DEFAULT_LANGUAGE
|
||||
from modeltranslation.translator import translator
|
||||
from modeltranslation.utils import build_localized_fieldname
|
||||
from wagtail.wagtailcore.models import Page
|
||||
from modeltranslation.management.commands.update_translation_fields import Command as UpdateTranslationFieldsCommand
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = ('Updates empty values of default translation fields using'
|
||||
' values from original fields (in all translated models).')
|
||||
|
||||
def handle(self, **options):
|
||||
verbosity = int(options['verbosity'])
|
||||
if verbosity > 0:
|
||||
self.stdout.write(
|
||||
"Using default language: %s\n" % DEFAULT_LANGUAGE)
|
||||
models = translator.get_registered_models(abstract=False)
|
||||
for model in models:
|
||||
if verbosity > 0:
|
||||
self.stdout.write("Updating data of model '%s'\n" % model)
|
||||
opts = translator.get_options_for_model(model)
|
||||
for field_name in opts.fields.keys():
|
||||
def_lang_fieldname = build_localized_fieldname(
|
||||
field_name, DEFAULT_LANGUAGE)
|
||||
|
||||
# We'll only update fields which do not have an existing value
|
||||
q = Q(**{def_lang_fieldname: None})
|
||||
field = model._meta.get_field(field_name)
|
||||
if field.empty_strings_allowed:
|
||||
q |= Q(**{def_lang_fieldname: ''})
|
||||
|
||||
if issubclass(model, Page):
|
||||
for obj in model._default_manager.filter(q):
|
||||
# Get table description in order to know if field is
|
||||
# in child or parent table
|
||||
# TODO: Tested only on PostgreSQL engine
|
||||
db_table = model._meta.db_table
|
||||
db_table_desc = connection.introspection. \
|
||||
get_table_description(
|
||||
connection.cursor(), db_table)
|
||||
# original field in child class
|
||||
if field_name in [x.name for x in db_table_desc]:
|
||||
raw = model._default_manager.raw(
|
||||
'SELECT *, %s AS original_field FROM %s \
|
||||
WHERE page_ptr_id=%d LIMIT 1' % (
|
||||
field_name, db_table, obj.page_ptr_id))[0]
|
||||
setattr(
|
||||
obj, def_lang_fieldname, raw.original_field)
|
||||
# field is a foreign key
|
||||
elif (field_name + '_id') in \
|
||||
[x.name for x in db_table_desc]:
|
||||
raw = model._default_manager.raw(
|
||||
'SELECT *, %s AS original_field FROM %s \
|
||||
WHERE page_ptr_id=%d LIMIT 1' % (
|
||||
field_name + '_id',
|
||||
db_table,
|
||||
obj.page_ptr_id))[0]
|
||||
setattr(
|
||||
obj,
|
||||
def_lang_fieldname + '_id',
|
||||
raw.original_field)
|
||||
# original field parent class
|
||||
else:
|
||||
raw = Page._default_manager.raw(
|
||||
'SELECT *, %s AS original_field FROM \
|
||||
wagtailcore_page WHERE id=%d LIMIT 1' % (
|
||||
field_name, obj.page_ptr_id))[0]
|
||||
setattr(
|
||||
obj, def_lang_fieldname, raw.original_field)
|
||||
obj.save(update_fields=[def_lang_fieldname])
|
||||
else:
|
||||
model._default_manager.filter(q).rewrite(False).update(
|
||||
**{def_lang_fieldname: F(field_name)})
|
||||
class Command(UpdateTranslationFieldsCommand):
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -552,4 +552,3 @@ def patch_wagtail_models():
|
|||
for model_class in registered_models:
|
||||
if issubclass(model_class, Page) or model_class in get_snippet_models() or issubclass(model_class, BaseSetting):
|
||||
WagtailTranslator(model_class)
|
||||
|
||||
|
|
|
|||
26
wagtail_modeltranslation/patch_wagtailcore.py
Normal file
26
wagtail_modeltranslation/patch_wagtailcore.py
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
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)
|
||||
Loading…
Reference in a new issue