Skip to content

v10.8.0 release #924

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Feb 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Change Log

## [10.8.0] - 2025-02-27 - [Release notes](https://beta.frontmatter.codes/updates/v10.8.0)

### 🎨 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
- [#922](https://github.com/estruyf/vscode-front-matter/issues/922): Added `{{fileName}}` and `{{sluggedFileName}}` placeholders for the slug template setting

### 🐞 Fixes

- Fix for media folder parsing on Windows
- Refresh button was not available on the media dashboard when having custom scripts defined
- [#909](https://github.com/estruyf/vscode-front-matter/issues/909): Schema fix for the view modes
- [#913](https://github.com/estruyf/vscode-front-matter/issues/913): Fix for relative media paths in page bundles
- [#914](https://github.com/estruyf/vscode-front-matter/issues/914): Fix sanitizing of default filenames with an `_` in it

## [10.7.0] - 2024-12-31 - [Release notes](https://beta.frontmatter.codes/updates/v10.7.0)

### 🎨 Enhancements
Expand Down
5 changes: 3 additions & 2 deletions l10n/bundle.l10n.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@
"settings.view.integration": "Integration",

"settings.openOnStartup": "Open dashboard on startup",
"settings.openPanelForSupportedFiles": "Open panel for supported files",
"settings.openPanelForSupportedFiles.label": "Do you want to open the panel for supported files?",
"settings.contentTypes": "Content types",
"settings.contentFolders": "Content folders",
"settings.diagnostic": "Diagnostic",
Expand Down Expand Up @@ -799,7 +801,6 @@
"listeners.panel.dataListener.createDataFile.error": "No data file id or path defined.",
"listeners.panel.dataListener.createDataFile.noFileName": "No filename provided.",


"listeners.panel.taxonomyListener.aiSuggestTaxonomy.noEditor.error": "No active editor",
"listeners.panel.taxonomyListener.aiSuggestTaxonomy.noData.error": "No article data",

Expand All @@ -817,4 +818,4 @@
"services.sponsorAi.getTaxonomySuggestions.warning": "The AI taxonomy generation took too long. Please try again later.",

"services.terminal.openLocalServerTerminal.terminalOption.message": "Starting local server"
}
}
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 9 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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.7.0",
"version": "10.8.0",
"preview": false,
"publisher": "eliostruyf",
"galleryBanner": {
Expand Down Expand Up @@ -1061,8 +1061,9 @@
"panel.globalSettings",
"panel.seo",
"panel.actions",
"panel.contentType",
"panel.metadata",
"panel.contentType",
"panel.gitActions",
"panel.recentlyModified",
"panel.otherActions",
"dashboard.snippets.view",
Expand Down Expand Up @@ -1213,6 +1214,12 @@
},
"scope": "Media"
},
"frontMatter.panel.openOnSupportedFile": {
"type": "boolean",
"default": false,
"markdownDescription": "%setting.frontMatter.panel.openOnSupportedFile.markdownDescription%",
"scope": "Dashboard"
},
"frontMatter.panel.freeform": {
"type": "boolean",
"default": true,
Expand Down
3 changes: 2 additions & 1 deletion package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@
"setting.frontMatter.media.contentTypes.items.properties.fields.properties.type.description": "Define the type of field",
"setting.frontMatter.media.contentTypes.items.properties.fields.properties.single.description": "Is a single line field",

"setting.frontMatter.panel.openOnSupportedFile.markdownDescription": "Specifies if you want to open the panel when opening a supported file. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.panel.openonsupportedfile) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.panel.openonsupportedfile%22%5D)",
"setting.frontMatter.panel.freeform.markdownDescription": "Specifies if you want to allow yourself from entering unknown tags/categories in the tag picker (when enabled, you will have the option to store them afterwards). Default: true. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.panel.freeform) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.panel.freeform%22%5D)",
"setting.frontMatter.panel.actions.disabled.markdownDescription": "Specify the actions you want to disable in the panel. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.panel.actions.disabled) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.panel.actions.disabled%22%5D)",
"setting.frontMatter.preview.host.markdownDescription": "Specify the host URL (example: http://localhost:1313) to be used when opening the preview. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.preview.host) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.preview.host%22%5D)",
Expand Down Expand Up @@ -292,4 +293,4 @@
"setting.frontMatter.git.disableOnBranches.markdownDescription": "Specify the branches on which you want to disable the Git actions. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.git.disableonbranches) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.git.disableonbranches%22%5D)",
"setting.frontMatter.git.requiresCommitMessage.markdownDescription": "Specify if you want to require a commit message when publishing your changes for a specified branch. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.git.requirescommitmessage) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.git.requirescommitmessage%22%5D)",
"setting.frontMatter.copilot.family.markdownDescription": "Specify the LLM family of the Copilot you want to use. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.copilot.family) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.copilot.family%22%5D)"
}
}
21 changes: 16 additions & 5 deletions src/commands/Article.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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 {
Expand Down Expand Up @@ -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 &&
Expand Down Expand Up @@ -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],
Expand Down Expand Up @@ -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);
}
}
}
Expand Down
16 changes: 13 additions & 3 deletions src/commands/Folders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,9 @@ export class Folders {
: Folders.getAbsFilePath(assetFolder);
const wsFolder = Folders.getWorkspaceFolder();
if (wsFolder) {
const relativePath = relative(parseWinPath(wsFolder.fsPath), parseWinPath(assetFolder));
const relativePath = parseWinPath(
relative(parseWinPath(wsFolder.fsPath), parseWinPath(assetFolder))
);
return relativePath === '' ? '/' : relativePath;
}
}
Expand Down Expand Up @@ -636,15 +638,23 @@ export class Folders {
}
}

// For Windows, we need to make sure the drive letter is lowercased for consistency
if (isWindows()) {
folders = folders.map((folder) => parseWinPath(folder));
}

// Filter out the workspace folder
if (wsFolder) {
folders = folders.filter((folder) => folder !== wsFolder.fsPath);
folders = folders.filter((folder) => folder !== parseWinPath(wsFolder.fsPath));
}

const uniqueFolders = [...new Set(folders)];
const relativeFolderPaths = uniqueFolders.map((folder) =>
parseWinPath(relative(parseWinPath(wsFolder.fsPath), folder))
);

Logger.verbose('Folders:getContentFolders:end');
return uniqueFolders.map((folder) => relative(wsFolder?.path || '', folder));
return relativeFolderPaths;
}

/**
Expand Down
6 changes: 3 additions & 3 deletions src/constants/Features.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ export const FEATURE_FLAG = {
seo: 'panel.seo',
actions: 'panel.actions',
metadata: 'panel.metadata',
recentlyModified: 'panel.recentlyModified',
otherActions: 'panel.otherActions',
contentType: 'panel.contentType',
gitActions: 'panel.gitActions'
gitActions: 'panel.gitActions',
recentlyModified: 'panel.recentlyModified',
otherActions: 'panel.otherActions'
},
dashboard: {
snippets: {
Expand Down
1 change: 1 addition & 0 deletions src/constants/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export const SETTING_TEMPLATES_FOLDER = 'templates.folder';
export const SETTING_TEMPLATES_PREFIX = 'templates.prefix';
export const SETTING_TEMPLATES_ENABLED = 'templates.enabled';

export const SETTING_PANEL_OPEN_ON_SUPPORTED_FILE = 'panel.openOnSupportedFile';
export const SETTING_PANEL_FREEFORM = 'panel.freeform';
export const SETTING_PANEL_ACTIONS_DISABLED = 'panel.actions.disabled';

Expand Down
38 changes: 38 additions & 0 deletions src/dashboardWebView/components/Header/BooleanOption.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import * as React from 'react';
import { Messenger } from '@estruyf/vscode/dist/client';
import { DashboardMessage } from '../../DashboardMessage';
import { Checkbox as VSCodeCheckbox } from 'vscrui';

export interface IBooleanOptionProps {
value: boolean | undefined | null;
name: string;
label: string;
}

export const BooleanOption: React.FunctionComponent<IBooleanOptionProps> = ({
value,
name,
label
}: React.PropsWithChildren<IBooleanOptionProps>) => {
const [isChecked, setIsChecked] = React.useState(false);

const onChange = React.useCallback((newValue: boolean) => {
setIsChecked(newValue);
Messenger.send(DashboardMessage.updateSetting, {
name: name,
value: newValue
});
}, [name]);

React.useEffect(() => {
setIsChecked(!!value);
}, [value]);

return (
<VSCodeCheckbox
onChange={onChange}
checked={isChecked}>
{label}
</VSCodeCheckbox>
);
};
5 changes: 4 additions & 1 deletion src/dashboardWebView/components/Media/FolderCreation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,9 @@ export const FolderCreation: React.FunctionComponent<IFolderCreationProps> = (

if (scripts.length > 0) {
return (
<div className="flex flex-1 justify-start">
<div className="flex flex-1 justify-start space-x-2">
{renderPostAssetsButton}

<ChoiceButton
title={l10n.t(LocalizationKey.dashboardMediaFolderCreationFolderCreate)}
choices={scripts.map((s) => ({
Expand All @@ -103,6 +104,8 @@ export const FolderCreation: React.FunctionComponent<IFolderCreationProps> = (
onClick={onFolderCreation}
disabled={!settings?.initialized}
/>

<RefreshDashboardData />
</div>
);
}
Expand Down
13 changes: 11 additions & 2 deletions src/dashboardWebView/components/Media/Item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
PlusIcon,
VideoCameraIcon,
} from '@heroicons/react/24/outline';
import { basename } from 'path';
import { basename, parse } from 'path';
import * as React from 'react';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { useRecoilState, useRecoilValue } from 'recoil';
Expand Down Expand Up @@ -55,8 +55,17 @@ export const Item: React.FunctionComponent<IItemProps> = ({
const { mediaFolder, mediaDetails, isAudio, isImage, isVideo } = useMediaInfo(media);

const relPath = useMemo(() => {
if (viewData?.data?.pageBundle && viewData?.data?.filePath) {
const articlePath = viewData?.data?.filePath;
const articleDir = parse(parseWinPath(articlePath)).dir;

const mediaPath = parseWinPath(media.fsPath);
if (mediaPath.startsWith(articleDir)) {
return getRelPath(media.fsPath, undefined, articleDir);
}
}
return getRelPath(media.fsPath, settings?.staticFolder, settings?.wsFolder);
}, [media.fsPath, settings?.staticFolder, settings?.wsFolder]);
}, [media.fsPath, settings?.staticFolder, settings?.wsFolder, viewData?.data?.pageBundle, viewData?.data?.filePath]);

const hasViewData = useMemo(() => {
return viewData?.data?.filePath !== undefined;
Expand Down
12 changes: 11 additions & 1 deletion src/dashboardWebView/components/SettingsView/CommonSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import { useRecoilValue } from 'recoil';
import { SettingsSelector } from '../../state';
import { SettingsInput } from './SettingsInput';
import { Button as VSCodeButton } from 'vscrui';
import { DOCS_SUBMODULES, FrameworkDetectors, GIT_CONFIG, SETTING_FRAMEWORK_START, SETTING_GIT_COMMIT_MSG, SETTING_GIT_ENABLED, SETTING_PREVIEW_HOST, SETTING_WEBSITE_URL } from '../../../constants';
import { DOCS_SUBMODULES, FrameworkDetectors, GIT_CONFIG, SETTING_FRAMEWORK_START, SETTING_GIT_COMMIT_MSG, SETTING_GIT_ENABLED, SETTING_PANEL_OPEN_ON_SUPPORTED_FILE, SETTING_PREVIEW_HOST, SETTING_WEBSITE_URL } from '../../../constants';
import { messageHandler } from '@estruyf/vscode/dist/client';
import { DashboardMessage } from '../../DashboardMessage';
import { SettingsCheckbox } from './SettingsCheckbox';
import { ChevronRightIcon } from '@heroicons/react/24/outline';
import { BooleanOption } from '../Header/BooleanOption';

export interface ICommonSettingsProps { }

Expand Down Expand Up @@ -73,6 +74,15 @@ export const CommonSettings: React.FunctionComponent<ICommonSettingsProps> = (pr
<Startup settings={settings} />
</div>

<div className='py-4'>
<h2 className='text-xl mb-2'>{l10n.t(LocalizationKey.settingsOpenPanelForSupportedFiles)}</h2>

<BooleanOption
label={l10n.t(LocalizationKey.settingsOpenPanelForSupportedFilesLabel)}
name={SETTING_PANEL_OPEN_ON_SUPPORTED_FILE}
value={settings?.openPanelForSupportedFiles} />
</div>

<div className='py-4'>
<h2 className='text-xl mb-2'>{l10n.t(LocalizationKey.settingsGit)}</h2>

Expand Down
1 change: 1 addition & 0 deletions src/dashboardWebView/models/Settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export interface Settings {
categories: string[];
customTaxonomy: CustomTaxonomy[];
openOnStart: boolean | null;
openPanelForSupportedFiles: boolean | null;
versionInfo: VersionInfo;
pageViewType: DashboardViewType | undefined;
contentTypes: ContentType[];
Expand Down
3 changes: 2 additions & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,13 +245,14 @@ export async function activate(context: vscode.ExtensionContext) {
// eslint-disable-next-line @typescript-eslint/no-empty-function
export function deactivate() {}

const triggerPageUpdate = (location: string) => {
const triggerPageUpdate = async (location: string) => {
Logger.verbose(`Trigger page update: ${location}`);
pageUpdateDebouncer(() => {
StatusListener.verify(collection);
}, 1000);

if (location === 'onDidChangeActiveTextEditor') {
await PanelProvider.openOnSupportedFile();
PanelProvider.getInstance()?.updateCurrentFile();
}
};
4 changes: 2 additions & 2 deletions src/helpers/ArticleHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ export class ArticleHelper {
await mkdirAsync(newFolder, { recursive: true });
newFilePath = join(
newFolder,
`${sanitize(contentType.defaultFileName ?? `index`)}.${
`${sanitize(contentType.defaultFileName || `index`, { isFileName: true })}.${
fileExtension || contentType.fileType || fileType
}`
);
Expand Down Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion src/helpers/ContentType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand Down
Loading
Loading