Repository: django-cms/django-cms

Issue:
publishing on apphook sub pages redirects to apphook root page



Discussion:

Resolving patch:
diff --git a/cms/admin/pageadmin.py b/cms/admin/pageadmin.py
--- a/cms/admin/pageadmin.py
+++ b/cms/admin/pageadmin.py
@@ -1084,6 +1084,9 @@ def publish_page(self, request, page_id, language):
         if 'node' in request.REQUEST:
             # if request comes from tree..
             return admin_utils.render_admin_menu_item(request, page)
+
+        if 'redirect' in request.GET:
+            return HttpResponseRedirect(request.GET['redirect'])
         referrer = request.META.get('HTTP_REFERER', '')
 
         path = reverse("admin:cms_page_changelist")
diff --git a/cms/cms_toolbar.py b/cms/cms_toolbar.py
--- a/cms/cms_toolbar.py
+++ b/cms/cms_toolbar.py
@@ -1,7 +1,11 @@
 # -*- coding: utf-8 -*-
+try:
+    from urllib import urlencode
+except ImportError:
+    from urllib.parse import urlencode
 
 from django.conf import settings
-from django.core.urlresolvers import reverse, NoReverseMatch
+from django.core.urlresolvers import reverse, NoReverseMatch, resolve, Resolver404
 from django.utils.translation import ugettext_lazy as _
 from django.contrib import admin
 from django.contrib.auth.models import AnonymousUser
@@ -240,8 +244,20 @@ def post_template_populate(self):
                     pk = self.page.pk
                 with force_language(self.current_lang):
                     publish_url = reverse('admin:cms_page_publish_page', args=(pk, self.current_lang))
+                publish_url_args = {}
                 if dirty_statics:
-                    publish_url += "?statics=%s" % ','.join(str(static.pk) for static in dirty_statics)
+                    publish_url_args['statics'] = ','.join(str(static.pk) for static in dirty_statics)
+                # detect if we are in an apphook
+                with(force_language(self.toolbar.language)):
+                    try:
+                        resolver = resolve(self.request.path)
+                        from cms.views import details
+                        if resolver.func != details:
+                            publish_url_args['redirect'] = self.request.path
+                    except Resolver404:
+                        pass
+                if publish_url_args:
+                    publish_url = "%s?%s" % (publish_url, urlencode(publish_url_args))
                 if publish_permission:
                     self.toolbar.add_button(title, url=publish_url, extra_classes=classes, side=self.toolbar.RIGHT,
                                             disabled=not dirty)


Test patch:
diff --git a/cms/tests/apphooks.py b/cms/tests/apphooks.py
--- a/cms/tests/apphooks.py
+++ b/cms/tests/apphooks.py
@@ -203,6 +203,7 @@ def test_get_page_for_apphook_on_preview_or_edit(self):
         create_title('de', page.get_title(), page)
         page.publish('en')
         page.publish('de')
+        page.save()
         public_page = page.get_public_object()
 
         with self.login_user_context(superuser):
@@ -211,7 +212,8 @@ def test_get_page_for_apphook_on_preview_or_edit(self):
                 request = self.get_request(path + '?edit')
                 request.LANGUAGE_CODE = 'en'
                 attached_to_page = applications_page_check(request, path=path[1:])  # strip leading slash
-                self.assertEqual(attached_to_page.pk, public_page.pk)
+                response = self.client.get(path+"?edit")
+                self.assertContains(response, '?redirect=')
             with force_language("de"):
                 path = reverse('sample-settings')
                 request = self.get_request(path + '?edit')
@@ -306,6 +308,9 @@ def test_get_i18n_apphook_with_explicit_current_app(self):
                 reverse('namespaced_app_ns:current-app', current_app="instance_2")
                 reverse('namespaced_app_ns:current-app')
 
+
+
+
     def test_apphook_include_extra_parameters(self):
         with SettingsOverride(ROOT_URLCONF='cms.test_utils.project.second_urls_for_apphook_tests'):
             self.create_base_structure(NS_APP_NAME, ['en', 'de'], 'instance_1')