Skip to content

Commit

Permalink
add extra_context to NavGroup and NavItem
Browse files Browse the repository at this point in the history
  • Loading branch information
joshuadavidthomas committed Feb 23, 2024
1 parent 1a40cff commit 632e944
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/django_simple_nav/nav.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from dataclasses import dataclass
from dataclasses import field
from typing import Any

from django.http import HttpRequest
from django.template.loader import render_to_string
Expand Down Expand Up @@ -38,20 +39,29 @@ class NavGroup:
items: list[NavGroup | NavItem]
url: str | None = None
permissions: list[str] = field(default_factory=list)
extra_context: dict[str, Any] = field(default_factory=dict)


@dataclass(frozen=True)
class NavItem:
title: str
url: str
permissions: list[str] = field(default_factory=list)
extra_context: dict[str, Any] = field(default_factory=dict)


@dataclass(frozen=True)
class RenderedNavItem:
item: NavItem | NavGroup
request: HttpRequest

def __getattr__(self, name: str) -> Any:
try:
return self.item.extra_context[name]
except KeyError as err:
msg = f"{self.item!r} object has no attribute {name!r}"
raise AttributeError(msg) from err

@property
def title(self) -> str:
return mark_safe(self.item.title)
Expand Down
25 changes: 25 additions & 0 deletions tests/test_nav.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from django.utils.module_loading import import_string
from model_bakery import baker

from django_simple_nav.nav import NavItem
from django_simple_nav.nav import RenderedNavItem
from tests.navs import DummyNav
from tests.utils import count_anchors

Expand Down Expand Up @@ -96,3 +98,26 @@ def test_nav_render_from_request_with_template_name(req):
rendered_template = DummyNav.render_from_request(req, "tests/alternate.html")

assert "This is an alternate template." in rendered_template


def test_extra_context(req):
item = NavItem(
title="Test",
url="/test/",
extra_context={"foo": "bar"},
)

rendered_item = RenderedNavItem(item, req)

assert rendered_item.foo == "bar"


def test_extra_context_with_no_extra_context(req):
item = NavItem(
title="Test",
url="/test/",
)
rendered_item = RenderedNavItem(item, req)

with pytest.raises(AttributeError):
assert rendered_item.foo == "bar"

0 comments on commit 632e944

Please sign in to comment.