#570 - Clear empty values

This commit is contained in:
Elio Struyf
2023-09-06 12:06:19 +02:00
parent ab3988e253
commit 69a18bdcea
7 changed files with 187 additions and 165 deletions
+1
View File
@@ -4,6 +4,7 @@
### ✨ New features
- [#570](https://github.com/estruyf/vscode-front-matter/issues/570): Clear empty values on content creation and editing
- [#645](https://github.com/estruyf/vscode-front-matter/issues/645): French localization added (thanks to [Clément Barbaza](https://github.com/cba85))
### 🎨 Enhancements
+127 -153
View File
@@ -10,8 +10,7 @@
"color": "#0e131f",
"theme": "dark"
},
"badges": [
{
"badges": [{
"description": "version",
"url": "https://img.shields.io/github/package-json/v/estruyf/vscode-front-matter?color=green&label=vscode-front-matter&style=flat-square",
"href": "https://github.com/estruyf/vscode-front-matter"
@@ -62,8 +61,7 @@
"**/.frontmatter/config/*.json": "jsonc"
}
},
"keybindings": [
{
"keybindings": [{
"command": "frontMatter.dashboard",
"key": "alt+d"
},
@@ -81,24 +79,20 @@
}
],
"viewsContainers": {
"activitybar": [
{
"id": "frontmatter-explorer",
"title": "Front Matter",
"icon": "assets/frontmatter-short-min.svg"
}
]
"activitybar": [{
"id": "frontmatter-explorer",
"title": "Front Matter",
"icon": "assets/frontmatter-short-min.svg"
}]
},
"views": {
"frontmatter-explorer": [
{
"id": "frontMatter.explorer",
"name": "Front Matter",
"icon": "assets/frontmatter-short-min.svg",
"contextualTitle": "Front Matter",
"type": "webview"
}
]
"frontmatter-explorer": [{
"id": "frontMatter.explorer",
"name": "Front Matter",
"icon": "assets/frontmatter-short-min.svg",
"contextualTitle": "Front Matter",
"type": "webview"
}]
},
"configuration": {
"$id": "#globalconfiguration",
@@ -162,8 +156,7 @@
"frontMatter.content.defaultFileType": {
"type": "string",
"default": "md",
"oneOf": [
{
"oneOf": [{
"enum": [
"md",
"mdx"
@@ -179,8 +172,7 @@
"frontMatter.content.defaultSorting": {
"type": "string",
"default": "",
"oneOf": [
{
"oneOf": [{
"enum": [
"LastModifiedAsc",
"LastModifiedDesc",
@@ -527,8 +519,7 @@
"command": {
"$id": "#scriptCommand",
"type": "string",
"anyOf": [
{
"anyOf": [{
"enum": [
"node",
"bash",
@@ -728,8 +719,7 @@
"title",
"file"
],
"anyOf": [
{
"anyOf": [{
"required": [
"schema"
]
@@ -783,8 +773,7 @@
"id",
"path"
],
"anyOf": [
{
"anyOf": [{
"required": [
"schema"
]
@@ -1152,8 +1141,7 @@
"default": "",
"description": "%setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.taxonomyId.description%",
"not": {
"anyOf": [
{
"anyOf": [{
"const": ""
},
{
@@ -1273,6 +1261,11 @@
"default": false,
"description": "%setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.required.description%"
},
"clearEmpty": {
"type": "boolean",
"default": false,
"description": "%setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.clearEmpty.description%"
},
"customType": {
"type": "string",
"default": "",
@@ -1342,8 +1335,7 @@
"type",
"name"
],
"allOf": [
{
"allOf": [{
"if": {
"properties": {
"type": {
@@ -1529,51 +1521,48 @@
"fields"
]
},
"default": [
{
"name": "default",
"pageBundle": false,
"fields": [
{
"title": "Title",
"name": "title",
"type": "string"
},
{
"title": "Description",
"name": "description",
"type": "string"
},
{
"title": "Publishing date",
"name": "date",
"type": "datetime",
"default": "{{now}}",
"isPublishDate": true
},
{
"title": "Content preview",
"name": "preview",
"type": "image"
},
{
"title": "Is in draft",
"name": "draft",
"type": "boolean"
},
{
"title": "Tags",
"name": "tags",
"type": "tags"
},
{
"title": "Categories",
"name": "categories",
"type": "categories"
}
]
}
],
"default": [{
"name": "default",
"pageBundle": false,
"fields": [{
"title": "Title",
"name": "title",
"type": "string"
},
{
"title": "Description",
"name": "description",
"type": "string"
},
{
"title": "Publishing date",
"name": "date",
"type": "datetime",
"default": "{{now}}",
"isPublishDate": true
},
{
"title": "Content preview",
"name": "preview",
"type": "image"
},
{
"title": "Is in draft",
"name": "draft",
"type": "boolean"
},
{
"title": "Tags",
"name": "tags",
"type": "tags"
},
{
"title": "Categories",
"name": "categories",
"type": "categories"
}
]
}],
"scope": "Taxonomy"
},
"frontMatter.taxonomy.customTaxonomy": {
@@ -1586,8 +1575,7 @@
"type": "string",
"description": "%setting.frontMatter.taxonomy.customTaxonomy.items.properties.id.description%",
"not": {
"anyOf": [
{
"anyOf": [{
"const": ""
},
{
@@ -1769,8 +1757,7 @@
}
}
},
"commands": [
{
"commands": [{
"command": "frontMatter.project.switch",
"title": "%command.frontMatter.project.switch%",
"category": "Front Matter",
@@ -2099,15 +2086,12 @@
"category": "Front Matter"
}
],
"submenus": [
{
"id": "frontmatter.submenu",
"label": "Front Matter"
}
],
"submenus": [{
"id": "frontmatter.submenu",
"label": "Front Matter"
}],
"menus": {
"editor/title": [
{
"editor/title": [{
"command": "frontMatter.markup.heading",
"group": "navigation@-133",
"when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg"
@@ -2188,14 +2172,11 @@
"when": "resourceFilename == 'frontmatter.json'"
}
],
"explorer/context": [
{
"submenu": "frontmatter.submenu",
"group": "frontmatter@1"
}
],
"frontmatter.submenu": [
{
"explorer/context": [{
"submenu": "frontmatter.submenu",
"group": "frontmatter@1"
}],
"frontmatter.submenu": [{
"command": "frontMatter.createFromTemplate",
"when": "explorerResourceIsFolder",
"group": "frontmatter@1"
@@ -2211,8 +2192,7 @@
"group": "frontmatter@3"
}
],
"commandPalette": [
{
"commandPalette": [{
"command": "frontMatter.init",
"when": "frontMatterCanInit"
},
@@ -2357,8 +2337,7 @@
"when": "frontMatter:file:isValid == true"
}
],
"view/title": [
{
"view/title": [{
"command": "frontMatter.chatbot",
"group": "navigation@0",
"when": "view == frontMatter.explorer"
@@ -2385,57 +2364,52 @@
}
]
},
"grammars": [
{
"path": "./syntaxes/hugo.tmLanguage.json",
"scopeName": "frontmatter.markdown.hugo",
"injectTo": [
"text.html.markdown"
]
}
],
"walkthroughs": [
{
"id": "frontmatter.welcome",
"title": "Get started with Front Matter",
"description": "Discover the features of Front Matter and learn how to use the CMS for your SSG or static site.",
"steps": [
{
"id": "frontmatter.welcome.init",
"title": "Get started",
"description": "Initial steps to get started.\n[Open dashboard](command:frontMatter.dashboard)",
"media": {
"markdown": "assets/walkthrough/get-started.md"
},
"completionEvents": [
"onContext:frontMatterInitialized"
]
"grammars": [{
"path": "./syntaxes/hugo.tmLanguage.json",
"scopeName": "frontmatter.markdown.hugo",
"injectTo": [
"text.html.markdown"
]
}],
"walkthroughs": [{
"id": "frontmatter.welcome",
"title": "Get started with Front Matter",
"description": "Discover the features of Front Matter and learn how to use the CMS for your SSG or static site.",
"steps": [{
"id": "frontmatter.welcome.init",
"title": "Get started",
"description": "Initial steps to get started.\n[Open dashboard](command:frontMatter.dashboard)",
"media": {
"markdown": "assets/walkthrough/get-started.md"
},
{
"id": "frontmatter.welcome.documentation",
"title": "Documentation",
"description": "Check out the documentation for Front Matter.\n[View our documentation](https://frontmatter.codes/docs)",
"media": {
"markdown": "assets/walkthrough/documentation.md"
},
"completionEvents": [
"onLink:https://frontmatter.codes/docs"
]
"completionEvents": [
"onContext:frontMatterInitialized"
]
},
{
"id": "frontmatter.welcome.documentation",
"title": "Documentation",
"description": "Check out the documentation for Front Matter.\n[View our documentation](https://frontmatter.codes/docs)",
"media": {
"markdown": "assets/walkthrough/documentation.md"
},
{
"id": "frontmatter.welcome.supporter",
"title": "Support the project",
"description": "Become a supporter.\n[Support the project](https://github.com/sponsors/estruyf)",
"media": {
"markdown": "assets/walkthrough/support-the-project.md"
},
"completionEvents": [
"onLink:https://github.com/sponsors/estruyf"
]
}
]
}
]
"completionEvents": [
"onLink:https://frontmatter.codes/docs"
]
},
{
"id": "frontmatter.welcome.supporter",
"title": "Support the project",
"description": "Become a supporter.\n[Support the project](https://github.com/sponsors/estruyf)",
"media": {
"markdown": "assets/walkthrough/support-the-project.md"
},
"completionEvents": [
"onLink:https://github.com/sponsors/estruyf"
]
}
]
}]
},
"scripts": {
"dev:ext": "npm run clean && npm run localization:generate && npm-run-all --parallel watch:*",
@@ -2569,4 +2543,4 @@
"vsce": {
"dependencies": false
}
}
}
+2 -1
View File
@@ -239,5 +239,6 @@
"setting.frontMatter.dashboard.mediaSnippet.deprecationMessage": "This setting is deprecated and will be removed in the next major version. Please define your media snippet in the `frontMatter.content.snippet` setting.",
"setting.frontMatter.taxonomy.dateField.deprecationMessage": "This setting is deprecated and will be removed in the next major version. Please use the new `isPublishDate` settings instead in your content types date fields.",
"setting.frontMatter.taxonomy.modifiedField.deprecationMessage": "This setting is deprecated and will be removed in the next major version. Please use the new `isModifiedDate` settings instead in your content types date fields.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.customType.description": "Specify the name of the custom field type to use."
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.customType.description": "Specify the name of the custom field type to use.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.clearEmpty.description": "Specify if the empty values should be cleared."
}
+32 -9
View File
@@ -737,7 +737,8 @@ export class ContentType {
contentType,
titleValue,
templateData?.data || {},
newFilePath
newFilePath,
!!contentType.clearEmpty
);
data = ArticleHelper.updateDates(Object.assign({}, data));
@@ -785,6 +786,7 @@ export class ContentType {
titleValue: string,
data: any,
filePath: string,
clearEmpty: boolean,
isRoot: boolean = true
): Promise<any> {
if (obj.fields) {
@@ -805,12 +807,23 @@ export class ContentType {
);
} else if (isRoot) {
data[field.name] = titleValue;
} else {
} else if (!clearEmpty) {
data[field.name] = '';
}
} else {
if (field.type === 'fields') {
data[field.name] = await this.processFields(field, titleValue, {}, filePath, false);
data[field.name] = await this.processFields(
field,
titleValue,
{},
filePath,
clearEmpty,
false
);
if (clearEmpty && Object.keys(data[field.name]).length === 0) {
delete data[field.name];
}
} else {
const defaultValue = field.default;
@@ -841,30 +854,40 @@ export class ContentType {
case 'choice':
if (field.multiple) {
data[field.name] = [];
} else {
} else if (!clearEmpty) {
data[field.name] = '';
}
break;
case 'boolean':
data[field.name] = false;
if (!clearEmpty) {
data[field.name] = false;
}
break;
case 'number':
data[field.name] = 0;
if (!clearEmpty) {
data[field.name] = 0;
}
break;
case 'datetime':
data[field.name] = null;
if (!clearEmpty) {
data[field.name] = null;
}
break;
case 'list':
case 'tags':
case 'categories':
case 'taxonomy':
data[field.name] = [];
if (!clearEmpty) {
data[field.name] = [];
}
break;
case 'string':
case 'image':
case 'file':
default:
data[field.name] = '';
if (!clearEmpty) {
data[field.name] = '';
}
break;
}
}
+21
View File
@@ -232,6 +232,8 @@ export class DataListener extends BaseListener {
return;
}
const titleField = (Settings.get(SETTING_SEO_TITLE_FIELD) as string) || DefaultFields.Title;
const editor = window.activeTextEditor;
let article;
@@ -248,6 +250,10 @@ export class DataListener extends BaseListener {
const contentType = ArticleHelper.getContentType(article.data);
if (!value && field !== titleField && contentType.clearEmpty) {
value = undefined;
}
const dateFields = ContentType.findFieldsByTypeDeep(contentType.fields, 'datetime');
const imageFields = ContentType.findFieldsByTypeDeep(contentType.fields, 'image');
const fileFields = ContentType.findFieldsByTypeDeep(contentType.fields, 'file');
@@ -263,6 +269,7 @@ export class DataListener extends BaseListener {
}
});
// Check multi-image fields
const multiImageFieldsArray = imageFields.find((f: Field[]) => {
const lastField = f?.[f.length - 1];
if (lastField) {
@@ -270,6 +277,7 @@ export class DataListener extends BaseListener {
}
});
// Check multi-file fields
const multiFileFieldsArray = fileFields.find((f: Field[]) => {
const lastField = f?.[f.length - 1];
if (lastField) {
@@ -277,6 +285,7 @@ export class DataListener extends BaseListener {
}
});
// Check date fields
if (dateFieldsArray && dateFieldsArray.length > 0) {
for (const dateField of dateFieldsArray) {
if (field === dateField.name && value) {
@@ -322,6 +331,18 @@ export class DataListener extends BaseListener {
}
}
// Clear the field if it is empty
if (
value === undefined ||
(value instanceof Array && value.length === 0 && contentType.clearEmpty)
) {
delete parentObj[field];
}
if (Object.keys(parentObj).length === 0 && field !== titleField && contentType.clearEmpty) {
delete article.data[parents![0]];
}
if (editor) {
ArticleHelper.update(editor, article);
} else if (filePath) {
+1
View File
@@ -53,6 +53,7 @@ export interface ContentType {
template?: string;
postScript?: string;
filePrefix?: string;
clearEmpty?: boolean;
}
export type FieldType =
+3 -2
View File
@@ -68,7 +68,7 @@ export const Engines = {
// Check if there are values to remove
for (const key in docYaml.toJSON()) {
if (typeof obj[key] === undefined) {
if (typeof obj[key] === 'undefined') {
docYaml.delete(key);
}
}
@@ -77,7 +77,8 @@ export const Engines = {
return yaml.stringify(updatedValue, {
lineWidth: 5000,
defaultStringType: 'PLAIN'
defaultStringType: 'PLAIN',
keepUndefined: false
});
}
}