Skip to content

Commit

Permalink
Allow creation of new (virtual) section from .pages
Browse files Browse the repository at this point in the history
Allows the `nav` config of `.pages` to create new sections to organize
pages.

Fixes #37
  • Loading branch information
dimrozakis authored Feb 12, 2022
1 parent fcb37dd commit b4a843c
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 16 deletions.
9 changes: 6 additions & 3 deletions mkdocs_awesome_pages_plugin/meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def __init__(self, item: str, context: str):


class MetaNavItem:
def __init__(self, value: str, title: Optional[str] = None):
def __init__(self, value: Union[str, List["MetaNavItem"]], title: Optional[str] = None):
self.value = value
self.title = title

Expand All @@ -34,8 +34,11 @@ def from_yaml(item: Union[str, dict], context: str):

if isinstance(item, dict) and len(item) == 1:
(title, value) = list(item.items())[0]
if isinstance(value, str) and isinstance(title, str):
return MetaNavItem(value, title)
if isinstance(title, str):
if isinstance(value, str):
return MetaNavItem(value, title)
elif isinstance(value, list):
return MetaNavItem([MetaNavItem.from_yaml(it, context) for it in value], title)

raise TypeError("Invalid nav item format {type} [{context}]".format(type=item, context=context))

Expand Down
45 changes: 32 additions & 13 deletions mkdocs_awesome_pages_plugin/navigation.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
)
from mkdocs.structure.pages import Page

from .meta import Meta, MetaNavRestItem, RestItemList
from .meta import Meta, MetaNavItem, MetaNavRestItem, RestItemList
from .options import Options
from .utils import dirname, basename, join_paths

Expand All @@ -37,6 +37,10 @@ def __init__(self, filename: str):
)


class VirtualSection(Section):
pass


class AwesomeNavigation:
def __init__(
self,
Expand Down Expand Up @@ -65,7 +69,7 @@ def _process_children(self, children: List[NavigationItem], collapse: bool, meta
result = []

for item in children:
if isinstance(item, Section):
if isinstance(item, Section) and not isinstance(item, VirtualSection):
item = self._process_section(item, collapse)
if item is None:
continue
Expand All @@ -86,19 +90,25 @@ def _nav(self, items: List[NavigationItem], meta: Meta) -> List[NavigationItem]:

items_by_basename = {basename(self._get_item_path(item)): item for item in items}

result = []
used_items = []
rest_items = RestItemList()

for index, meta_item in enumerate(meta.nav):
if isinstance(meta_item, MetaNavRestItem):
rest_items.append(meta_item)
result.append(meta_item)
else:
if meta_item.value in items_by_basename:
def _make_nav_rec(meta_nav: List[MetaNavItem]) -> List[Union[NavigationItem, MetaNavRestItem]]:
result = []
for meta_item in meta_nav:
if isinstance(meta_item, MetaNavRestItem):
rest_items.append(meta_item)
result.append(meta_item)

elif isinstance(meta_item.value, list):
result.append(VirtualSection(meta_item.title, children=_make_nav_rec(meta_item.value)))

elif meta_item.value in items_by_basename:
item = items_by_basename[meta_item.value]
if meta_item.title is not None:
item.title = meta_item.title
result.append(item)
used_items.append(item)

elif meta_item.title is not None:
result.append(Link(meta_item.title, meta_item.value))
Expand All @@ -109,21 +119,30 @@ def _nav(self, items: List[NavigationItem], meta: Meta) -> List[NavigationItem]:
raise warning
else:
warnings.warn(warning)
return result

result = _make_nav_rec(meta.nav)

if rest_items:
rest = {rest_item: [] for rest_item in rest_items}

for item in items:
if item not in result:
if item not in used_items:
path = basename(self._get_item_path(item))
for rest_item in rest_items:
if rest_item.matches(path):
rest[rest_item].append(item)
break

for index, item in enumerate(result):
if isinstance(item, MetaNavRestItem):
result[index : index + 1] = rest[item]
def _expand_rest_rec(result: List[Union[NavigationItem, MetaNavRestItem]]):
for index, item in enumerate(result):
if isinstance(item, MetaNavRestItem):
result[index : index + 1] = rest[item]
elif isinstance(item, Section):
if item.children:
_expand_rest_rec(item.children)

_expand_rest_rec(result)

return result

Expand Down
46 changes: 46 additions & 0 deletions mkdocs_awesome_pages_plugin/tests/e2e/test_nav.py
Original file line number Diff line number Diff line change
Expand Up @@ -423,3 +423,49 @@ def test_not_found_strict(self):
def test_not_found_not_strict(self):
with self.assertWarns(NavEntryNotFound):
self.mkdocs(self.createConfig(strict=False), [self.pagesFile(nav=["1.md", "..."])])

def test_virtual_section(self):
navigation = self.mkdocs(
self.config,
[
"a.md",
"b.md",
(
"x",
[
"1a.md",
"1b.md",
"2a.md",
"2b.md",
"3.md",
"4.md",
self.pagesFile(
nav=[
"4.md",
{"BB": ["... | *b.md"]},
"...",
{"AA": ["... | *a.md"]},
]
),
],
),
self.pagesFile(nav=["...", "b.md"]),
],
)

self.assertEqual(
navigation,
[
("A", "/a"),
(
"X",
[
("4", "/x/4"),
("BB", [("1b", "/x/1b"), ("2b", "/x/2b")]),
("3", "/x/3"),
("AA", [("1a", "/x/1a"), ("2a", "/x/2a")]),
],
),
("B", "/b"),
],
)
36 changes: 36 additions & 0 deletions mkdocs_awesome_pages_plugin/tests/navigation/test_nav.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,3 +388,39 @@ def test_not_found_not_strict(self):
],
strict=False,
)

def test_virtual_section(self):
navigation = self.createAwesomeNavigation(
[
self.page("1"),
self.page("2a"),
self.page("2b"),
self.page("2c"),
self.page("3a"),
self.page("3b"),
self.page("3c"),
self.page("4"),
Meta(
nav=[
MetaNavItem("4.md"),
MetaNavItem([MetaNavItem("2a.md"), MetaNavItem("3a.md")], "AA"),
MetaNavRestItem("..."),
MetaNavItem([MetaNavItem("2b.md"), MetaNavItem("3b.md")], "BB"),
MetaNavItem("1.md"),
]
),
]
)

self.assertNavigationEqual(
navigation.items,
[
self.page("4"),
self.section("AA", [self.page("2a"), self.page("3a")]),
self.page("2c"),
self.page("3c"),
self.section("BB", [self.page("2b"), self.page("3b")]),
self.page("1"),
],
)
self.assertValidNavigation(navigation.to_mkdocs())

0 comments on commit b4a843c

Please sign in to comment.