Skip to content
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

Added index.html pattern #256

Merged
merged 1 commit into from
Mar 2, 2025
Merged
Show file tree
Hide file tree
Changes from all 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
23 changes: 20 additions & 3 deletions django_cotton/templatetags/_component.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from typing import Union

from django.conf import settings
from django.template import Library
from django.template import Library, TemplateDoesNotExist
from django.template.base import (
Node,
)
Expand Down Expand Up @@ -85,13 +85,30 @@ def _get_cached_template(self, context, attrs):

template_path = self._generate_component_template_path(self.component_name, attrs.get("is"))

if template_path not in cache:
if template_path in cache:
return cache[template_path]

# Try to get the primary template
try:
template = get_template(template_path)
if hasattr(template, "template"):
template = template.template
cache[template_path] = template
return template
except TemplateDoesNotExist:
# If the primary template doesn't exist, try the fallback path (index.html)
fallback_path = template_path.rsplit(".html", 1)[0] + "/index.html"

# Check if the fallback template is already cached
if fallback_path in cache:
return cache[fallback_path]

return cache[template_path]
# Try to get the fallback template
template = get_template(fallback_path)
if hasattr(template, "template"):
template = template.template
cache[fallback_path] = template
return template

@staticmethod
@functools.lru_cache(maxsize=400)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,57 +3,7 @@
from django_cotton.tests.utils import CottonTestCase, get_rendered


class BasicComponentTests(CottonTestCase):
def test_component_is_rendered(self):
self.create_template(
"cotton/render.html",
"""<div class="i-am-component">{{ slot }}</div>""",
)

self.create_template(
"view.html",
"""<c-render>Hello, World!</c-render>""",
"view/",
)

# Override URLconf
with self.settings(ROOT_URLCONF=self.url_conf()):
response = self.client.get("/view/")
self.assertContains(response, '<div class="i-am-component">')
self.assertContains(response, "Hello, World!")

def test_nested_rendering(self):
self.create_template(
"cotton/parent.html",
"""
<div class="i-am-parent">
{{ slot }}
</div>
""",
)

self.create_template(
"cotton/child.html",
"""
<div class="i-am-child"></div>
""",
)

self.create_template(
"cotton/nested_render_view.html",
"""
<c-parent>
<c-child>d</c-child>
</c-parent>
""",
"view/",
)

with self.settings(ROOT_URLCONF=self.url_conf()):
response = self.client.get("/view/")
self.assertContains(response, '<div class="i-am-parent">')
self.assertContains(response, '<div class="i-am-child">')

class MiscComponentTests(CottonTestCase):
def test_cotton_directory_can_be_configured(self):
custom_dir = "components"

Expand All @@ -74,24 +24,6 @@ def test_cotton_directory_can_be_configured(self):
self.assertContains(response, '<div class="i-am-component">')
self.assertContains(response, "Hello, World!")

def test_self_closing_is_rendered(self):
self.create_template("cotton/self_closing.html", """I self closed!""")
self.create_template(
"self_closing_view.html",
"""
1: <c-self-closing/>
2: <c-self-closing />
3: <c-self-closing />
""",
"view/",
)

with self.settings(ROOT_URLCONF=self.url_conf()):
response = self.client.get("/view/")
self.assertContains(response, "1: I self closed!")
self.assertContains(response, "2: I self closed!")
self.assertContains(response, "3: I self closed!")

def test_loader_scans_all_app_directories(self):
self.create_template(
"app_outside_of_dirs_view.html", """<c-app-outside-of-dirs />""", "view/"
Expand Down Expand Up @@ -221,3 +153,17 @@ def test_multiple_app_subdirectory_access(self):
self.assertTrue("I'm from app templates!" in rendered)
self.assertTrue("I'm from project root templates!" in rendered)
self.assertTrue("i'm sub in project root" in rendered)

def test_index_file_access(self):
self.create_template(
"cotton/accordion/index.html",
"I'm an index file!",
)

html = """
<c-accordion />
"""

rendered = get_rendered(html)

self.assertTrue("I'm an index file!" in rendered)
78 changes: 73 additions & 5 deletions django_cotton/tests/test_template_rendering.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,74 @@


class TemplateRenderingTests(CottonTestCase):
def test_component_is_rendered(self):
self.create_template(
"cotton/render.html",
"""<div class="i-am-component">{{ slot }}</div>""",
)

self.create_template(
"view.html",
"""<c-render>Hello, World!</c-render>""",
"view/",
)

# Override URLconf
with self.settings(ROOT_URLCONF=self.url_conf()):
response = self.client.get("/view/")
self.assertContains(response, '<div class="i-am-component">')
self.assertContains(response, "Hello, World!")

def test_nested_rendering(self):
self.create_template(
"cotton/parent.html",
"""
<div class="i-am-parent">
{{ slot }}
</div>
""",
)

self.create_template(
"cotton/child.html",
"""
<div class="i-am-child"></div>
""",
)

self.create_template(
"cotton/nested_render_view.html",
"""
<c-parent>
<c-child>d</c-child>
</c-parent>
""",
"view/",
)

with self.settings(ROOT_URLCONF=self.url_conf()):
response = self.client.get("/view/")
self.assertContains(response, '<div class="i-am-parent">')
self.assertContains(response, '<div class="i-am-child">')

def test_self_closing_is_rendered(self):
self.create_template("cotton/self_closing.html", """I self closed!""")
self.create_template(
"self_closing_view.html",
"""
1: <c-self-closing/>
2: <c-self-closing />
3: <c-self-closing />
""",
"view/",
)

with self.settings(ROOT_URLCONF=self.url_conf()):
response = self.client.get("/view/")
self.assertContains(response, "1: I self closed!")
self.assertContains(response, "2: I self closed!")
self.assertContains(response, "3: I self closed!")

def test_new_lines_in_attributes_are_preserved(self):
self.create_template(
"cotton/preserved.html",
Expand Down Expand Up @@ -142,15 +210,15 @@ def test_querystring_can_be_rendered(self):

def test_cvars_isnt_changing_global_context(self):
self.create_template(
"cotton/child.html",
"cotton/cvars_child.html",
"""
<c-vars />

name: child (class: {{ class }})
""",
)
self.create_template(
"cotton/parent.html",
"cotton/cvars_parent.html",
"""
name: parent (class: {{ class }}))

Expand All @@ -161,9 +229,9 @@ def test_cvars_isnt_changing_global_context(self):
self.create_template(
"slot_scope_view.html",
"""
<c-parent>
<c-child class="testy" />
</c-parent>
<c-cvars-parent>
<c-cvars-child class="testy" />
</c-cvars-parent>
""",
"view/",
)
Expand Down