Navigation
Learning Website with Django
Chapter 6 ยท Navigation & Breadcrumbs
A visitor needs to know three things at every moment: which site am I on, what is on this site, and where am I within it. Learning Website: Framework & Architecture 5 designed three layers of navigation for that. This chapter builds them in Django, and keeps one rule throughout: every layer is derived from data that already exists, so none of them can drift out of date the way the live site's hand-written menu has.
Three Layers, Three Sources
| Layer | Answers | Derived from |
|---|---|---|
| 1. Global bar | Which site am I on, and what are the others? | The site map (SITES); the current site is marked |
| 2. Site menu | What is on this site? | The folders in the site map that really have pages in the database |
| 3. Breadcrumb, previous/next | Where am I? | The page's path, its course and its chapter number |
All three are exposed to every template by the context processor from Chapter 5, so a template only has to loop
over global_bar, site_menu and breadcrumbs.
Layer 1: The Global Bar
It lists the eight sites in the site map's order, the same on every page, with the current one marked
aria-current (so a screen reader says so as well as the colour). Each address comes from one setting,
SITE_URL_TEMPLATE:
Changing the domain, or the development port, is one line, and the bar follows. It scrolls sideways on a narrow screen instead of wrapping into several rows.
Layer 2: The Site Menu
The menu is the site's folders, in the site map's order, that have pages. It reads the database once and is
kept in Django's cache for an hour; the importer clears it when it finishes, so a new import shows at once. After
the first request, the menu costs no database query, which a test proves with assertNumQueries(0).
Readable labels
A menu entry is a folder name made readable. The live site's helper capitalised every word, giving “Data Science And Ml” and “Cloud And Devops”. The new one lower-cases small joining words, upper-cases acronyms, and has a short list of names with their own capitals:
| Folder name | Live site | Here |
|---|---|---|
data-science-and-ml | Data Science And Ml | Data Science and ML |
cloud-and-devops | Cloud And Devops | Cloud and DevOps |
maths-for-programmers | Maths For Programmers | Maths for Programmers |
ios-development | Ios Development | iOS Development |
The sidebar needs routes too
Building the menu exposed a gap from Chapter 2: its URL configuration was made from the folders in the site map, so
/sidebar/... was a 404 on every site. The sidebar belongs to the site its subject is routed to
(sidebar/linux to systems, sidebar/football to humanities), and /sidebar/
is that site's own index. The pattern keeps the sidebar index as a separate alternative (sidebar/?)
so that /sidebar/football/x/ can never match on the systems site. Tests check both directions.
Layer 3: Where You Are
The breadcrumb
The trail is built from the page's path: Site › folder › folder › this page. A course folder is labelled with the course's real name (“Hungarian Basic Conversation 3”, one query for all the folders on the path), any other folder with its readable name, and the page you are on is plain text, not a link.
Previous and next
They follow the chapter number, so chapter 10 comes after 9, and a page with no course or number simply
has neither link. The links carry rel="prev" and rel="next".
Every folder is a page
A breadcrumb that links to a folder is a promise that the folder page exists. So the page view serves either a page or a folder: a folder lists its sub-folders (with page counts) and its own pages, and a course folder lists its chapters in numeric order under the course's name. An address that is neither is a 404, and another site's folder is a 404 on this one.
Links Between Sites
The global bar links across sites with absolute addresses. For links inside page content, the resolver from
the framework course is included (resolve_link): a same-site link stays root-relative, a cross-site
link becomes an absolute address on the right site, and a path that belongs to no site raises an error rather than
being guessed. It is not applied to page bodies today because the content has no real cross-site links (Learning
Website: Framework & Architecture 11); it is ready for the first one.
What It Costs, and What Was Not Checked
- Queries: a chapter page costs 4 database queries and a folder listing 4 (the page, the course names for the breadcrumb, the two neighbours). The menus add none, because they are cached.
- Looked at: screenshots of the Hungarian course listing and of the Linux folder show the global bar with the current site in the accent colour, the site menu with the active subject underlined, the breadcrumb, and the twelve chapters numbered in order.
- Not verified: phone width. A headless screenshot at 390 pixels did not look like a true phone layout (it seemed to be laid out about 500 pixels wide and cropped, so one menu item looked cut off), so the narrow layout has not been checked. Test it with a real browser's device toolbar.
Hands-On Exercises
Build the global bar and the cached site menu from the site map and the database, write readable folder labels (small words, acronyms, product names), add the link resolver, and make the importer clear the cached menus.
๐ View solutionAdd breadcrumbs, previous and next links and folder listings, make the page view serve a page or a folder, route the sidebar to the right site, and test all of it, including numeric chapter order and the sidebar boundaries.
๐ View solutionCheck the navigation against the real imported pages: which folders appear in which menu, whether any folder is missing or in two menus, and how many queries a page costs. Look at it in a browser, and write down what you could not verify.
๐ View solutionChapter 6 Quick Reference
- Three layers, all derived: the global bar (site map), the site menu (folders with pages), the breadcrumb and previous/next (path, course, chapter number)
- Site addresses come from one setting,
SITE_URL_TEMPLATE; the current site and active subject usearia-current - The menu is cached for an hour and cleared by the importer; a repeat request makes no query for it
- Labels: small words lower case, acronyms upper case, product names their own capitals ("Data Science and ML", "Cloud and DevOps")
- Course folders are labelled with the course name in the breadcrumb; the page you are on is not a link
- Previous/next use the chapter number; a page with no number has neither
- Every folder is a page (sub-folders with counts, then the pages); an unknown folder, or another site's, is a 404
- The sidebar routes to the site its subject belongs to;
/sidebar/is that site's own index; the index is a separate pattern so subjects cannot leak resolve_linkturns cross-site links absolute and raises for a path in no site- All 49 real folders appear in a menu; a page costs 4 queries; phone width still needs a real-browser check