Skip to content

Commit 6dcd072

Browse files
committed
moar docs
1 parent b182e2f commit 6dcd072

File tree

9 files changed

+3279
-43
lines changed

9 files changed

+3279
-43
lines changed
Lines changed: 331 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,331 @@
1+
# Navigation Documentation
2+
3+
Welcome to the documentation for `Elastic.Documentation.Navigation`, the library that powers documentation navigation for Elastic's documentation sites.
4+
5+
## What This Is
6+
7+
This library builds hierarchical navigation trees for documentation sites with a unique capability: navigation built for isolated repositories can be **efficiently re-homed** during site assembly without rebuilding the entire tree.
8+
9+
**Why does this matter?**
10+
11+
Individual documentation teams can build and test their docs in isolation with URLs like `/api/overview/`, then those same docs can be assembled into a unified site with URLs like `/elasticsearch/api/overview/` - with **zero tree reconstruction**. It's an O(1) operation.
12+
13+
## Documentation Map
14+
15+
Start with any document based on what you want to learn:
16+
17+
### 🎯 [navigation.md](navigation.md) - Start Here
18+
**Overview of the navigation system**
19+
20+
Read this first to understand:
21+
- The two build modes (isolated vs assembler)
22+
- Core concepts at a high level
23+
- Quick introduction to re-homing
24+
- Links to detailed documentation
25+
26+
### 🎨 [visual-walkthrough.md](visual-walkthrough.md) - See It In Action
27+
**Visual tour with diagrams showing navigation structures**
28+
29+
Read this to understand:
30+
- What different node types look like in the tree
31+
- How isolated builds differ from assembler builds visually
32+
- How the same content appears with different URLs
33+
- How to split and reorganize documentation across sites
34+
- Common patterns for multi-repository organization
35+
- Includes actual tree diagrams from this repository
36+
37+
### 🧭 [first-principles.md](first-principles.md) - Design Philosophy
38+
**Core principles that guide the architecture**
39+
40+
Read this to understand:
41+
- Why two-phase loading (configuration → navigation)
42+
- Why URLs are calculated dynamically, not stored
43+
- Why navigation roots can be re-homed
44+
- Design patterns used (factory, provider, visitor)
45+
- Performance characteristics and invariants
46+
47+
### 🔄 [two-phase-loading.md](two-phase-loading.md) - The Loading Process
48+
**Deep dive into Phase 1 (configuration) and Phase 2 (navigation)**
49+
50+
Read this to understand:
51+
- What happens in Phase 1: Configuration resolution
52+
- What happens in Phase 2: Navigation construction
53+
- Why these phases are separate
54+
- Data flow diagrams
55+
- How to test each phase independently
56+
57+
### 🏠 [home-provider-architecture.md](home-provider-architecture.md) - The Re-homing Magic
58+
**How O(1) re-homing works**
59+
60+
Read this to understand:
61+
- The problem: naive re-homing requires O(n) tree traversal
62+
- The solution: HomeProvider pattern with indirection
63+
- How `INavigationHomeProvider` and `INavigationHomeAccessor` work
64+
- Why URLs are lazily calculated and cached
65+
- Detailed examples of re-homing in action
66+
- Performance analysis
67+
68+
**This is the most important technical concept in the system.**
69+
70+
### 📦 [node-types.md](node-types.md) - Node Type Reference
71+
**Complete reference for every navigation node type**
72+
73+
Read this to understand:
74+
- All 7 node types in detail:
75+
- **Leaves**: FileNavigationLeaf, CrossLinkNavigationLeaf
76+
- **Nodes**: FolderNavigation, VirtualFileNavigation
77+
- **Roots**: DocumentationSetNavigation, TableOfContentsNavigation, SiteNavigation
78+
- Constructor signatures
79+
- URL calculation for each type
80+
- Factory methods
81+
- Model types (IDocumentationFile)
82+
83+
### 🔨 [assembler-process.md](assembler-process.md) - Building Unified Sites
84+
**How multiple repositories become one site**
85+
86+
Read this to understand:
87+
- The assembler build process step-by-step
88+
- How `SiteNavigation` works
89+
- Re-homing in practice during assembly
90+
- Path prefix requirements
91+
- Phantom nodes
92+
- Nested re-homing
93+
- Error handling
94+
95+
## Suggested Reading Order
96+
97+
**If you're new to the codebase:**
98+
1. [navigation.md](navigation.md) - Get the overview
99+
2. [visual-walkthrough.md](visual-walkthrough.md) - See it visually
100+
3. [first-principles.md](first-principles.md) - Understand the why
101+
4. [home-provider-architecture.md](home-provider-architecture.md) - Understand the how
102+
5. [node-types.md](node-types.md) - Reference as needed
103+
104+
**If you're debugging an issue:**
105+
1. [node-types.md](node-types.md) - Find the node type
106+
2. [home-provider-architecture.md](home-provider-architecture.md) - Understand URL calculation
107+
3. [two-phase-loading.md](two-phase-loading.md) - Check which phase
108+
109+
**If you're adding a feature:**
110+
1. [first-principles.md](first-principles.md) - Ensure design consistency
111+
2. [node-types.md](node-types.md) - See existing patterns
112+
3. [two-phase-loading.md](two-phase-loading.md) - Determine which phase
113+
4. [assembler-process.md](assembler-process.md) - Consider assembler impact
114+
115+
**If you're optimizing performance:**
116+
1. [home-provider-architecture.md](home-provider-architecture.md) - Understand caching
117+
2. [first-principles.md](first-principles.md) - See performance characteristics
118+
3. [two-phase-loading.md](two-phase-loading.md) - Find expensive operations
119+
120+
## Key Concepts Summary
121+
122+
### Two Build Modes
123+
124+
1. **Isolated Build**
125+
- Single repository
126+
- URLs relative to `/`
127+
- `DocumentationSetNavigation` is the root
128+
- Fast iteration for doc teams
129+
130+
2. **Assembler Build**
131+
- Multiple repositories
132+
- Custom URL prefixes
133+
- `SiteNavigation` is the root
134+
- Docsets/TOCs are re-homed
135+
136+
### Two-Phase Loading
137+
138+
1. **Phase 1: Configuration** (`Elastic.Documentation.Configuration`)
139+
- Parse YAML files
140+
- Resolve all relative paths to absolute paths from docset root
141+
- Validate structure and file references
142+
- Load nested `toc.yml` files
143+
- Output: Fully resolved configuration
144+
145+
2. **Phase 2: Navigation** (`Elastic.Documentation.Navigation`)
146+
- Build tree from resolved configuration
147+
- Establish parent-child relationships
148+
- Set up home providers
149+
- Calculate navigation indexes
150+
- Output: Complete navigation tree
151+
152+
### Home Provider Pattern
153+
154+
The secret to O(1) re-homing:
155+
156+
```csharp
157+
// Provider defines URL context
158+
public interface INavigationHomeProvider
159+
{
160+
string PathPrefix { get; }
161+
IRootNavigationItem<...> NavigationRoot { get; }
162+
}
163+
164+
// Accessor references provider
165+
public interface INavigationHomeAccessor
166+
{
167+
INavigationHomeProvider HomeProvider { get; set; }
168+
}
169+
170+
// Nodes calculate URLs from current provider
171+
public string Url =>
172+
$"{_homeAccessor.HomeProvider.PathPrefix}/{_relativePath}/";
173+
```
174+
175+
**Re-homing:**
176+
```csharp
177+
// Change provider → all URLs update instantly!
178+
node.HomeProvider = new NavigationHomeProvider("/new-prefix", newRoot);
179+
```
180+
181+
### Node Types
182+
183+
7 types organized by capabilities:
184+
185+
**Leaves** (no children):
186+
- `FileNavigationLeaf<TModel>` - Markdown file
187+
- `CrossLinkNavigationLeaf` - External link
188+
189+
**Nodes** (have children):
190+
- `FolderNavigation<TModel>` - Directory
191+
- `VirtualFileNavigation<TModel>` - File with YAML-defined children
192+
193+
**Roots** (can be re-homed):
194+
- `DocumentationSetNavigation<TModel>` - Docset root
195+
- `TableOfContentsNavigation<TModel>` - Nested TOC
196+
- `SiteNavigation` - Assembled site root
197+
198+
## Code Organization
199+
200+
The library is organized into:
201+
202+
### `Elastic.Documentation.Navigation/`
203+
Root namespace - shared types:
204+
- `IDocumentationFile.cs` - Base interface for documentation files
205+
- `NavigationModels.cs` - Common model types (CrossLinkModel, SiteNavigationNoIndexFile)
206+
207+
### `Elastic.Documentation.Navigation/Isolated/`
208+
Isolated build navigation:
209+
- `DocumentationSetNavigation.cs` - Docset root
210+
- `TableOfContentsNavigation.cs` - Nested TOC
211+
- `FolderNavigation.cs` - Folder nodes
212+
- `FileNavigationLeaf.cs` - File leaves
213+
- `VirtualFileNavigation.cs` - Virtual file nodes
214+
- `CrossLinkNavigationLeaf.cs` - Crosslink leaves
215+
- `DocumentationNavigationFactory.cs` - Factory for creating nodes
216+
- `NavigationArguments.cs` - Constructor argument records
217+
- `NavigationHomeProvider.cs` - Home provider implementation
218+
219+
### `Elastic.Documentation.Navigation/Assembler/`
220+
Assembler build navigation:
221+
- `SiteNavigation.cs` - Unified site root
222+
223+
### Supporting Files
224+
- `README.md` - High-level overview (in src/)
225+
- `url-building.md` - URL building rules (in src/)
226+
227+
## Testing
228+
229+
Tests are in `tests/Navigation.Tests/`:
230+
231+
**Isolated build tests:**
232+
- `Isolation/ConstructorTests.cs` - Basic navigation construction
233+
- `Isolation/FileNavigationTests.cs` - File leaf behavior
234+
- `Isolation/FolderIndexFileRefTests.cs` - Folder navigation
235+
- `Isolation/PhysicalDocsetTests.cs` - Real docset loading
236+
237+
**Assembler build tests:**
238+
- `Assembler/SiteNavigationTests.cs` - Site assembly
239+
- `Assembler/SiteDocumentationSetsTests.cs` - Multiple docsets
240+
- `Assembler/ComplexSiteNavigationTests.cs` - Complex scenarios
241+
242+
**Test pattern:**
243+
```csharp
244+
[Fact]
245+
public void FeatureUnderTest_Scenario_ExpectedBehavior()
246+
{
247+
// Arrange: Create mock file system and configuration
248+
var fileSystem = new MockFileSystem();
249+
var config = CreateConfig(...);
250+
251+
// Act: Build navigation
252+
var nav = new DocumentationSetNavigation<IDocumentationFile>(...);
253+
254+
// Assert: Verify behavior
255+
Assert.Equal("/expected/url/", nav.Index.Url);
256+
}
257+
```
258+
259+
## Common Tasks
260+
261+
### Adding a New Node Type
262+
263+
1. Create class in `Isolated/` namespace
264+
2. Implement appropriate interface (`ILeafNavigationItem` or `INodeNavigationItem`)
265+
3. Add factory method if needed
266+
4. Update `ConvertToNavigationItem` in `DocumentationSetNavigation`
267+
5. Add tests in `Isolation/`
268+
6. Update [node-types.md](node-types.md)
269+
270+
### Changing URL Calculation
271+
272+
1. Review [first-principles.md](first-principles.md) - ensure consistency
273+
2. Update `FileNavigationLeaf.Url` property
274+
3. Consider cache invalidation
275+
4. Update tests
276+
5. Update [home-provider-architecture.md](home-provider-architecture.md)
277+
278+
### Modifying Configuration
279+
280+
1. Update classes in `Elastic.Documentation.Configuration`
281+
2. Update `LoadAndResolve` methods
282+
3. Update Phase 2 consumption in navigation classes
283+
4. Update tests for both phases
284+
5. Update [two-phase-loading.md](two-phase-loading.md)
285+
286+
### Debugging Re-homing Issues
287+
288+
1. Check `HomeProvider` assignments in [assembler-process.md](assembler-process.md)
289+
2. Verify `PathPrefix` values
290+
3. Check `NavigationRoot` points to correct root
291+
4. Look for cache issues (HomeProvider ID changed?)
292+
5. Review [home-provider-architecture.md](home-provider-architecture.md)
293+
294+
## Related Documentation
295+
296+
- `Elastic.Documentation.Configuration` - Phase 1 (configuration resolution)
297+
- `Elastic.Documentation.Links` - Cross-link resolution
298+
- `Elastic.Markdown` - Markdown processing
299+
300+
## Source Reference
301+
302+
For the actual implementation, see:
303+
- Library: `src/Elastic.Documentation.Navigation/`
304+
- Tests: `tests/Navigation.Tests/`
305+
- Configuration: `src/Elastic.Documentation.Configuration/`
306+
307+
## Contributing
308+
309+
When making changes:
310+
311+
1. **Maintain invariants** from [first-principles.md](first-principles.md)
312+
2. **Keep phases separate** - don't mix configuration and navigation
313+
3. **Preserve O(1) re-homing** - don't add tree traversals
314+
4. **Add tests** for both isolated and assembler scenarios
315+
5. **Update documentation** in this directory
316+
6. **Run all 111+ tests** - they should all pass
317+
318+
## Questions?
319+
320+
- **"How do URLs get calculated?"**[home-provider-architecture.md](home-provider-architecture.md)
321+
- **"Why two phases?"**[two-phase-loading.md](two-phase-loading.md)
322+
- **"What is re-homing?"**[navigation.md](navigation.md) then [home-provider-architecture.md](home-provider-architecture.md)
323+
- **"Which node type do I need?"**[node-types.md](node-types.md)
324+
- **"How does the assembler work?"**[assembler-process.md](assembler-process.md)
325+
- **"What are the design principles?"**[first-principles.md](first-principles.md)
326+
327+
---
328+
329+
**Welcome to Elastic.Documentation.Navigation!**
330+
331+
The library that makes it possible to build documentation in isolation and efficiently assemble it into unified sites with custom URL structures - no rebuilding required. 🚀

0 commit comments

Comments
 (0)