Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Feature/remove languages per site setting #161

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/source/settings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ If set to ``False`` wagtailtrans will work with ``Freeform`` trees.
.. seealso::
The documentation about :ref:`freeform_trees`


# TODO: Update this for the loaddata env var
``WAGTAILTRANS_LANGUAGES_PER_SITE``
-----------------------------------

Expand Down
7 changes: 6 additions & 1 deletion src/wagtailtrans/conf.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import logging

from django.conf import settings

logger = logging.getLogger(__name__)

DEFAULT_SETTINGS = {
'SYNC_TREE': True,
'LANGUAGES_PER_SITE': False,
'HIDE_TRANSLATION_TREES': False,
}


def get_wagtailtrans_setting(name):
if name == "LANGUAGES_PER_SITE":
logger.warning("WAGTAILTRANS_LANGUAGES_PER_SITE is removed, please update your code.")
return getattr(settings, 'WAGTAILTRANS_{}'.format(name), DEFAULT_SETTINGS[name])
6 changes: 1 addition & 5 deletions src/wagtailtrans/managers.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
from django.db import models

from .conf import get_wagtailtrans_setting


class LanguageManager(models.Manager):
"""Custom manager for the `Language` model."""
Expand All @@ -16,6 +14,4 @@ def default(self):

def default_for_site(self, site):
"""Return default language for site"""
if get_wagtailtrans_setting('LANGUAGES_PER_SITE'):
return self.filter(site_default_language__site=site).first()
return self.default()
return self.filter(site_default_language__site=site).first()
6 changes: 4 additions & 2 deletions src/wagtailtrans/middleware.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from django.conf import settings
from django.utils import translation
from django.utils.deprecation import MiddlewareMixin
from django.utils.translation import LANGUAGE_SESSION_KEY, check_for_language, get_language_from_path
from django.utils.translation.trans_real import get_languages, get_supported_language_variant
from django.utils.translation import (LANGUAGE_SESSION_KEY, check_for_language,
get_language_from_path)
from django.utils.translation.trans_real import (get_languages,
get_supported_language_variant)

from .models import Language
from .sites import get_languages_for_site
Expand Down
83 changes: 18 additions & 65 deletions src/wagtailtrans/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from django.utils.functional import cached_property
from django.utils.translation import activate
from django.utils.translation import ugettext_lazy as _

from wagtail.admin.edit_handlers import FieldPanel, MultiFieldPanel, PageChooserPanel
from wagtail.admin.forms import WagtailAdminModelForm, WagtailAdminPageForm
from wagtail.contrib.settings.models import BaseSetting
Expand All @@ -37,7 +36,6 @@ class WagtailAdminLanguageForm(WagtailAdminModelForm):
class Meta:
fields = [
'code',
'is_default',
'position',
'live',
]
Expand All @@ -48,42 +46,6 @@ def __init__(self, *args, **kwargs):
sorted_choices = sorted(self.fields['code'].choices, key=itemgetter(1))
self.fields['code'].choices = sorted_choices

def clean_is_default(self):
is_default = self.cleaned_data['is_default']

if self.initial.get('is_default') and not is_default:
raise ValidationError(_(
"You can not remove is_default from a language. To change the "
"default language, select is_default on a different language"))

return is_default

def save(self, commit=True):
is_default = self.cleaned_data.get('is_default', False)
if (
not self.initial.get('is_default') == is_default and
is_default and
not get_wagtailtrans_setting('LANGUAGES_PER_SITE')
):
from wagtailtrans.utils.language_switch import change_default_language # noqa
change_default_language(self.instance)
return super().save(commit=commit)


def get_language_panels():
children = [
FieldPanel('code'),
FieldPanel('position'),
FieldPanel('live'),
]

if not get_wagtailtrans_setting('LANGUAGES_PER_SITE'):
children.insert(1, FieldPanel('is_default'))

return [
MultiFieldPanel(heading=_("Language details"), children=children),
]


class Language(models.Model):
"""User defined language."""
Expand All @@ -100,7 +62,13 @@ class Language(models.Model):
objects = LanguageManager()

base_form_class = WagtailAdminLanguageForm
panels = get_language_panels()
panels = [
MultiFieldPanel(heading=_("Language details"), children=[
FieldPanel('code'),
FieldPanel('position'),
FieldPanel('live'),
])
]

class Meta:
ordering = ['position']
Expand All @@ -110,9 +78,6 @@ class Meta:
def __str__(self):
return force_text(dict(settings.LANGUAGES).get(self.code))

def has_pages_in_site(self, site):
return self.pages.filter(path__startswith=site.root_page.path).exists()


class AdminTranslatablePageForm(WagtailAdminPageForm):
"""Form to be used in the wagtail admin."""
Expand Down Expand Up @@ -183,12 +148,9 @@ def move(self, target, pos=None, suppress_sync=False):
"""
super().move(target, pos)

if get_wagtailtrans_setting('LANGUAGES_PER_SITE'):
site = self.get_site()
lang_settings = SiteLanguages.for_site(site)
is_default = lang_settings.default_language == self.language
else:
is_default = self.language.is_default
site = self.get_site()
lang_settings = SiteLanguages.for_site(site)
is_default = lang_settings.default_language == self.language

if not suppress_sync and get_wagtailtrans_setting('SYNC_TREE') and is_default:
self.move_translated_pages(canonical_target=target, pos=pos)
Expand Down Expand Up @@ -247,15 +209,15 @@ def has_translation(self, language):

def get_translation_parent(self, language):
site = self.get_site()
if not language.has_pages_in_site(site):
return site.root_page

translation_parent = (
TranslatablePage.objects
.filter(canonical_page=self.get_parent(), language=language, path__startswith=site.root_page.path)
.in_site(site)
.filter(canonical_page=self.get_parent(), language=language)
.order_by('path')
.first()
)
return translation_parent

return translation_parent or site.root_page

def create_translation(self, language, copy_fields=False, parent=None):
"""Create a translation for this page. If tree syncing is enabled the
Expand Down Expand Up @@ -354,9 +316,8 @@ def serve(self, request, *args, **kwargs):
def page_permissions_for_user(self, user):
"""Patch for the page permissions adding our custom proxy

Note: Since wagtail doesn't call this method on the
specific page we need to patch the default page
implementation for this.
Note: Since wagtail doesn't call this method on the specific page we need to patch
the default page implementation for this.

:param user: User instance
:return: user permissions for page
Expand Down Expand Up @@ -389,15 +350,7 @@ def save(self, commit=True):
return super().save(commit=commit)


def register_site_languages():
def decorate(func):
if get_wagtailtrans_setting('LANGUAGES_PER_SITE'):
return register_setting(func)
return func
return decorate


@register_site_languages()
@register_setting()
class SiteLanguages(BaseSetting):
"""Site specific settings are stored in the database"""
default_language = models.ForeignKey(
Expand Down
9 changes: 4 additions & 5 deletions src/wagtailtrans/permissions.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from django.contrib.auth.models import Group, Permission
from wagtail.core.models import (
Collection, GroupCollectionPermission, GroupPagePermission,
PagePermissionTester, UserPagePermissionsProxy)
from wagtail.core.models import (Collection, GroupCollectionPermission,
GroupPagePermission, PagePermissionTester,
UserPagePermissionsProxy)

from wagtailtrans.conf import get_wagtailtrans_setting

Expand Down Expand Up @@ -31,8 +31,7 @@ def create_group_permissions(group, language):
'access_admin', 'wagtailadmin', 'admin'
))

collection = Collection.objects.filter(
name='collection-%s' % language.code).first()
collection = Collection.objects.filter(name='collection-%s' % language.code).first()
if not collection:
root = Collection.objects.first().get_root()
collection = root.add_child(name='collection-%s' % language.code)
Expand Down
30 changes: 11 additions & 19 deletions src/wagtailtrans/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

from django.core.exceptions import ObjectDoesNotExist
from django.db.models.signals import m2m_changed, post_save, pre_delete

from wagtail.admin.signals import init_new_page
from wagtail.core.models import Site, get_page_models

from wagtailtrans.conf import get_wagtailtrans_setting
from wagtailtrans.models import Language, SiteLanguages, TranslatablePage
from wagtailtrans.permissions import create_group_permissions, get_or_create_language_group
Expand Down Expand Up @@ -38,13 +38,9 @@ def synchronize_trees(sender, instance, **kwargs):
except ObjectDoesNotExist:
return

if get_wagtailtrans_setting('LANGUAGES_PER_SITE'):
site_default = site.sitelanguages.default_language
is_default_language = instance.language == site_default
other_languages = site.sitelanguages.other_languages.all()
else:
is_default_language = instance.language.is_default
other_languages = Language.objects.filter(is_default=False)
site_default = site.sitelanguages.default_language
is_default_language = instance.language == site_default
other_languages = site.sitelanguages.other_languages.all()

if not kwargs.get('created') or not getattr(instance, 'language', False) or not is_default_language:
return
Expand Down Expand Up @@ -75,15 +71,13 @@ def create_new_language_tree_for_site(site, language):
:param language: The language in which the tree wil be created
"""
site_pages = site.root_page.get_children().values_list('pk', flat=True)
default_language = (
site.sitelanguages.default_language
if get_wagtailtrans_setting('LANGUAGES_PER_SITE')
else Language.objects.default()
)
default_language = site.sitelanguages.default_language

canonical_home_page = TranslatablePage.objects.filter(pk__in=site_pages, language=default_language).first()
if not canonical_home_page:
# no pages created yet.
return

descendants = canonical_home_page.get_descendants(inclusive=True)
for child_page in descendants:
child_page = child_page.specific
Expand Down Expand Up @@ -157,11 +151,11 @@ def force_parent_language(**kwargs):
#: For now we assume there isn't more than 1 site rooted at the parent.
if hasattr(parent, 'language'):
page.language = parent.language
elif get_wagtailtrans_setting('LANGUAGES_PER_SITE'):
else:
site = parent.sites_rooted_here.first()
if site:
lang_settings = SiteLanguages.for_site(site)
page.language = lang_settings.default_language or Language.objects.default()
page.language = lang_settings.default_language


def register_signal_handlers():
Expand All @@ -173,11 +167,9 @@ def register_signal_handlers():
"""
post_save.connect(create_language_permissions_and_group, sender=Language)
init_new_page.connect(force_parent_language)

if get_wagtailtrans_setting('SYNC_TREE'):
if get_wagtailtrans_setting('LANGUAGES_PER_SITE'):
m2m_changed.connect(update_language_trees_for_site, sender=SiteLanguages.other_languages.through)
else:
post_save.connect(create_new_language_tree, sender=Language)
m2m_changed.connect(update_language_trees_for_site, sender=SiteLanguages.other_languages.through)

for model in get_page_models():
if hasattr(model, 'create_translation'):
Expand Down
12 changes: 4 additions & 8 deletions src/wagtailtrans/sites.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
from .conf import get_wagtailtrans_setting
from .models import Language, SiteLanguages
from .models import SiteLanguages


def get_languages_for_site(site):
"""Utility to retrieve available languages for provided site."""
if get_wagtailtrans_setting('LANGUAGES_PER_SITE'):
site_languages = SiteLanguages.for_site(site)
languages = [site_languages.default_language] + list(site_languages.other_languages.all())
else:
languages = list(Language.objects.live().order_by('position'))
"""Utility to retrieve all available languages for site."""
site_languages = SiteLanguages.for_site(site)
languages = [site_languages.default_language] + list(site_languages.other_languages.all())

return languages
15 changes: 7 additions & 8 deletions src/wagtailtrans/wagtail_hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
from django.utils.encoding import force_text
from django.utils.html import format_html
from django.utils.translation import ugettext_lazy as _

from wagtail.admin import widgets
from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register
from wagtail.core import hooks

from wagtailtrans.conf import get_wagtailtrans_setting
from wagtailtrans.models import Language, TranslatablePage
from wagtailtrans.urls import translations
Expand All @@ -33,13 +33,12 @@ def register_admin_urls():
]


if get_wagtailtrans_setting('LANGUAGES_PER_SITE'):
@hooks.register('insert_global_admin_js')
def global_admin_js():
return format_html(
'<script type="text/javascript" src="{path}"></script>'.format(
path=static('wagtailtrans/js/site_languages_editor.js'))
)
@hooks.register('insert_global_admin_js')
def global_admin_js():
return format_html(
'<script type="text/javascript" src="{path}"></script>'.format(
path=static('wagtailtrans/js/site_languages_editor.js'))
)


if not get_wagtailtrans_setting('SYNC_TREE'):
Expand Down
9 changes: 6 additions & 3 deletions tests/factories/sites.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import factory

from wagtail.core.models import Site

from wagtailtrans import models

from tests.factories.language import LanguageFactory
from tests.factories.pages import HomePageFactory, TranslatableSiteRootFactory
from wagtailtrans import models


class SiteFactory(factory.DjangoModelFactory):
Expand All @@ -19,6 +17,11 @@ class Meta:
model = Site
django_get_or_create = ['hostname']

@factory.post_generation
def sitelanguages(self, create, extracted, **kwargs):
if create:
self.sitelanguages = SiteLanguagesFactory(site=self)


def create_site_tree(language, site=None, *items, **homepage_kwargs):
if not items:
Expand Down
Loading