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

Allow to collapse even with multiple children #93

Closed
wants to merge 2 commits into from
Closed
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
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,15 @@ If you want to enable or disable collapsing of a single page, without applying t
collapse: true
```

If you want to force the section to collapse even when having multiple children, add the flag `force_collapse`:

```yaml
collapse: true
force_collapse: true
```

Note that setting `collapse: false` will ignore `force_collapse`

### Hide Directory

Create a file named `.pages` in a directory and set the `hide` attribute to `true` to hide the directory, including all sub-pages and sub-sections, from the navigation:
Expand Down
22 changes: 19 additions & 3 deletions mkdocs_awesome_pages_plugin/meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ class Meta:
ARRANGE_REST_TOKEN = "..."
COLLAPSE_ATTRIBUTE = "collapse"
COLLAPSE_SINGLE_PAGES_ATTRIBUTE = "collapse_single_pages"
FORCE_COLLAPSE_ATTRIBUTE = "force_collapse"
HIDE_ATTRIBUTE = "hide"
ORDER_ATTRIBUTE = "order"
SORT_TYPE_ATTRIBUTE = "sort_type"
Expand All @@ -125,9 +126,10 @@ def __init__(
arrange: Optional[List[str]] = None,
nav: Optional[List[MetaNavItem]] = None,
path: Optional[str] = None,
collapse: bool = None,
collapse_single_pages: bool = None,
hide: bool = None,
collapse: Optional[bool] = None,
collapse_single_pages: Optional[bool] = None,
force_collapse: Optional[bool] = None,
hide: Optional[bool] = None,
order: Optional[str] = None,
sort_type: Optional[str] = None,
order_by: Optional[str] = None,
Expand All @@ -142,6 +144,7 @@ def __init__(
self.path = path
self.collapse = collapse
self.collapse_single_pages = collapse_single_pages
self.force_collapse = force_collapse
self.hide = hide
self.order = order
self.sort_type = sort_type
Expand Down Expand Up @@ -172,6 +175,7 @@ def load_from(path: str) -> "Meta":
nav = contents.get(Meta.NAV_ATTRIBUTE)
collapse = contents.get(Meta.COLLAPSE_ATTRIBUTE)
collapse_single_pages = contents.get(Meta.COLLAPSE_SINGLE_PAGES_ATTRIBUTE)
force_collapse = contents.get(Meta.FORCE_COLLAPSE_ATTRIBUTE)
hide = contents.get(Meta.HIDE_ATTRIBUTE)
order = contents.get(Meta.ORDER_ATTRIBUTE)
sort_type = contents.get(Meta.SORT_TYPE_ATTRIBUTE)
Expand Down Expand Up @@ -232,6 +236,17 @@ def load_from(path: str) -> "Meta":
context=path,
)
)

if force_collapse is not None:
if not isinstance(force_collapse, bool):
raise TypeError(
'Expected "{attribute}" attribute to be a boolean - got {type} [{context}]'.format(
attribute=Meta.FORCE_COLLAPSE_ATTRIBUTE,
type=type(force_collapse),
context=path,
)
)

if hide is not None:
if not isinstance(hide, bool):
raise TypeError(
Expand Down Expand Up @@ -277,6 +292,7 @@ def load_from(path: str) -> "Meta":
path=path,
collapse=collapse,
collapse_single_pages=collapse_single_pages,
force_collapse=force_collapse,
hide=hide,
order=order,
sort_type=sort_type,
Expand Down
32 changes: 18 additions & 14 deletions mkdocs_awesome_pages_plugin/navigation.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,12 @@ def _process_child_sections(self, children: List[NavigationItem], collapse: bool
for item in children:
if isinstance(item, VirtualSection):
item.children = self._process_child_sections(item.children, collapse)
result.append(item)
elif isinstance(item, Section):
item = self._process_section(item, collapse)
if item is None:
continue
result.append(item)

items = self._process_section(item, collapse)
result.extend(items)
else:
result.append(item)
return result

def _order(self, items: List[NavigationItem], meta: Meta):
Expand Down Expand Up @@ -168,11 +168,11 @@ def _expand_rest_rec(result: List[Union[NavigationItem, MetaNavRestItem]]):

return result

def _process_section(self, section: Section, collapse_recursive: bool) -> Optional[NavigationItem]:
def _process_section(self, section: Section, collapse_recursive: bool) -> List[NavigationItem]:
meta = self.meta.sections[section]

if meta.hide is True:
return None
return []

if meta.collapse_single_pages is not None:
collapse_recursive = meta.collapse_single_pages
Expand All @@ -182,12 +182,12 @@ def _process_section(self, section: Section, collapse_recursive: bool) -> Option
section.children = self._process_children(section.children, collapse_recursive, meta)

if section in self.explicit_sections:
return section
return [section]

if not section.children:
return None
return []

return self._collapse(section, meta.collapse, collapse_recursive)
return self._collapse(section, meta.collapse, collapse_recursive, force_collapse=meta.force_collapse)

def _get_item_path(self, item: NavigationItem) -> Optional[str]:
if isinstance(item, Section):
Expand Down Expand Up @@ -241,13 +241,17 @@ def _set_title(section: Section, meta: Meta):
section.title = meta.title

@staticmethod
def _collapse(section: Section, collapse: Optional[bool], collapse_recursive: bool) -> NavigationItem:
def _collapse(
section: Section, collapse: Optional[bool], collapse_recursive: bool, force_collapse: bool = False
) -> List[NavigationItem]:
if collapse is None:
collapse = collapse_recursive

if collapse and len(section.children) == 1:
return section.children[0]
return section
if collapse:
if force_collapse or len(section.children) == 1:
return section.children

return [section]

def to_mkdocs(self) -> MkDocsNavigation:
pages = get_by_type(self.items, Page)
Expand Down
2 changes: 2 additions & 0 deletions mkdocs_awesome_pages_plugin/tests/e2e/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def pagesFile(
nav: Optional[List[Union[str, dict]]] = None,
collapse: bool = None,
collapse_single_pages: bool = None,
force_collapse: bool = None,
hide: bool = None,
order: Optional[str] = None,
sort_type: Optional[str] = None,
Expand All @@ -43,6 +44,7 @@ def pagesFile(
"nav": nav,
"collapse": collapse,
"collapse_single_pages": collapse_single_pages,
"force_collapse": force_collapse,
"hide": hide,
"order": order,
"sort_type": sort_type,
Expand Down
64 changes: 64 additions & 0 deletions mkdocs_awesome_pages_plugin/tests/e2e/test_collapse.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,38 @@ def test_local(self):

self.assertEqual(navigation, [("A", [("C", [("Page", "/a/b/c/page")])])])

def test_local_multichildren(self):
navigation = self.mkdocs(
self.config,
[("a", [("b", [("c", ["page.md"]), ("d", ["page2.md"]), self.pagesFile(collapse=True)])])],
)

self.assertEqual(
navigation, [("A", [("B", [("C", [("Page", "/a/b/c/page")]), ("D", [("Page2", "/a/b/d/page2")])])])]
)

def test_local_multichildren_force_collapse(self):
navigation = self.mkdocs(
self.config,
[
(
"a",
[
(
"b",
[
("c", ["page.md"]),
("d", ["page2.md"]),
self.pagesFile(collapse=True, force_collapse=True),
],
)
],
)
],
)

self.assertEqual(navigation, [("A", [("C", [("Page", "/a/b/c/page")]), ("D", [("Page2", "/a/b/d/page2")])])])

def test_local_recursively(self):
navigation = self.mkdocs(
self.config,
Expand Down Expand Up @@ -79,6 +111,29 @@ def test_local_with_hide(self):

self.assertEqual(navigation, [("A", [("C", [("1", "/a/b/c/1")])])])

def test_local_with_hide_multichildren_force_collapse(self):
navigation = self.mkdocs(
self.config,
[
(
"a",
[
(
"b",
[
("c", ["1.md"]),
("d", ["2.md", self.pagesFile(hide=True)]),
("e", ["3.md"]),
self.pagesFile(collapse=True, force_collapse=True),
],
)
],
)
],
)

self.assertEqual(navigation, [("A", [("C", [("1", "/a/b/c/1")]), ("E", [("3", "/a/b/e/3")])])])


class TestCollapseGlobalEnabled(E2ETestCase):
def setUp(self):
Expand All @@ -102,6 +157,15 @@ def test_override_local(self):

self.assertEqual(navigation, [("B", [("Page", "/a/b/c/page")])])

def test_override_local_force_collapse(self):
# force_collapse is only effective if when collapse is active
navigation = self.mkdocs(
self.config,
[("a", [("b", [("c", ["page.md"]), self.pagesFile(collapse=False, force_collapse=True)])])],
)

self.assertEqual(navigation, [("B", [("Page", "/a/b/c/page")])])

def test_override_local_recursively(self):
navigation = self.mkdocs(
self.config,
Expand Down
35 changes: 23 additions & 12 deletions mkdocs_awesome_pages_plugin/tests/navigation/test_static.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,45 +31,56 @@ def setUp(self):
def test_default(self):
self.assertEqual(
AwesomeNavigation._collapse(self.parent, collapse=None, collapse_recursive=False),
self.parent,
[self.parent],
)

def test_local_false(self):
self.assertEqual(
AwesomeNavigation._collapse(self.parent, collapse=False, collapse_recursive=False),
self.parent,
[self.parent],
)

def test_explicit(self):
self.assertEqual(
AwesomeNavigation._collapse(self.parent, collapse=True, collapse_recursive=False),
self.child,
[self.child],
)

def test_explicit_and_recursive(self):
self.assertEqual(
AwesomeNavigation._collapse(self.parent, collapse=True, collapse_recursive=True),
self.child,
[self.child],
)

def test_recursive(self):
self.assertEqual(
AwesomeNavigation._collapse(self.parent, collapse=None, collapse_recursive=True),
self.child,
[self.child],
)

def test_local_override_false(self):
self.assertEqual(
AwesomeNavigation._collapse(self.parent, collapse=False, collapse_recursive=True),
self.parent,
[self.parent],
)

def test_multiple_children(self):
section = Section("Parent", [Section("Child 1", []), Section("Child 2", [])])

self.assertEqual(AwesomeNavigation._collapse(section, None, False), section)
self.assertEqual(AwesomeNavigation._collapse(section, None, True), section)
self.assertEqual(AwesomeNavigation._collapse(section, False, False), section)
self.assertEqual(AwesomeNavigation._collapse(section, True, False), section)
self.assertEqual(AwesomeNavigation._collapse(section, True, True), section)
self.assertEqual(AwesomeNavigation._collapse(section, False, True), section)
self.assertEqual(AwesomeNavigation._collapse(section, None, False), [section])
self.assertEqual(AwesomeNavigation._collapse(section, None, True), [section])
self.assertEqual(AwesomeNavigation._collapse(section, False, False), [section])
self.assertEqual(AwesomeNavigation._collapse(section, True, False), [section])
self.assertEqual(AwesomeNavigation._collapse(section, True, True), [section])
self.assertEqual(AwesomeNavigation._collapse(section, False, True), [section])

def test_multiple_children_force_collapse(self):
children = [Section("Child 1", []), Section("Child 2", [])]
section = Section("Parent", children)

self.assertEqual(AwesomeNavigation._collapse(section, None, False, True), [section])
self.assertEqual(AwesomeNavigation._collapse(section, None, True, True), children)
self.assertEqual(AwesomeNavigation._collapse(section, False, False, True), [section])
self.assertEqual(AwesomeNavigation._collapse(section, True, False, True), children)
self.assertEqual(AwesomeNavigation._collapse(section, True, True, True), children)
self.assertEqual(AwesomeNavigation._collapse(section, False, True, True), [section])