mirror of
https://github.com/estruyf/vscode-front-matter.git
synced 2026-07-04 08:51:05 +02:00
#281 - Introduce new date fields and deprecate settings
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
### ✨ Features
|
||||
|
||||
- [#175](https://github.com/estruyf/vscode-front-matter/issues/175): New snippet support + dashboard
|
||||
- [#281](https://github.com/estruyf/vscode-front-matter/issues/281): New `isPublishDate` and `isModifiedDate` datetime field properties
|
||||
|
||||
### 🎨 Enhancements
|
||||
|
||||
|
||||
+16
-3
@@ -763,6 +763,16 @@
|
||||
"type": "number",
|
||||
"default": 0,
|
||||
"description": "Limit the number of taxonomies to select. Set to 0 to allow unlimited."
|
||||
},
|
||||
"isPublishDate": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Specify if the field is the publish date field"
|
||||
},
|
||||
"isModifiedDate": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Specify if the field is the modified date field"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
@@ -883,7 +893,8 @@
|
||||
"title": "Publishing date",
|
||||
"name": "date",
|
||||
"type": "datetime",
|
||||
"default": "{{now}}"
|
||||
"default": "{{now}}",
|
||||
"isPublishDate": true
|
||||
},
|
||||
{
|
||||
"title": "Content preview",
|
||||
@@ -939,7 +950,8 @@
|
||||
"frontMatter.taxonomy.dateField": {
|
||||
"type": "string",
|
||||
"default": "date",
|
||||
"markdownDescription": "This setting is used to define the publishing date field of your articles. [Check in the docs](https://frontmatter.codes/docs/settings#frontmatter.taxonomy.datefield)"
|
||||
"markdownDescription": "This setting is used to define the publishing date field of your articles. [Check in the docs](https://frontmatter.codes/docs/settings#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."
|
||||
},
|
||||
"frontMatter.taxonomy.dateFormat": {
|
||||
"type": "string",
|
||||
@@ -993,7 +1005,8 @@
|
||||
"frontMatter.taxonomy.modifiedField": {
|
||||
"type": "string",
|
||||
"default": "lastmod",
|
||||
"markdownDescription": "This setting is used to define the modified date field of your articles. [Check in the docs](https://frontmatter.codes/docs/settings#frontmatter.taxonomy.modifiedfield)"
|
||||
"markdownDescription": "This setting is used to define the modified date field of your articles. [Check in the docs](https://frontmatter.codes/docs/settings#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."
|
||||
},
|
||||
"frontMatter.taxonomy.noPropertyValueQuotes": {
|
||||
"type": "array",
|
||||
|
||||
@@ -154,7 +154,7 @@ export class Article {
|
||||
}
|
||||
|
||||
const cloneArticle = Object.assign({}, article);
|
||||
const dateField = Settings.get(SETTING_MODIFIED_FIELD) as string || DefaultFields.LastModified;
|
||||
const dateField = ArticleHelper.getModifiedDateField(article) || DefaultFields.LastModified;
|
||||
try {
|
||||
cloneArticle.data[dateField] = Article.formatDate(new Date());
|
||||
return cloneArticle;
|
||||
|
||||
@@ -12,8 +12,6 @@ export const SETTING_TAXONOMY_FIELD_GROUPS = "taxonomy.fieldGroups";
|
||||
export const SETTING_DATE_FORMAT = "taxonomy.dateFormat";
|
||||
export const SETTING_COMMA_SEPARATED_FIELDS = "taxonomy.commaSeparatedFields";
|
||||
export const SETTING_TAXONOMY_CONTENT_TYPES = "taxonomy.contentTypes";
|
||||
export const SETTING_DATE_FIELD = "taxonomy.dateField";
|
||||
export const SETTING_MODIFIED_FIELD = "taxonomy.modifiedField";
|
||||
|
||||
export const SETTING_SLUG_PREFIX = "taxonomy.slugPrefix";
|
||||
export const SETTING_SLUG_SUFFIX = "taxonomy.slugSuffix";
|
||||
@@ -76,3 +74,13 @@ export const SETTING_SITE_BASEURL = "site.baseURL";
|
||||
* @deprecated
|
||||
*/
|
||||
export const SETTING_CONTENT_FOLDERS = "content.folders";
|
||||
/**
|
||||
* @deprecated
|
||||
* Use the `isPublishDate` property on the content type datetime field instead
|
||||
*/
|
||||
export const SETTING_DATE_FIELD = "taxonomy.dateField";
|
||||
/**
|
||||
* @deprecated
|
||||
* Use the `isModifiedDate` property on the content type datetime field instead
|
||||
*/
|
||||
export const SETTING_MODIFIED_FIELD = "taxonomy.modifiedField";
|
||||
|
||||
@@ -2,7 +2,7 @@ import { MarkdownFoldingProvider } from './../providers/MarkdownFoldingProvider'
|
||||
import { DEFAULT_CONTENT_TYPE, DEFAULT_CONTENT_TYPE_NAME } from './../constants/ContentType';
|
||||
import * as vscode from 'vscode';
|
||||
import * as fs from "fs";
|
||||
import { DefaultFields, SETTING_CONTENT_DEFAULT_FILETYPE, SETTING_CONTENT_PLACEHOLDERS, SETTING_CONTENT_SUPPORTED_FILETYPES, SETTING_FILE_PRESERVE_CASING, SETTING_COMMA_SEPARATED_FIELDS, SETTING_DATE_FIELD, SETTING_DATE_FORMAT, SETTING_INDENT_ARRAY, SETTING_REMOVE_QUOTES, SETTING_SITE_BASEURL, SETTING_TAXONOMY_CONTENT_TYPES, SETTING_TEMPLATES_PREFIX } from '../constants';
|
||||
import { DefaultFields, SETTING_CONTENT_DEFAULT_FILETYPE, SETTING_CONTENT_PLACEHOLDERS, SETTING_CONTENT_SUPPORTED_FILETYPES, SETTING_FILE_PRESERVE_CASING, SETTING_COMMA_SEPARATED_FIELDS, SETTING_DATE_FIELD, SETTING_DATE_FORMAT, SETTING_INDENT_ARRAY, SETTING_REMOVE_QUOTES, SETTING_SITE_BASEURL, SETTING_TAXONOMY_CONTENT_TYPES, SETTING_TEMPLATES_PREFIX, SETTING_MODIFIED_FIELD } from '../constants';
|
||||
import { DumpOptions } from 'js-yaml';
|
||||
import { FrontMatterParser, ParsedFrontMatter } from '../parsers';
|
||||
import { Extension, Logger, Settings, SlugHelper } from '.';
|
||||
@@ -167,12 +167,12 @@ export class ArticleHelper {
|
||||
* Get date from front matter
|
||||
*/
|
||||
public static getDate(article: ParsedFrontMatter | null) {
|
||||
if (!article) {
|
||||
if (!article || !article.data) {
|
||||
return;
|
||||
}
|
||||
|
||||
const dateFormat = Settings.get(SETTING_DATE_FORMAT) as string;
|
||||
const dateField = Settings.get(SETTING_DATE_FIELD) as string || DefaultFields.PublishingDate;
|
||||
const dateField = ArticleHelper.getPublishDateField(article) || DefaultFields.PublishingDate;
|
||||
|
||||
if (typeof article.data[dateField] !== "undefined") {
|
||||
if (dateFormat && typeof dateFormat === "string") {
|
||||
@@ -186,6 +186,38 @@ export class ArticleHelper {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the publishing date field name
|
||||
* @param article
|
||||
* @returns
|
||||
*/
|
||||
public static getPublishDateField(article: ParsedFrontMatter | null) {
|
||||
if (!article || !article.data) {
|
||||
return;
|
||||
}
|
||||
|
||||
const articleCt = ArticleHelper.getContentType(article.data);
|
||||
const pubDateField = articleCt.fields.find(f => f.isPublishDate);
|
||||
|
||||
return pubDateField?.name || Settings.get(SETTING_DATE_FIELD) as string || DefaultFields.PublishingDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the publishing date field name
|
||||
* @param article
|
||||
* @returns
|
||||
*/
|
||||
public static getModifiedDateField(article: ParsedFrontMatter | null) {
|
||||
if (!article || !article.data) {
|
||||
return;
|
||||
}
|
||||
|
||||
const articleCt = ArticleHelper.getContentType(article.data);
|
||||
const modDateField = articleCt.fields.find(f => f.isModifiedDate);
|
||||
|
||||
return modDateField?.name || Settings.get(SETTING_MODIFIED_FIELD) as string || DefaultFields.PublishingDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the content type of the current file
|
||||
* @param updatedMetadata
|
||||
|
||||
+19
-105
@@ -1,11 +1,7 @@
|
||||
import { existsSync, renameSync } from "fs";
|
||||
import { basename, join } from "path";
|
||||
import { basename } from "path";
|
||||
import { extensions, Uri, ExtensionContext, window, workspace, commands, ExtensionMode, DiagnosticCollection, languages } from "vscode";
|
||||
import { Folders, WORKSPACE_PLACEHOLDER } from "../commands/Folders";
|
||||
import { EXTENSION_NAME, GITHUB_LINK, SETTING_CONTENT_FOLDERS, SETTING_CONTENT_PAGE_FOLDERS, SETTING_DATE_FIELD, SETTING_MODIFIED_FIELD, SETTING_SEO_DESCRIPTION_FIELD, SETTING_TAXONOMY_CONTENT_TYPES, DEFAULT_CONTENT_TYPE_NAME, EXTENSION_BETA_ID, EXTENSION_ID, ExtensionState, DefaultFields, LocalStore, SETTING_TEMPLATES_FOLDER } from "../constants";
|
||||
import { ContentType } from "../models";
|
||||
import { EXTENSION_NAME, GITHUB_LINK, SETTING_DATE_FIELD, SETTING_MODIFIED_FIELD, EXTENSION_BETA_ID, EXTENSION_ID, ExtensionState } from "../constants";
|
||||
import { Notifications } from "./Notifications";
|
||||
import { parseWinPath } from "./parseWinPath";
|
||||
import { Settings } from "./SettingsHelper";
|
||||
|
||||
|
||||
@@ -135,115 +131,33 @@ export class Extension {
|
||||
const minor = parseInt(version[1]);
|
||||
const patch = parseInt(version[2]);
|
||||
|
||||
// Migration to version 3.1.0
|
||||
if (major < 3 || (major === 3 && minor < 1)) {
|
||||
const folders = Settings.get<any>(SETTING_CONTENT_FOLDERS);
|
||||
if (folders && folders.length > 0) {
|
||||
const workspace = Folders.getWorkspaceFolder();
|
||||
const projectFolder = basename(workspace?.fsPath || "");
|
||||
|
||||
const paths = folders.map((folder: any) => ({
|
||||
...folder,
|
||||
path: `${WORKSPACE_PLACEHOLDER}${folder.fsPath.split(projectFolder).slice(1).join('')}`.split('\\').join('/')
|
||||
}));
|
||||
|
||||
await Settings.update(SETTING_CONTENT_PAGE_FOLDERS, paths);
|
||||
}
|
||||
}
|
||||
|
||||
// Create team settings
|
||||
if (Settings.hasSettings()) {
|
||||
Settings.createTeamSettings();
|
||||
}
|
||||
|
||||
// Migration to version 4.0.0
|
||||
if (major < 4) {
|
||||
const dateField = Settings.get<string>(SETTING_DATE_FIELD);
|
||||
const lastModField = Settings.get<string>(SETTING_MODIFIED_FIELD);
|
||||
const description = Settings.get<string>(SETTING_SEO_DESCRIPTION_FIELD);
|
||||
const contentTypes = Settings.get<ContentType[]>(SETTING_TAXONOMY_CONTENT_TYPES);
|
||||
// Migration scripts can be written here
|
||||
const publishField = Settings.inspect(SETTING_DATE_FIELD);
|
||||
const modifiedField = Settings.inspect(SETTING_MODIFIED_FIELD);
|
||||
|
||||
if (contentTypes) {
|
||||
let needsUpdate = false;
|
||||
let defaultContentType = contentTypes.find(ct => ct.name === DEFAULT_CONTENT_TYPE_NAME);
|
||||
|
||||
// Check if fields need to be changed for the default content type
|
||||
if (defaultContentType) {
|
||||
if (dateField && dateField !== DefaultFields.PublishingDate) {
|
||||
const newDateField = defaultContentType.fields.find(f => f.name === dateField);
|
||||
|
||||
if (!newDateField) {
|
||||
defaultContentType.fields = defaultContentType.fields.filter(f => f.name !== DefaultFields.PublishingDate);
|
||||
defaultContentType.fields.push({
|
||||
title: dateField,
|
||||
name: dateField,
|
||||
type: "datetime"
|
||||
});
|
||||
needsUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (lastModField && lastModField !== DefaultFields.LastModified) {
|
||||
const newModField = defaultContentType.fields.find(f => f.name === lastModField);
|
||||
|
||||
if (!newModField) {
|
||||
defaultContentType.fields = defaultContentType.fields.filter(f => f.name !== DefaultFields.LastModified);
|
||||
defaultContentType.fields.push({
|
||||
title: lastModField,
|
||||
name: lastModField,
|
||||
type: "datetime"
|
||||
});
|
||||
needsUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (description && description !== DefaultFields.Description) {
|
||||
const newDescField = defaultContentType.fields.find(f => f.name === description);
|
||||
|
||||
if (!newDescField) {
|
||||
defaultContentType.fields = defaultContentType.fields.filter(f => f.name !== DefaultFields.Description);
|
||||
defaultContentType.fields.push({
|
||||
title: description,
|
||||
name: description,
|
||||
type: "string"
|
||||
});
|
||||
needsUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (needsUpdate) {
|
||||
await Settings.update(SETTING_TAXONOMY_CONTENT_TYPES, contentTypes, true);
|
||||
}
|
||||
// Check for deprecation
|
||||
if (publishField?.workspaceValue ||
|
||||
publishField?.globalValue ||
|
||||
publishField?.teamValue ||
|
||||
modifiedField?.workspaceValue ||
|
||||
modifiedField?.globalValue ||
|
||||
modifiedField?.teamValue) {
|
||||
Notifications.warning(`The "${SETTING_DATE_FIELD}" and "${SETTING_MODIFIED_FIELD}" settings have been deprecated. Please use the "isPublishDate" and "isModifiedDate" datetime field properties instead.`, "See migration guide").then(value => {
|
||||
if (value === "See migration guide") {
|
||||
const isProd = this.isProductionMode;
|
||||
commands.executeCommand("vscode.open", Uri.parse(`https://${isProd ? '' : 'beta.'}frontmatter.codes/docs/troubleshooting#publish-and-modified-date-migration`));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Migration to version 5
|
||||
if (major <= 5) {
|
||||
const isMoved = await Extension.getInstance().getState<boolean | undefined>(ExtensionState.MoveTemplatesFolder);
|
||||
if (!isMoved) {
|
||||
const wsFolder= Folders.getWorkspaceFolder();
|
||||
if (wsFolder) {
|
||||
const templateFolder = join(parseWinPath(wsFolder.fsPath), `.templates`);
|
||||
if (existsSync(templateFolder)) {
|
||||
window.showInformationMessage(`Would you like to move your ".templates" folder to the new ".frontmatter" folder?`, 'Yes', 'No').then(async (result) => {
|
||||
if (result === "Yes") {
|
||||
const newFolderPath = join(parseWinPath(wsFolder.fsPath), LocalStore.rootFolder, LocalStore.templatesFolder);
|
||||
renameSync(templateFolder, newFolderPath);
|
||||
commands.executeCommand(`workbench.action.reloadWindow`);
|
||||
Settings.update(SETTING_TEMPLATES_FOLDER, undefined, true);
|
||||
Settings.update(SETTING_TEMPLATES_FOLDER, undefined);
|
||||
} else if (result === "No") {
|
||||
Settings.update(SETTING_TEMPLATES_FOLDER, `.templates`, true);
|
||||
}
|
||||
|
||||
if (result === "No" || result === "Yes") {
|
||||
Extension.getInstance().setState(ExtensionState.MoveTemplatesFolder, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (major < 7) {
|
||||
// No migration needed
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -94,6 +94,21 @@ export class Settings {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Inspect a setting
|
||||
* @param name
|
||||
* @returns
|
||||
*/
|
||||
public static inspect<T>(name: string): any {
|
||||
const configInpection = Settings.config.inspect<T>(name);
|
||||
const settingKey = `${CONFIG_KEY}.${name}`;
|
||||
|
||||
return {
|
||||
...configInpection,
|
||||
teamValue: Settings.globalConfig[settingKey]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a setting from global and local config
|
||||
*/
|
||||
@@ -162,6 +177,10 @@ export class Settings {
|
||||
this.createGlobalFile(wsFolder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the frontmatter.json file
|
||||
* @param wsFolder
|
||||
*/
|
||||
public static createGlobalFile(wsFolder: Uri | undefined | null) {
|
||||
const initialConfig = {
|
||||
"$schema": `https://${Extension.getInstance().isBetaVersion() ? `beta.` : ``}frontmatter.codes/frontmatter.schema.json`
|
||||
|
||||
@@ -139,7 +139,7 @@ export class PagesListener extends BaseListener {
|
||||
if (article?.data.title) {
|
||||
const wsFolder = Folders.getWorkspaceFolder();
|
||||
const descriptionField = Settings.get(SETTING_SEO_DESCRIPTION_FIELD) as string || DefaultFields.Description;
|
||||
const dateField = Settings.get(SETTING_DATE_FIELD) as string || DefaultFields.PublishingDate;
|
||||
const dateField = ArticleHelper.getPublishDateField(article) || DefaultFields.PublishingDate;
|
||||
const staticFolder = Settings.get<string>(SETTING_CONTENT_STATIC_FOLDER);
|
||||
|
||||
const page: Page = {
|
||||
|
||||
@@ -65,6 +65,10 @@ export interface Field {
|
||||
fieldGroup?: string | string[];
|
||||
dataType?: string | string[];
|
||||
taxonomyLimit?: number;
|
||||
|
||||
// Date fields
|
||||
isPublishDate?: boolean;
|
||||
isModifiedDate?: boolean;
|
||||
}
|
||||
|
||||
export interface DateInfo {
|
||||
|
||||
Reference in New Issue
Block a user