diff --git a/src/commands/Folders.ts b/src/commands/Folders.ts index f5f8fc7d..5dd69306 100644 --- a/src/commands/Folders.ts +++ b/src/commands/Folders.ts @@ -368,6 +368,7 @@ export class Folders { return { ...folder, + originalPath: folder.path, path: folderPath }; }); diff --git a/src/commands/Preview.ts b/src/commands/Preview.ts index 4701040d..d0349b76 100644 --- a/src/commands/Preview.ts +++ b/src/commands/Preview.ts @@ -1,3 +1,5 @@ +import { processFmPlaceholders } from './../helpers/processFmPlaceholders'; +import { processPathPlaceholders } from './../helpers/processPathPlaceholders'; import { Telemetry } from './../helpers/Telemetry'; import { SETTING_PREVIEW_HOST, @@ -5,12 +7,13 @@ import { CONTEXT, TelemetryEvent, PreviewCommands, - SETTING_EXPERIMENTAL + SETTING_EXPERIMENTAL, + SETTING_DATE_FORMAT } from './../constants'; import { ArticleHelper } from './../helpers/ArticleHelper'; import { join } from 'path'; import { commands, env, Uri, ViewColumn, window } from 'vscode'; -import { Extension, parseWinPath, Settings } from '../helpers'; +import { Extension, parseWinPath, processKnownPlaceholders, Settings } from '../helpers'; import { ContentFolder, PreviewSettings } from '../models'; import { format } from 'date-fns'; import { DateHelper } from '../helpers/DateHelper'; @@ -63,6 +66,32 @@ export class Preview { if (selectedFolder) { pathname = selectedFolder.previewPath; } + + if (pathname) { + // Known placeholders + const dateFormat = Settings.get(SETTING_DATE_FORMAT) as string; + pathname = processKnownPlaceholders(pathname, article?.data?.title, dateFormat); + + // Custom placeholders + pathname = await ArticleHelper.processCustomPlaceholders( + pathname, + article?.data?.title, + filePath + ); + + // Process the path placeholders - {{pathToken.}} + if (selectedFolder?.originalPath) { + const folderPath = processKnownPlaceholders( + selectedFolder.originalPath, + article?.data?.title, + dateFormat + ); + pathname = processPathPlaceholders(pathname, folderPath); + } + + // Support front matter placeholders - {{fm.}} + pathname = processFmPlaceholders(pathname, article?.data); + } } // Check if there is a pathname defined on content type level diff --git a/src/helpers/index.ts b/src/helpers/index.ts index 7284ae68..b2fc5964 100644 --- a/src/helpers/index.ts +++ b/src/helpers/index.ts @@ -32,3 +32,5 @@ export * from './getTaxonomyField'; export * from './isValidFile'; export * from './openFileInEditor'; export * from './parseWinPath'; +export * from './processFmPlaceholders'; +export * from './processPathPlaceholders'; diff --git a/src/helpers/processFmPlaceholders.ts b/src/helpers/processFmPlaceholders.ts new file mode 100644 index 00000000..4dda9ee7 --- /dev/null +++ b/src/helpers/processFmPlaceholders.ts @@ -0,0 +1,19 @@ +export const processFmPlaceholders = (value: string, fmData: any) => { + if (value && value.includes('{{fm.')) { + const regex = new RegExp('{{fm.(\\w+)}}', 'g'); + const matches = value.match(regex); + + if (matches) { + for (const match of matches) { + const field = match.replace('{{fm.', '').replace('}}', ''); + const fieldValue = fmData[field]; + + if (fieldValue) { + value = value.replace(match, fieldValue); + } + } + } + } + + return value; +}; diff --git a/src/helpers/processPathPlaceholders.ts b/src/helpers/processPathPlaceholders.ts new file mode 100644 index 00000000..4baba7ab --- /dev/null +++ b/src/helpers/processPathPlaceholders.ts @@ -0,0 +1,19 @@ +export const processPathPlaceholders = (value: string, path: string) => { + if (value && value.includes('{{pathToken.')) { + const regex = new RegExp('{{pathToken.(\\d+)}}', 'g'); + const matches = value.match(regex); + + if (matches) { + for (const match of matches) { + const index = parseInt(match.replace('{{pathToken.', '').replace('}}', ''), 10); + const pathTokens = path.split('/'); + + if (pathTokens.length >= index) { + value = value.replace(match, pathTokens[index - 1]); + } + } + } + } + + return value; +}; diff --git a/src/models/ContentFolder.ts b/src/models/ContentFolder.ts index 7e12eb69..9f65d361 100644 --- a/src/models/ContentFolder.ts +++ b/src/models/ContentFolder.ts @@ -6,4 +6,5 @@ export interface ContentFolder { previewPath?: string; filePrefix?: string; contentTypes?: string[]; + originalPath?: string; }