feat: support .md
overrides for content collections
This commit is contained in:
parent
d049a48cf1
commit
5aebbd88ca
7 changed files with 35 additions and 3 deletions
|
@ -979,6 +979,7 @@ export interface AstroConfig extends z.output<typeof AstroConfigSchema> {
|
|||
}
|
||||
|
||||
export interface ContentEntryType {
|
||||
name: string;
|
||||
extensions: string[];
|
||||
getEntryInfo(params: { fileUrl: URL; contents: string }): Promise<{
|
||||
data: Record<string, unknown>;
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
export { attachContentServerListeners } from './server-listeners.js';
|
||||
export { createContentTypesGenerator } from './types-generator.js';
|
||||
export { contentObservable, getContentPaths, getDotAstroTypeReference } from './utils.js';
|
||||
export {
|
||||
contentObservable,
|
||||
getContentPaths,
|
||||
getDotAstroTypeReference,
|
||||
hasMdContentEntryTypeOverride,
|
||||
} from './utils.js';
|
||||
export { astroContentAssetPropagationPlugin } from './vite-plugin-content-assets.js';
|
||||
export { astroContentImportPlugin } from './vite-plugin-content-imports.js';
|
||||
export { astroContentVirtualModPlugin } from './vite-plugin-content-virtual-mod.js';
|
||||
|
|
|
@ -7,6 +7,7 @@ import { ErrorPayload as ViteErrorPayload, normalizePath, ViteDevServer } from '
|
|||
import { z } from 'zod';
|
||||
import { AstroConfig, AstroSettings } from '../@types/astro.js';
|
||||
import { AstroError, AstroErrorData } from '../core/errors/index.js';
|
||||
import { MARKDOWN_CONTENT_ENTRY_TYPE_NAME } from '../vite-plugin-markdown/content-entry-type.js';
|
||||
import { CONTENT_TYPES_FILE } from './consts.js';
|
||||
|
||||
export const collectionConfigParser = z.object({
|
||||
|
@ -350,3 +351,11 @@ function search(fs: typeof fsMod, srcDir: URL) {
|
|||
}
|
||||
return { exists: false, url: paths[0] };
|
||||
}
|
||||
|
||||
export function hasMdContentEntryTypeOverride(settings: Pick<AstroSettings, 'contentEntryTypes'>) {
|
||||
return settings.contentEntryTypes.some(
|
||||
(contentEntryType) =>
|
||||
contentEntryType.name !== MARKDOWN_CONTENT_ENTRY_TYPE_NAME &&
|
||||
contentEntryType.extensions.includes('.md')
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,10 @@ import { fileURLToPath } from 'node:url';
|
|||
import { ContentEntryType } from '../@types/astro.js';
|
||||
import { parseFrontmatter } from '../content/utils.js';
|
||||
|
||||
export const MARKDOWN_CONTENT_ENTRY_TYPE_NAME = 'astro:markdown';
|
||||
|
||||
export const markdownContentEntryType: ContentEntryType = {
|
||||
name: MARKDOWN_CONTENT_ENTRY_TYPE_NAME,
|
||||
extensions: ['.md'],
|
||||
async getEntryInfo({ fileUrl, contents }: { fileUrl: URL; contents: string }) {
|
||||
const parsed = parseFrontmatter(contents, fileURLToPath(fileUrl));
|
||||
|
|
|
@ -10,6 +10,7 @@ import type { Plugin } from 'vite';
|
|||
import { normalizePath } from 'vite';
|
||||
import type { AstroSettings } from '../@types/astro';
|
||||
import { getContentPaths } from '../content/index.js';
|
||||
import { hasMdContentEntryTypeOverride } from '../content/index.js';
|
||||
import { AstroError, AstroErrorData, MarkdownError } from '../core/errors/index.js';
|
||||
import type { LogOptions } from '../core/logger/core.js';
|
||||
import { warn } from '../core/logger/core.js';
|
||||
|
@ -66,6 +67,15 @@ export default function markdown({ settings, logging }: AstroPluginOptions): Plu
|
|||
async load(id) {
|
||||
if (isMarkdownFile(id)) {
|
||||
const { fileId, fileUrl } = getFileInfo(id, settings.config);
|
||||
if (
|
||||
// Integrations can override the Markdown parser for content collections.
|
||||
// If an override is present, skip this file.
|
||||
fileId.startsWith(getContentPaths(settings.config).contentDir.pathname) &&
|
||||
hasMdContentEntryTypeOverride(settings)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const rawFile = await fs.promises.readFile(fileId, 'utf-8');
|
||||
const raw = safeMatter(rawFile, id);
|
||||
const renderResult = await renderMarkdown(raw.content, {
|
||||
|
|
|
@ -6,13 +6,16 @@ import { parseFrontmatter } from './utils.js';
|
|||
import { fileURLToPath } from 'node:url';
|
||||
import fs from 'node:fs';
|
||||
|
||||
const DEFAULT_MARKDOC_EXTS = ['.mdoc', '.md'];
|
||||
|
||||
export default function markdoc(): AstroIntegration {
|
||||
return {
|
||||
name: '@astrojs/markdoc',
|
||||
hooks: {
|
||||
'astro:config:setup': async ({ updateConfig, config, addContentEntryType, command }: any) => {
|
||||
const contentEntryType = {
|
||||
extensions: ['.mdoc'],
|
||||
name: 'astro:markdoc',
|
||||
extensions: DEFAULT_MARKDOC_EXTS,
|
||||
async getEntryInfo({ fileUrl, contents }: { fileUrl: URL; contents: string }) {
|
||||
const parsed = parseFrontmatter(contents, fileURLToPath(fileUrl));
|
||||
return {
|
||||
|
@ -34,7 +37,7 @@ export default function markdoc(): AstroIntegration {
|
|||
{
|
||||
name: '@astrojs/markdoc',
|
||||
async transform(code, id) {
|
||||
if (!id.endsWith('.mdoc')) return;
|
||||
if (!DEFAULT_MARKDOC_EXTS.some((ext) => id.endsWith(ext))) return;
|
||||
return `import { jsx as h } from 'astro/jsx-runtime';\nimport { Markdoc } from '@astrojs/markdoc';\nimport { Renderer } from '@astrojs/markdoc/components';\nexport const body = ${JSON.stringify(
|
||||
code
|
||||
)};\nexport function getParsed() { return Markdoc.parse(body); }\nexport function getTransformed(inlineConfig) { return Markdoc.transform(getParsed(), inlineConfig) }\nexport async function Content ({ config, components }) { return h(Renderer, { content: getTransformed(config), components }); }\nContent[Symbol.for('astro.needsHeadRendering')] = true;`;
|
||||
|
|
|
@ -35,6 +35,7 @@ export default function mdx(partialMdxOptions: Partial<MdxOptions> = {}): AstroI
|
|||
command,
|
||||
}: any) => {
|
||||
const contentEntryType = {
|
||||
name: 'astro:mdx',
|
||||
extensions: ['.mdx'],
|
||||
async getEntryInfo({ fileUrl, contents }: { fileUrl: URL; contents: string }) {
|
||||
const parsed = parseFrontmatter(contents, fileURLToPath(fileUrl));
|
||||
|
|
Loading…
Reference in a new issue