diff --git a/CHANGELOG.md b/CHANGELOG.md index a04a8488..55564f5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,14 +2,11 @@ ## [10.8.0] - 2025-02-xx -### ✨ New features - ### 🎨 Enhancements - [#915](https://github.com/estruyf/vscode-front-matter/issues/915): Added a new setting `frontMatter.panel.openOnSupportedFile` which allows you to open the panel view on supported files - [#921](https://github.com/estruyf/vscode-front-matter/issues/921): Improve the filename sanitization - -### ⚡️ Optimizations +- [#922](https://github.com/estruyf/vscode-front-matter/issues/922): Added `{{fileName}}` and `{{sluggedFileName}}` placeholders for the slug template setting ### 🐞 Fixes diff --git a/src/commands/Article.ts b/src/commands/Article.ts index 75d70a4a..837262e1 100644 --- a/src/commands/Article.ts +++ b/src/commands/Article.ts @@ -172,7 +172,12 @@ export class Article { /** * Generate the new slug */ - public static generateSlug(title: string, article?: ParsedFrontMatter, slugTemplate?: string) { + public static generateSlug( + title: string, + article?: ParsedFrontMatter, + filePath?: string, + slugTemplate?: string + ) { if (!title) { return; } @@ -181,7 +186,7 @@ export class Article { const suffix = Settings.get(SETTING_SLUG_SUFFIX) as string; if (article?.data) { - const slug = SlugHelper.createSlug(title, article?.data, slugTemplate); + const slug = SlugHelper.createSlug(title, article?.data, filePath, slugTemplate); if (typeof slug === 'string') { return { @@ -224,7 +229,12 @@ export class Article { articleDate ); - const slugInfo = Article.generateSlug(articleTitle, article, contentType.slugTemplate); + const slugInfo = Article.generateSlug( + articleTitle, + article, + editor.document.uri.fsPath, + contentType.slugTemplate + ); if ( slugInfo && @@ -255,7 +265,8 @@ export class Article { article.data[pField.name] = processArticlePlaceholdersFromData( article.data[pField.name], article.data, - contentType + contentType, + editor.document.uri.fsPath ); article.data[pField.name] = processTimePlaceholders( article.data[pField.name], @@ -335,7 +346,7 @@ export class Article { } else { const article = ArticleHelper.getFrontMatter(editor); if (article?.data) { - return SlugHelper.createSlug(article.data[titleField], article.data, slugTemplate); + return SlugHelper.createSlug(article.data[titleField], article.data, file, slugTemplate); } } } diff --git a/src/helpers/ArticleHelper.ts b/src/helpers/ArticleHelper.ts index e42e4251..9f96db7a 100644 --- a/src/helpers/ArticleHelper.ts +++ b/src/helpers/ArticleHelper.ts @@ -684,7 +684,7 @@ export class ArticleHelper { } if (fieldName === 'slug' && (fieldValue === null || fieldValue === '')) { - fmData[fieldName] = SlugHelper.createSlug(title, fmData, slugTemplate); + fmData[fieldName] = SlugHelper.createSlug(title, fmData, filePath, slugTemplate); } fmData[fieldName] = await processArticlePlaceholdersFromPath(fmData[fieldName], filePath); diff --git a/src/helpers/ContentType.ts b/src/helpers/ContentType.ts index dcfe4e81..14438c26 100644 --- a/src/helpers/ContentType.ts +++ b/src/helpers/ContentType.ts @@ -1063,7 +1063,8 @@ export class ContentType { data[field.name] = processArticlePlaceholdersFromData( field.default as string, data, - contentType + contentType, + filePath ); data[field.name] = processTimePlaceholders( data[field.name], diff --git a/src/helpers/SlugHelper.ts b/src/helpers/SlugHelper.ts index 5122be8d..0f020408 100644 --- a/src/helpers/SlugHelper.ts +++ b/src/helpers/SlugHelper.ts @@ -1,6 +1,7 @@ -import { Settings } from '.'; +import { parseWinPath, Settings } from '.'; import { stopWords, charMap, SETTING_DATE_FORMAT, SETTING_SLUG_TEMPLATE } from '../constants'; import { processTimePlaceholders, processFmPlaceholders } from '.'; +import { parse } from 'path'; export class SlugHelper { /** @@ -11,6 +12,7 @@ export class SlugHelper { public static createSlug( articleTitle: string, articleData: { [key: string]: any }, + filePath?: string, slugTemplate?: string ): string | null { if (!articleTitle) { @@ -28,6 +30,16 @@ export class SlugHelper { } else if (slugTemplate.includes('{{seoTitle}}')) { const regex = new RegExp('{{seoTitle}}', 'g'); slugTemplate = slugTemplate.replace(regex, SlugHelper.slugify(articleTitle)); + } else if (slugTemplate.includes(`{{fileName}}`)) { + const file = parse(filePath || ''); + const fileName = file.name; + const regex = new RegExp('{{fileName}}', 'g'); + slugTemplate = slugTemplate.replace(regex, fileName); + } else if (slugTemplate.includes(`{{sluggedFileName}}`)) { + const file = parse(filePath || ''); + const fileName = SlugHelper.slugify(file.name); + const regex = new RegExp('{{sluggedFileName}}', 'g'); + slugTemplate = slugTemplate.replace(regex, fileName); } const dateFormat = Settings.get(SETTING_DATE_FORMAT) as string; diff --git a/src/helpers/processArticlePlaceholders.ts b/src/helpers/processArticlePlaceholders.ts index 816271d3..1cd98c6b 100644 --- a/src/helpers/processArticlePlaceholders.ts +++ b/src/helpers/processArticlePlaceholders.ts @@ -6,7 +6,8 @@ import { SlugHelper } from './SlugHelper'; export const processArticlePlaceholdersFromData = ( value: string, data: { [key: string]: any }, - contentType: ContentType + contentType: ContentType, + filePath?: string ): string => { const titleField = getTitleField(); if (value.includes('{{title}}') && data[titleField]) { @@ -18,7 +19,7 @@ export const processArticlePlaceholdersFromData = ( const regex = new RegExp('{{slug}}', 'g'); value = value.replace( regex, - SlugHelper.createSlug(data[titleField] || '', data, contentType.slugTemplate) || '' + SlugHelper.createSlug(data[titleField] || '', data, filePath, contentType.slugTemplate) || '' ); } @@ -50,6 +51,7 @@ export const processArticlePlaceholdersFromPath = async ( SlugHelper.createSlug( article.data[titleField] || '', article.data, + filePath, contentType.slugTemplate ) || '' ); diff --git a/src/listeners/panel/DataListener.ts b/src/listeners/panel/DataListener.ts index 15369a25..2ea7f904 100644 --- a/src/listeners/panel/DataListener.ts +++ b/src/listeners/panel/DataListener.ts @@ -794,7 +794,9 @@ export class DataListener extends BaseListener { const crntFile = window.activeTextEditor?.document; const dateFormat = Settings.get(SETTING_DATE_FORMAT) as string; value = - data && contentType ? processArticlePlaceholdersFromData(value, data, contentType) : value; + data && contentType + ? processArticlePlaceholdersFromData(value, data, contentType, crntFile?.uri.fsPath) + : value; value = processTimePlaceholders(value, dateFormat); value = processFmPlaceholders(value, data);