Skip to content

Commit

Permalink
Refactor navigation module
Browse files Browse the repository at this point in the history
The purpose is to make it simpler to understand and modify the
presentation layer.
  • Loading branch information
pedro-psb committed Jan 18, 2024
1 parent 7e0905f commit 355dd57
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 83 deletions.
1 change: 0 additions & 1 deletion .vagrant/machines/default/libvirt/vagrant_cwd

This file was deleted.

9 changes: 0 additions & 9 deletions .vagrant/rgloader/loader.rb

This file was deleted.

2 changes: 1 addition & 1 deletion src/pulp_docs/mkdocs_macros.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def prepare_repositories(TMPDIR: Path, repos: Repos, config: Config):
with as_file(data_file_docs) as _docs:
shutil.copytree(_docs, repo_docs / "pulp-docs")
shutil.copy(
repo_sources / repos.core.name / SRC_DOCS_DIRNAME / "index.md",
repo_sources / repos.core_repo.name / SRC_DOCS_DIRNAME / "index.md",
repo_docs / "index.md",
)

Expand Down
226 changes: 160 additions & 66 deletions src/pulp_docs/navigation.py
Original file line number Diff line number Diff line change
@@ -1,94 +1,97 @@
"""
The navigation generator module.
Responsible for creating a specific structure out of the available content-types, personas
and repository types. This structure should be compatible with how it would be written
in mkdocs.yml.
`get_navigation` is the entrypoint used for the final render.
```
# yml
- pageA: some-file.md
- some-other-file.md
# python
[
{"pageA": "/abs/path/to/some-file.md"},
"/abs/path/to/some-other-file.md",
]
```
Note that you either specify:
1. {title: file.md} -> define title explicitly
2. "/path/to/file.md" -> uses markdown '# title' or the filename, if former isnt present.
"""
from __future__ import annotations

import typing as t
from pathlib import Path

from pulp_docs.repository import Repos


def get_navigation(tmpdir: Path, repos: Repos):
"""The dynamic generated 'nav' section of mkdocs.yml"""
"""
The entrypoint for dynamic 'nav' generation for mkdocs.
# {repo}/docs/{persona}/{content-type}/*md
# {repo}/docs/reference/*md
def get_children(path: t.Union[str, Path]):
_path = tmpdir / path if isinstance(path, str) else path
result = [
str(file.relative_to(tmpdir))
for file in _path.glob("*.md")
if not file.name.startswith("_")
]
return result
Replace by another generation function to change how content is structured.
"""
NAV_GENERATOR_FUNCTION = grouped_by_content_type
return NAV_GENERATOR_FUNCTION(tmpdir, repos)

def expand_repos(template_str: str):
_nav = {}
for repo in repos.content:
lookup_path = tmpdir / template_str.format(repo=repo.name)
_repo_content = get_children(lookup_path)
_nav[repo.title] = _repo_content
return _nav

def expand_reference(template_str: str):
_nav = {}
for repo in repos.all:
lookup_path = tmpdir / template_str.format(repo=repo.name)
_repo_content = get_children(lookup_path)
reference_section = [
{"REST API": f"{repo.name}/docs/rest_api.md"},
{"Readme": f"{repo.name}/README.md"},
{"Code API": _repo_content},
{"Changelog": f"{repo.name}/CHANGELOG.md"},
]
_nav[repo.title] = reference_section
return _nav
def grouped_by_content_type(tmpdir: Path, repos: Repos):
"""
A specific nav generator function.
def from_core(url: str):
corename = "pulpcore"
return f"{corename}/{url}"
Organizes content (roughly) with the pattern.
{content-type}/
Overview/
{persona}/
{repos}
"""
f = AgregationUtils(tmpdir, repos)

# Aggregation and Grouping
getting_started = [
{"Overview": from_core("docs/sections/getting_started/index.md")},
{"Overview": f.section_file("getting_started/index.md")},
{"Quickstart": f.section_children("getting_started/quickstart")},
{"Fundamentals": f.section_children("getting_started/fundamentals")},
]
guides = [
{"Overview": f.section_file("guides/index.md")},
{
"Quickstart": get_children(
from_core("docs/sections/getting_started/quickstart")
"For Content-Management": f.repo_grouping(
"{repo}/docs/content-manager/guides"
)
},
{"For Sys-Admins": f.repo_grouping("{repo}/docs/sys-admin/guides")},
]
learn = [
{"Overview": f.section_file("learn/index.md")},
{
"Fundamentals": get_children(
from_core("docs/sections/getting_started/fundamentals")
"For Content-Management": f.repo_grouping(
"{repo}/docs/content-manager/learn"
)
},
]
guides = [
{"Overview": from_core("docs/sections/guides/index.md")},
{"For Content-Management": expand_repos("{repo}/docs/content-manager/guides")},
{"For Sys-Admins": expand_repos("{repo}/docs/sys-admin/guides")},
]
learn = [
{"Overview": from_core("docs/sections/learn/index.md")},
{"For Content-Management": expand_repos("{repo}/docs/content-manager/learn")},
{"For Sys-Admins": expand_repos("{repo}/docs/sys-admin/learn")},
{"For Sys-Admins": f.repo_grouping("{repo}/docs/sys-admin/learn")},
]
reference = [
{"Overview": from_core("docs/sections/reference/index.md")},
{"Repository Map": from_core("docs/sections/reference/01-repository-map.md")},
{"Glossary": from_core("docs/sections/reference/02-glossary.md")},
{"Repositories": expand_reference("{repo}/docs/reference")},
{"Overview": f.section_file("reference/index.md")},
{"Repository Map": f.section_file("reference/01-repository-map.md")},
{"Glossary": f.section_file("reference/02-glossary.md")},
{"Repositories": f.repo_reference_grouping()},
]
development = [
{"Overview": from_core("docs/sections/development/index.md")},
{
"Quickstart": get_children(
from_core("docs/sections/development/quickstart/")
)
},
{
"Onboarding": get_children(
from_core("docs/sections/development/onboarding/")
)
},
{"Guides": get_children("core/docs/sections/development/guides/")},
{"Overview": f.section_file("development/index.md")},
{"Quickstart": f.section_children("development/quickstart/")},
{"Onboarding": f.section_children("development/onboarding/")},
{"Guides": f.section_children("/development/guides/")},
]

# main navigation
# Main Section
navigation = [
{"Home": "index.md"},
{"Getting Started": getting_started},
Expand All @@ -98,3 +101,94 @@ def from_core(url: str):
{"Development": development},
]
return navigation


class AgregationUtils:
def __init__(self, tmpdir: Path, repos: Repos):
self.tmpdir = tmpdir
self.repos = repos

def get_children(self, path: t.Union[str, Path]) -> list[str]:
"""
Get all markdown files contained in @path non recursively.
Excludes files which startswith "_".
"""
_path = self.tmpdir / path if isinstance(path, str) else path
result = [
str(file.relative_to(self.tmpdir))
for file in _path.glob("*.md")
if not file.name.startswith("_")
]
return result

def repo_grouping(self, template_str: str):
"""
Get all markdown files that matches @template_str basepath and group by repos.
The @template_str should contain:
{repo} - use 'content' and 'other' repo types
{content-repo} - use 'content' repos only
{other-repo} - use 'other' repos only
Example:
>>> expand_repos("{repo}/docs/dev/guides")
{
"repoA": ["docs/dev/guides/file1.md", "docs/dev/guides/file2.md"],
"repoB": ["docs/dev/guides/file3.md", "docs/dev/guides/file4.md"],
}
"""
_nav = {}
selected_repos = None
if "{repo}" in template_str:
selected_repos = self.repos.other_repos + self.repos.content_repos
elif "{content-repo}" in template_str:
selected_repos = self.repos.content_repos
elif "{other-repo}" in template_str:
selected_repos = self.repos.other_repos
else:
raise ValueError("Malformed template_str. See docstring for usage.")

for repo in selected_repos:
lookup_path = self.tmpdir / template_str.format(repo=repo.name)
_repo_content = self.get_children(lookup_path)
_nav[repo.title] = _repo_content
return _nav

def repo_reference_grouping(self):
"""
Create reference section by aggregating some specific files.
Group according to the pattern:
{repo}/
Readme.md
Rest Api.md
Code Api/
Module A.md
Module B.md
Changelog.md
"""
template_str = "{repo}/docs/reference"
_nav = {}
for repo in self.repos.all:
lookup_path = self.tmpdir / template_str.format(repo=repo.name)
_repo_content = self.get_children(lookup_path)
reference_section = [
{"REST API": f"{repo.name}/docs/rest_api.md"},
{"Readme": f"{repo.name}/README.md"},
{"Code API": _repo_content},
{"Changelog": f"{repo.name}/CHANGELOG.md"},
]
_nav[repo.title] = reference_section
return _nav

def section_file(self, url: str):
"""Get a markdown file from the website section folder."""
basepath = "pulpcore/docs/sections"
return f"{basepath}/{url}"

def section_children(self, url: str):
"""Get children markdown files from the website section folder."""
basepath = "pulpcore/docs/sections"
return self.get_children(f"{basepath}/{url}")
14 changes: 8 additions & 6 deletions src/pulp_docs/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,9 @@ def download_from_gh_latest(dest_dir: Path, owner: str, name: str):
class Repos:
"""A collection of Repos"""

core: Repo
content: t.List[Repo] = field(default_factory=list)
other: t.List[Repo] = field(default_factory=list)
core_repo: Repo
content_repos: t.List[Repo] = field(default_factory=list)
other_repos: t.List[Repo] = field(default_factory=list)

def update_local_checkouts(self):
"""Update repos to use local checkout, if exists in the parent dir of CWD"""
Expand All @@ -199,7 +199,7 @@ def update_local_checkouts(self):

@property
def all(self):
return [self.core] + self.content + self.other
return [self.core_repo] + self.content_repos + self.other_repos

@classmethod
def from_yaml(cls, path: str):
Expand Down Expand Up @@ -231,7 +231,9 @@ def from_yaml(cls, path: str):
core_repo = Repo(**repos["core"][0], type="core")
content_repos = [Repo(**repo, type="content") for repo in repos["content"]]
other_repos = [Repo(**repo, type="other") for repo in repos["other"]]
return Repos(core=core_repo, content=content_repos, other=other_repos)
return Repos(
core_repo=core_repo, content_repos=content_repos, other_repos=other_repos
)

@classmethod
def test_fixtures(cls):
Expand All @@ -253,4 +255,4 @@ def test_fixtures(cls):
),
Repo("Maven", "new_repo3", local_basepath=FIXTURE_WORKDIR, type="content"),
]
return Repos(core=DEFAULT_CORE, content=DEFAULT_CONTENT_REPOS)
return Repos(core_repo=DEFAULT_CORE, content_repos=DEFAULT_CONTENT_REPOS)

0 comments on commit 355dd57

Please sign in to comment.