-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add markdown rendering to content layer (#11440)
* feat: add glob loader * Enable watching and fix paths * Store the full entry object, not just data * Add generateId support * Fix test * Rename loaders to sync * Refacctor imports * Use getEntry * Format * Fix import * Remove type from output * Windows path * Add test for absolute path * Update lockfile * Debugging windows * Allow file URL for base dir * Reset time limit * wip: add markdown rendering to content layer * use cached entries * CLean up types * Instrument more of the build * Add digest helper * Add comments * Make image extraction work * feat: image support for content layer (#11469) * wip * wip * Add image to benchmark * Stub assets if missing * Resolve assets in data * Ignore virtual module * Format * rm log * Handle images when using cached data * Fix CCC * Add a comment * Changes from review * Format * Use relative paths for asset files * Pass all md props to getImage * Ensure dotastro dir exists * Fix tests * Changes from review * Don't use temp array in getcollection * Add error handling * Format * Handle paths that are already relative * Dedupe sync runs * Fix syncing in dev * Changes from review * Windows paths ftw * feat(content-layer): support references in content layer (#11494) * Support references in content layer * Fix utf8 rendering * Warn for invalid entries * Fix test * lol windows paths * Remove assertion
- Loading branch information
Showing
38 changed files
with
992 additions
and
181 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import fs from 'node:fs/promises'; | ||
import { loremIpsumMd } from './_util.js'; | ||
|
||
/** | ||
* @param {URL} projectDir | ||
*/ | ||
export async function run(projectDir) { | ||
await fs.rm(projectDir, { recursive: true, force: true }); | ||
await fs.mkdir(new URL('./src/pages/blog', projectDir), { recursive: true }); | ||
await fs.mkdir(new URL('./src/content/blog', projectDir), { recursive: true }); | ||
await fs.copyFile(new URL('./image.jpg', import.meta.url), new URL('./src/image.jpg', projectDir)); | ||
|
||
const promises = []; | ||
|
||
|
||
for (let i = 0; i < 10000; i++) { | ||
const content = `\ | ||
# Article ${i} | ||
${loremIpsumMd} | ||
![image ${i}](../../image.jpg) | ||
`; | ||
promises.push( | ||
fs.writeFile(new URL(`./src/content/blog/article-${i}.md`, projectDir), content, 'utf-8') | ||
); | ||
} | ||
|
||
|
||
await fs.writeFile( | ||
new URL(`./src/pages/blog/[...slug].astro`, projectDir), | ||
`\ | ||
--- | ||
import { getCollection } from 'astro:content'; | ||
export async function getStaticPaths() { | ||
const blogEntries = await getCollection('blog'); | ||
return blogEntries.map(entry => ({ | ||
params: { slug: entry.slug }, props: { entry }, | ||
})); | ||
} | ||
const { entry } = Astro.props; | ||
const { Content } = await entry.render(); | ||
--- | ||
<h1>{entry.data.title}</h1> | ||
<Content /> | ||
`, | ||
'utf-8' | ||
); | ||
|
||
await Promise.all(promises); | ||
|
||
await fs.writeFile( | ||
new URL('./astro.config.js', projectDir), | ||
`\ | ||
import { defineConfig } from 'astro/config'; | ||
export default defineConfig({ | ||
});`, | ||
'utf-8' | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import fs from 'node:fs/promises'; | ||
import { loremIpsumMd } from './_util.js'; | ||
|
||
/** | ||
* @param {URL} projectDir | ||
*/ | ||
export async function run(projectDir) { | ||
await fs.rm(projectDir, { recursive: true, force: true }); | ||
await fs.mkdir(new URL('./src/pages/blog', projectDir), { recursive: true }); | ||
await fs.mkdir(new URL('./data/blog', projectDir), { recursive: true }); | ||
await fs.mkdir(new URL('./src/content', projectDir), { recursive: true }); | ||
await fs.copyFile(new URL('./image.jpg', import.meta.url), new URL('./image.jpg', projectDir)); | ||
|
||
const promises = []; | ||
|
||
for (let i = 0; i < 10000; i++) { | ||
const content = `\ | ||
# Article ${i} | ||
${loremIpsumMd} | ||
![image ${i}](../../image.jpg) | ||
`; | ||
promises.push( | ||
fs.writeFile(new URL(`./data/blog/article-${i}.md`, projectDir), content, 'utf-8') | ||
); | ||
} | ||
|
||
await fs.writeFile( | ||
new URL(`./src/content/config.ts`, projectDir), | ||
/*ts */ ` | ||
import { defineCollection, z } from 'astro:content'; | ||
import { glob } from 'astro/loaders'; | ||
const blog = defineCollection({ | ||
type: 'experimental_data', | ||
loader: glob({ pattern: '*', base: './data/blog' }), | ||
}); | ||
export const collections = { blog } | ||
` | ||
); | ||
|
||
await fs.writeFile( | ||
new URL(`./src/pages/blog/[...slug].astro`, projectDir), | ||
`\ | ||
--- | ||
import { getCollection } from 'astro:content'; | ||
export async function getStaticPaths() { | ||
const blogEntries = await getCollection('blog'); | ||
return blogEntries.map(entry => ({ | ||
params: { slug: entry.id }, props: { entry }, | ||
})); | ||
} | ||
const { entry } = Astro.props; | ||
const { Content } = await entry.render(); | ||
--- | ||
<h1>{entry.data.title}</h1> | ||
<Content /> | ||
`, | ||
'utf-8' | ||
); | ||
|
||
await Promise.all(promises); | ||
|
||
await fs.writeFile( | ||
new URL('./astro.config.js', projectDir), | ||
`\ | ||
import { defineConfig } from 'astro/config'; | ||
export default defineConfig({ | ||
});`, | ||
'utf-8' | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { isRemotePath, removeBase } from '@astrojs/internal-helpers/path'; | ||
import { CONTENT_IMAGE_FLAG, IMAGE_IMPORT_PREFIX } from '../../content/consts.js'; | ||
import { shorthash } from '../../runtime/server/shorthash.js'; | ||
import { VALID_INPUT_FORMATS } from '../consts.js'; | ||
|
||
/** | ||
* Resolves an image src from a content file (such as markdown) to a module ID or import that can be resolved by Vite. | ||
* | ||
* @param imageSrc The src attribute of an image tag | ||
* @param filePath The path to the file that contains the imagem relative to the site root | ||
* @returns A module id of the image that can be rsolved by Vite, or undefined if it is not a local image | ||
*/ | ||
export function imageSrcToImportId(imageSrc: string, filePath: string): string | undefined { | ||
// If the import is coming from the data store it will have a special prefix to identify it | ||
// as an image import. We remove this prefix so that we can resolve the image correctly. | ||
imageSrc = removeBase(imageSrc, IMAGE_IMPORT_PREFIX); | ||
|
||
// We only care about local imports | ||
if (isRemotePath(imageSrc) || imageSrc.startsWith('/')) { | ||
return; | ||
} | ||
// We only care about images | ||
const ext = imageSrc.split('.').at(-1) as (typeof VALID_INPUT_FORMATS)[number] | undefined; | ||
if (!ext || !VALID_INPUT_FORMATS.includes(ext)) { | ||
return; | ||
} | ||
|
||
// The import paths are relative to the content (md) file, but when it's actually resolved it will | ||
// be in a single assets file, so relative paths will no longer work. To deal with this we use | ||
// a query parameter to store the original path to the file and append a query param flag. | ||
// This allows our Vite plugin to intercept the import and resolve the path relative to the | ||
// importer and get the correct full path for the imported image. | ||
|
||
const params = new URLSearchParams(CONTENT_IMAGE_FLAG); | ||
params.set('importer', filePath); | ||
return `${imageSrc}?${params.toString()}`; | ||
} | ||
|
||
export const importIdToSymbolName = (importId: string) => | ||
`__ASTRO_IMAGE_IMPORT_${shorthash(importId)}`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.