fix: avoid nested django contexts when rendering (#415)

* fix: avoid nested django contexts when rendering

* refactor: make input for slot context processing more specific

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Juro Oravec 2024-03-30 09:17:55 +01:00 committed by GitHub
parent 20847b978b
commit 2c8fc6c3a2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -262,14 +262,18 @@ class Component(View, metaclass=SimplifiedInterfaceMediaDefiningClass):
slots_data: Optional[Dict[SlotName, str]] = None, slots_data: Optional[Dict[SlotName, str]] = None,
escape_slots_content: bool = True, escape_slots_content: bool = True,
) -> str: ) -> str:
context = Context(context_data) # NOTE: This if/else is important to avoid nested Contexts,
# See https://github.com/EmilStenstrom/django-components/issues/414
context = context_data if isinstance(context_data, Context) else Context(context_data)
template = self.get_template(context) template = self.get_template(context)
if slots_data: if slots_data:
self._fill_slots(slots_data, escape_slots_content) self._fill_slots(slots_data, escape_slots_content)
updated_filled_slots_context: FilledSlotsContext = self._process_template_and_update_filled_slot_context( prev_filled_slots_context: Optional[FilledSlotsContext] = context.get(FILLED_SLOTS_CONTENT_CONTEXT_KEY)
context, template updated_filled_slots_context = self._process_template_and_update_filled_slot_context(
template,
prev_filled_slots_context,
) )
with context.update({FILLED_SLOTS_CONTENT_CONTEXT_KEY: updated_filled_slots_context}): with context.update({FILLED_SLOTS_CONTENT_CONTEXT_KEY: updated_filled_slots_context}):
return template.render(context) return template.render(context)
@ -305,8 +309,8 @@ class Component(View, metaclass=SimplifiedInterfaceMediaDefiningClass):
def _process_template_and_update_filled_slot_context( def _process_template_and_update_filled_slot_context(
self, self,
context: Context,
template: Template, template: Template,
slots_context: Optional[FilledSlotsContext],
) -> FilledSlotsContext: ) -> FilledSlotsContext:
if isinstance(self.fill_content, NodeList): if isinstance(self.fill_content, NodeList):
default_fill_content = (self.fill_content, None) default_fill_content = (self.fill_content, None)
@ -401,8 +405,7 @@ class Component(View, metaclass=SimplifiedInterfaceMediaDefiningClass):
for slot_name, content_data in slot_name2fill_content.items() for slot_name, content_data in slot_name2fill_content.items()
if content_data # Slots whose content is None (i.e. unfilled) are dropped. if content_data # Slots whose content is None (i.e. unfilled) are dropped.
} }
try: if slots_context is not None:
prev_context: FilledSlotsContext = context[FILLED_SLOTS_CONTENT_CONTEXT_KEY] return slots_context.new_child(filled_slots_map)
return prev_context.new_child(filled_slots_map) else:
except KeyError:
return ChainMap(filled_slots_map) return ChainMap(filled_slots_map)