10000 fix: Fail silently when rendering a placeholder on a missing toolbar object by fsbraun · Pull Request #7954 · django-cms/django-cms · GitHub
[go: up one dir, main page]

Skip to content

fix: Fail silently when rendering a placeholder on a missing toolbar object #7954

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

Merged
merged 3 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
1 change: 1 addition & 0 deletions .github/workflows/new_contributor_pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ jobs:
needs: new
steps:
- name: Send Discord Webhook
continue-on-error: true
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK_URL }}
DISCORD_EMBEDS: |
Expand Down
3 changes: 3 additions & 0 deletions cms/plugin_rendering.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from django.utils.translation import override

from cms.cache.placeholder import get_placeholder_cache, set_placeholder_cache
from cms.exceptions import PlaceholderNotFound
from cms.models import PageContent, Placeholder
from cms.toolbar.utils import (
get_placeholder_toolbar_js,
Expand Down Expand Up @@ -343,6 +344,8 @@ def render_obj_placeholder(self, slot, context, inherit,
# Not page, therefore we will use toolbar object as
# the current object and render the placeholder
current_obj = self.toolbar.get_object()
if current_obj is None:
< 10000 /td> raise PlaceholderNotFound(f"No object found for placeholder '{slot}'")
rescan_placeholders_for_obj(current_obj)
placeholder = Placeholder.objects.get_for_obj(current_obj).get(slot=slot)
content = self.render_placeholder(
Expand Down
13 changes: 12 additions & 1 deletion cms/tests/test_placeholder.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

from cms import constants
from cms.api import add_plugin, create_page, create_page_content
from cms.exceptions import DuplicatePlaceholderWarning
from cms.exceptions import DuplicatePlaceholderWarning, PlaceholderNotFound
from cms.models.fields import PlaceholderField
from cms.models.placeholdermodel import Placeholder
from cms.models.pluginmodel import CMSPlugin
Expand Down Expand Up @@ -141,6 +141,17 @@ def test_placeholder_scanning_var(self):
phs = sorted(node.get_declaration().slot for node in _scan_placeholders(t.nodelist))
self.assertListEqual(phs, sorted(['two', 'new_one', 'base_outside']))

def test_placeholder_scanning_no_object(self):
"""Placeholder scanning for a template without a toolbar object raises PlaceholderNotFound"""

context = SekizaiContext()
request = self.get_request(language="en", page=None)
toolbar = get_toolbar_from_request(request)
renderer = toolbar.get_content_renderer()
with self.assertRaises(PlaceholderNotFound):
renderer.render_obj_placeholder("someslot", context, False)


def test_fieldsets_requests(self):
response = self.client.get(admin_reverse('placeholderapp_example1_add'))
self.assertEqual(response.status_code, 200)
Expand Down
5 changes: 4 additions & 1 deletion cms/utils/placeholder.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import operator
import warnings
from collections import OrderedDict
from typing import Union

from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
Expand Down Expand Up @@ -406,11 +407,13 @@ def rescan_placeholders_for_obj(obj):
return existing


def get_declared_placeholders_for_obj(obj):
def get_declared_placeholders_for_obj(obj: Union[models.Model, None]) -> list[Placeholder]:
"""Returns declared placeholders for an object. The object is supposed to have a method ``get_template``
which returns the template path as a string that renders the object. ``get_declared_placeholders`` returns
a list of placeholders used in the template by the ``{% placeholder %}`` template tag.
"""
if obj is None:
return []
if not hasattr(obj, "get_template"):
raise NotImplementedError(
"%s should implement get_template" % obj.__class__.__name__
Expand Down
Loading
0