Skip to content

Commit 56667dd

Browse files
committed
Support custom nested filenames in entry paths
Fix #672
1 parent ed8a6d0 commit 56667dd

2 files changed

Lines changed: 82 additions & 11 deletions

File tree

src/lib/services/contents/draft/save/assets.js

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -68,27 +68,37 @@ const fillTemplateIfNeeded = (pathString, fillSlugOptions) =>
6868
pathString.includes('{{') ? fillTemplate(pathString, fillSlugOptions) : pathString;
6969

7070
/**
71-
* Extract the entry folder path from an entry file path. Removes file extension and `/index` suffix
72-
* for nested entries.
71+
* Extract the entry folder path from an entry file path. Removes file extension and the filename
72+
* suffix for nested entries (e.g., `/index`, `/_index`, or any custom filename from the `path`
73+
* config).
7374
* @param {string} entryFilePath Entry file path, e.g., `src/content/blog/hello-world.md`.
75+
* @param {string | undefined} subPath Collection's file subPath template, e.g., `{{slug}}/index`.
7476
* @returns {string} Entry folder path, e.g., `src/content/blog/hello-world`.
7577
* @example
7678
* // Simple files
77-
* getEntryFolderPath('src/content/blog/hello-world.md')
79+
* getEntryFolderPath('src/content/blog/hello-world.md', '{{slug}}')
7880
* // => 'src/content/blog/hello-world'
7981
* @example
80-
* // Nested files
81-
* getEntryFolderPath('src/content/blog/hello-world/index.md')
82+
* // Nested files with `index`
83+
* getEntryFolderPath('src/content/blog/hello-world/index.md', '{{slug}}/index')
8284
* // => 'src/content/blog/hello-world'
85+
* @example
86+
* // Nested files with `_index`
87+
* getEntryFolderPath('content/learn/my-slug/_index.md', '{{slug}}/_index')
88+
* // => 'content/learn/my-slug'
8389
*/
84-
const getEntryFolderPath = (entryFilePath) => {
90+
const getEntryFolderPath = (entryFilePath, subPath) => {
8591
// Remove file extension (always present)
8692
const extensionIndex = entryFilePath.lastIndexOf('.');
8793
let folderPath = entryFilePath.substring(0, extensionIndex);
88-
89-
// Remove `/index` suffix for nested entries
90-
if (folderPath.endsWith('/index')) {
91-
folderPath = folderPath.substring(0, folderPath.length - 6);
94+
// For nested entries where the path config has a fixed filename suffix (e.g., `{{slug}}/index` or
95+
// `{{slug}}/_index`), strip that last segment to get the folder path. Paths like
96+
// `{{year}}/{{month}}/{{slug}}` are not nested in this sense — the slug IS the last segment, so
97+
// nothing is stripped.
98+
const lastSubPathSegment = subPath?.includes('/') ? subPath.split('/').at(-1) : undefined;
99+
100+
if (lastSubPathSegment && !lastSubPathSegment.includes('{{')) {
101+
folderPath = folderPath.match(FOLDER_PATH_REGEX)?.groups?.path ?? folderPath;
92102
}
93103

94104
return folderPath;
@@ -200,7 +210,7 @@ export const resolveAssetFolderPaths = ({ folder, fillSlugOptions }) => {
200210
: undefined;
201211

202212
const subPathFolderPath = subPath?.match(FOLDER_PATH_REGEX)?.groups?.path ?? '';
203-
const entryFolderPath = getEntryFolderPath(entryFilePath ?? '');
213+
const entryFolderPath = getEntryFolderPath(entryFilePath ?? '', subPath);
204214
const isNestedEntry = subPath?.includes('/') ?? false;
205215

206216
const resolvedInternalPath = resolveInternalPath({

src/lib/services/contents/draft/save/assets.test.js

Lines changed: 61 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)