Skip to content

Commit df1a175

Browse files
create slots helper module (#51)
1 parent c3395cd commit df1a175

File tree

2 files changed

+52
-38
lines changed

2 files changed

+52
-38
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from __future__ import annotations
2+
3+
from dataclasses import dataclass
4+
5+
from django.template.base import NodeList
6+
from django.template.base import Template
7+
from django.template.context import Context
8+
9+
DEFAULT_SLOT = "default"
10+
11+
12+
@dataclass
13+
class Slots:
14+
slots: dict[str, list[str]]
15+
context: Context
16+
17+
@classmethod
18+
def collect(cls, nodelist: NodeList | None, context: Context):
19+
from django_bird.templatetags.tags.slot import SlotNode
20+
21+
if nodelist is None:
22+
return cls({}, context)
23+
24+
slots: dict[str, list[str]] = {DEFAULT_SLOT: []}
25+
active_slot = DEFAULT_SLOT
26+
27+
for node in nodelist:
28+
if isinstance(node, SlotNode):
29+
active_slot = node.name
30+
slots.setdefault(active_slot, [])
31+
else:
32+
active_slot = DEFAULT_SLOT
33+
34+
rendered_content = node.render(context)
35+
slots[active_slot].append(rendered_content)
36+
37+
if all(not content for content in slots[DEFAULT_SLOT]) and "slot" in context:
38+
slots[DEFAULT_SLOT] = [context["slot"]]
39+
40+
return cls(slots, context)
41+
42+
def render(self):
43+
return {
44+
slot: Template("".join(content)).render(self.context)
45+
for slot, content in self.slots.items()
46+
}

src/django_bird/templatetags/tags/bird.py

Lines changed: 6 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,14 @@
1010
from django.template.context import Context
1111
from django.template.loader import select_template
1212
from django.utils.safestring import SafeString
13-
from django.utils.safestring import mark_safe
1413

1514
from django_bird._typing import TagBits
1615
from django_bird._typing import override
1716
from django_bird.components.attrs import Attrs
17+
from django_bird.components.slots import DEFAULT_SLOT
18+
from django_bird.components.slots import Slots
1819
from django_bird.components.templates import get_template_names
1920

20-
from .slot import SlotNode
21-
2221
TAG = "bird"
2322
END_TAG = "endbird"
2423

@@ -62,7 +61,6 @@ def __init__(self, name: str, attrs: list[str], nodelist: NodeList | None) -> No
6261
self.name = name
6362
self.attrs = attrs
6463
self.nodelist = nodelist
65-
self.default_slot = "default"
6664

6765
@override
6866
def render(self, context: Context) -> SafeString:
@@ -81,40 +79,10 @@ def get_component_name(self, context: Context) -> str:
8179

8280
def get_component_context_data(self, context: Context) -> dict[str, Any]:
8381
attrs = Attrs.parse(self.attrs, context)
84-
rendered_slots = self.render_slots(context)
85-
default_slot = rendered_slots.get(self.default_slot) or context.get("slot")
82+
slots = Slots.collect(self.nodelist, context).render()
83+
default_slot = slots.get(DEFAULT_SLOT) or context.get("slot")
8684
return {
8785
"attrs": attrs.flatten(),
88-
"slot": mark_safe(default_slot),
89-
"slots": {
90-
name: mark_safe(content) for name, content in rendered_slots.items()
91-
},
92-
}
93-
94-
def render_slots(self, context: Context) -> dict[str, str]:
95-
if self.nodelist is None:
96-
return {}
97-
98-
contents: dict[str, list[str]] = {self.default_slot: []}
99-
active_slot = self.default_slot
100-
101-
for node in self.nodelist:
102-
if isinstance(node, SlotNode):
103-
active_slot = node.name
104-
contents.setdefault(active_slot, [])
105-
else:
106-
active_slot = self.default_slot
107-
108-
rendered_content = node.render(context)
109-
contents[active_slot].append(rendered_content)
110-
111-
if (
112-
all(not content for content in contents[self.default_slot])
113-
and "slot" in context
114-
):
115-
contents[self.default_slot] = [context["slot"]]
116-
117-
return {
118-
slot: template.Template("".join(content)).render(context)
119-
for slot, content in contents.items()
86+
"slot": default_slot,
87+
"slots": slots,
12088
}

0 commit comments

Comments
 (0)