@janga/norna 0.7.17 → 0.7.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -6
- package/bin/norna-cli.mjs +1 -1
- package/docs/README.md +11 -9
- package/docs/configuration.md +25 -2
- package/docs/content.md +21 -12
- package/docs/design/navigation-and-theme-plan.md +90 -19
- package/docs/design/site-examples-structure.md +7 -3
- package/docs/engine-development.md +19 -22
- package/docs/getting-started.md +3 -3
- package/docs/images-and-metadata.md +6 -4
- package/docs/pages.md +120 -64
- package/docs/public-files.md +1 -1
- package/docs/site-files.md +36 -29
- package/docs/sitewide-content.md +1 -1
- package/docs/theme.md +107 -141
- package/docs/typography.md +15 -27
- package/examples/README.md +8 -2
- package/examples/complete-sites/dog-shelter-multi-page/site/.norna/generated-images.json +5 -5
- package/examples/complete-sites/dog-shelter-single-page/site/.norna/generated-images.json +10 -10
- package/examples/feature-demos/media-and-surfaces/.astro/collections/theme.schema.json +35 -43
- package/examples/feature-demos/media-and-surfaces/.astro/data-store.json +1 -1
- package/examples/feature-demos/media-and-surfaces/site/pages/020-surfaces/content.md +2 -1
- package/examples/feature-demos/media-and-surfaces/site/pages/020-surfaces/theme.yaml +2 -3
- package/examples/feature-demos/theme-preset-documentation/README.md +16 -0
- package/examples/feature-demos/theme-preset-documentation/site/.norna/generated-images.json +74 -0
- package/examples/feature-demos/{theme-presets/site/pages/020-documentation → theme-preset-documentation/site/pages/000-home}/content.md +1 -1
- package/examples/feature-demos/theme-preset-portfolio/README.md +16 -0
- package/examples/feature-demos/theme-preset-portfolio/site/.norna/generated-images.json +74 -0
- package/examples/feature-demos/theme-preset-portfolio/site/config.yaml +1 -0
- package/examples/feature-demos/{theme-presets/site/pages/010-portfolio → theme-preset-portfolio/site/pages/000-home}/content.md +1 -1
- package/examples/feature-demos/theme-preset-portfolio/site/public/robots.txt +2 -0
- package/examples/feature-demos/theme-preset-portfolio/site/sitewide-content.yaml +3 -0
- package/examples/feature-demos/theme-preset-project/README.md +16 -0
- package/examples/feature-demos/theme-preset-project/site/.norna/generated-images.json +74 -0
- package/examples/feature-demos/theme-preset-project/site/config.yaml +1 -0
- package/examples/feature-demos/{theme-presets/site/pages/030-project → theme-preset-project/site/pages/000-home}/content.md +1 -1
- package/examples/feature-demos/theme-preset-project/site/public/robots.txt +2 -0
- package/examples/feature-demos/theme-preset-project/site/sitewide-content.yaml +3 -0
- package/examples/feature-demos/theme-preset-statement/README.md +16 -0
- package/examples/feature-demos/theme-preset-statement/site/.norna/generated-images.json +74 -0
- package/examples/feature-demos/theme-preset-statement/site/config.yaml +1 -0
- package/examples/feature-demos/{theme-presets/site/pages/040-statement → theme-preset-statement/site/pages/000-home}/content.md +1 -1
- package/examples/feature-demos/theme-preset-statement/site/public/robots.txt +2 -0
- package/examples/feature-demos/theme-preset-statement/site/sitewide-content.yaml +3 -0
- package/fixtures/basic/site/theme.yaml +1 -8
- package/fixtures/nested-pages/.astro/collections/site.schema.json +35 -0
- package/fixtures/nested-pages/.astro/collections/sitewide.schema.json +97 -0
- package/fixtures/nested-pages/.astro/collections/theme.schema.json +844 -0
- package/fixtures/nested-pages/.astro/content-assets.mjs +4 -0
- package/fixtures/nested-pages/.astro/content-modules.mjs +1 -0
- package/fixtures/nested-pages/.astro/content.d.ts +183 -0
- package/fixtures/nested-pages/.astro/data-store.json +1 -0
- package/fixtures/nested-pages/.astro/dev-local.json +8 -0
- package/fixtures/nested-pages/.astro/dev.log +1128 -0
- package/fixtures/nested-pages/.astro/settings.json +5 -0
- package/fixtures/nested-pages/.astro/types.d.ts +2 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/_metadata.json +74 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/astro-D_GIpJIE.js +434 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/astro-D_GIpJIE.js.map +1 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_aria-query.js +6390 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_aria-query.js.map +1 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_axobject-query.js +2702 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_axobject-query.js.map +1 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_html-escaper.js +65 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_html-escaper.js.map +1 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +455 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +1 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/audit-DM9Hkl5B.js +1534 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/audit-DM9Hkl5B.js.map +1 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/highlight-DnZ1ULOL.js +48 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/highlight-DnZ1ULOL.js.map +1 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/icons-RyebKi45.js +42 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/icons-RyebKi45.js.map +1 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/package.json +3 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +4 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/settings-DaU-gNnK.js +190 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/settings-DaU-gNnK.js.map +1 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/toolbar-63PA619H.js +458 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/toolbar-63PA619H.js.map +1 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/ui-library--bkcNSYz.js +1016 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/ui-library--bkcNSYz.js.map +1 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/window-jPkpKVcy.js +32 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/window-jPkpKVcy.js.map +1 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/xray-BXCHpEJP.js +111 -0
- package/fixtures/nested-pages/node_modules/.vite/deps/xray-BXCHpEJP.js.map +1 -0
- package/fixtures/nested-pages/site/config.yaml +2 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/pages/010-macos/content.md +4 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/theme.yaml +2 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/030-release-notes/content.md +9 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/040-configuration/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/050-content/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/060-themes/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/070-images/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/080-cards/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/090-notes/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/100-validation/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/110-synchronization/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/120-building/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/130-publishing/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/140-troubleshooting/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/150-migration/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/160-accessibility/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/170-performance/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/180-security/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/190-localization/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/200-upgrading/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/210-faq/content.md +3 -0
- package/fixtures/nested-pages/site/pages/010-guides/theme.yaml +7 -3
- package/fixtures/nested-pages/site/theme.yaml +1 -3
- package/package.json +2 -1
- package/schemas/config.schema.json +45 -4
- package/schemas/content-frontmatter.schema.json +5 -5
- package/schemas/manifest.json +3 -2
- package/schemas/page-theme.schema.json +192 -0
- package/schemas/sitewide-content.schema.json +17 -17
- package/schemas/theme.schema.json +188 -216
- package/scripts/check-config.mjs +2 -1
- package/scripts/deploy-site.mjs +1 -1
- package/scripts/generate-images.mjs +7 -14
- package/scripts/generate-schemas.mjs +4 -1
- package/scripts/lib/editor-language-service.mjs +0 -14
- package/scripts/lib/example-sites.mjs +15 -3
- package/scripts/lib/page-model.mjs +26 -7
- package/scripts/lib/presentation.mjs +25 -17
- package/scripts/lib/project-config.mjs +26 -16
- package/scripts/lib/schema-definitions.mjs +42 -14
- package/scripts/lib/schema-editor-metadata.mjs +70 -26
- package/scripts/lib/schema-value-definitions.mjs +14 -0
- package/scripts/lib/site-content.mjs +50 -25
- package/scripts/lib/site-conventions.mjs +1 -0
- package/scripts/lib/site-paths.mjs +9 -3
- package/scripts/lib/theme-config.mjs +3 -2
- package/scripts/lib/theme-presets.mjs +54 -21
- package/scripts/show-typography.mjs +1 -33
- package/scripts/sync-content-sections.mjs +1 -3
- package/scripts/test-banner-visibility.mjs +2 -2
- package/scripts/test-client-javascript.mjs +11 -4
- package/scripts/test-content-check.mjs +25 -25
- package/scripts/test-content-model-v2.mjs +165 -101
- package/scripts/test-documentation.mjs +4 -2
- package/scripts/test-editor-language-service.mjs +11 -8
- package/scripts/test-engine-commands.mjs +5 -5
- package/scripts/test-examples.mjs +30 -1
- package/scripts/test-heading-ids.mjs +2 -2
- package/scripts/test-navigation.mjs +11 -2
- package/scripts/test-nested-pages.mjs +25 -10
- package/scripts/test-package-check.mjs +29 -60
- package/scripts/test-page-model.mjs +30 -2
- package/scripts/test-project-config.mjs +5 -10
- package/scripts/test-schemas.mjs +18 -3
- package/scripts/test-theme-presets.mjs +33 -27
- package/src/components/NavigationPageTree.astro +114 -25
- package/src/components/PageContentsLinks.astro +40 -0
- package/src/components/SectionNavigationScript.astro +12 -5
- package/src/components/SiteBreadcrumbs.astro +17 -14
- package/src/components/SiteNavigation.astro +45 -12
- package/src/components/SitePage.astro +37 -23
- package/src/components/SiteSection.astro +2 -7
- package/src/components/SiteTreeNavigation.astro +35 -0
- package/src/components/TreeNavigationScript.astro +83 -0
- package/src/content.config.ts +2 -8
- package/src/layouts/BaseLayout.astro +10 -0
- package/src/lib/pageThemes.ts +11 -9
- package/src/lib/sectionContent.ts +1 -5
- package/src/lib/siteNavigation.ts +2 -1
- package/src/lib/sitePages.ts +25 -14
- package/src/pages/index.astro +2 -1
- package/src/styles/global.css +411 -43
- package/starters/basic/README.md +7 -7
- package/starters/basic/site/theme.yaml +1 -105
- package/starters/project/README.md +8 -8
- package/starters/project/site/theme.yaml +1 -31
- package/examples/feature-demos/theme-presets/README.md +0 -18
- package/examples/feature-demos/theme-presets/site/.norna/generated-images.json +0 -290
- package/examples/feature-demos/theme-presets/site/content.md +0 -14
- package/examples/feature-demos/theme-presets/site/theme.yaml +0 -1
- /package/examples/complete-sites/dog-shelter-multi-page/site/{content.md → pages/000-home/content.md} +0 -0
- /package/examples/complete-sites/dog-shelter-multi-page/site/{images → pages/000-home/images}/shelter-dog.jpg +0 -0
- /package/examples/complete-sites/dog-shelter-single-page/site/{content.md → pages/000-home/content.md} +0 -0
- /package/examples/complete-sites/dog-shelter-single-page/site/{images → pages/000-home/images}/foster-dog.jpg +0 -0
- /package/examples/complete-sites/dog-shelter-single-page/site/{images → pages/000-home/images}/rescue-dog.jpg +0 -0
- /package/examples/feature-demos/media-and-surfaces/site/{content.md → pages/000-home/content.md} +0 -0
- /package/examples/feature-demos/sitewide-content/site/{content.md → pages/000-home/content.md} +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-documentation}/site/config.yaml +0 -0
- /package/examples/feature-demos/{theme-presets/site/pages/020-documentation → theme-preset-documentation/site/pages/000-home}/images/black-schnauzer.jpg +0 -0
- /package/examples/feature-demos/{theme-presets/site/pages/020-documentation → theme-preset-documentation/site/pages/000-home}/images/retriever-portrait.jpg +0 -0
- /package/examples/feature-demos/{theme-presets/site/pages/020-documentation → theme-preset-documentation/site/pages/000-home}/images/schnauzer-portrait.jpg +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-documentation}/site/public/robots.txt +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-documentation}/site/sitewide-content.yaml +0 -0
- /package/examples/feature-demos/{theme-presets/site/pages/020-documentation → theme-preset-documentation/site}/theme.yaml +0 -0
- /package/examples/feature-demos/{theme-presets/site/pages/010-portfolio → theme-preset-portfolio/site/pages/000-home}/images/puppy-portrait.jpg +0 -0
- /package/examples/feature-demos/{theme-presets/site/pages/010-portfolio → theme-preset-portfolio/site/pages/000-home}/images/shepherd-portrait.jpg +0 -0
- /package/examples/feature-demos/{theme-presets/site/pages/010-portfolio → theme-preset-portfolio/site/pages/000-home}/images/white-puppy.jpg +0 -0
- /package/examples/feature-demos/{theme-presets/site/pages/010-portfolio → theme-preset-portfolio/site}/theme.yaml +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/.astro/collections/routeTheme.schema.json +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/.astro/collections/site.schema.json +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/.astro/collections/sitewide.schema.json +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/.astro/collections/theme.schema.json +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/.astro/content-assets.mjs +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/.astro/content-modules.mjs +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/.astro/content.d.ts +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/.astro/data-store.json +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/.astro/dev-local.json +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/.astro/dev.json +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/.astro/dev.log +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/.astro/settings.json +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/.astro/types.d.ts +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/_metadata.json +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/astro-D_GIpJIE.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/astro-D_GIpJIE.js.map +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/astro_n_aria-query.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/astro_n_axobject-query.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/astro_n_html-escaper.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/audit-DM9Hkl5B.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/audit-DM9Hkl5B.js.map +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/embla-carousel.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/embla-carousel.js.map +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/highlight-DnZ1ULOL.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/highlight-DnZ1ULOL.js.map +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/icons-RyebKi45.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/icons-RyebKi45.js.map +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/package.json +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/settings-DaU-gNnK.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/settings-DaU-gNnK.js.map +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/toolbar-63PA619H.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/toolbar-63PA619H.js.map +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/ui-library--bkcNSYz.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/ui-library--bkcNSYz.js.map +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/window-jPkpKVcy.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/window-jPkpKVcy.js.map +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/xray-BXCHpEJP.js +0 -0
- /package/examples/feature-demos/{theme-presets → theme-preset-project}/node_modules/.vite/deps/xray-BXCHpEJP.js.map +0 -0
- /package/examples/feature-demos/{theme-presets/site/pages/030-project → theme-preset-project/site/pages/000-home}/images/boxer-portrait.jpg +0 -0
- /package/examples/feature-demos/{theme-presets/site/pages/030-project → theme-preset-project/site/pages/000-home}/images/grass-puppy.jpg +0 -0
- /package/examples/feature-demos/{theme-presets/site/pages/030-project → theme-preset-project/site/pages/000-home}/images/grey-street-dog.jpg +0 -0
- /package/examples/feature-demos/{theme-presets/site/pages/030-project → theme-preset-project/site}/theme.yaml +0 -0
- /package/examples/feature-demos/{theme-presets/site/pages/040-statement → theme-preset-statement/site/pages/000-home}/images/black-pedigree.jpg +0 -0
- /package/examples/feature-demos/{theme-presets/site/pages/040-statement → theme-preset-statement/site/pages/000-home}/images/sheepdog-grass.jpg +0 -0
- /package/examples/feature-demos/{theme-presets/site/pages/040-statement → theme-preset-statement/site/pages/000-home}/images/sheepdog-wide.jpg +0 -0
- /package/examples/feature-demos/{theme-presets/site/pages/040-statement → theme-preset-statement/site}/theme.yaml +0 -0
- /package/fixtures/basic/site/{content.md → pages/000-home/content.md} +0 -0
- /package/fixtures/basic/site/{images → pages/000-home/images}/.gitkeep +0 -0
- /package/fixtures/content-model-v2/site/{content.md → pages/000-home/content.md} +0 -0
- /package/fixtures/content-model-v2/site/{images → pages/000-home/images}/adopt.svg +0 -0
- /package/fixtures/content-model-v2/site/{images → pages/000-home/images}/detail.jpg +0 -0
- /package/fixtures/content-model-v2/site/{images → pages/000-home/images}/duplicate.jpg +0 -0
- /package/fixtures/content-model-v2/site/{images → pages/000-home/images}/foster.svg +0 -0
- /package/fixtures/content-model-v2/site/{images → pages/000-home/images}/hero.jpg +0 -0
- /package/fixtures/content-model-v2/site/{images → pages/000-home/images}/image.jpg +0 -0
- /package/fixtures/content-model-v2/site/{images → pages/000-home/images}/slide-one.jpg +0 -0
- /package/fixtures/content-model-v2/site/{images → pages/000-home/images}/slide-three.jpg +0 -0
- /package/fixtures/content-model-v2/site/{images → pages/000-home/images}/slide-two.jpg +0 -0
- /package/fixtures/nested-pages/site/{content.md → pages/000-home/content.md} +0 -0
- /package/starters/basic/site/{content.md → pages/000-home/content.md} +0 -0
- /package/starters/basic/site/{images → pages/000-home/images}/.gitkeep +0 -0
- /package/starters/project/site/{content.md → pages/000-home/content.md} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import projectConfig from '../../scripts/lib/project-config.mjs';
|
|
3
|
-
import { resolveSectionSurface } from '../../scripts/lib/presentation.mjs';
|
|
3
|
+
import { getTextWidthCssValue, resolveSectionSurface } from '../../scripts/lib/presentation.mjs';
|
|
4
4
|
import CardList from './CardList.astro';
|
|
5
5
|
import ImageCarousel from './ImageCarousel.astro';
|
|
6
6
|
import ImageStack from './ImageStack.astro';
|
|
@@ -165,11 +165,6 @@ const getSizeValue = (
|
|
|
165
165
|
const getHeadingSizeValue = (level: HeadingLevel, size: TextSize) => (
|
|
166
166
|
headingSizeValues[level][size]
|
|
167
167
|
);
|
|
168
|
-
const textWidthValues: Record<TextWidth, string> = {
|
|
169
|
-
narrow: 'min(60ch, var(--text-width))',
|
|
170
|
-
normal: 'min(72ch, var(--text-width))',
|
|
171
|
-
wide: 'min(72ch, var(--image-layout-width))',
|
|
172
|
-
};
|
|
173
168
|
const surface = isPageTitle
|
|
174
169
|
? pagePresentation.palette.surfaces.base
|
|
175
170
|
: resolveSectionSurface(pagePresentation, sectionIndex);
|
|
@@ -205,7 +200,7 @@ const justifyByAlign: Record<TextAlign, string> = {
|
|
|
205
200
|
center: 'center',
|
|
206
201
|
right: 'flex-end',
|
|
207
202
|
};
|
|
208
|
-
const bodyWidthValue =
|
|
203
|
+
const bodyWidthValue = getTextWidthCssValue(typography.body.width as TextWidth);
|
|
209
204
|
const headingWidth = {
|
|
210
205
|
desktop: bodyWidthValue,
|
|
211
206
|
mobile: bodyWidthValue,
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
import projectConfig from '../../scripts/lib/project-config.mjs';
|
|
3
|
+
import { withBasePath } from '../lib/basePath';
|
|
4
|
+
import { getListedPageNavigationTree, type PageNavigationEntry } from '../lib/siteNavigation';
|
|
5
|
+
import type { SitePage } from '../lib/sitePages';
|
|
6
|
+
import NavigationPageTree from './NavigationPageTree.astro';
|
|
7
|
+
|
|
8
|
+
interface Props {
|
|
9
|
+
currentPage: SitePage;
|
|
10
|
+
pageNavigation: PageNavigationEntry[];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const { currentPage, pageNavigation } = Astro.props;
|
|
14
|
+
const roots = getListedPageNavigationTree(pageNavigation);
|
|
15
|
+
const activeRoot = roots.find((node) => (
|
|
16
|
+
currentPage.pageDirectory === node.page.pageDirectory
|
|
17
|
+
|| currentPage.pageDirectory.startsWith(`${node.page.pageDirectory}/pages/`)
|
|
18
|
+
));
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
{activeRoot && (
|
|
22
|
+
<aside
|
|
23
|
+
class="tree-local-navigation"
|
|
24
|
+
data-navigation-root={withBasePath(projectConfig.site.basePath, activeRoot.page.pathname)}
|
|
25
|
+
>
|
|
26
|
+
<nav aria-label={`${activeRoot.page.title}: ${projectConfig.locale.labels.siteNavigation}`}>
|
|
27
|
+
<NavigationPageTree
|
|
28
|
+
nodes={[activeRoot]}
|
|
29
|
+
currentPage={currentPage}
|
|
30
|
+
variant="sidebar"
|
|
31
|
+
integratePageSections
|
|
32
|
+
/>
|
|
33
|
+
</nav>
|
|
34
|
+
</aside>
|
|
35
|
+
)}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
type NavigationState = {
|
|
3
|
+
openPaths: string[];
|
|
4
|
+
sectionPaths: string[];
|
|
5
|
+
scrollTop: number;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const setupNavigationState = (container: HTMLElement, scope: 'desktop' | 'mobile') => {
|
|
9
|
+
const root = container.dataset.navigationRoot ?? '/';
|
|
10
|
+
const stateKey = `norna:tree-navigation:${scope}:${root}`;
|
|
11
|
+
const branches = Array.from(container.querySelectorAll<HTMLDetailsElement>(
|
|
12
|
+
'.navigation-page-disclosure[data-page-path]',
|
|
13
|
+
));
|
|
14
|
+
let storedState: NavigationState = { openPaths: [], sectionPaths: [], scrollTop: 0 };
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
const parsedState = JSON.parse(sessionStorage.getItem(stateKey) ?? '{}');
|
|
18
|
+
storedState = {
|
|
19
|
+
openPaths: Array.isArray(parsedState.openPaths) ? parsedState.openPaths : [],
|
|
20
|
+
sectionPaths: Array.isArray(parsedState.sectionPaths) ? parsedState.sectionPaths : [],
|
|
21
|
+
scrollTop: Number.isFinite(Number(parsedState.scrollTop)) ? Number(parsedState.scrollTop) : 0,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
branches.forEach((branch) => {
|
|
25
|
+
const pagePath = branch.dataset.pagePath ?? '';
|
|
26
|
+
branch.open = branch.dataset.currentBranch === 'true'
|
|
27
|
+
|| storedState.openPaths.includes(pagePath);
|
|
28
|
+
|
|
29
|
+
if (storedState.sectionPaths.includes(pagePath)) {
|
|
30
|
+
branch.dataset.sectionsOpen = 'true';
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
if (storedState.scrollTop > 0) {
|
|
35
|
+
requestAnimationFrame(() => {
|
|
36
|
+
container.scrollTop = storedState.scrollTop;
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
} catch {
|
|
40
|
+
// Navigation remains fully usable when browser storage is unavailable.
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const saveState = () => {
|
|
44
|
+
try {
|
|
45
|
+
const openBranches = branches.filter((branch) => branch.open);
|
|
46
|
+
const state: NavigationState = {
|
|
47
|
+
openPaths: openBranches.map((branch) => branch.dataset.pagePath ?? ''),
|
|
48
|
+
sectionPaths: openBranches
|
|
49
|
+
.filter((branch) => (
|
|
50
|
+
branch.dataset.sectionsOpen === 'true'
|
|
51
|
+
|| branch.dataset.currentPage === 'true'
|
|
52
|
+
))
|
|
53
|
+
.map((branch) => branch.dataset.pagePath ?? ''),
|
|
54
|
+
scrollTop: container.scrollTop,
|
|
55
|
+
};
|
|
56
|
+
sessionStorage.setItem(stateKey, JSON.stringify(state));
|
|
57
|
+
} catch {
|
|
58
|
+
// Navigation state persistence is an optional enhancement.
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
requestAnimationFrame(() => {
|
|
63
|
+
branches.forEach((branch) => branch.addEventListener('toggle', () => {
|
|
64
|
+
if (branch.open && branch.dataset.hasSections === 'true') {
|
|
65
|
+
branch.dataset.sectionsOpen = 'true';
|
|
66
|
+
} else if (!branch.open) {
|
|
67
|
+
delete branch.dataset.sectionsOpen;
|
|
68
|
+
}
|
|
69
|
+
saveState();
|
|
70
|
+
}));
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
container.addEventListener('scroll', saveState, { passive: true });
|
|
74
|
+
container.querySelectorAll('a').forEach((link) => link.addEventListener('click', saveState));
|
|
75
|
+
window.addEventListener('pagehide', saveState);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const desktopNavigation = document.querySelector<HTMLElement>('.tree-local-navigation');
|
|
79
|
+
const mobileNavigation = document.querySelector<HTMLElement>('.mobile-site-nav[data-navigation-root]');
|
|
80
|
+
|
|
81
|
+
if (desktopNavigation) setupNavigationState(desktopNavigation, 'desktop');
|
|
82
|
+
if (mobileNavigation) setupNavigationState(mobileNavigation, 'mobile');
|
|
83
|
+
</script>
|
package/src/content.config.ts
CHANGED
|
@@ -23,21 +23,15 @@ const siteThemeSchema = themeVisualSchema;
|
|
|
23
23
|
|
|
24
24
|
const site = defineCollection({
|
|
25
25
|
loader: glob({
|
|
26
|
-
pattern:
|
|
26
|
+
pattern: 'pages/**/content.md',
|
|
27
27
|
base: pathToFileURL(siteDir),
|
|
28
28
|
generateId: ({ entry }) => {
|
|
29
|
-
if (entry === 'content.md') {
|
|
30
|
-
return siteEntryId;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
29
|
const pageEntryDirectory = entry.split('/').slice(1, -1).join('/');
|
|
34
30
|
const pageDirectory = pageEntryDirectory
|
|
35
31
|
.split('/')
|
|
36
32
|
.filter((segment) => segment !== 'pages')
|
|
37
33
|
.join('/pages/');
|
|
38
|
-
return pageDirectory
|
|
39
|
-
? `${siteEntryId.replace(/-content$/, '')}-page-${encodePageDirectoryPath(parsePageDirectoryPath(pageDirectory, `page directory pages/${pageEntryDirectory}`).pageDirectory)}`
|
|
40
|
-
: entry.replace(/[^a-zA-Z0-9-]+/g, '-').replace(/^-+|-+$/g, '');
|
|
34
|
+
return `${siteEntryId.replace(/-content$/, '')}-page-${encodePageDirectoryPath(parsePageDirectoryPath(pageDirectory, `page directory pages/${pageEntryDirectory}`).pageDirectory)}`;
|
|
41
35
|
},
|
|
42
36
|
}),
|
|
43
37
|
schema: siteSchema,
|
|
@@ -20,6 +20,7 @@ type Presentation = {
|
|
|
20
20
|
type VisualTheme = {
|
|
21
21
|
layout: {
|
|
22
22
|
gutter: { desktop: string; mobile: string };
|
|
23
|
+
localNavigationGap: string;
|
|
23
24
|
pageWidth: string;
|
|
24
25
|
spacing: {
|
|
25
26
|
firstSectionTop: { desktop: string; mobile: string };
|
|
@@ -36,6 +37,11 @@ type VisualTheme = {
|
|
|
36
37
|
maxAvailableHeightPercent: { desktop: number; mobile: number };
|
|
37
38
|
};
|
|
38
39
|
typography: { fontFamily: string };
|
|
40
|
+
shape: {
|
|
41
|
+
radiusSmall: string;
|
|
42
|
+
radiusMedium: string;
|
|
43
|
+
radiusLarge: string;
|
|
44
|
+
};
|
|
39
45
|
};
|
|
40
46
|
|
|
41
47
|
interface Props {
|
|
@@ -72,7 +78,11 @@ const documentStyle = [
|
|
|
72
78
|
`scroll-behavior: ${scrollBehavior}`,
|
|
73
79
|
...Object.entries(getPresentationCssVariables(presentation)).map(([name, value]) => `${name}: ${value}`),
|
|
74
80
|
`--font-sans: ${visualTheme.typography.fontFamily}`,
|
|
81
|
+
`--shape-radius-small: ${visualTheme.shape.radiusSmall}`,
|
|
82
|
+
`--shape-radius-medium: ${visualTheme.shape.radiusMedium}`,
|
|
83
|
+
`--shape-radius-large: ${visualTheme.shape.radiusLarge}`,
|
|
75
84
|
`--page-width: ${visualTheme.layout.pageWidth}`,
|
|
85
|
+
`--local-navigation-gap: ${visualTheme.layout.localNavigationGap}`,
|
|
76
86
|
`--content-gutter-desktop: ${visualTheme.layout.gutter.desktop}`,
|
|
77
87
|
`--content-gutter-mobile: ${visualTheme.layout.gutter.mobile}`,
|
|
78
88
|
`--space-nav-to-first-section-desktop: ${layoutSpacing.firstSectionTop.desktop}`,
|
package/src/lib/pageThemes.ts
CHANGED
|
@@ -3,7 +3,9 @@ import path from 'node:path';
|
|
|
3
3
|
import {
|
|
4
4
|
validatePageThemeYamlStructure,
|
|
5
5
|
} from '../../scripts/lib/site-content.mjs';
|
|
6
|
+
import { pageThemeSchema } from '../../scripts/lib/schema-definitions.mjs';
|
|
6
7
|
import { sitePagesDir, sitePagesLabel } from '../../scripts/lib/site-paths.mjs';
|
|
8
|
+
import { mergePageThemeConfig } from '../../scripts/lib/theme-presets.mjs';
|
|
7
9
|
import { parseYamlConfig } from '../../scripts/lib/yaml-config.mjs';
|
|
8
10
|
import { getPageDirectoryAncestors } from '../../scripts/lib/page-model.mjs';
|
|
9
11
|
|
|
@@ -15,7 +17,9 @@ type PageTheme = {
|
|
|
15
17
|
export const getPageTheme = async (pageDirectory: string | null): Promise<PageTheme | null> => {
|
|
16
18
|
if (!pageDirectory) return null;
|
|
17
19
|
|
|
18
|
-
const pageAncestors = getPageDirectoryAncestors(pageDirectory)
|
|
20
|
+
const pageAncestors = getPageDirectoryAncestors(pageDirectory);
|
|
21
|
+
let inheritedData: Record<string, unknown> = {};
|
|
22
|
+
const inheritedIds: string[] = [];
|
|
19
23
|
for (const pageAncestor of pageAncestors) {
|
|
20
24
|
const themeSegments = pageAncestor.split('/');
|
|
21
25
|
const themePath = path.join(sitePagesDir, ...themeSegments, 'theme.yaml');
|
|
@@ -27,16 +31,14 @@ export const getPageTheme = async (pageDirectory: string | null): Promise<PageTh
|
|
|
27
31
|
const themeLabel = `${sitePagesLabel}/${themeSegments.join('/')}/theme.yaml`;
|
|
28
32
|
|
|
29
33
|
const data = parseYamlConfig(source, themeLabel, {
|
|
34
|
+
schema: pageThemeSchema,
|
|
30
35
|
validateStructure: validatePageThemeYamlStructure,
|
|
31
36
|
});
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
return {
|
|
36
|
-
id: `pages/${themeSegments.join('/')}/theme`,
|
|
37
|
-
data,
|
|
38
|
-
};
|
|
37
|
+
inheritedData = mergePageThemeConfig(inheritedData, data);
|
|
38
|
+
inheritedIds.push(`pages/${themeSegments.join('/')}/theme`);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
return
|
|
41
|
+
return inheritedIds.length > 0
|
|
42
|
+
? { id: inheritedIds.join(' + '), data: inheritedData }
|
|
43
|
+
: null;
|
|
42
44
|
};
|
|
@@ -246,11 +246,7 @@ const applyH3HeadingIds = (
|
|
|
246
246
|
return result;
|
|
247
247
|
};
|
|
248
248
|
|
|
249
|
-
const getImageSourceKey = (page: SitePage, image: string) =>
|
|
250
|
-
page.pageDirectory
|
|
251
|
-
? `pages/${page.pageDirectory}/images/${image}`
|
|
252
|
-
: `images/${image}`
|
|
253
|
-
);
|
|
249
|
+
const getImageSourceKey = (page: SitePage, image: string) => `pages/${page.pageDirectory}/images/${image}`;
|
|
254
250
|
|
|
255
251
|
const renderInlineNoteMarkdown = async (markdown: string) => {
|
|
256
252
|
const result = await markdownToHtml(markdown, {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type { SectionNavigation } from './sectionContent';
|
|
1
|
+
import type { HeadingNavigation, SectionNavigation } from './sectionContent';
|
|
2
2
|
import type { SitePage } from './sitePages';
|
|
3
3
|
|
|
4
4
|
export type PageNavigationEntry = {
|
|
5
5
|
page: SitePage;
|
|
6
|
+
headings: HeadingNavigation[];
|
|
6
7
|
sections: SectionNavigation[];
|
|
7
8
|
};
|
|
8
9
|
|
package/src/lib/sitePages.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CollectionEntry } from 'astro:content';
|
|
2
2
|
import { decodePageDirectoryPath, parsePageDirectoryPath } from '../../scripts/lib/page-model.mjs';
|
|
3
|
+
import { homePageDirectory } from '../../scripts/lib/site-conventions.mjs';
|
|
3
4
|
|
|
4
5
|
type SiteEntry = CollectionEntry<'site'>;
|
|
5
6
|
|
|
@@ -14,7 +15,7 @@ export type SitePage = {
|
|
|
14
15
|
pageDirectories: string[];
|
|
15
16
|
pathSegment: string;
|
|
16
17
|
pathname: string;
|
|
17
|
-
pageDirectory: string
|
|
18
|
+
pageDirectory: string;
|
|
18
19
|
pageId: string;
|
|
19
20
|
pageIds: string[];
|
|
20
21
|
pageOrders: number[];
|
|
@@ -37,13 +38,17 @@ const stripPageIdPrefix = (id: string) => {
|
|
|
37
38
|
}
|
|
38
39
|
};
|
|
39
40
|
|
|
40
|
-
export const isHomePageEntry = (entry: SiteEntry) => stripPageIdPrefix(entry.id) ===
|
|
41
|
+
export const isHomePageEntry = (entry: SiteEntry) => stripPageIdPrefix(entry.id) === homePageDirectory;
|
|
41
42
|
|
|
42
|
-
const getPageDirectory = (entry: SiteEntry) =>
|
|
43
|
+
const getPageDirectory = (entry: SiteEntry) => {
|
|
44
|
+
const pageDirectory = stripPageIdPrefix(entry.id);
|
|
45
|
+
if (!pageDirectory) throw new Error(`Page entry "${entry.id}" has no valid page directory.`);
|
|
46
|
+
return pageDirectory;
|
|
47
|
+
};
|
|
43
48
|
|
|
44
49
|
const getPageMetadata = (entry: SiteEntry) => {
|
|
45
50
|
const pageDirectory = getPageDirectory(entry);
|
|
46
|
-
return
|
|
51
|
+
return parsePageDirectoryPath(pageDirectory, `page directory ${pageDirectory}`);
|
|
47
52
|
};
|
|
48
53
|
|
|
49
54
|
const getPagePathname = (pathSegment: string) => pathSegment ? `/${pathSegment}/` : '/';
|
|
@@ -78,29 +83,29 @@ const getPageTitle = (entry: SiteEntry) => {
|
|
|
78
83
|
export const getSitePage = (entry: SiteEntry): SitePage => {
|
|
79
84
|
const isHome = isHomePageEntry(entry);
|
|
80
85
|
const pageMetadata = getPageMetadata(entry);
|
|
81
|
-
const pageDirectory = pageMetadata
|
|
82
|
-
const pageId = pageMetadata
|
|
83
|
-
const pagePath = pageMetadata
|
|
86
|
+
const pageDirectory = pageMetadata.pageDirectory;
|
|
87
|
+
const pageId = pageMetadata.pageId;
|
|
88
|
+
const pagePath = pageMetadata.pagePath;
|
|
84
89
|
const pathSegment = isHome ? '' : pagePath;
|
|
85
90
|
const navigation = entry.data.navigation ?? {};
|
|
86
91
|
|
|
87
92
|
return {
|
|
88
93
|
entry,
|
|
89
94
|
isHome,
|
|
90
|
-
depth: pageMetadata
|
|
95
|
+
depth: pageMetadata.depth,
|
|
91
96
|
navigation: {
|
|
92
97
|
listed: navigation.listed ?? true,
|
|
93
|
-
order: isHome ? 0 : pageMetadata
|
|
98
|
+
order: isHome ? 0 : pageMetadata.pageOrder,
|
|
94
99
|
},
|
|
95
100
|
pathSegment,
|
|
96
101
|
pathname: getPagePathname(pathSegment),
|
|
97
102
|
pageDirectory,
|
|
98
|
-
pageDirectories: pageMetadata
|
|
103
|
+
pageDirectories: pageMetadata.pageDirectories,
|
|
99
104
|
pageId,
|
|
100
|
-
pageIds: pageMetadata
|
|
101
|
-
pageOrders: pageMetadata
|
|
105
|
+
pageIds: pageMetadata.pageIds,
|
|
106
|
+
pageOrders: pageMetadata.pageOrders,
|
|
102
107
|
pagePath,
|
|
103
|
-
parentPagePath:
|
|
108
|
+
parentPagePath: isHome ? null : pageMetadata.parentPagePath,
|
|
104
109
|
title: getPageTitle(entry),
|
|
105
110
|
};
|
|
106
111
|
};
|
|
@@ -112,6 +117,9 @@ export const getSitePages = (entries: SiteEntry[]) => {
|
|
|
112
117
|
const siblingPageOrders = new Map<string, SitePage>();
|
|
113
118
|
|
|
114
119
|
for (const page of pages) {
|
|
120
|
+
if (page.isHome && page.navigation.listed === false) {
|
|
121
|
+
throw new Error(`${homePageDirectory} is the required homepage and cannot set navigation.listed to false.`);
|
|
122
|
+
}
|
|
115
123
|
const existing = pathnames.get(page.pathname);
|
|
116
124
|
if (existing) {
|
|
117
125
|
throw new Error(`Duplicate page path "${page.pathname}" from "${existing.entry.id}" and "${page.entry.id}".`);
|
|
@@ -121,7 +129,7 @@ export const getSitePages = (entries: SiteEntry[]) => {
|
|
|
121
129
|
|
|
122
130
|
if (page.isHome) continue;
|
|
123
131
|
|
|
124
|
-
const siblingScope = page.
|
|
132
|
+
const siblingScope = page.pageDirectories.slice(0, -1).join('/pages/');
|
|
125
133
|
const pageIdKey = `${siblingScope}\0${page.pageId}`;
|
|
126
134
|
const existingPageId = siblingPageIds.get(pageIdKey);
|
|
127
135
|
if (existingPageId) {
|
|
@@ -138,6 +146,9 @@ export const getSitePages = (entries: SiteEntry[]) => {
|
|
|
138
146
|
|
|
139
147
|
siblingPageOrders.set(pageOrderKey, page);
|
|
140
148
|
}
|
|
149
|
+
if (!pages.some(({ isHome }) => isHome)) {
|
|
150
|
+
throw new Error(`Homepage page entry ${homePageDirectory} is missing.`);
|
|
151
|
+
}
|
|
141
152
|
|
|
142
153
|
return pages.sort((left, right) => (
|
|
143
154
|
left.isHome ? -1 : right.isHome ? 1 :
|
package/src/pages/index.astro
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
import { getCollection } from 'astro:content';
|
|
3
3
|
import SitePage from '../components/SitePage.astro';
|
|
4
4
|
import { isHomePageEntry } from '../lib/sitePages';
|
|
5
|
+
import { homePageDirectory } from '../../scripts/lib/site-conventions.mjs';
|
|
5
6
|
|
|
6
7
|
const siteDirectory = (process.env.NORNA_SITE_DIR ?? 'site').trim();
|
|
7
|
-
const siteContentLabel = `${siteDirectory || 'site'}/content.md`;
|
|
8
|
+
const siteContentLabel = `${siteDirectory || 'site'}/pages/${homePageDirectory}/content.md`;
|
|
8
9
|
const entries = await getCollection('site');
|
|
9
10
|
const site = entries.find(isHomePageEntry);
|
|
10
11
|
|