diff --git a/.templates/content.md b/.templates/content.md new file mode 100644 index 00000000..a4eb185b --- /dev/null +++ b/.templates/content.md @@ -0,0 +1,9 @@ +--- +title: Content Types +slug: content-types +description: null +date: '2021-09-17T07:36:26.654Z' +lastmod: '2019-08-22T15:20:28.000Z' +weight: 3 +--- + diff --git a/.templates/documentation.md b/.templates/documentation.md index 57201c1c..0da65a1c 100644 --- a/.templates/documentation.md +++ b/.templates/documentation.md @@ -1,8 +1,9 @@ --- -title: "{{name}}" -slug: "/{{kebabCase name}}/" -description: +title: +slug: +description: date: 2019-08-22T15:20:28.000Z lastmod: 2019-08-22T15:20:28.000Z weight: 1 +type: documentation --- diff --git a/.vscode/settings.json b/.vscode/settings.json index 58e5ca2c..8d17a741 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -29,5 +29,47 @@ "title": "documentation", "path": "[[workspace]]/docs/content/docs" } + ], + "frontMatter.taxonomy.contentTypes": [ + { + "name": "default", + "fields": [ + { + "title": "Title", + "name": "title", + "type": "string" + }, + { + "title": "Description", + "name": "description", + "type": "string" + }, + { + "title": "Publishing date", + "name": "date", + "type": "datetime" + }, + { + "title": "Article 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" + } + ] + } ] } \ No newline at end of file diff --git a/assets/media/styles.css b/assets/media/styles.css index 3c1dcb32..7c29ff73 100644 --- a/assets/media/styles.css +++ b/assets/media/styles.css @@ -446,6 +446,11 @@ input:checked + .field__toggle__slider:before { margin-top: .25rem; } +.metadata_field__number { + border: 1px solid var(--vscode-inputValidation-infoBorder) !important; + outline: none !important; +} + .metadata_field__datetime { display: flex; justify-content: space-between; diff --git a/docs/components/Docs/PageInfo.tsx b/docs/components/Docs/PageInfo.tsx index af5d4c04..189889e2 100644 --- a/docs/components/Docs/PageInfo.tsx +++ b/docs/components/Docs/PageInfo.tsx @@ -13,7 +13,7 @@ export const PageInfo: React.FunctionComponent = ({page}: React. return null; } - const date = parseJSON(page.date); + const date = parseJSON(page.lastmod); return (
diff --git a/docs/content/changelog/CHANGELOG.md b/docs/content/changelog/CHANGELOG.md index 7eccd5ed..4ae2a7d9 100644 --- a/docs/content/changelog/CHANGELOG.md +++ b/docs/content/changelog/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## [3.2.0] - (upcoming release) + +- [#101](https://github.com/estruyf/vscode-front-matter/issues/101): Date picker available on the metadata section +- [#102](https://github.com/estruyf/vscode-front-matter/issues/102): Support comma separated arrays in front matter +- [#103](https://github.com/estruyf/vscode-front-matter/issues/103): Added title and description field to the metadata section +- [#104](https://github.com/estruyf/vscode-front-matter/issues/104): Allow to set images in front matter from the metadata panel section +- [#105](https://github.com/estruyf/vscode-front-matter/issues/105): Content Type support with backwards compatibility + ## [3.1.0] - 2021-09-10 - BETA version available at: [beta.frontmatter.codes](https://beta.frontmatter.codes) diff --git a/docs/content/docs/commands.md b/docs/content/docs/commands.md index 7c2e9678..f353996d 100644 --- a/docs/content/docs/commands.md +++ b/docs/content/docs/commands.md @@ -9,6 +9,8 @@ weight: 6 # Commands +## Overview + Front Matter actions are also available as commands. In this section of the documentation all commands will be explained. ![Commands](/assets/commands.png) diff --git a/docs/content/docs/content-types.md b/docs/content/docs/content-types.md new file mode 100644 index 00000000..f9cce507 --- /dev/null +++ b/docs/content/docs/content-types.md @@ -0,0 +1,201 @@ +--- +title: Content Types +slug: content-types +description: null +date: '2021-09-17T07:36:26.654Z' +lastmod: '2019-08-22T15:20:28.000Z' +weight: 3 +--- + +# Content Types + +## Overview + +As each website is different, we allow you to define your types of content to use with Front Matter. Front Matter will adapt the metadata fields to show in its editor panel depending on the type of content. + +Front Matter comes with a default content type definition which you can adapt to your needs or add your types next to it. + +## How it works + +Behind the scenes, Front Matter uses the `frontMatter.taxonomy.contentTypes` setting to understand which type of content you'll use for your website. + +Our default content type consists of the following fields: + +- title: `string` +- description: `string` +- date: `datetime` +- preview: `image` +- draft: `boolean` +- tags: `tags` +- categories: `categories` + +We'll use the default one when you start writing your markdown content, and no other content type is defined. + +![Default content type fields](assets/default-contenttype.png) + +## Changing the default content type + +If you want to change the default content type, open your `.vscode/settings.json` and write an entry for the `frontMatter.taxonomy.contentTypes` setting. Visual Studio Code will automatically autocomplete it with the default content type fields. + +If in some case it wouldn't do this, here is the default content type structure: + +```json +"frontMatter.taxonomy.contentTypes": [ + { + "name": "default", + "fields": [ + { + "title": "Title", + "name": "title", + "type": "string" + }, + { + "title": "Description", + "name": "description", + "type": "string" + }, + { + "title": "Publishing date", + "name": "date", + "type": "datetime" + }, + { + "title": "Article 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" + } + ] + } +] +``` + +Adapt the fields to your needs. For our documentation it looks as follows: + +```json +"frontMatter.taxonomy.contentTypes": [ + { + "name": "default", + "fields": [ + { + "title": "Title", + "name": "title", + "type": "string" + }, + { + "title": "Description", + "name": "description", + "type": "string" + }, + { + "title": "Publishing date", + "name": "date", + "type": "datetime" + }, + { + "title": "Last modified date", + "name": "lastmod", + "type": "datetime" + }, + { + "title": "Navigation weight", + "name": "weight", + "type": "number" + } + ] + } +] +``` + +The metadata section on the editor panel will render the following fields: + +![Adapted default content type fields](/assets/adapted-default-ct.png) + +## Define your own type + +In most cases, you'll work with multiple types of content where each type will have its defined set of fields. If this is the case for your website, you'll need to add another content type to the `frontMatter.taxonomy.contentTypes` setting. + +Instead of overriding the default content type, you can also define a new content type. It requires you to specify the `name` and `fields`. + +> **Important**: The `name` property value needs to be equal to the `type` value you set in your Markdown front matter. You best define it via a template so that it's always defined. A default template will be available when initializing Front Matter in your project in the `.templates` folder. + +Sample: + +```json +"frontMatter.taxonomy.contentTypes": [ + { + "name": "default", + "fields": [ + ... + ] + }, + { + "name": "documentation", + "fields": [ + ... + ] + } +] +``` + +In the sample, `documentation` is used as the content type name. This means that in your article, you'll need to add the `type: documentation` to your front matter to let the editor panel understand which fields to show. + +```markdown +--- +title: Content Types +slug: content-types +description: null +date: '2021-09-17T07:36:26.654Z' +lastmod: '2019-08-22T15:20:28.000Z' +weight: 4 +type: documentation +--- +``` + +## Supported field types + +Front Matter its metadata section supports the following fields: + +- `string` +- `number` +- `datetime` +- `boolean` +- `image` +- `tags`: mapped to the tags defined in your settings. +- `categories`: mapped to the categories defined in your settings. + +## Creating a template + +To make sure that your type of content is already defined when creating a new Markdown file. It will be easier to set the type of content within a template. + +You can create Markdown templates in your project's `.templates` folder (or defined differently). + +```markdown +--- +title: +slug: +description: +date: 2019-08-22T15:20:28.000Z +lastmod: 2019-08-22T15:20:28.000Z +weight: 1 +type: documentation +--- +``` + +If you already have an existing page, you can automatically create a template from it by running the `Front Matter: Create a template from the current file` command. + +The create template command will ask you the template's name and if you want to include the content. The front matter data is included by default. \ No newline at end of file diff --git a/docs/content/docs/custom-actions.md b/docs/content/docs/custom-actions.md index 4b9c732b..37a37b83 100644 --- a/docs/content/docs/custom-actions.md +++ b/docs/content/docs/custom-actions.md @@ -9,6 +9,8 @@ weight: 5 # Custom actions +## Overview + Not every website is the same. That is why we want to give you the ability to extend Front Matter and you can do this by adding your custom actions to the Front Matter panel. A custom action is nothing more than a Node.js script which is referenced from within your project. ![Custom action](/assets/custom-action.png) diff --git a/docs/content/docs/dashboard.md b/docs/content/docs/dashboard.md index 7c6e02f2..f1d5bd80 100644 --- a/docs/content/docs/dashboard.md +++ b/docs/content/docs/dashboard.md @@ -9,6 +9,8 @@ weight: 3 # Dashboard +## Overview + Managing your Markdown pages/media has never been easier in VS Code. With the Front Matter dashboard, you will be able to view all your pages and media. On the contents view, you can **search**, **filter**, **sort** your pages and much more. diff --git a/docs/content/docs/getting-started.md b/docs/content/docs/getting-started.md index 2850aa5c..32e33b13 100644 --- a/docs/content/docs/getting-started.md +++ b/docs/content/docs/getting-started.md @@ -9,6 +9,8 @@ weight: 2 # Getting started +## Overview + To get you started, you first need to install the extension in Visual Studio Code. ## Installation diff --git a/docs/content/docs/index.md b/docs/content/docs/index.md index 0cdd110b..69597373 100644 --- a/docs/content/docs/index.md +++ b/docs/content/docs/index.md @@ -9,6 +9,8 @@ weight: 1 # Introduction +## Overview + Front Matter is an essential Visual Studio Code extension that simplifies working and managing your markdown articles. We created the extension to support many static-site generators like Hugo, Jekyll, Hexo, NextJs, Gatsby, and more. The extension brings Content Management System (CMS) capabilities straight within Visual Studio Code. For example, you can keep a list of the used tags, categories, create content, and so much more. diff --git a/docs/content/docs/markdown.md b/docs/content/docs/markdown.md index 0674433a..fc53103e 100644 --- a/docs/content/docs/markdown.md +++ b/docs/content/docs/markdown.md @@ -9,6 +9,8 @@ weight: 6 # Markdown features +## Overview + The Front Matter extension tries to make it easy to manage your Markdown pages/content. Within a Markdown page, we allow you to fold the file's Front Matter to be less distracting when writing. Also, do we highlight the Front Matter content to create a visual difference between content and metadata. ## Front Matter folding diff --git a/docs/content/docs/panel.md b/docs/content/docs/panel.md index 9651433d..7f2c4f1b 100644 --- a/docs/content/docs/panel.md +++ b/docs/content/docs/panel.md @@ -1,13 +1,15 @@ --- -title: Panel +title: Editor panel slug: panel -description: +description: null date: '2021-08-30T16:13:00.546Z' -lastmod: '2021-08-30T16:13:01.763Z' +lastmod: '2021-09-17T16:13:01.763Z' weight: 4 --- -# Panel +# Editor panel + +## Overview The Front Matter panel allows you to perform most of the extension actions by just a click on the button, and it shows the SEO statuses of your title, description, and more. @@ -64,6 +66,8 @@ When writing articles, there are always a couple of actions you need/want to per > **Important**: You are able to add your own actions, more information about this you can read in our [custom actions](/docs/custom-actions) section. +> **Info**: In version `3.2.0` a couple of actions were moved to the metadata section like changing the draft state and date time properties. + ### Settings The following settings are related to these actions: @@ -106,4 +110,4 @@ This section provides a couple of other useful actions, like opening the current > **Info**: The `writing settings enabled / enable write settings` action allows you to make Markdown specific changes to optimize the writing of your articles. It will change settings like the `fontSize`, `lineHeight`, `wordWrap`, `lineNumbers` and more. -> **Info**: The other actions section will also be shown when you have the panel open on other types of files. \ No newline at end of file +> **Info**: The other actions section will also be shown when you have the panel open on other types of files. diff --git a/docs/content/docs/settings.md b/docs/content/docs/settings.md index b5ef7a04..a3923e6e 100644 --- a/docs/content/docs/settings.md +++ b/docs/content/docs/settings.md @@ -3,12 +3,14 @@ title: Settings slug: settings description: null date: '2021-08-30T16:13:00.546Z' -lastmod: '2021-09-08T07:08:17.747Z' +lastmod: '2021-09-17T07:08:17.747Z' weight: 7 --- # Settings +## Overview + Most of the actions are configurable to your needs. In this part of the documentation all settings are explained. ## Where is the data stored? @@ -112,18 +114,22 @@ Specify the path you want to add after the host and before your slug. This can b ### frontMatter.taxonomy.dateField -Specifies the date field name to use in your Front Matter. +This setting is used to define the publishing date field of your articles. - Type: `string` - Default: `date` +> **Important**: if you would use another field in your content types, be sure to remap this setting. + ### frontMatter.taxonomy.modifiedField -Specifies the modified date field name to use in your Front Matter. +This setting is used to define the modified date field of your articles. - Type: `string` - Default: `lastmod` +> **Important**: if you would use another field in your content types, be sure to remap this setting. + ### frontMatter.taxonomy.dateFormat Specify the date format for your articles. Check [date-fns formating](https://date-fns.org/v2.0.1/docs/format) for more information. @@ -131,7 +137,7 @@ Specify the date format for your articles. Check [date-fns formating](https://da - Type: `string` - Default: `iso` -## frontMatter.taxonomy.commaSeparatedFields +### frontMatter.taxonomy.commaSeparatedFields Specify the fields names that Front Matter should treat as a comma-separated array. @@ -230,6 +236,8 @@ Specifies the name of the SEO description field for your page. - Type: `string` - Default: `description` +> **Important**: if you would use another field in your content types, be sure to remap this setting. + ### frontMatter.templates.folder Specify the folder to use for your article templates. @@ -245,7 +253,7 @@ Specify the prefix you want to add for your new article filenames. - Default: `yyyy-MM-dd` -## Deprecated settings +## Removed settings ### frontMatter.content.folders diff --git a/docs/content/docs/site-preview.md b/docs/content/docs/site-preview.md index 025dcd9b..8e43a0b8 100644 --- a/docs/content/docs/site-preview.md +++ b/docs/content/docs/site-preview.md @@ -9,6 +9,8 @@ weight: 6 # Site preview +## Overview + The Markdown preview is not consistently delivering the same result as the one you will see on your site. The Front Matter extension provides you a way to show the actual site instead. ![Site preview](/assets/site-preview.png) diff --git a/docs/locale/en.ts b/docs/locale/en.ts index 5c608580..2c0320e9 100644 --- a/docs/locale/en.ts +++ b/docs/locale/en.ts @@ -36,23 +36,23 @@ export const strings = { features_cta_button: "Tell us what you need", // Feature - feature_title_1: "Offline management", - feature_description_1: "A Content Management System built to run within Visual Studio Code. No dependencies on any website or API. Write wherever you are, commit when you are online.", + feature_title_1: "Content Types", + feature_description_1: "A Content Management System wouldn't be a CMS if you cannot define your type of content to use. Front Matter provides a default content mapping, but you can extend it or change it to your needs. It is your content, and Front Matter will change its behavior to your needs.", - feature_title_2: "Full site/page preview", - feature_description_2: "Allow showing your site and page previews within Visual Studio Code without the need of opening a browser.", + feature_title_2: "Offline management", + feature_description_2: "A Content Management System built to run within Visual Studio Code. You do not require an account or any dependencies on a website or API. Write wherever you are, commit when you are online.", - feature_title_3: "Content dashboard", - feature_description_3: "Our page dashboard allows you to search, filter, sort, and group all your static site pages.", + feature_title_3: "Full site/page preview", + feature_description_3: "Allow showing your site and page previews within Visual Studio Code without the need of opening a browser.", - feature_title_4: "SEO Checks", - feature_description_4: "Our search engine optimization checks allow you to write better articles. We show you more information about your title, description, content, keywords, and more.", + feature_title_4: "Content/media dashboard", + feature_description_4: "One of the most powerful features is our dashboard, from where you get an overview of all your content and media files. We tightly integrate with our editor panel so that you can use it, for example, to insert media files into your articles.", - feature_title_5: "Use it the way you want it", - feature_description_5: "All of the functionalities are configurable to your needs. You can define how you want to use Front Matter in your editor experience.", + feature_title_5: "SEO Checks", + feature_description_5: "Our search engine optimization checks allow you to write better articles. We show you more information about your title, description, content, keywords, and more.", - feature_title_6: "Extensibility", - feature_description_6: "Add your actions with our custom scripting capability. For instance, you can use a script and hook it up to the extension if you want to generate preview images. If we do not support it, you can build it and share it with us.", + feature_title_6: "Use it the way you want it", + feature_description_6: "All of the functionalities are configurable to your needs. You can define how you want to use Front Matter in your editor experience, but it doesn't stop there. If you are missing something or want to automate. We allow you to add your own actions with the custom scripting capability. For instance, you can use a script and hook it up to the extension to generate preview images.", // Sponsors sponsors_title: "Special thanks to our sponsor", diff --git a/docs/public/assets/actions.png b/docs/public/assets/actions.png index 24d0b169..5f246188 100644 Binary files a/docs/public/assets/actions.png and b/docs/public/assets/actions.png differ diff --git a/docs/public/assets/adapted-default-ct.png b/docs/public/assets/adapted-default-ct.png new file mode 100644 index 00000000..422ae166 Binary files /dev/null and b/docs/public/assets/adapted-default-ct.png differ diff --git a/docs/public/assets/default-contenttype.png b/docs/public/assets/default-contenttype.png new file mode 100644 index 00000000..ffa2e148 Binary files /dev/null and b/docs/public/assets/default-contenttype.png differ diff --git a/package.json b/package.json index 8b24208c..0e2587c3 100644 --- a/package.json +++ b/package.json @@ -186,6 +186,16 @@ "markdownDescription": "Specify the path you want to add after the host and before your slug. This can be used for instance to include the year/month like: `yyyy/MM`. The date will be generated based on the article its date field value. [Check in the docs](https://frontmatter.codes/docs/settings#frontmatter.preview.pathname)", "scope": "Site preview" }, + "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)" + }, + "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)" + }, "frontMatter.taxonomy.tags": { "type": "array", "markdownDescription": "Specifies the tags which can be used in the Front Matter. [Check in the docs](https://frontmatter.codes/docs/settings#frontmatter.taxonomy.tags)", @@ -323,6 +333,7 @@ "type": "string", "enum": [ "string", + "number", "datetime", "boolean", "image", diff --git a/src/commands/Dashboard.ts b/src/commands/Dashboard.ts index 32f87b41..33ca1c8d 100644 --- a/src/commands/Dashboard.ts +++ b/src/commands/Dashboard.ts @@ -111,6 +111,9 @@ export class Dashboard { Dashboard.webview.onDidDispose(() => { Dashboard.isDisposed = true; + Dashboard._viewData = undefined; + const panel = ExplorerView.getInstance(extensionUri); + panel.getMediaSelection(); }); workspace.onDidChangeConfiguration(() => { diff --git a/src/models/PanelSettings.ts b/src/models/PanelSettings.ts index 65a75061..87c217d5 100644 --- a/src/models/PanelSettings.ts +++ b/src/models/PanelSettings.ts @@ -26,7 +26,7 @@ export interface ContentType { export interface Field { title?: string; name: string; - type: "string" | "datetime" | "boolean" | "image" | "tags" | "categories"; + type: "string" | "number" | "datetime" | "boolean" | "image" | "tags" | "categories"; } export interface DateInfo { diff --git a/src/panelWebView/components/Fields/NumberField.tsx b/src/panelWebView/components/Fields/NumberField.tsx new file mode 100644 index 00000000..5f140501 --- /dev/null +++ b/src/panelWebView/components/Fields/NumberField.tsx @@ -0,0 +1,35 @@ +import { CalculatorIcon } from '@heroicons/react/outline'; +import * as React from 'react'; +import { VsLabel } from '../VscodeComponents'; + +export interface INumberFieldProps { + label: string; + value: number | null; + onChange: (nrValue: number | null) => void; +} + +export const NumberField: React.FunctionComponent = ({label, value, onChange}: React.PropsWithChildren) => { + const [ nrValue, setNrValue ] = React.useState(value); + + const onValueChange = (txtValue: string) => { + let newValue: number | null = parseInt(txtValue); + if (isNaN(newValue)) { + newValue = null; + } + + setNrValue(newValue); + onChange(newValue); + }; + + return ( +
+ +
+ {label} +
+
+ + onValueChange(e.target.value)} /> +
+ ); +}; \ No newline at end of file diff --git a/src/panelWebView/components/Fields/TextField.tsx b/src/panelWebView/components/Fields/TextField.tsx index 07c1a89b..8339e301 100644 --- a/src/panelWebView/components/Fields/TextField.tsx +++ b/src/panelWebView/components/Fields/TextField.tsx @@ -24,6 +24,11 @@ export const TextField: React.FunctionComponent = ({limit, labe } }, [ value ]); + let isValid = true; + if (limit && limit !== -1) { + isValid = ((text || "").length < limit); + } + return (
@@ -37,7 +42,7 @@ export const TextField: React.FunctionComponent = ({limit, labe rows={rows || 2} value={text || ""} onChange={(e) => onTextChange(e.currentTarget.value)} style={{ - border: !limit || ((text || "").length < limit) ? "1px solid var(--vscode-inputValidation-infoBorder)" : "1px solid var(--vscode-inputValidation-warningBorder)" + border: isValid ? "1px solid var(--vscode-inputValidation-infoBorder)" : "1px solid var(--vscode-inputValidation-warningBorder)" }} /> { diff --git a/src/panelWebView/components/Metadata.tsx b/src/panelWebView/components/Metadata.tsx index 1a790435..fe708a1d 100644 --- a/src/panelWebView/components/Metadata.tsx +++ b/src/panelWebView/components/Metadata.tsx @@ -16,6 +16,7 @@ import "react-datepicker/dist/react-datepicker.css"; import { PreviewImageField } from './Fields/PreviewImageField'; import { DEFAULT_CONTENT_TYPE, DEFAULT_CONTENT_TYPE_NAME } from '../../constants/ContentType'; import { ListUnorderedIcon } from './Icons/ListUnorderedIcon'; +import { NumberField } from './Fields/NumberField'; export interface IMetadataProps { settings: PanelSettings | undefined; metadata: { [prop: string]: string[] | string | null }; @@ -102,6 +103,20 @@ export const Metadata: React.FunctionComponent = ({settings, met onChange={(value) => sendUpdate(field.name, value)} value={textValue as string || null} /> ); + } else if (field.type === 'number') { + const fieldValue = metadata[field.name]; + let nrValue: number | null = parseInt(fieldValue as string); + if (isNaN(nrValue)) { + nrValue = null; + } + + return ( + sendUpdate(field.name, value)} + value={nrValue} /> + ); } else if (field.type === 'image') { return (