soames-astro-theme 0.1.0 → 0.1.2

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "soames-astro-theme",
3
3
  "type": "module",
4
- "version": "0.1.0",
4
+ "version": "0.1.2",
5
5
  "description": "Shared Astro theme for the Soames ecosystem (WordPress headless + React islands). Successor to soames-gatsby-theme.",
6
6
  "keywords": [
7
7
  "astro",
@@ -23,7 +23,19 @@ export async function getStaticPaths() {
23
23
  });
24
24
  }
25
25
 
26
- const { page } = Astro.props;
26
+ let { page } = Astro.props;
27
+
28
+ // Dev only: getStaticPaths (and the WP content it bakes into props) is cached for
29
+ // the life of `astro dev`, so edits in WordPress wouldn't show until a restart.
30
+ // Re-fetch the current page on each request in dev so a browser refresh reflects
31
+ // content changes. Tree-shaken out of production builds (import.meta.env.DEV).
32
+ if (import.meta.env.DEV) {
33
+ const clean = (Astro.params.uri ?? "").replace(/^\/+|\/+$/g, "");
34
+ const fresh = (await getPages()).find(
35
+ (p) => (p.uri ?? "").replace(/^\/+|\/+$/g, "") === clean
36
+ );
37
+ if (fresh) page = fresh;
38
+ }
27
39
  ---
28
40
  <Base pageTitle={page.title} description={page.excerpt}>
29
41
  <HeroHeader
@@ -36,8 +36,29 @@ export async function getStaticPaths() {
36
36
  });
37
37
  }
38
38
 
39
- const { posts, pageNum, totalPages, prevPath, nextPath, heroTitle, heroBg, heroOverlay } =
39
+ let { posts, pageNum, totalPages, prevPath, nextPath, heroTitle, heroBg, heroOverlay } =
40
40
  Astro.props;
41
+
42
+ // Dev only: refresh this archive page's data on each request (getStaticPaths is
43
+ // cached for the life of `astro dev`, so WP edits wouldn't show until a restart).
44
+ // Recomputes the same slice/hero as getStaticPaths for the current pageNum.
45
+ // Removed from production builds (import.meta.env.DEV).
46
+ if (import.meta.env.DEV) {
47
+ const [all, perPage, postsPage] = await Promise.all([
48
+ getPosts(),
49
+ getPostsPerPage(),
50
+ getPostsPage(),
51
+ ]);
52
+ const base = `/${postsPage?.slug || "blog"}`;
53
+ totalPages = Math.max(1, Math.ceil(all.length / perPage));
54
+ posts = all.slice((pageNum - 1) * perPage, pageNum * perPage);
55
+ prevPath = pageNum > 1 ? (pageNum === 2 ? `${base}/` : `${base}/${pageNum - 1}/`) : null;
56
+ nextPath = pageNum < totalPages ? `${base}/${pageNum + 1}/` : null;
57
+ heroTitle = postsPage?.title || "Blog";
58
+ heroBg = postsPage?.featuredImage?.sourceUrl ?? null;
59
+ heroOverlay = postsPage?.overlayOpacity ?? 0.6;
60
+ }
61
+
41
62
  const fmtDate = (d: string) =>
42
63
  new Date(d).toLocaleDateString("en-US", { year: "numeric", month: "long", day: "2-digit" });
43
64
 
@@ -8,10 +8,17 @@ import HeroHeader from "@theme/components/HeroHeader";
8
8
  import Shortcodes from "@theme/components/shortcodes/Shortcodes";
9
9
  import Bio from "@theme/components/Bio";
10
10
  import BlogSidebar from "@theme/components/BlogSidebar";
11
- import { getPosts } from "../../../lib/wp";
11
+ import { getPosts, getPostsPage } from "../../../lib/wp";
12
12
 
13
13
  export async function getStaticPaths() {
14
14
  const posts = await getPosts();
15
+ // Single posts inherit the posts page (blog roll) hero — title, background
16
+ // image, overlay — falling back to "Blog" / placeholder when none is set.
17
+ // Fetched once here and shared across all paths (one WP round-trip).
18
+ const postsPage = await getPostsPage();
19
+ const heroTitle = postsPage?.title ?? "Blog";
20
+ const heroBg = postsPage?.featuredImage?.sourceUrl ?? null;
21
+ const heroOverlay = postsPage?.overlayOpacity ?? null;
15
22
  return posts.map((post, i) => ({
16
23
  params: { slug: post.slug },
17
24
  props: {
@@ -19,17 +26,39 @@ export async function getStaticPaths() {
19
26
  posts,
20
27
  previous: posts[i + 1] ?? null, // posts are date DESC → next index is older
21
28
  next: posts[i - 1] ?? null,
29
+ heroTitle,
30
+ heroBg,
31
+ heroOverlay,
22
32
  },
23
33
  }));
24
34
  }
25
35
 
26
- const { post, posts, previous, next } = Astro.props;
36
+ let { post, posts, previous, next, heroTitle, heroBg, heroOverlay } = Astro.props;
37
+
38
+ // Dev only: re-fetch on each request so WP edits show on refresh without
39
+ // restarting `astro dev` (getStaticPaths props are cached otherwise). Stripped
40
+ // from production builds (import.meta.env.DEV).
41
+ if (import.meta.env.DEV) {
42
+ const all = await getPosts();
43
+ const i = all.findIndex((p) => p.slug === Astro.params.slug);
44
+ if (i !== -1) {
45
+ posts = all;
46
+ post = all[i];
47
+ previous = all[i + 1] ?? null;
48
+ next = all[i - 1] ?? null;
49
+ }
50
+ const pp = await getPostsPage();
51
+ heroTitle = pp?.title ?? "Blog";
52
+ heroBg = pp?.featuredImage?.sourceUrl ?? null;
53
+ heroOverlay = pp?.overlayOpacity ?? null;
54
+ }
55
+
27
56
  const img = post.featuredImage;
28
57
  const fmtDate = (d: string) =>
29
58
  new Date(d).toLocaleDateString("en-US", { year: "numeric", month: "long", day: "2-digit" });
30
59
  ---
31
60
  <Base pageTitle={post.title} description={post.excerpt}>
32
- <HeroHeader title="Blog" subhead="" backgroundImage={null} overlayOpacity={0.6} />
61
+ <HeroHeader title={heroTitle} subhead="" backgroundImage={heroBg} overlayOpacity={heroOverlay} />
33
62
  <section>
34
63
  <div class="media-container-row">
35
64
  <div class="col-12 col-lg-8">
@@ -7,7 +7,7 @@ import Base from "@theme/layouts/Base.astro";
7
7
  import HeroHeader from "@theme/components/HeroHeader";
8
8
  import Shortcodes from "@theme/components/shortcodes/Shortcodes";
9
9
  import DocsSidebar from "@theme/components/DocsSidebar";
10
- import { getDocs, buildDocTree } from "../../lib/wp";
10
+ import { getDocs, buildDocTree, getDocsPage } from "../../lib/wp";
11
11
 
12
12
  export async function getStaticPaths() {
13
13
  // Derive the [...slug] param from the doc's WP uri (e.g. /docs/getting-started/
@@ -19,19 +19,43 @@ export async function getStaticPaths() {
19
19
 
20
20
  const docs = await getDocs();
21
21
  const tree = buildDocTree(docs);
22
+ // Single docs inherit the /docs/ page hero — title, background image, overlay —
23
+ // falling back to "Documentation" / placeholder when none is set. Fetched once
24
+ // here and shared across all paths (one WP round-trip).
25
+ const docsPage = await getDocsPage();
26
+ const heroTitle = docsPage?.title ?? "Documentation";
27
+ const heroBg = docsPage?.featuredImage?.sourceUrl ?? null;
28
+ const heroOverlay = docsPage?.overlayOpacity ?? null;
22
29
  return docs
23
30
  .map((doc) => ({ doc, slug: toSlug(doc.uri) }))
24
31
  .filter(({ slug }) => slug.length > 0)
25
32
  .map(({ doc, slug }) => ({
26
33
  params: { slug },
27
- props: { doc, tree },
34
+ props: { doc, tree, heroTitle, heroBg, heroOverlay },
28
35
  }));
29
36
  }
30
37
 
31
- const { doc, tree } = Astro.props;
38
+ let { doc, tree, heroTitle, heroBg, heroOverlay } = Astro.props;
39
+
40
+ // Dev only: re-fetch on each request so WP doc edits show on refresh without
41
+ // restarting `astro dev` (getStaticPaths props are cached otherwise). Stripped
42
+ // from production builds (import.meta.env.DEV).
43
+ if (import.meta.env.DEV) {
44
+ const toSlug = (uri: string) => uri.replace(/^\/+|\/+$/g, "").replace(/^docs\/?/, "");
45
+ const docs = await getDocs();
46
+ const fresh = docs.find((d) => toSlug(d.uri) === Astro.params.slug);
47
+ if (fresh) {
48
+ doc = fresh;
49
+ tree = buildDocTree(docs);
50
+ }
51
+ const dp = await getDocsPage();
52
+ heroTitle = dp?.title ?? "Documentation";
53
+ heroBg = dp?.featuredImage?.sourceUrl ?? null;
54
+ heroOverlay = dp?.overlayOpacity ?? null;
55
+ }
32
56
  ---
33
57
  <Base pageTitle={doc.title} description={doc.excerpt}>
34
- <HeroHeader title="Documentation" subhead="" backgroundImage={null} overlayOpacity={0.6} />
58
+ <HeroHeader title={heroTitle} subhead="" backgroundImage={heroBg} overlayOpacity={heroOverlay} />
35
59
  <section>
36
60
  <div class="media-container-row">
37
61
  <div class="col-12 col-lg-8">