Skip to content

Commit

Permalink
Issue: slug placeholder not working if there is no title field #830
Browse files Browse the repository at this point in the history
  • Loading branch information
estruyf committed Jul 3, 2024
1 parent 5b3223a commit 47e8cae
Show file tree
Hide file tree
Showing 17 changed files with 131 additions and 111 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
### 🐞 Fixes

- [#827](https://github.com/estruyf/vscode-front-matter/issues/827): Fix for `frontmatter.json` file which gets created when already present in a sub-folder
- [#830](https://github.com/estruyf/vscode-front-matter/issues/830): Fix for using the SEO title field setting to change the title field reference

## [10.2.0] - 2024-06-12 - [Release notes](https://beta.frontmatter.codes/updates/v10.2.0)

Expand Down
13 changes: 8 additions & 5 deletions src/commands/Article.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import { NavigationType } from '../dashboardWebView/models';
import { SNIPPET } from '../constants/Snippet';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../localization';
import { getTitleField } from '../utils';

export class Article {
/**
Expand Down Expand Up @@ -213,7 +214,7 @@ export class Article {
contentType
);

const titleField = 'title';
const titleField = getTitleField();
const articleTitle: string = article.data[titleField];
const slugInfo = Article.generateSlug(articleTitle, article, contentType.slugTemplate);

Expand Down Expand Up @@ -307,17 +308,18 @@ export class Article {

const parsedFile = parse(file);

const titleField = getTitleField();
const slugTemplate = Settings.get<string>(SETTING_SLUG_TEMPLATE);
if (slugTemplate) {
if (slugTemplate === '{{title}}') {
const article = ArticleHelper.getFrontMatter(editor);
if (article?.data?.title) {
return article.data.title.toLowerCase().replace(/\s/g, '-');
if (article?.data && article.data[titleField]) {
return article.data[titleField].toLowerCase().replace(/\s/g, '-');
}
} else {
const article = ArticleHelper.getFrontMatter(editor);
if (article?.data) {
return SlugHelper.createSlug(article.data.title, article.data, slugTemplate);
return SlugHelper.createSlug(article.data[titleField], article.data, slugTemplate);
}
}
}
Expand Down Expand Up @@ -490,11 +492,12 @@ export class Article {

const article = ArticleHelper.getFrontMatter(editor);
const contentType = article ? await ArticleHelper.getContentType(article) : undefined;
const tileField = getTitleField();

await commands.executeCommand(COMMAND_NAME.dashboard, {
type: NavigationType.Snippets,
data: {
fileTitle: article?.data.title || '',
fileTitle: article?.data[tileField] || '',
filePath: editor.document.uri.fsPath,
fieldName: basename(editor.document.uri.fsPath),
contentType,
Expand Down
8 changes: 5 additions & 3 deletions src/commands/Preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { ParsedFrontMatter } from '../parsers';
import { getLocalizationFile } from '../utils/getLocalizationFile';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../localization';
import { joinUrl } from '../utils';
import { getTitleField, joinUrl } from '../utils';
import { i18n } from './i18n';

export class Preview {
Expand Down Expand Up @@ -77,11 +77,13 @@ export class Preview {
return;
}

const titleField = getTitleField();

// Create the preview webview
const webView = window.createWebviewPanel(
'frontMatterPreview',
article?.data?.title
? l10n.t(LocalizationKey.commandsPreviewPanelTitle, article?.data.title)
article?.data && article?.data[titleField]
? l10n.t(LocalizationKey.commandsPreviewPanelTitle, article?.data[titleField])
: 'Front Matter Preview',
{
viewColumn: ViewColumn.Beside,
Expand Down
14 changes: 5 additions & 9 deletions src/commands/StatusListener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,12 @@ import {
CONTEXT,
EXTENSION_NAME,
NOTIFICATION_TYPE,
SETTING_SEO_DESCRIPTION_FIELD,
SETTING_SEO_DESCRIPTION_LENGTH,
SETTING_SEO_TITLE_FIELD,
SETTING_SEO_TITLE_LENGTH
} from './../constants';
import * as vscode from 'vscode';
import { ArticleHelper, Notifications, SeoHelper, Settings } from '../helpers';
import { PanelProvider } from '../panelWebView/PanelProvider';
import { DefaultFields } from '../constants';
import { ContentType } from '../helpers/ContentType';
import { DataListener } from '../listeners/panel';
import { commands } from 'vscode';
Expand All @@ -20,6 +17,7 @@ import { Preview } from './Preview';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../localization';
import { i18n } from './i18n';
import { getDescriptionField, getTitleField } from '../utils';

export class StatusListener {
/**
Expand Down Expand Up @@ -56,12 +54,10 @@ export class StatusListener {
collection.clear();

// Retrieve the SEO config properties
const titleLength = (Settings.get(SETTING_SEO_TITLE_LENGTH) as number) || -1;
const descLength = (Settings.get(SETTING_SEO_DESCRIPTION_LENGTH) as number) || -1;
const titleField =
(Settings.get(SETTING_SEO_TITLE_FIELD) as string) || DefaultFields.Title;
const descriptionField =
(Settings.get(SETTING_SEO_DESCRIPTION_FIELD) as string) || DefaultFields.Description;
const titleLength = Settings.get<number>(SETTING_SEO_TITLE_LENGTH) || -1;
const descLength = Settings.get<number>(SETTING_SEO_DESCRIPTION_LENGTH) || -1;
const titleField = getTitleField();
const descriptionField = getDescriptionField();

if (editor && article.data[titleField] && titleLength > -1) {
SeoHelper.checkLength(editor, collection, article, titleField, titleLength);
Expand Down
13 changes: 8 additions & 5 deletions src/commands/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
import { COMMAND_NAME, SETTING_CONTENT_I18N } from '../constants';
import { ContentFolder, Field, I18nConfig, ContentType as IContentType } from '../models';
import { join, parse } from 'path';
import { existsAsync } from '../utils';
import { existsAsync, getDescriptionField, getTitleField } from '../utils';
import { Folders } from '.';
import { ParsedFrontMatter } from '../parsers';
import { PagesListener } from '../listeners/dashboard';
Expand Down Expand Up @@ -412,8 +412,11 @@ export class i18n {
},
async () => {
try {
const title = article.data.title || '';
const description = article.data.description || '';
const titleField = getTitleField();
const descriptionField = getDescriptionField();

const title = article.data[titleField] || '';
const description = article.data[descriptionField] || '';
const content = article.content || '';

const text = [title, description, content];
Expand All @@ -428,8 +431,8 @@ export class i18n {
return;
}

article.data.title = article.data.title ? translations[0] : '';
article.data.description = article.data.description ? translations[1] : '';
article.data[titleField] = article.data[titleField] ? translations[0] : '';
article.data[descriptionField] = article.data[descriptionField] ? translations[1] : '';
article.content = article.content ? translations[2] : '';
} catch (error) {
Notifications.error(`${(error as Error).message}`);
Expand Down
5 changes: 3 additions & 2 deletions src/helpers/ArticleHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import { Link, Parent } from 'mdast-util-from-markdown/lib';
import { Content } from 'mdast';
import { CustomScript } from './CustomScript';
import { Folders } from '../commands/Folders';
import { existsAsync } from '../utils';
import { existsAsync, getTitleField } from '../utils';
import { mkdirAsync } from '../utils/mkdirAsync';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../localization';
Expand Down Expand Up @@ -635,11 +635,12 @@ export class ArticleHelper {
) {
const dateFormat = Settings.get(SETTING_DATE_FORMAT) as string;
const fmData = Object.assign({}, data);
const titleField = getTitleField();

for (const fieldName of Object.keys(fmData)) {
const fieldValue = fmData[fieldName];

if (fieldName === 'title' && (fieldValue === null || fieldValue === '')) {
if (fieldName === titleField && (fieldValue === null || fieldValue === '')) {
fmData[fieldName] = title;
}

Expand Down
11 changes: 8 additions & 3 deletions src/helpers/ContentType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
import {
COMMAND_NAME,
DefaultFieldValues,
DefaultFields,
EXTENSION_NAME,
FEATURE_FLAG,
SETTING_CONTENT_DRAFT_FIELD,
Expand All @@ -37,7 +38,7 @@ import { DEFAULT_CONTENT_TYPE_NAME } from '../constants/ContentType';
import { Telemetry } from './Telemetry';
import { basename } from 'path';
import { ParsedFrontMatter } from '../parsers';
import { encodeEmoji, existsAsync, fieldWhenClause, writeFileAsync } from '../utils';
import { encodeEmoji, existsAsync, fieldWhenClause, getTitleField, writeFileAsync } from '../utils';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../localization';

Expand Down Expand Up @@ -950,8 +951,11 @@ export class ContentType {
}

titleValue = titleValue.trim();

const titleFieldName = getTitleField();

// Check if the title needs to encode the emoji's used in it
const titleField = contentType.fields.find((f) => f.name === 'title');
const titleField = contentType.fields.find((f) => f.name === titleFieldName);
if (titleField && titleField.encodeEmoji) {
titleValue = encodeEmoji(titleValue);
}
Expand Down Expand Up @@ -1058,6 +1062,7 @@ export class ContentType {
isRoot: boolean = true
): Promise<any> {
if (obj.fields) {
const titleField = getTitleField();
const dateFormat = Settings.get(SETTING_DATE_FORMAT) as string;

for (const field of obj.fields) {
Expand All @@ -1066,7 +1071,7 @@ export class ContentType {
continue;
}

if (field.name === 'title') {
if (field.name === titleField) {
if (field.default) {
data[field.name] = processArticlePlaceholdersFromData(
field.default as string,
Expand Down
11 changes: 4 additions & 7 deletions src/helpers/PanelSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { Preview } from '../commands/Preview';
import { Project } from '../commands/Project';
import {
CONTEXT,
DefaultFields,
SETTING_CONTENT_DRAFT_FIELD,
SETTING_CONTENT_FRONTMATTER_HIGHLIGHT,
SETTING_DATA_TYPES,
Expand All @@ -22,16 +21,14 @@ import {
SETTING_DATE_FORMAT,
SETTING_PANEL_FREEFORM,
SETTING_SEO_CONTENT_MIN_LENGTH,
SETTING_SEO_DESCRIPTION_FIELD,
SETTING_SEO_DESCRIPTION_LENGTH,
SETTING_SEO_SLUG_LENGTH,
SETTING_SEO_TITLE_LENGTH,
SETTING_SLUG_PREFIX,
SETTING_SLUG_SUFFIX,
SETTING_SLUG_UPDATE_FILE_NAME,
SETTING_TAXONOMY_CUSTOM,
SETTING_TAXONOMY_FIELD_GROUPS,
SETTING_SEO_TITLE_FIELD
SETTING_TAXONOMY_FIELD_GROUPS
} from '../constants';
import { GitListener } from '../listeners/general';
import {
Expand All @@ -46,6 +43,7 @@ import {
} from '../models';
import { Folders } from '../commands';
import { Copilot } from '../services/Copilot';
import { getDescriptionField, getTitleField } from '../utils';

export class PanelSettings {
public static async get(): Promise<IPanelSettings> {
Expand All @@ -61,9 +59,8 @@ export class PanelSettings {
slug: (Settings.get(SETTING_SEO_SLUG_LENGTH) as number) || -1,
description: (Settings.get(SETTING_SEO_DESCRIPTION_LENGTH) as number) || -1,
content: (Settings.get(SETTING_SEO_CONTENT_MIN_LENGTH) as number) || -1,
titleField: (Settings.get(SETTING_SEO_TITLE_FIELD) as string) || DefaultFields.Title,
descriptionField:
(Settings.get(SETTING_SEO_DESCRIPTION_FIELD) as string) || DefaultFields.Description
titleField: getTitleField(),
descriptionField: getDescriptionField()
},
slug: {
prefix: Settings.get(SETTING_SLUG_PREFIX) || '',
Expand Down
19 changes: 13 additions & 6 deletions src/helpers/processArticlePlaceholders.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ContentType } from '../models';
import { getTitleField } from '../utils';
import { ArticleHelper } from './ArticleHelper';
import { SlugHelper } from './SlugHelper';

Expand All @@ -7,16 +8,17 @@ export const processArticlePlaceholdersFromData = (
data: { [key: string]: any },
contentType: ContentType
): string => {
if (value.includes('{{title}}') && data.title) {
const titleField = getTitleField();
if (value.includes('{{title}}') && data[titleField]) {
const regex = new RegExp('{{title}}', 'g');
value = value.replace(regex, data.title || '');
value = value.replace(regex, data[titleField] || '');
}

if (value.includes('{{slug}}')) {
const regex = new RegExp('{{slug}}', 'g');
value = value.replace(
regex,
SlugHelper.createSlug(data.title || '', data, contentType.slugTemplate) || ''
SlugHelper.createSlug(data[titleField] || '', data, contentType.slugTemplate) || ''
);
}

Expand All @@ -32,9 +34,11 @@ export const processArticlePlaceholdersFromPath = async (
return value;
}

const titleField = getTitleField();

if (value.includes('{{title}}')) {
const regex = new RegExp('{{title}}', 'g');
value = value.replace(regex, article.data.title || '');
value = value.replace(regex, article.data[titleField] || '');
}

if (value.includes('{{slug}}') && filePath) {
Expand All @@ -43,8 +47,11 @@ export const processArticlePlaceholdersFromPath = async (
const regex = new RegExp('{{slug}}', 'g');
value = value.replace(
regex,
SlugHelper.createSlug(article.data.title || '', article.data, contentType.slugTemplate) ||
''
SlugHelper.createSlug(
article.data[titleField] || '',
article.data,
contentType.slugTemplate
) || ''
);
}
}
Expand Down
Loading

0 comments on commit 47e8cae

Please sign in to comment.