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

Convert to alias #515

Merged
merged 10 commits into from
Feb 17, 2022
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{% extends "wagtailadmin/base.html" %}
{% load i18n wagtailadmin_tags %}
{% block titletag %}{% blocktrans with title=page.get_admin_display_title %}Convert to alias {{ title }}{% endblocktrans %}{% endblock %}

{% block content %}
{% trans "Convert to alias" as del_str %}
{% include "wagtailadmin/shared/header.html" with title=del_str subtitle=page.get_admin_display_title icon="doc-empty-inverse" %}

<div class="nice-padding">
<p>
{% trans 'Are you sure you want to convert this page into an alias?' %}
zerolab marked this conversation as resolved.
Show resolved Hide resolved
</p>

<form action="{% url 'wagtail_localize:convert_to_alias' page.id %}" method="POST">
{% csrf_token %}
<input type="hidden" name="next" value="{{ next }}">
<button type="submit" class="button serious">{% trans 'Yes, convert it' %}</button>
<a href="{% if next %}{{ next }}{% else %}{% url 'wagtailadmin_explore' page.get_parent.id %}{% endif %}" class="button button-secondary">{% trans "No, leave it as a page" %}</a>
</form>
</div>
{% endblock %}
62 changes: 62 additions & 0 deletions wagtail_localize/views/convert.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
from django.core.exceptions import PermissionDenied
from django.db import transaction
from django.http import Http404
from django.shortcuts import get_object_or_404, redirect
from django.template.response import TemplateResponse
from django.utils.translation import gettext as _
from wagtail.admin import messages
from wagtail.admin.views.pages.utils import get_valid_next_url_from_request
from wagtail.core.models import Page

from wagtail_localize.models import Translation


def convert_to_alias(request, page_id):
page = get_object_or_404(Page, id=page_id, alias_of_id__isnull=True)
if not page.permissions_for_user(request.user).can_edit():
kaedroho marked this conversation as resolved.
Show resolved Hide resolved
raise PermissionDenied

try:
source_locale_id = Translation.objects.filter(
source__object_id=page.translation_key,
target_locale_id=page.locale_id,
enabled=False,
).values_list("source__locale_id", flat=True)[0]
except (Translation.DoesNotExist, IndexError):
raise Http404

try:
source_page_id = Page.objects.filter(
translation_key=page.translation_key, locale_id=source_locale_id
).values_list("pk", flat=True)[0]
except (Page.DoesNotExist, IndexError):
raise Http404

with transaction.atomic():
next_url = get_valid_next_url_from_request(request)

if request.method == "POST":
page.alias_of_id = source_page_id
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we synchronise the content of the source page at this point?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably worth it, will check

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The consensus is that ye, we should synchronise with the source page at this point

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tl;dr
Tried with Translation.save_target() but that is very much dependent on the translatable_fields definition or lack thereof.

Resorted to a tweaked copy of Page.update_alias

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, do you think we could get those tweaks rolled back in to Wagtail core?

I'm happy with this change anyhow

page.save(update_fields=["alias_of_id"], clean=False)

# TODO: log entry

messages.success(
request,
_("Page '{}' has been converted into an alias.").format(
page.get_admin_display_title()
zerolab marked this conversation as resolved.
Show resolved Hide resolved
),
)

if next_url:
return redirect(next_url)
return redirect("wagtailadmin_pages:edit", page.id)

return TemplateResponse(
request,
"wagtail_localize/admin/confirm_convert_to_alias.html",
{
"page": page,
"next": next_url,
},
)
69 changes: 59 additions & 10 deletions wagtail_localize/wagtail_hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from django.contrib.admin.utils import quote
from django.contrib.auth.models import Permission
from django.shortcuts import redirect
from django.urls import include, path, reverse
from django.utils.translation import gettext as _
from django.utils.translation import gettext_lazy
Expand Down Expand Up @@ -29,6 +30,7 @@
from . import synctree # noqa
from .models import Translation, TranslationSource
from .views import (
convert,
edit_translation,
report,
snippets_api,
Expand Down Expand Up @@ -100,6 +102,11 @@ def register_admin_urls():
edit_translation.stop_translation,
name="stop_translation",
),
path(
"page/<int:page_id>/convert_to_alias/",
convert.convert_to_alias,
name="convert_to_alias",
),
path(
"reports/translations/",
report.TranslationsReportView.as_view(),
Expand Down Expand Up @@ -225,17 +232,22 @@ def before_edit_page(request, page):
return edit_translation.edit_translatable_alias_page(request, page)

# Check if the user has clicked the "Start Synced translation" menu item
if request.method == "POST" and "localize-restart-translation" in request.POST:
try:
translation = Translation.objects.get(
source__object_id=page.translation_key,
target_locale_id=page.locale_id,
enabled=False,
if request.method == "POST":
if "localize-restart-translation" in request.POST:
try:
translation = Translation.objects.get(
source__object_id=page.translation_key,
target_locale_id=page.locale_id,
enabled=False,
)
except Translation.DoesNotExist:
pass
else:
return edit_translation.restart_translation(request, translation, page)
elif "localize-convert-to-alias" in request.POST:
return redirect(
reverse("wagtail_localize:convert_to_alias", args=[page.id])
)
except Translation.DoesNotExist:
pass
else:
return edit_translation.restart_translation(request, translation, page)

# Overrides the edit page view if the page is the target of a translation
try:
Expand Down Expand Up @@ -283,6 +295,43 @@ def register_restart_translation_page_action_menu_item():
return RestartTranslationPageActionMenuItem(order=0)


class ConvertToAliasPageActionMenuItem(PageActionMenuItem):
label = gettext_lazy("Convert to alias page")
name = "localize-convert-to-alias"
icon_name = "undo"
classname = "action-secondary"

def _is_shown(self, context):
# Only show this menu item on the edit view where there was a previous translation record
if context["view"] != "edit":
return False
page = context["page"]

return (
page.alias_of_id is None
and Translation.objects.filter(
source__object_id=page.translation_key,
target_locale_id=page.locale_id,
enabled=False,
).exists()
)

if WAGTAIL_VERSION >= (2, 15):

def is_shown(self, context):
return self._is_shown(context)

else:

def is_shown(self, request, context):
return self._is_shown(context)


@hooks.register("register_page_action_menu_item")
def register_convert_back_to_alias_page_action_menu_item():
return ConvertToAliasPageActionMenuItem(order=0)


@hooks.register("before_edit_snippet")
def before_edit_snippet(request, instance):
if isinstance(instance, TranslatableMixin):
Expand Down