1616use function file_put_contents ;
1717use function glob ;
1818use function implode ;
19+ use function in_array ;
1920use function preg_match ;
2021use function sprintf ;
2122use function strcasecmp ;
@@ -70,6 +71,24 @@ class LlmsGenerator
7071 'design-pattern ' => 'naming conventions for PSR-15 handlers ' ,
7172 ];
7273
74+ /**
75+ * Static page slugs listed under `## Docs` instead of `## Pages` - reference/setup content
76+ * rather than product pages.
77+ *
78+ * @var list<non-empty-string>
79+ */
80+ private const array DOCS_PAGES = [
81+ 'architecture ' ,
82+ 'wsl2 ' ,
83+ 'dotboost ' ,
84+ ];
85+
86+ /**
87+ * Slug of the packages lifecycle page, hardcoded under `## Docs` in `buildHeader()` -
88+ * excluded from `## Pages` here so it is not listed twice.
89+ */
90+ private const string OSS_LIFECYCLE_SLUG = 'dotkernel-packages-oss-lifecycle ' ;
91+
7392 public function __construct (
7493 private readonly PostRepository $ postRepository ,
7594 private readonly string $ sourceDir ,
@@ -239,6 +258,11 @@ private function buildPagesSection(): string
239258
240259 $ pages = [];
241260 foreach (glob ($ this ->pagesDir . '/*.md ' ) ?: [] as $ path ) {
261+ $ slug = basename ($ path , '.md ' );
262+ if ($ slug === self ::OSS_LIFECYCLE_SLUG || in_array ($ slug , self ::DOCS_PAGES , true )) {
263+ continue ;
264+ }
265+
242266 $ contents = file_get_contents ($ path );
243267 if ($ contents === false ) {
244268 continue ;
@@ -252,7 +276,7 @@ private function buildPagesSection(): string
252276
253277 $ pages [] = [
254278 'title ' => trim (explode ('| ' , $ title , 2 )[0 ]),
255- 'slug ' => basename ( $ path , ' .md ' ) ,
279+ 'slug ' => $ slug ,
256280 'description ' => $ description ,
257281 ];
258282 }
@@ -277,6 +301,41 @@ private function buildPagesSection(): string
277301 return implode ("\n" , $ lines ) . "\n\n" ;
278302 }
279303
304+ /**
305+ * Adds `self::DOCS_PAGES` under `## Docs`
306+ */
307+ private function buildDocsPageLinks (): string
308+ {
309+ if ($ this ->pagesDir === null ) {
310+ return '' ;
311+ }
312+
313+ $ lines = [];
314+ foreach (self ::DOCS_PAGES as $ slug ) {
315+ $ path = sprintf ('%s/%s.md ' , $ this ->pagesDir , $ slug );
316+ $ contents = @file_get_contents ($ path );
317+ if ($ contents === false ) {
318+ continue ;
319+ }
320+
321+ $ title = $ this ->extractFrontMatterField ($ contents , 'title ' );
322+ $ description = $ this ->extractFrontMatterField ($ contents , 'description ' );
323+ if ($ title === null || $ description === null ) {
324+ continue ;
325+ }
326+
327+ $ lines [] = sprintf (
328+ '- [%s](%s/%s.md): %s ' ,
329+ trim (explode ('| ' , $ title , 2 )[0 ]),
330+ $ this ->baseUrl ,
331+ $ slug ,
332+ $ description ,
333+ );
334+ }
335+
336+ return $ lines === [] ? '' : implode ("\n" , $ lines ) . "\n" ;
337+ }
338+
280339 private function extractFrontMatterField (string $ contents , string $ field ): ?string
281340 {
282341 if (preg_match (sprintf ('/^%s:\s*"(.*)"\s*$/m ' , $ field ), $ contents , $ matches ) === 1 ) {
@@ -306,8 +365,8 @@ private function buildHeader(): string
306365 . $ intro . "\n\n"
307366 . $ body . "\n\n"
308367 . "## Docs \n\n"
309- . "- [OSS Package Lifecycle]( {$ this ->baseUrl }/dotkernel-packages-oss-lifecycle .md): "
368+ . "- [OSS Package Lifecycle]( {$ this ->baseUrl }/ " . self :: OSS_LIFECYCLE_SLUG . " .md): "
310369 . "support/maintenance status of Dotkernel's open-source packages \n"
311- . " - [Contact]( { $ this ->baseUrl } /contact/) \n \n" ;
370+ . $ this ->buildDocsPageLinks () . " \n" ;
312371 }
313372}
0 commit comments