learning-website-framework1-5 Exercise 3: Generate Each Site's Menu ========================================================================= Write a function that returns a site's top menu from the site map and the real folders, with readable labels, and adds a Sidebar entry only for sites that actually receive sidebar pages. Save as nav_for_site.py next to sitemap.py: import os, re, sys from sitemap import SITES, SIDEBAR_ROUTES ACRONYMS = {"ai", "css", "html", "js", "php", "sql", "api", "seo", "tls", "https", "ssh", "vpn", "rdp", "vnc", "grub", "awk", "sed", "iis", "obs", "vfx", "pdf", "k8s", "llm", "nlp", "gpu", "cpu", "os", "ui", "ux", "cli", "sdk", "ide", "json", "xml", "yaml", "rest", "graphql", "grpc", "cicd", "ci-cd", "iot", "orm", "jwt", "oauth", "cdn"} def humanize(segment): words = [w for w in re.split(r"[-_]+", segment) if w] return " ".join(w.upper() if w.lower() in ACRONYMS else w.capitalize() for w in words) def nav_for(site, content): on_disk = {d for d in os.listdir(content) if os.path.isdir(os.path.join(content, d))} items = [] for folder in SITES[site]: if folder in on_disk: items.append({"label": humanize(folder), "href": f"/{folder}/"}) # a site only gets a Sidebar entry if some sidebar// is routed to it if "sidebar" in on_disk and site in SIDEBAR_ROUTES.values(): items.append({"label": "Sidebar", "href": "/sidebar/"}) return items if __name__ == "__main__": content = sys.argv[1] for site in sys.argv[2:]: print(site) for it in nav_for(site, content): print(f" {it['label']:<36} {it['href']}") Run it: python nav_for_site.py "/content" languages systems Output (checked by running it): languages France /france/ Germany /germany/ Hungary /hungary/ Japan /japan/ Culture /culture/ systems Linux /linux/ Operating Systems /operating-systems/ Networking /networking/ Cloud And Devops /cloud-and-devops/ Security /security/ Technical Support /technical-support/ Raspberry Pi /raspberry-pi/ Windows /windows/ Sidebar /sidebar/ Notes ----- - The labels use the same rule as the live site's humanize(): split on hyphens, capitalise, upper-case known acronyms. So "data-science-and-ml" comes out as "Data Science And Ml" and "cloud-and-devops" as "Cloud And Devops". The live site shows the same (its acronym list has no "ml", and it does not lower-case "and"). Fix both in the shared helper once, instead of renaming folders. - The languages site gets no Sidebar entry because no sidebar subject is routed to it. The systems site does, because sidebar/linux/ belongs to it. - The menu is generated, so it cannot drift from the folders the way the hand-written list did in Exercise 1. WHY THIS WORKS AS AN ANSWER --------------------------- Each site needs a menu limited to its own subjects. Deriving it from the one map keeps menus complete, avoids a second list to maintain, and makes the fix for a label (such as the acronym list) a single change.