|
5 | 5 | namespace Hyde\Framework\Factories; |
6 | 6 |
|
7 | 7 | use function array_flip; |
8 | | -use function array_key_exists; |
9 | | -use function array_merge; |
10 | 8 | use function config; |
11 | 9 | use Hyde\Framework\Concerns\InteractsWithFrontMatter; |
12 | 10 | use Hyde\Framework\Factories\Concerns\CoreDataObject; |
13 | 11 | use Hyde\Markdown\Contracts\FrontMatter\SubSchemas\NavigationSchema; |
14 | 12 | use Hyde\Markdown\Models\FrontMatter; |
15 | 13 | use Hyde\Pages\DocumentationPage; |
16 | 14 | use Hyde\Pages\MarkdownPost; |
| 15 | +use Illuminate\Support\Arr; |
17 | 16 | use Illuminate\Support\Str; |
18 | 17 | use function in_array; |
19 | 18 | use function is_a; |
@@ -71,115 +70,132 @@ public function toArray(): array |
71 | 70 |
|
72 | 71 | protected function makeLabel(): ?string |
73 | 72 | { |
74 | | - return $this->matter('navigation.label') |
| 73 | + return $this->searchForLabelInFrontMatter() |
75 | 74 | ?? $this->searchForLabelInConfig() |
76 | 75 | ?? $this->matter('title') |
77 | 76 | ?? $this->title; |
78 | 77 | } |
79 | 78 |
|
80 | 79 | protected function makeGroup(): ?string |
81 | 80 | { |
82 | | - if ($this->isInstanceOf(DocumentationPage::class)) { |
83 | | - return $this->getDocumentationPageGroup(); |
84 | | - } |
85 | | - |
86 | | - if (Str::contains($this->identifier, '/') && $this->getSubdirectoryConfiguration() === 'dropdown') { |
87 | | - return Str::before($this->identifier, '/'); |
| 81 | + if ($this->pageIsInSubdirectory() && $this->canUseSubdirectoryForGroups()) { |
| 82 | + return $this->getSubdirectoryName(); |
88 | 83 | } |
89 | 84 |
|
90 | | - // TODO Check in front matter for group? |
91 | | -
|
92 | | - return null; |
| 85 | + return $this->searchForGroupInFrontMatter() ?? $this->defaultGroup(); |
93 | 86 | } |
94 | 87 |
|
95 | 88 | protected function makeHidden(): ?bool |
96 | 89 | { |
97 | | - if ($this->isInstanceOf(MarkdownPost::class)) { |
98 | | - return true; |
99 | | - } |
| 90 | + return $this->isInstanceOf(MarkdownPost::class) |
| 91 | + || $this->searchForHiddenInFrontMatter() |
| 92 | + || in_array($this->routeKey, config('hyde.navigation.exclude', ['404'])) |
| 93 | + || $this->pageIsInSubdirectory() && ($this->getSubdirectoryConfiguration() === 'hidden'); |
| 94 | + } |
100 | 95 |
|
101 | | - if ($this->matter('navigation.hidden', false)) { |
102 | | - return true; |
103 | | - } |
| 96 | + protected function makePriority(): int |
| 97 | + { |
| 98 | + return $this->searchForPriorityInFrontMatter() |
| 99 | + ?? $this->searchForPriorityInConfigs() |
| 100 | + ?? self::FALLBACK_PRIORITY; |
| 101 | + } |
104 | 102 |
|
105 | | - if (in_array($this->routeKey, config('hyde.navigation.exclude', ['404']))) { |
106 | | - return true; |
107 | | - } |
| 103 | + private function searchForLabelInFrontMatter(): ?string |
| 104 | + { |
| 105 | + return $this->matter('navigation.label') |
| 106 | + ?? $this->matter('navigation.title'); |
| 107 | + } |
108 | 108 |
|
109 | | - if (Str::contains($this->identifier, '/') && $this->getSubdirectoryConfiguration() === 'hidden') { |
110 | | - return true; |
111 | | - } |
| 109 | + private function searchForGroupInFrontMatter(): ?string |
| 110 | + { |
| 111 | + return $this->matter('navigation.group') |
| 112 | + ?? $this->matter('navigation.category'); |
| 113 | + } |
112 | 114 |
|
113 | | - return false; |
| 115 | + private function searchForHiddenInFrontMatter(): ?bool |
| 116 | + { |
| 117 | + return $this->matter('navigation.hidden') |
| 118 | + ?? $this->invert($this->matter('navigation.visible')); |
114 | 119 | } |
115 | 120 |
|
116 | | - protected function makePriority(): ?int |
| 121 | + private function searchForPriorityInFrontMatter(): ?int |
117 | 122 | { |
118 | | - if ($this->matter('navigation.priority') !== null) { |
119 | | - return $this->matter('navigation.priority'); |
120 | | - } |
| 123 | + return $this->matter('navigation.priority') |
| 124 | + ?? $this->matter('navigation.order'); |
| 125 | + } |
121 | 126 |
|
122 | | - return $this->isInstanceOf(DocumentationPage::class) |
123 | | - ? $this->findPriorityInSidebarConfig(array_flip(config('docs.sidebar_order', []))) ?? self::FALLBACK_PRIORITY |
124 | | - : $this->findPriorityInNavigationConfig(config('hyde.navigation.order', [])) ?? self::FALLBACK_PRIORITY; |
| 127 | + private function searchForLabelInConfig(): ?string |
| 128 | + { |
| 129 | + return Arr::get(config('hyde.navigation.labels', [ |
| 130 | + 'index' => 'Home', |
| 131 | + 'docs/index' => 'Docs', |
| 132 | + ]), $this->routeKey); |
125 | 133 | } |
126 | 134 |
|
127 | | - private function findPriorityInNavigationConfig(array $config): ?int |
| 135 | + private function searchForPriorityInConfigs(): ?int |
128 | 136 | { |
129 | | - return array_key_exists($this->routeKey, $config) ? (int) $config[$this->routeKey] : null; |
| 137 | + return $this->isInstanceOf(DocumentationPage::class) |
| 138 | + ? $this->searchForPriorityInSidebarConfig() |
| 139 | + : $this->searchForPriorityInNavigationConfig(); |
130 | 140 | } |
131 | 141 |
|
132 | | - private function findPriorityInSidebarConfig(array $config): ?int |
| 142 | + private function searchForPriorityInSidebarConfig(): ?int |
133 | 143 | { |
134 | | - // Sidebars uses a special syntax where the keys are just the page identifiers in a flat array |
| 144 | + // Sidebars uses a special syntax where the keys are just the page identifiers in a flat array. |
| 145 | + // TODO: In the future we could normalize this with the standard navigation config so both strategies can be auto-detected and used. |
135 | 146 |
|
136 | | - // Adding 250 makes so that pages with a front matter priority that is lower can be shown first. |
137 | | - // It's lower than the fallback of 500 so that the config ones still come first. |
| 147 | + // Adding an offset makes so that pages with a front matter priority that is lower can be shown first. |
138 | 148 | // This is all to make it easier to mix ways of adding priorities. |
139 | 149 |
|
140 | | - return isset($config[$this->identifier]) |
141 | | - ? $config[$this->identifier] + (self::CONFIG_OFFSET) |
142 | | - : null; |
| 150 | + return $this->offset(Arr::get( |
| 151 | + array_flip(config('docs.sidebar_order', [])), $this->identifier), |
| 152 | + self::CONFIG_OFFSET |
| 153 | + ); |
143 | 154 | } |
144 | 155 |
|
145 | | - private function getDocumentationPageGroup(): ?string |
| 156 | + private function searchForPriorityInNavigationConfig(): ?int |
146 | 157 | { |
147 | | - // If the documentation page is in a subdirectory, |
148 | | - return str_contains($this->identifier, '/') |
149 | | - // then we can use that as the category name. |
150 | | - ? Str::before($this->identifier, '/') |
151 | | - // Otherwise, we look in the front matter. |
152 | | - : $this->findGroupFromMatter(); |
| 158 | + return config("hyde.navigation.order.$this->routeKey"); |
153 | 159 | } |
154 | 160 |
|
155 | | - protected function searchForLabelInConfig(): ?string |
| 161 | + private function canUseSubdirectoryForGroups(): bool |
156 | 162 | { |
157 | | - $labelConfig = array_merge([ |
158 | | - 'index' => 'Home', |
159 | | - 'docs/index' => 'Docs', |
160 | | - ], config('hyde.navigation.labels', [])); |
| 163 | + return $this->getSubdirectoryConfiguration() === 'dropdown' |
| 164 | + || $this->isInstanceOf(DocumentationPage::class); |
| 165 | + } |
161 | 166 |
|
162 | | - if (isset($labelConfig[$this->routeKey])) { |
163 | | - return $labelConfig[$this->routeKey]; |
164 | | - } |
| 167 | + private function defaultGroup(): ?string |
| 168 | + { |
| 169 | + return $this->isInstanceOf(DocumentationPage::class) ? 'other' : null; |
| 170 | + } |
165 | 171 |
|
166 | | - return null; |
| 172 | + private function pageIsInSubdirectory(): bool |
| 173 | + { |
| 174 | + return Str::contains($this->identifier, '/'); |
| 175 | + } |
| 176 | + |
| 177 | + private function getSubdirectoryName(): string |
| 178 | + { |
| 179 | + return Str::before($this->identifier, '/'); |
| 180 | + } |
| 181 | + |
| 182 | + protected function getSubdirectoryConfiguration(): string |
| 183 | + { |
| 184 | + return config('hyde.navigation.subdirectories', 'hidden'); |
167 | 185 | } |
168 | 186 |
|
169 | 187 | protected function isInstanceOf(string $class): bool |
170 | 188 | { |
171 | 189 | return is_a($this->pageClass, $class, true); |
172 | 190 | } |
173 | 191 |
|
174 | | - protected function findGroupFromMatter(): mixed |
| 192 | + protected function invert(?bool $value): ?bool |
175 | 193 | { |
176 | | - return $this->matter('navigation.group') |
177 | | - ?? $this->matter('navigation.category') |
178 | | - ?? 'other'; |
| 194 | + return $value === null ? null : ! $value; |
179 | 195 | } |
180 | 196 |
|
181 | | - protected static function getSubdirectoryConfiguration(): string |
| 197 | + protected function offset(?int $value, int $offset): ?int |
182 | 198 | { |
183 | | - return config('hyde.navigation.subdirectories', 'hidden'); |
| 199 | + return $value === null ? null : $value + $offset; |
184 | 200 | } |
185 | 201 | } |
0 commit comments