Skip to content

Commit 870b217

Browse files
stefanwfsbraun
andauthored
feat: Allow "View on Site" for objects not on the current site (#479)
* feat: Use `get_full_url` on versioned content if available This allows viewing versioned content on different sites * fix: Add a site query paramter to page admin change form * feat: Use django-cms core's get_object_live_url if available * fix: Linting issues * fix: tests --------- Co-authored-by: Fabian Braun <[email protected]>
1 parent 929442d commit 870b217

File tree

7 files changed

+32
-12
lines changed

7 files changed

+32
-12
lines changed

djangocms_versioning/admin.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,10 @@
4747
content_is_unlocked_for_user,
4848
create_version_lock,
4949
get_admin_url,
50+
get_current_site,
5051
get_editable_url,
5152
get_latest_admin_viewable_content,
53+
get_object_live_url,
5254
get_preview_url,
5355
proxy_model,
5456
remove_version_lock,
@@ -1097,9 +1099,9 @@ def publish_view(self, request, object_id):
10971099
self.message_user(request, _("Version published"))
10981100

10991101
# Redirect to published?
1100-
if conf.ON_PUBLISH_REDIRECT == "published":
1102+
if not requested_redirect and conf.ON_PUBLISH_REDIRECT == "published":
11011103
if hasattr(version.content, "get_absolute_url"):
1102-
requested_redirect = requested_redirect or version.content.get_absolute_url()
1104+
redirect_url = get_object_live_url(version.content, site=get_current_site(request)) or redirect_url
11031105

11041106
return self._internal_redirect(requested_redirect, redirect_url)
11051107

djangocms_versioning/cms_toolbars.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@
3232
from djangocms_versioning.conf import ALLOW_DELETING_VERSIONS, LOCK_VERSIONS
3333
from djangocms_versioning.constants import DRAFT
3434
from djangocms_versioning.helpers import (
35+
get_current_site,
3536
get_latest_admin_viewable_content,
37+
get_object_live_url,
3638
version_list_url,
3739
)
3840
from djangocms_versioning.models import Version
@@ -250,7 +252,9 @@ def _add_view_published_button(self):
250252
if not published_version:
251253
return
252254

253-
url = published_version.get_absolute_url() if hasattr(published_version, "get_absolute_url") else None
255+
url = None
256+
if hasattr(published_version, "get_absolute_url"):
257+
url = get_object_live_url(published_version, site=get_current_site(self.toolbar.request))
254258
if url and (self.toolbar.edit_mode_active or self.toolbar.preview_mode_active):
255259
item = ButtonList(side=self.toolbar.RIGHT)
256260
item.add_button(

djangocms_versioning/helpers.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from django.http import HttpRequest
1919
from django.template.loader import render_to_string
2020
from django.utils.encoding import force_str
21-
from django.utils.translation import get_language
21+
from django.utils.translation import get_language, override as force_language
2222

2323
from . import versionables
2424
from .conf import EMAIL_NOTIFICATIONS_FAIL_SILENTLY
@@ -29,6 +29,21 @@
2929
except ImportError:
3030
emit_content_change = None
3131

32+
try:
33+
# django CMS >= 5.1
34+
from cms.toolbar.utils import get_object_live_url # noqa F401
35+
from cms.utils import get_current_site # noqa F401
36+
except ImportError:
37+
# cms < 5.1
38+
def get_object_live_url(obj, language=None, site=None) -> str:
39+
with force_language(language):
40+
return obj.get_absolute_url()
41+
42+
def get_current_site(request) -> models.Model:
43+
from django.contrib.sites.models import Site
44+
45+
return Site.objects.get_current()
46+
3247

3348
def is_editable(content_obj: models.Model, request: HttpRequest) -> bool:
3449
"""Check of content_obj is editable"""
@@ -72,9 +87,7 @@ def _replace_admin_for_model(modeladmin: type[admin.ModelAdmin], mixin: type, ad
7287
admin_site.register(modeladmin.model, new_admin_class)
7388

7489

75-
def replace_admin_for_models(
76-
pairs: Iterable[tuple[type[models.Model], type]], admin_site: admin.AdminSite | None = None
77-
):
90+
def replace_admin_for_models(pairs: tuple[type[models.Model], type], admin_site: admin.AdminSite | None = None):
7891
"""
7992
:param pairs: Iterable of (model class, admin mixin class) tuples
8093
:param admin_site: AdminSite instance

djangocms_versioning/templates/admin/djangocms_versioning/page/change_form.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434

3535

3636

37-
<form {% if has_file_field %}enctype="multipart/form-data" {% endif %}action="?language={{ language }}{% if request.GET.parent_page %}&amp;parent_page={{ request.GET.parent_page }}{% endif %}{# parameter `parent_node` only for django CMS 4.1 support #}{% if request.GET.parent_node %}&amp;parent_node={{ request.GET.parent_node }}{% endif %}{%if request.GET.source %}&amp;source={{ request.GET.source }}{% endif %}" method="post" id="{{ opts.model_name }}_form">
37+
<form {% if has_file_field %}enctype="multipart/form-data" {% endif %}action="?language={{ language }}{% if request.GET.site %}&amp;site={{ request.GET.site }}{% endif %}{% if request.GET.parent_page %}&amp;parent_page={{ request.GET.parent_page }}{% endif %}{# parameter `parent_node` only for django CMS 4.1 support #}{% if request.GET.parent_node %}&amp;parent_node={{ request.GET.parent_node }}{% endif %}{%if request.GET.source %}&amp;source={{ request.GET.source }}{% endif %}" method="post" id="{{ opts.model_name }}_form">
3838
{% csrf_token %}
3939
{% block form_top %}{% endblock %}
4040

djangocms_versioning/test_utils/polls/models.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from cms.models import CMSPlugin
22
from django.db import models
33
from django.urls import reverse
4+
from django.utils.translation import override
45

56

67
class Poll(models.Model):
@@ -19,7 +20,8 @@ def __str__(self):
1920
return self.text
2021

2122
def get_absolute_url(self):
22-
return reverse("admin:polls_pollcontent_changelist")
23+
with override(self.language):
24+
return reverse("admin:polls_pollcontent_changelist")
2325

2426
def get_preview_url(self):
2527
return reverse("admin:polls_pollcontent_preview", args=[self.id])

tests/test_handlers.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ def test_change_plugin(self):
4646
plugin = add_plugin(
4747
placeholder, "PollPlugin", version.content.language, poll=poll
4848
)
49-
plugin.page.get_absolute_url = lambda *args, **kwargs: "/test_page/" # Fake URL needed for URI
5049

5150
dt = datetime(2016, 6, 6)
5251
with freeze_time(dt):

tests/test_menus.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from cms import constants as cms_constants
22
from cms.test_utils.testcases import CMSTestCase
33
from cms.toolbar.toolbar import CMSToolbar
4-
from cms.toolbar.utils import get_object_preview_url
4+
from cms.toolbar.utils import get_object_edit_url, get_object_preview_url
55
from django.contrib.auth.models import AnonymousUser
66
from django.template import Context, Template
77
from django.test import RequestFactory
@@ -74,7 +74,7 @@ def _assert_node(self, node, version, edit_or_preview=True):
7474
self.assertEqual(node.title, content.title)
7575

7676
if edit_or_preview:
77-
self.assertEqual(node.url, get_object_preview_url(content))
77+
self.assertIn(node.url, (get_object_preview_url(content), get_object_edit_url(content),))
7878
else:
7979
self.assertEqual(node.url, content.get_absolute_url())
8080

0 commit comments

Comments
 (0)