vite-wp 0.1.3 → 0.1.7

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.
Files changed (29) hide show
  1. package/README.md +2 -20
  2. package/{starter/src → defaults}/templates/partials/Header.astro +1 -1
  3. package/{starter/src → defaults}/templates/posts/archive.astro +1 -1
  4. package/{starter/src → defaults}/templates/search.astro +1 -1
  5. package/{starter/src → defaults}/templates/taxonomies/taxonomy-[taxonomy].astro +1 -1
  6. package/dist/astro.js +23 -1
  7. package/dist/config.js +1 -1
  8. package/dist/dev-toolbar/vitewp-toolbar.d.ts +1 -0
  9. package/dist/dev-toolbar/vitewp-toolbar.js +1 -0
  10. package/dist/wordpress/index.d.ts +3 -0
  11. package/dist/wordpress/index.js +3 -0
  12. package/package.json +23 -1
  13. package/{starter/src/pages/[...slug].astro → runtime/route.astro} +19 -10
  14. package/starter/src/live.config.ts +1 -1
  15. package/starter/src/templates/.gitkeep +0 -0
  16. package/starter/src/wordpress/client.ts +0 -263
  17. package/starter/src/wordpress/generated-types.ts +0 -38
  18. package/starter/src/wordpress/menus.ts +0 -51
  19. package/starter/src/wordpress/schemas.ts +0 -44
  20. package/starter/src/wordpress/templates.ts +0 -113
  21. /package/{starter/src → defaults}/templates/404.astro +0 -0
  22. /package/{starter/src → defaults}/templates/pages/.gitkeep +0 -0
  23. /package/{starter/src → defaults}/templates/pages/default.astro +0 -0
  24. /package/{starter/src → defaults}/templates/pages/front-page.astro +0 -0
  25. /package/{starter/src → defaults}/templates/partials/Pagination.astro +0 -0
  26. /package/{starter/src → defaults}/templates/post-types/.gitkeep +0 -0
  27. /package/{starter/src → defaults}/templates/posts/.gitkeep +0 -0
  28. /package/{starter/src → defaults}/templates/posts/single.astro +0 -0
  29. /package/{starter/src → defaults}/templates/taxonomies/.gitkeep +0 -0
package/README.md CHANGED
@@ -66,24 +66,7 @@ my-site/
66
66
 
67
67
  src/
68
68
  live.config.ts
69
- pages/
70
- [...slug].astro
71
- templates/
72
- pages/
73
- front-page.astro
74
- default.astro
75
- posts/
76
- single.astro
77
- archive.astro
78
- taxonomies/
79
- taxonomy-[taxonomy].astro
80
- search.astro
81
- 404.astro
82
- wordpress/
83
- client.ts
84
- templates.ts
85
- menus.ts
86
- generated-types.ts
69
+ templates/ # optional template overrides
87
70
 
88
71
  wordpress/
89
72
  public/ # Composer-installed WordPress core
@@ -96,14 +79,13 @@ my-site/
96
79
 
97
80
  ## Templates
98
81
 
99
- The catch-all Astro route asks WordPress what the current URL is, then renders the first matching template from `src/templates`.
82
+ ViteWP ships default templates from the package. Create files in `src/templates` only when you want to override them. Project templates always win over package defaults.
100
83
 
101
84
  Examples:
102
85
 
103
86
  ```txt
104
87
  src/templates/pages/front-page.astro
105
88
  src/templates/pages/page-about.astro
106
- src/templates/pages/default.astro
107
89
  src/templates/posts/single.astro
108
90
  src/templates/posts/archive.astro
109
91
  src/templates/taxonomies/category.astro
@@ -1,5 +1,5 @@
1
1
  ---
2
- import { getMenuByLocation, getMenuBySlug } from '../../wordpress/menus.js';
2
+ import { getMenuByLocation, getMenuBySlug } from 'vite-wp/wordpress/menus';
3
3
 
4
4
  interface Props {
5
5
  location?: string;
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  import Pagination from '../partials/Pagination.astro';
3
- import type { WpContentItem } from '../../wordpress/client.js';
3
+ import type { WpContentItem } from 'vite-wp/wordpress';
4
4
 
5
5
  interface Props {
6
6
  title?: string;
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  import Pagination from './partials/Pagination.astro';
3
- import type { WpContentItem } from '../wordpress/client.js';
3
+ import type { WpContentItem } from 'vite-wp/wordpress';
4
4
 
5
5
  interface Props {
6
6
  title?: string;
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  import Pagination from '../partials/Pagination.astro';
3
- import type { WpContentItem } from '../../wordpress/client.js';
3
+ import type { WpContentItem } from 'vite-wp/wordpress';
4
4
 
5
5
  interface Props {
6
6
  title?: string;
package/dist/astro.js CHANGED
@@ -1,10 +1,18 @@
1
1
  import { existsSync } from 'node:fs';
2
+ import { join } from 'node:path';
2
3
  import { fileURLToPath } from 'node:url';
3
4
  export default function vitewp(_options = {}) {
4
5
  return {
5
6
  name: 'vitewp',
6
7
  hooks: {
7
- 'astro:config:setup': ({ command, addDevToolbarApp, logger }) => {
8
+ 'astro:config:setup': ({ command, config, injectRoute, addDevToolbarApp, logger }) => {
9
+ if (!hasProjectCatchAllRoute(fileURLToPath(config.root))) {
10
+ injectRoute({
11
+ pattern: '/[...slug]',
12
+ entrypoint: getDefaultRouteEntrypoint(),
13
+ prerender: false,
14
+ });
15
+ }
8
16
  if (command === 'dev') {
9
17
  addDevToolbarApp({
10
18
  id: 'vitewp',
@@ -18,6 +26,20 @@ export default function vitewp(_options = {}) {
18
26
  },
19
27
  };
20
28
  }
29
+ function hasProjectCatchAllRoute(root) {
30
+ return [
31
+ join(root, 'src/pages/[...slug].astro'),
32
+ join(root, 'src/pages/[...slug].ts'),
33
+ join(root, 'src/pages/[...slug].js'),
34
+ ].some((file) => existsSync(file));
35
+ }
36
+ function getDefaultRouteEntrypoint() {
37
+ const sourceEntrypoint = new URL('../runtime/route.astro', import.meta.url);
38
+ if (existsSync(fileURLToPath(sourceEntrypoint))) {
39
+ return sourceEntrypoint;
40
+ }
41
+ return new URL('../runtime/route.astro', import.meta.url);
42
+ }
21
43
  function getDevToolbarEntrypoint() {
22
44
  const sourceEntrypoint = new URL('./dev-toolbar/vitewp-toolbar.ts', import.meta.url);
23
45
  if (existsSync(fileURLToPath(sourceEntrypoint))) {
package/dist/config.js CHANGED
@@ -17,7 +17,7 @@ export async function loadViteWpConfig(root = process.cwd()) {
17
17
  .find((file) => existsSync(file));
18
18
  let userConfig = {};
19
19
  if (configFile) {
20
- const loaded = await loadConfigFromFile({ command: 'serve', mode: 'development' }, configFile, root);
20
+ const loaded = await loadConfigFromFile({ command: 'serve', mode: 'development' }, configFile, root, undefined, undefined, 'runner');
21
21
  userConfig = (loaded?.config ?? {});
22
22
  }
23
23
  return {
@@ -12,6 +12,7 @@ interface ViteWpRouteInfo {
12
12
  postType: string | null;
13
13
  slug: string | null;
14
14
  template: string | null;
15
+ templateSource: 'project' | 'vite-wp' | null;
15
16
  totalPages: number | null;
16
17
  }
17
18
  declare global {
@@ -98,6 +98,7 @@ function renderInfo(info) {
98
98
  <section class="grid">
99
99
  ${row('URL path', info.path)}
100
100
  ${row('Selected template', info.template ?? 'No template matched')}
101
+ ${row('Template source', info.templateSource ?? '—')}
101
102
  ${row('Live collection', info.liveCollection ? `${info.liveCollection.collection} → ${info.liveCollection.entryId}` : '—')}
102
103
  ${row('Post type', info.postType ?? '—')}
103
104
  ${row('Slug', info.slug ?? '—')}
@@ -0,0 +1,3 @@
1
+ export * from './client.js';
2
+ export * from './menus.js';
3
+ export * from './templates.js';
@@ -0,0 +1,3 @@
1
+ export * from './client.js';
2
+ export * from './menus.js';
3
+ export * from './templates.js';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vite-wp",
3
3
  "private": false,
4
- "version": "0.1.3",
4
+ "version": "0.1.7",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "vite-wp": "dist/cli.js"
@@ -18,6 +18,26 @@
18
18
  "./content": {
19
19
  "types": "./dist/content.d.ts",
20
20
  "import": "./dist/content.js"
21
+ },
22
+ "./wordpress": {
23
+ "types": "./dist/wordpress/index.d.ts",
24
+ "import": "./dist/wordpress/index.js"
25
+ },
26
+ "./wordpress/client": {
27
+ "types": "./dist/wordpress/client.d.ts",
28
+ "import": "./dist/wordpress/client.js"
29
+ },
30
+ "./wordpress/menus": {
31
+ "types": "./dist/wordpress/menus.d.ts",
32
+ "import": "./dist/wordpress/menus.js"
33
+ },
34
+ "./wordpress/templates": {
35
+ "types": "./dist/wordpress/templates.d.ts",
36
+ "import": "./dist/wordpress/templates.js"
37
+ },
38
+ "./wordpress/schemas": {
39
+ "types": "./dist/wordpress/schemas.d.ts",
40
+ "import": "./dist/wordpress/schemas.js"
21
41
  }
22
42
  },
23
43
  "scripts": {
@@ -67,6 +87,8 @@
67
87
  },
68
88
  "files": [
69
89
  "dist",
90
+ "defaults",
91
+ "runtime",
70
92
  "starter",
71
93
  "README.md",
72
94
  "LICENSE"
@@ -2,8 +2,8 @@
2
2
  export const prerender = false;
3
3
 
4
4
  import { getLiveEntry } from 'astro:content';
5
- import type { WpResolvedRoute } from '../wordpress/client.js';
6
- import { createTemplateContext, templateCandidates } from '../wordpress/templates.js';
5
+ import type { WpResolvedRoute } from 'vite-wp/wordpress';
6
+ import { createTemplateContext, templateCandidates } from 'vite-wp/wordpress/templates';
7
7
 
8
8
  type TemplateModule = {
9
9
  default: unknown;
@@ -25,9 +25,11 @@ if (!route) {
25
25
  Astro.response.statusText = 'Not Found';
26
26
  }
27
27
 
28
- const templates = import.meta.glob<TemplateModule>('../templates/**/*.astro');
28
+ const projectTemplates = import.meta.glob<TemplateModule>('/src/templates/**/*.astro');
29
+ const defaultTemplates = import.meta.glob<TemplateModule>('../defaults/templates/**/*.astro');
29
30
  let Template: any = null;
30
31
  let templatePath = '';
32
+ let templateSource: 'project' | 'vite-wp' | null = null;
31
33
  const showDebug = import.meta.env.DEV;
32
34
  let context = null;
33
35
 
@@ -36,21 +38,29 @@ if (route) {
36
38
  candidates = templateCandidates(route);
37
39
 
38
40
  for (const candidate of candidates) {
39
- const path = `../templates/${candidate}`;
40
- const loader = templates[path];
41
+ const projectPath = `/src/templates/${candidate}`;
42
+ const defaultPath = `../defaults/templates/${candidate}`;
43
+ const projectLoader = projectTemplates[projectPath];
44
+ const defaultLoader = defaultTemplates[defaultPath];
45
+ const loader = projectLoader ?? defaultLoader;
41
46
 
42
47
  if (loader) {
43
48
  Template = (await loader()).default;
44
49
  templatePath = candidate;
50
+ templateSource = projectLoader ? 'project' : 'vite-wp';
45
51
  break;
46
52
  }
47
53
  }
48
54
  } else {
49
55
  candidates = ['404.astro'];
50
- const loader = templates['../templates/404.astro'];
56
+ const projectLoader = projectTemplates['/src/templates/404.astro'];
57
+ const defaultLoader = defaultTemplates['../defaults/templates/404.astro'];
58
+ const loader = projectLoader ?? defaultLoader;
59
+
51
60
  if (loader) {
52
61
  Template = (await loader()).default;
53
62
  templatePath = '404.astro';
63
+ templateSource = projectLoader ? 'project' : 'vite-wp';
54
64
  }
55
65
  }
56
66
 
@@ -68,10 +78,11 @@ const toolbarRouteInfo = showDebug ? {
68
78
  page: context?.page ?? null,
69
79
  totalPages: context?.totalPages ?? null,
70
80
  template: templatePath || null,
81
+ templateSource,
71
82
  candidateTemplates: candidates,
72
83
  } : null;
73
84
  const toolbarRouteInfoJson = toolbarRouteInfo
74
- ? JSON.stringify(toolbarRouteInfo).replaceAll('<', '\\u003c')
85
+ ? JSON.stringify(toolbarRouteInfo).replaceAll('<', '\u003c')
75
86
  : '';
76
87
  ---
77
88
  <html lang="en">
@@ -85,9 +96,7 @@ const toolbarRouteInfoJson = toolbarRouteInfo
85
96
  <body>
86
97
  <main>
87
98
  {Template && context ? (
88
- <>
89
- <Template {...context} />
90
- </>
99
+ <Template {...context} />
91
100
  ) : Template ? (
92
101
  <Template slug={slug} />
93
102
  ) : (
@@ -1,6 +1,6 @@
1
1
  import { defineLiveCollection } from 'astro/content/config';
2
2
  import { wpMenuLoader, wpPostTypeLoader, wpRouteLoader } from 'vite-wp/content';
3
- import { wpContentItemSchema, wpMenuSchema, wpResolvedRouteSchema } from './wordpress/schemas.js';
3
+ import { wpContentItemSchema, wpMenuSchema, wpResolvedRouteSchema } from 'vite-wp/wordpress/schemas';
4
4
 
5
5
  export const collections = {
6
6
  routes: defineLiveCollection({
File without changes
@@ -1,263 +0,0 @@
1
- export interface WpRenderedField {
2
- rendered: string;
3
- }
4
-
5
- export interface WpContentItem {
6
- id: number;
7
- slug: string;
8
- type: string;
9
- link: string;
10
- title: WpRenderedField;
11
- content: WpRenderedField;
12
- excerpt?: WpRenderedField;
13
- date?: string;
14
- modified?: string;
15
- }
16
-
17
- export interface WpArchivePayload {
18
- items: WpContentItem[];
19
- page: number;
20
- perPage: number;
21
- total: number;
22
- totalPages: number;
23
- }
24
-
25
- interface BaseArchiveResolution {
26
- found: true;
27
- slug: string;
28
- postType: string;
29
- restBase: string;
30
- title: string;
31
- page?: number;
32
- }
33
-
34
- export type WpBridgeResolution =
35
- | {
36
- found: true;
37
- kind: 'page' | 'single';
38
- id: number;
39
- slug: string;
40
- postType: string;
41
- restBase: string;
42
- isFrontPage?: boolean;
43
- isPostsPage?: boolean;
44
- }
45
- | (BaseArchiveResolution & {
46
- kind: 'postsArchive' | 'postTypeArchive';
47
- })
48
- | (BaseArchiveResolution & {
49
- kind: 'taxonomyArchive';
50
- taxonomy: string;
51
- taxonomyRestBase: string;
52
- termId: number;
53
- termName: string;
54
- })
55
- | (BaseArchiveResolution & {
56
- kind: 'search';
57
- search: string;
58
- })
59
- | {
60
- found: false;
61
- kind: 'notFound';
62
- };
63
-
64
- export type WpResolvedRoute =
65
- | {
66
- kind: 'page';
67
- postType: 'page';
68
- restBase: 'pages';
69
- slug: string;
70
- item: WpContentItem;
71
- isFrontPage?: boolean;
72
- }
73
- | {
74
- kind: 'single';
75
- postType: string;
76
- restBase: string;
77
- slug: string;
78
- item: WpContentItem;
79
- }
80
- | {
81
- kind: 'postsArchive' | 'postTypeArchive' | 'search';
82
- postType: string;
83
- restBase: string;
84
- slug: string;
85
- title: string;
86
- items: WpContentItem[];
87
- page: number;
88
- perPage: number;
89
- total: number;
90
- totalPages: number;
91
- search?: string;
92
- }
93
- | {
94
- kind: 'taxonomyArchive';
95
- postType: string;
96
- restBase: string;
97
- slug: string;
98
- title: string;
99
- items: WpContentItem[];
100
- page: number;
101
- perPage: number;
102
- total: number;
103
- totalPages: number;
104
- taxonomy: string;
105
- taxonomyRestBase: string;
106
- termId: number;
107
- termName: string;
108
- };
109
-
110
- export async function resolveWordPressRoute(pathname: string): Promise<WpResolvedRoute | null> {
111
- const resolution = await resolveViaWordPress(pathname);
112
-
113
- if (!resolution.found) {
114
- return null;
115
- }
116
-
117
- switch (resolution.kind) {
118
- case 'postsArchive':
119
- case 'postTypeArchive': {
120
- const archive = await getArchive({
121
- kind: resolution.kind,
122
- postType: resolution.postType,
123
- page: resolution.page ?? 1,
124
- });
125
- return {
126
- kind: resolution.kind,
127
- postType: resolution.postType,
128
- restBase: resolution.restBase,
129
- slug: resolution.slug,
130
- title: resolution.title,
131
- ...archive,
132
- };
133
- }
134
- case 'taxonomyArchive': {
135
- const archive = await getArchive({
136
- kind: resolution.kind,
137
- postType: resolution.postType,
138
- taxonomy: resolution.taxonomy,
139
- termId: resolution.termId,
140
- page: resolution.page ?? 1,
141
- });
142
- return {
143
- kind: 'taxonomyArchive',
144
- postType: resolution.postType,
145
- restBase: resolution.restBase,
146
- slug: resolution.slug,
147
- title: resolution.title,
148
- taxonomy: resolution.taxonomy,
149
- taxonomyRestBase: resolution.taxonomyRestBase,
150
- termId: resolution.termId,
151
- termName: resolution.termName,
152
- ...archive,
153
- };
154
- }
155
- case 'search': {
156
- const archive = await getArchive({
157
- kind: resolution.kind,
158
- search: resolution.search,
159
- page: resolution.page ?? 1,
160
- });
161
- return {
162
- kind: 'search',
163
- postType: resolution.postType,
164
- restBase: resolution.restBase,
165
- slug: resolution.slug,
166
- title: resolution.title,
167
- search: resolution.search,
168
- ...archive,
169
- };
170
- }
171
- case 'page':
172
- case 'single':
173
- break;
174
- }
175
-
176
- if (resolution.isPostsPage) {
177
- const archive = await getArchive({ kind: 'postsArchive', postType: 'post', page: 1 });
178
- return {
179
- kind: 'postsArchive',
180
- postType: 'post',
181
- restBase: 'posts',
182
- slug: resolution.slug,
183
- title: '',
184
- ...archive,
185
- };
186
- }
187
-
188
- const item = await getById(resolution.restBase, resolution.id);
189
-
190
- if (resolution.kind === 'page') {
191
- return {
192
- kind: 'page',
193
- postType: 'page',
194
- restBase: 'pages',
195
- slug: resolution.slug,
196
- item,
197
- isFrontPage: resolution.isFrontPage,
198
- };
199
- }
200
-
201
- return {
202
- kind: 'single',
203
- postType: resolution.postType,
204
- restBase: resolution.restBase,
205
- slug: resolution.slug,
206
- item,
207
- };
208
- }
209
-
210
- export function getWordPressApiBase() {
211
- const base = getWordPressBaseUrl();
212
- return `${base}/wp-json/wp/v2`;
213
- }
214
-
215
- export function getWordPressBaseUrl() {
216
- return (process.env.VITEWP_PUBLIC_URL ?? process.env.WP_URL ?? 'http://localhost:3000').replace(/\/$/, '');
217
- }
218
-
219
- async function resolveViaWordPress(pathname: string) {
220
- const url = new URL(`${getWordPressBaseUrl()}/wp-json/vitewp/v1/resolve`);
221
- url.searchParams.set('path', pathname || '/');
222
-
223
- const response = await fetch(url);
224
-
225
- if (response.status === 404) {
226
- return { found: false, kind: 'notFound' } satisfies WpBridgeResolution;
227
- }
228
-
229
- if (!response.ok) {
230
- throw new Error(`ViteWP route resolution failed: ${response.status} ${response.statusText}`);
231
- }
232
-
233
- return response.json() as Promise<WpBridgeResolution>;
234
- }
235
-
236
- async function getById(restBase: string, id: number) {
237
- const url = new URL(`${getWordPressApiBase()}/${restBase}/${id}`);
238
- url.searchParams.set('_embed', '1');
239
-
240
- return getJson<WpContentItem>(url);
241
- }
242
-
243
- async function getArchive(params: Record<string, string | number | undefined>) {
244
- const url = new URL(`${getWordPressBaseUrl()}/wp-json/vitewp/v1/archive`);
245
-
246
- for (const [key, value] of Object.entries(params)) {
247
- if (value !== undefined) {
248
- url.searchParams.set(key, String(value));
249
- }
250
- }
251
-
252
- return getJson<WpArchivePayload>(url);
253
- }
254
-
255
- async function getJson<T>(url: URL): Promise<T> {
256
- const response = await fetch(url);
257
-
258
- if (!response.ok) {
259
- throw new Error(`WordPress REST request failed: ${response.status} ${response.statusText}`);
260
- }
261
-
262
- return response.json() as Promise<T>;
263
- }
@@ -1,38 +0,0 @@
1
- // Generated by ViteWP. Do not edit by hand.
2
-
3
- export type WpPostType = "post" | "page" | "attachment";
4
- export type WpTaxonomy = "category" | "post_tag";
5
-
6
- export type WpRestBaseByPostType = {
7
- "post": "posts";
8
- "page": "pages";
9
- "attachment": "media";
10
- };
11
- export type WpArchiveSlugByPostType = {
12
- "post": null;
13
- "page": null;
14
- "attachment": null;
15
- };
16
- export type WpRestBaseByTaxonomy = {
17
- "category": "categories";
18
- "post_tag": "tags";
19
- };
20
-
21
- export interface WpRenderedField {
22
- rendered: string;
23
- protected?: boolean;
24
- }
25
-
26
- export interface WpContentItem<PostType extends WpPostType = WpPostType> {
27
- id: number;
28
- slug: string;
29
- type: PostType;
30
- link: string;
31
- title: WpRenderedField;
32
- content: WpRenderedField;
33
- excerpt?: WpRenderedField;
34
- date?: string;
35
- modified?: string;
36
- }
37
-
38
- export interface WpArchiveItem<PostType extends WpPostType = WpPostType> extends WpContentItem<PostType> {}
@@ -1,51 +0,0 @@
1
- import { getWordPressBaseUrl } from './client.js';
2
-
3
- export interface WpMenuItem {
4
- id: number;
5
- parent: number;
6
- title: string;
7
- url: string;
8
- target: string;
9
- classes: string[];
10
- object: string;
11
- objectId: number;
12
- type: string;
13
- }
14
-
15
- export interface WpMenu {
16
- id: number;
17
- slug: string;
18
- name: string;
19
- items: WpMenuItem[];
20
- }
21
-
22
- export interface WpMenusPayload {
23
- locations: Record<string, number>;
24
- menus: WpMenu[];
25
- }
26
-
27
- export async function getMenus(): Promise<WpMenusPayload> {
28
- const response = await fetch(`${getWordPressBaseUrl()}/wp-json/vitewp/v1/menus`);
29
-
30
- if (!response.ok) {
31
- throw new Error(`Could not fetch WordPress menus: ${response.status} ${response.statusText}`);
32
- }
33
-
34
- return response.json() as Promise<WpMenusPayload>;
35
- }
36
-
37
- export async function getMenuByLocation(location: string): Promise<WpMenu | null> {
38
- const payload = await getMenus();
39
- const menuId = payload.locations[location];
40
-
41
- if (!menuId) {
42
- return null;
43
- }
44
-
45
- return payload.menus.find((menu) => menu.id === menuId) ?? null;
46
- }
47
-
48
- export async function getMenuBySlug(slug: string): Promise<WpMenu | null> {
49
- const payload = await getMenus();
50
- return payload.menus.find((menu) => menu.slug === slug) ?? null;
51
- }
@@ -1,44 +0,0 @@
1
- import { z } from 'astro/zod';
2
-
3
- export const wpRenderedFieldSchema = z.looseObject({
4
- rendered: z.string(),
5
- protected: z.boolean().optional(),
6
- });
7
-
8
- export const wpContentItemSchema = z.looseObject({
9
- id: z.number(),
10
- slug: z.string(),
11
- type: z.string(),
12
- link: z.string(),
13
- title: wpRenderedFieldSchema,
14
- content: wpRenderedFieldSchema,
15
- excerpt: wpRenderedFieldSchema.optional(),
16
- date: z.string().optional(),
17
- modified: z.string().optional(),
18
- });
19
-
20
- export const wpResolvedRouteSchema = z.looseObject({
21
- kind: z.string(),
22
- postType: z.string(),
23
- restBase: z.string(),
24
- slug: z.string(),
25
- });
26
-
27
- export const wpMenuItemSchema = z.looseObject({
28
- id: z.number(),
29
- parent: z.number(),
30
- title: z.string(),
31
- url: z.string(),
32
- target: z.string(),
33
- classes: z.array(z.string()),
34
- object: z.string(),
35
- objectId: z.number(),
36
- type: z.string(),
37
- });
38
-
39
- export const wpMenuSchema = z.looseObject({
40
- id: z.number(),
41
- slug: z.string(),
42
- name: z.string(),
43
- items: z.array(wpMenuItemSchema),
44
- });
@@ -1,113 +0,0 @@
1
- import type { WpContentItem, WpResolvedRoute } from './client.js';
2
-
3
- export interface TemplateContext {
4
- route: WpResolvedRoute;
5
- title: string;
6
- content: string;
7
- excerpt: string;
8
- slug: string;
9
- postType: string;
10
- items: WpContentItem[];
11
- page: number;
12
- perPage: number;
13
- total: number;
14
- totalPages: number;
15
- search?: string;
16
- taxonomy?: string;
17
- termName?: string;
18
- }
19
-
20
- export function createTemplateContext(route: WpResolvedRoute): TemplateContext {
21
- switch (route.kind) {
22
- case 'postsArchive':
23
- case 'postTypeArchive':
24
- case 'search':
25
- return {
26
- route,
27
- title: route.title,
28
- content: '',
29
- excerpt: '',
30
- slug: route.slug,
31
- postType: route.postType,
32
- items: route.items,
33
- page: route.page,
34
- perPage: route.perPage,
35
- total: route.total,
36
- totalPages: route.totalPages,
37
- search: route.search,
38
- };
39
- case 'taxonomyArchive':
40
- return {
41
- route,
42
- title: route.title,
43
- content: '',
44
- excerpt: '',
45
- slug: route.slug,
46
- postType: route.postType,
47
- items: route.items,
48
- page: route.page,
49
- perPage: route.perPage,
50
- total: route.total,
51
- totalPages: route.totalPages,
52
- taxonomy: route.taxonomy,
53
- termName: route.termName,
54
- };
55
- case 'page':
56
- case 'single':
57
- return {
58
- route,
59
- title: route.item.title.rendered,
60
- content: route.item.content.rendered,
61
- excerpt: route.item.excerpt?.rendered ?? '',
62
- slug: route.slug,
63
- postType: route.postType,
64
- items: [],
65
- page: 1,
66
- perPage: 0,
67
- total: 0,
68
- totalPages: 0,
69
- };
70
- }
71
- }
72
-
73
- export function templateCandidates(route: WpResolvedRoute): string[] {
74
- if (route.kind === 'search') {
75
- return ['search.astro', 'posts/archive.astro'];
76
- }
77
-
78
- if (route.kind === 'taxonomyArchive') {
79
- return [
80
- `taxonomies/${route.taxonomy}-${route.slug}.astro`,
81
- `taxonomies/${route.taxonomy}.astro`,
82
- 'taxonomies/taxonomy-[taxonomy].astro',
83
- 'posts/archive.astro',
84
- ];
85
- }
86
-
87
- if (route.kind === 'postsArchive') {
88
- return ['posts/archive.astro'];
89
- }
90
-
91
- if (route.kind === 'postTypeArchive') {
92
- return [
93
- `post-types/${route.postType}/archive.astro`,
94
- 'posts/archive.astro',
95
- ];
96
- }
97
-
98
- if (route.kind === 'page') {
99
- return [
100
- ...(route.isFrontPage ? ['pages/front-page.astro'] : []),
101
- `pages/page-${route.slug}.astro`,
102
- 'pages/default.astro',
103
- ];
104
- }
105
-
106
- return [
107
- `post-types/${route.postType}/single-${route.slug}.astro`,
108
- `post-types/${route.postType}/single.astro`,
109
- ...(route.postType === 'post' ? [] : ['posts/single.astro']),
110
- `posts/single-${route.slug}.astro`,
111
- 'posts/single.astro',
112
- ];
113
- }
File without changes