Repository: django-cms/django-cms

Issue:
Adding non existing placeholder to existing page throw NoReverseMatch (CMS 3.0)
When adding a NEW placeholder to an existing page's template, Django will throw the following exception:

`Reverse for 'cms_page_clear_placeholder' with arguments '('',)' and keyword arguments '{}' not found.`



Discussion:

Resolving patch:
diff --git a/cms/models/pagemodel.py b/cms/models/pagemodel.py
--- a/cms/models/pagemodel.py
+++ b/cms/models/pagemodel.py
@@ -1097,6 +1097,7 @@ def rescan_placeholders(self):
                 placeholder = Placeholder.objects.create(slot=placeholder_name)
                 self.placeholders.add(placeholder)
                 found[placeholder_name] = placeholder
+        return found
 
 
 def _reversion():
diff --git a/cms/templatetags/cms_tags.py b/cms/templatetags/cms_tags.py
--- a/cms/templatetags/cms_tags.py
+++ b/cms/templatetags/cms_tags.py
@@ -158,8 +158,7 @@ def _get_placeholder(current_page, page, context, name):
     if page.pk in placeholder_cache:
         return placeholder_cache[page.pk].get(name, None)
     placeholder_cache[page.pk] = {}
-    slots = get_placeholders(page.get_template())
-    placeholders = page.placeholders.filter(slot__in=slots)
+    placeholders = page.rescan_placeholders().values()
     assign_plugins(context['request'], placeholders, get_language())
     for placeholder in placeholders:
         placeholder_cache[page.pk][placeholder.slot] = placeholder


Test patch:
diff --git a/cms/tests/templatetags.py b/cms/tests/templatetags.py
--- a/cms/tests/templatetags.py
+++ b/cms/tests/templatetags.py
@@ -6,7 +6,7 @@
 from cms.api import create_page, create_title, add_plugin
 from cms.models.pagemodel import Page, Placeholder
 from djangocms_text_ckeditor.cms_plugins import TextPlugin
-from cms.templatetags.cms_tags import get_site_id, _get_page_by_untyped_arg, _show_placeholder_for_page
+from cms.templatetags.cms_tags import get_site_id, _get_page_by_untyped_arg, _show_placeholder_for_page, _get_placeholder
 from cms.test_utils.fixtures.templatetags import TwoPagesFixture
 from cms.test_utils.testcases import SettingsOverrideTestCase
 from cms.test_utils.util.context_managers import SettingsOverride
@@ -207,6 +207,23 @@ def test_untranslated_language_url(self):
             res = tpl.render(context)
             self.assertEqual(res, "/de/")
 
+    def test_create_placeholder_if_not_exist_in_template(self):
+        """
+        Tests that adding a new placeholder to a an exising page's template
+        creates the placeholder.
+        """
+        page = create_page('Test', 'col_two.html', 'en')
+        # I need to make it seem like the user added another plcaeholder to the SAME template.
+        page._template_cache = 'col_three.html'
+
+        class FakeRequest(object):
+            current_page = page
+            REQUEST = {'language': 'en'}
+
+        placeholder = _get_placeholder(page, page, dict(request=FakeRequest()), 'col_right')
+        db_placeholder = page.placeholders.get(slot='col_right')
+        self.assertEqual(placeholder.slot, 'col_right')
+
 
 class NoFixtureDatabaseTemplateTagTests(TestCase):
     def test_cached_show_placeholder_sekizai(self):