mirror of
https://github.com/estruyf/vscode-front-matter.git
synced 2026-05-14 21:35:43 +02:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1b5909b706 | |||
| 34ac4952e0 | |||
| c0614ad228 | |||
| 6c9de39501 | |||
| 59425d6fc7 | |||
| 9b81bbaafe | |||
| 43190099e5 | |||
| 9dfa1d8775 |
@@ -6,13 +6,14 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
PACKAGE_NAME: 'fm-localized'
|
||||
MS_URL: 'https://marketplace.visualstudio.com/items?itemName=eliostruyf.vscode-front-matter-beta'
|
||||
VSX_URL: 'https://open-vsx.org/extension/eliostruyf/vscode-front-matter-beta'
|
||||
PACKAGE_NAME: "fm-localized"
|
||||
MS_URL: "https://marketplace.visualstudio.com/items?itemName=eliostruyf.vscode-\
|
||||
front-matter-beta"
|
||||
VSX_URL: "https://open-vsx.org/extension/eliostruyf/vscode-front-matter-beta"
|
||||
|
||||
jobs:
|
||||
localization:
|
||||
name: 'Localization'
|
||||
name: "Localization"
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
@@ -27,11 +28,11 @@ jobs:
|
||||
PACKAGE_NAME: ${{ env.PACKAGE_NAME }}
|
||||
|
||||
release-ms:
|
||||
name: 'Release to VSCode Marketplace'
|
||||
name: "Release to VSCode Marketplace"
|
||||
runs-on: ubuntu-latest
|
||||
needs: localization
|
||||
environment:
|
||||
name: 'MS - BETA'
|
||||
name: "MS - BETA"
|
||||
url: ${{ env.MS_URL }}
|
||||
|
||||
steps:
|
||||
@@ -43,7 +44,7 @@ jobs:
|
||||
with:
|
||||
node-version: 20
|
||||
registry-url: https://registry.npmjs.org/
|
||||
cache: 'npm'
|
||||
cache: "npm"
|
||||
|
||||
- name: Install the dependencies
|
||||
run: npm ci
|
||||
@@ -52,14 +53,24 @@ jobs:
|
||||
run: node scripts/beta-release.js $GITHUB_RUN_ID
|
||||
|
||||
- name: Publish
|
||||
run: npx @vscode/vsce publish -p ${{ secrets.VSCE_PAT }} --baseImagesUrl https://raw.githubusercontent.com/estruyf/vscode-front-matter/dev
|
||||
run: npx @vscode/vsce publish -p ${{ secrets.VSCE_PAT }} --baseImagesUrl
|
||||
https://raw.githubusercontent.com/estruyf/vscode-front-matter/dev
|
||||
|
||||
- name: Package VSIX
|
||||
run: npx @vscode/vsce package
|
||||
|
||||
- name: Upload VSIX artifact
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: vscode-demo-time-alpha.vsix
|
||||
path: "*.vsix"
|
||||
|
||||
release-vsx:
|
||||
name: 'Release to Open VSX'
|
||||
name: "Release to Open VSX"
|
||||
runs-on: ubuntu-latest
|
||||
needs: localization
|
||||
environment:
|
||||
name: 'Open VSX - BETA'
|
||||
name: "Open VSX - BETA"
|
||||
url: ${{ env.VSX_URL }}
|
||||
|
||||
steps:
|
||||
@@ -71,7 +82,7 @@ jobs:
|
||||
with:
|
||||
node-version: 20
|
||||
registry-url: https://registry.npmjs.org/
|
||||
cache: 'npm'
|
||||
cache: "npm"
|
||||
|
||||
- name: Install the dependencies
|
||||
run: npm ci
|
||||
|
||||
+11
-1
@@ -1,12 +1,22 @@
|
||||
# Change Log
|
||||
|
||||
## [10.11.0] - 2026-xx-xx
|
||||
|
||||
### 🎨 Enhancements
|
||||
|
||||
- [#1030](https://github.com/estruyf/vscode-front-matter/pull/1030): Add `frontMatter.file.slugSeparator` setting
|
||||
|
||||
### 🐞 Fixes
|
||||
|
||||
- Fix number fields not being saved to front matter when used inside block field groups
|
||||
|
||||
## [10.10.1] - 2026-04-23
|
||||
|
||||
### 🐞 Fixes
|
||||
|
||||
- Fix Git detection when Git is configured via VS Code `git.path` and not installed globally on the system
|
||||
- [#1023](https://github.com/estruyf/vscode-front-matter/issues/1023): Fix validation errors for image, file, and keywords fields
|
||||
- [#1024](https://github.com/estruyf/vscode-front-matter/issues/1024): Re-add the `frontMatter.copilot.enabled` setting to allow users to disable the GitHub Copilot integration
|
||||
- Fix Git detection when Git is configured via VS Code `git.path` and not installed globally on the system
|
||||
|
||||
## [10.10.0] - 2026-04-03 - [Release notes](https://beta.frontmatter.codes/updates/v10.10.0)
|
||||
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "vscode-front-matter-beta",
|
||||
"version": "10.10.1",
|
||||
"version": "10.11.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "vscode-front-matter-beta",
|
||||
"version": "10.10.1",
|
||||
"version": "10.11.0",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@actions/core": "^1.10.0",
|
||||
|
||||
+7
-1
@@ -3,7 +3,7 @@
|
||||
"displayName": "Front Matter CMS",
|
||||
"description": "Front Matter is a CMS that runs within Visual Studio Code. It gives you the power and control of a full-blown CMS while also providing you the flexibility and speed of the static site generator of your choice like: Hugo, Jekyll, Docusaurus, NextJs, Gatsby, and many more...",
|
||||
"icon": "assets/frontmatter-teal-128x128.png",
|
||||
"version": "10.10.1",
|
||||
"version": "10.11.0",
|
||||
"preview": false,
|
||||
"publisher": "eliostruyf",
|
||||
"galleryBanner": {
|
||||
@@ -965,6 +965,12 @@
|
||||
"markdownDescription": "%setting.frontMatter.file.preserveCasing.markdownDescription%",
|
||||
"scope": "File"
|
||||
},
|
||||
"frontMatter.file.slugSeparator": {
|
||||
"type": "string",
|
||||
"default": "-",
|
||||
"markdownDescription": "%setting.frontMatter.file.slugSeparator.markdownDescription%",
|
||||
"scope": "File"
|
||||
},
|
||||
"frontMatter.framework.id": {
|
||||
"type": "string",
|
||||
"default": "",
|
||||
|
||||
@@ -155,6 +155,7 @@
|
||||
"setting.frontMatter.data.types.markdownDescription": "Specify the data types. These types can be used in for your data files. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.data.types) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.data.types%22%5D)",
|
||||
"setting.frontMatter.data.types.items.properties.id.description": "Your unique ID you want to use for your data type.",
|
||||
"setting.frontMatter.file.preserveCasing.markdownDescription": "Specify if you want to preserve the casing of your file names from the title. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.file.preservecasing) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.file.preservecasing%22%5D)",
|
||||
"setting.frontMatter.file.slugSeparator.markdownDescription": "Specify the separator character used between words when generating slugs and file names from titles. Default is `-` (hyphen). Use `_` for underscores.",
|
||||
"setting.frontMatter.framework.id.markdownDescription": "Specify the ID of your static site generator or framework you are using for your website. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.framework.id) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.framework.id%22%5D)",
|
||||
"setting.frontMatter.framework.startCommand.markdownDescription": "Specify the command you want to use to start your static site generator or framework. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.framework.startcommand) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.framework.startcommand%22%5D)",
|
||||
"setting.frontMatter.git.enabled.markdownDescription": "Specify if you want to use the Git actions for your website. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.git.enabled) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.git.enabled%22%5D)",
|
||||
|
||||
@@ -97,6 +97,7 @@ export const SETTING_DATA_FOLDERS = 'data.folders';
|
||||
export const SETTING_DATA_TYPES = 'data.types';
|
||||
|
||||
export const SETTING_FILE_PRESERVE_CASING = 'file.preserveCasing';
|
||||
export const SETTING_FILE_SLUG_SEPARATOR = 'file.slugSeparator';
|
||||
|
||||
export const SETTING_FRAMEWORK_ID = 'framework.id';
|
||||
export const SETTING_FRAMEWORK_START = 'framework.startCommand';
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
SETTING_CONTENT_PLACEHOLDERS,
|
||||
SETTING_CONTENT_SUPPORTED_FILETYPES,
|
||||
SETTING_FILE_PRESERVE_CASING,
|
||||
SETTING_FILE_SLUG_SEPARATOR,
|
||||
SETTING_COMMA_SEPARATED_FIELDS,
|
||||
SETTING_DATE_FIELD,
|
||||
SETTING_DATE_FORMAT,
|
||||
@@ -255,18 +256,14 @@ export class ArticleHelper {
|
||||
|
||||
const article = await ArticleHelper.getFrontMatterByPath(filePath);
|
||||
if (!article || !article.data) {
|
||||
Notifications.error(
|
||||
l10n.t(LocalizationKey.commandsArticleRenameFileNotExistsError)
|
||||
);
|
||||
Notifications.error(l10n.t(LocalizationKey.commandsArticleRenameFileNotExistsError));
|
||||
return;
|
||||
}
|
||||
|
||||
const titleField = getTitleField();
|
||||
const title: string = article.data[titleField];
|
||||
if (!title) {
|
||||
Notifications.warning(
|
||||
l10n.t(LocalizationKey.commandsArticleSmartRenameUnableToGenerate)
|
||||
);
|
||||
Notifications.warning(l10n.t(LocalizationKey.commandsArticleSmartRenameUnableToGenerate));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -303,9 +300,7 @@ export class ArticleHelper {
|
||||
const currentFolderName = parseFile(folderPath).base;
|
||||
|
||||
if (currentFolderName === newFileName) {
|
||||
Notifications.info(
|
||||
l10n.t(LocalizationKey.commandsArticleSmartRenameAlreadyInSync)
|
||||
);
|
||||
Notifications.info(l10n.t(LocalizationKey.commandsArticleSmartRenameAlreadyInSync));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -322,11 +317,7 @@ export class ArticleHelper {
|
||||
});
|
||||
|
||||
Notifications.info(
|
||||
l10n.t(
|
||||
LocalizationKey.commandsArticleSmartRenameSuccess,
|
||||
currentFolderName,
|
||||
newFileName
|
||||
)
|
||||
l10n.t(LocalizationKey.commandsArticleSmartRenameSuccess, currentFolderName, newFileName)
|
||||
);
|
||||
} else {
|
||||
// For regular files, rename the file
|
||||
@@ -340,9 +331,7 @@ export class ArticleHelper {
|
||||
}
|
||||
|
||||
if (parsed.base === newFileBase) {
|
||||
Notifications.info(
|
||||
l10n.t(LocalizationKey.commandsArticleSmartRenameAlreadyInSync)
|
||||
);
|
||||
Notifications.info(l10n.t(LocalizationKey.commandsArticleSmartRenameAlreadyInSync));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -367,11 +356,7 @@ export class ArticleHelper {
|
||||
});
|
||||
|
||||
Notifications.info(
|
||||
l10n.t(
|
||||
LocalizationKey.commandsArticleSmartRenameSuccess,
|
||||
parsed.base,
|
||||
newFileBase
|
||||
)
|
||||
l10n.t(LocalizationKey.commandsArticleSmartRenameSuccess, parsed.base, newFileBase)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -660,7 +645,9 @@ export class ArticleHelper {
|
||||
*/
|
||||
public static sanitize(value: string): string {
|
||||
const preserveCasing = Settings.get(SETTING_FILE_PRESERVE_CASING) as boolean;
|
||||
return sanitize((preserveCasing ? value : value.toLowerCase()).replace(/ /g, '-'));
|
||||
const separator = (Settings.get(SETTING_FILE_SLUG_SEPARATOR) as string) || '-';
|
||||
const sanitized = sanitize(preserveCasing ? value : value.toLowerCase());
|
||||
return sanitized.replace(/ /g, separator);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { parseWinPath, Settings } from '.';
|
||||
import { stopWords, charMap, SETTING_DATE_FORMAT, SETTING_SLUG_TEMPLATE } from '../constants';
|
||||
import { stopWords, charMap, SETTING_DATE_FORMAT, SETTING_SLUG_TEMPLATE, SETTING_FILE_SLUG_SEPARATOR } from '../constants';
|
||||
import { processTimePlaceholders, processFmPlaceholders } from '.';
|
||||
import { parse } from 'path';
|
||||
|
||||
@@ -26,7 +26,8 @@ export class SlugHelper {
|
||||
if (typeof slugTemplate === 'string') {
|
||||
if (slugTemplate.includes('{{title}}')) {
|
||||
const regex = new RegExp('{{title}}', 'g');
|
||||
slugTemplate = slugTemplate.replace(regex, articleTitle.toLowerCase().replace(/\s/g, '-'));
|
||||
const separator = (Settings.get(SETTING_FILE_SLUG_SEPARATOR) as string) || '-';
|
||||
slugTemplate = slugTemplate.replace(regex, articleTitle.toLowerCase().replace(/\s/g, separator));
|
||||
} else if (slugTemplate.includes('{{seoTitle}}')) {
|
||||
const regex = new RegExp('{{seoTitle}}', 'g');
|
||||
slugTemplate = slugTemplate.replace(regex, SlugHelper.slugify(articleTitle));
|
||||
@@ -69,7 +70,8 @@ export class SlugHelper {
|
||||
let words = cleanTitle.split(/\s/);
|
||||
// Removing stop words
|
||||
words = this.removeStopWords(words);
|
||||
cleanTitle = words.join('-');
|
||||
const separator = (Settings.get(SETTING_FILE_SLUG_SEPARATOR) as string) || '-';
|
||||
cleanTitle = words.join(separator);
|
||||
cleanTitle = this.replaceCharacters(cleanTitle);
|
||||
return cleanTitle;
|
||||
}
|
||||
|
||||
@@ -479,7 +479,11 @@ export class DataListener extends BaseListener {
|
||||
const contentType = await ArticleHelper.getContentType(article);
|
||||
const sourceField = ContentType.findFieldByName(contentType.fields, field);
|
||||
|
||||
if (!value && field !== titleField && contentType.clearEmpty) {
|
||||
if (
|
||||
(value === undefined || value === null || value === '' || value === false) &&
|
||||
field !== titleField &&
|
||||
contentType.clearEmpty
|
||||
) {
|
||||
// Check if the draft or boolean field needs to be cleared
|
||||
// This is only required when the default value is not set to true
|
||||
if (sourceField && (sourceField.type === 'draft' || sourceField.type === 'boolean')) {
|
||||
|
||||
@@ -98,7 +98,14 @@ export const DataBlockField: React.FunctionComponent<IDataBlockFieldProps> = ({
|
||||
|
||||
// Remove the empty fields
|
||||
Object.keys(data).forEach((key) => {
|
||||
if (data[key] === undefined || data[key] === null || Object.keys(data[key]).length === 0) {
|
||||
const currentValue = data[key];
|
||||
const isObjectValue =
|
||||
typeof currentValue === 'object' && currentValue !== null;
|
||||
const isEmptyArray = Array.isArray(currentValue) && currentValue.length === 0;
|
||||
const isEmptyObject =
|
||||
isObjectValue && !Array.isArray(currentValue) && Object.keys(currentValue).length === 0;
|
||||
|
||||
if (currentValue === undefined || currentValue === null || isEmptyArray || isEmptyObject) {
|
||||
delete data[key];
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user