From 47e8caeedea049bb794d55d16d3fa871ea8dd5ca Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Wed, 3 Jul 2024 14:35:25 +0200 Subject: [PATCH] Issue: slug placeholder not working if there is no title field #830 --- CHANGELOG.md | 1 + src/commands/Article.ts | 13 ++-- src/commands/Preview.ts | 8 ++- src/commands/StatusListener.ts | 14 ++-- src/commands/i18n.ts | 13 ++-- src/helpers/ArticleHelper.ts | 5 +- src/helpers/ContentType.ts | 11 ++- src/helpers/PanelSettings.ts | 11 ++- src/helpers/processArticlePlaceholders.ts | 19 ++++-- src/listeners/panel/DataListener.ts | 20 +++--- src/listeners/panel/TaxonomyListener.ts | 20 ++---- src/panelWebView/ViewPanel.tsx | 3 +- src/panelWebView/components/SeoStatus.tsx | 82 ++++++++++++----------- src/services/PagesParser.ts | 10 +-- src/utils/getDescriptionField.ts | 5 ++ src/utils/getTitleField.ts | 5 ++ src/utils/index.ts | 2 + 17 files changed, 131 insertions(+), 111 deletions(-) create mode 100644 src/utils/getDescriptionField.ts create mode 100644 src/utils/getTitleField.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 53e02f42..6ad3e17b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) diff --git a/src/commands/Article.ts b/src/commands/Article.ts index 9992f701..583aece4 100644 --- a/src/commands/Article.ts +++ b/src/commands/Article.ts @@ -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 { /** @@ -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); @@ -307,17 +308,18 @@ export class Article { const parsedFile = parse(file); + const titleField = getTitleField(); const slugTemplate = Settings.get(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); } } } @@ -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, diff --git a/src/commands/Preview.ts b/src/commands/Preview.ts index e4785d7d..1a2cb6e7 100644 --- a/src/commands/Preview.ts +++ b/src/commands/Preview.ts @@ -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 { @@ -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, diff --git a/src/commands/StatusListener.ts b/src/commands/StatusListener.ts index 79010a0e..9c1a9766 100644 --- a/src/commands/StatusListener.ts +++ b/src/commands/StatusListener.ts @@ -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'; @@ -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 { /** @@ -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(SETTING_SEO_TITLE_LENGTH) || -1; + const descLength = Settings.get(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); diff --git a/src/commands/i18n.ts b/src/commands/i18n.ts index e4a58826..845040ac 100644 --- a/src/commands/i18n.ts +++ b/src/commands/i18n.ts @@ -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'; @@ -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]; @@ -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}`); diff --git a/src/helpers/ArticleHelper.ts b/src/helpers/ArticleHelper.ts index f9c1eb6b..88cfbd2f 100644 --- a/src/helpers/ArticleHelper.ts +++ b/src/helpers/ArticleHelper.ts @@ -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'; @@ -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; } diff --git a/src/helpers/ContentType.ts b/src/helpers/ContentType.ts index a9fec798..04f97049 100644 --- a/src/helpers/ContentType.ts +++ b/src/helpers/ContentType.ts @@ -12,6 +12,7 @@ import { import { COMMAND_NAME, DefaultFieldValues, + DefaultFields, EXTENSION_NAME, FEATURE_FLAG, SETTING_CONTENT_DRAFT_FIELD, @@ -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'; @@ -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); } @@ -1058,6 +1062,7 @@ export class ContentType { isRoot: boolean = true ): Promise { if (obj.fields) { + const titleField = getTitleField(); const dateFormat = Settings.get(SETTING_DATE_FORMAT) as string; for (const field of obj.fields) { @@ -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, diff --git a/src/helpers/PanelSettings.ts b/src/helpers/PanelSettings.ts index 195a2732..577af426 100644 --- a/src/helpers/PanelSettings.ts +++ b/src/helpers/PanelSettings.ts @@ -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, @@ -22,7 +21,6 @@ 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, @@ -30,8 +28,7 @@ import { 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 { @@ -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 { @@ -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) || '', diff --git a/src/helpers/processArticlePlaceholders.ts b/src/helpers/processArticlePlaceholders.ts index 2bb508c9..816271d3 100644 --- a/src/helpers/processArticlePlaceholders.ts +++ b/src/helpers/processArticlePlaceholders.ts @@ -1,4 +1,5 @@ import { ContentType } from '../models'; +import { getTitleField } from '../utils'; import { ArticleHelper } from './ArticleHelper'; import { SlugHelper } from './SlugHelper'; @@ -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) || '' ); } @@ -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) { @@ -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 + ) || '' ); } } diff --git a/src/listeners/panel/DataListener.ts b/src/listeners/panel/DataListener.ts index a3eb87d8..dcf35b5f 100644 --- a/src/listeners/panel/DataListener.ts +++ b/src/listeners/panel/DataListener.ts @@ -5,12 +5,7 @@ import { Folders } from '../../commands/Folders'; import { Command } from '../../panelWebView/Command'; import { CommandToCode } from '../../panelWebView/CommandToCode'; import { BaseListener } from './BaseListener'; -import { - Uri, - authentication, - commands, - window -} from 'vscode'; +import { Uri, authentication, commands, window } from 'vscode'; import { ArticleHelper, Extension, @@ -30,7 +25,6 @@ import { SETTING_DATE_FORMAT, SETTING_GLOBAL_ACTIVE_MODE, SETTING_GLOBAL_MODES, - SETTING_SEO_TITLE_FIELD, SETTING_TAXONOMY_CONTENT_TYPES } from '../../constants'; import { Article, Preview } from '../../commands'; @@ -42,7 +36,7 @@ import { ContentType as IContentType, FolderInfo } from '../../models'; -import { encodeEmoji, fieldWhenClause } from '../../utils'; +import { encodeEmoji, fieldWhenClause, getTitleField } from '../../utils'; import { PanelProvider } from '../../panelWebView/PanelProvider'; import { MessageHandlerData } from '@estruyf/vscode'; import { SponsorAi } from '../../services/SponsorAI'; @@ -140,7 +134,7 @@ export class DataListener extends BaseListener { const extPath = Extension.getInstance().extensionPath; const panel = PanelProvider.getInstance(extPath); - const titleField = (Settings.get(SETTING_SEO_TITLE_FIELD) as string) || DefaultFields.Title; + const titleField = getTitleField(); const description = await Copilot.suggestDescription( articleDetails.data[titleField], articleDetails.content @@ -199,7 +193,7 @@ export class DataListener extends BaseListener { return; } - const titleField = (Settings.get(SETTING_SEO_TITLE_FIELD) as string) || DefaultFields.Title; + const titleField = getTitleField(); const suggestion = await SponsorAi.getDescription( githubAuth.accessToken, @@ -417,7 +411,7 @@ export class DataListener extends BaseListener { } let beforeValue: any; - const titleField = (Settings.get(SETTING_SEO_TITLE_FIELD) as string) || DefaultFields.Title; + const titleField = getTitleField(); const editor = window.activeTextEditor; @@ -774,9 +768,11 @@ export class DataListener extends BaseListener { data && contentType ? processArticlePlaceholdersFromData(value, data, contentType) : value; value = processTimePlaceholders(value, dateFormat); value = processFmPlaceholders(value, data); + + const titleField = getTitleField(); value = await ArticleHelper.processCustomPlaceholders( value, - data.title || '', + data[titleField] || '', crntFile?.uri.fsPath || '' ); } diff --git a/src/listeners/panel/TaxonomyListener.ts b/src/listeners/panel/TaxonomyListener.ts index 565e3992..cc5b59ae 100644 --- a/src/listeners/panel/TaxonomyListener.ts +++ b/src/listeners/panel/TaxonomyListener.ts @@ -5,17 +5,13 @@ import { authentication, window } from 'vscode'; import { ArticleHelper, Extension, Settings, TaxonomyHelper } from '../../helpers'; import { BlockFieldData, CustomTaxonomyData, PostMessageData, TaxonomyType } from '../../models'; import { DataListener } from '.'; -import { - DefaultFields, - SETTING_SEO_DESCRIPTION_FIELD, - SETTING_SEO_TITLE_FIELD -} from '../../constants'; import { SponsorAi } from '../../services/SponsorAI'; import { PanelProvider } from '../../panelWebView/PanelProvider'; import { MessageHandlerData } from '@estruyf/vscode'; import * as l10n from '@vscode/l10n'; import { LocalizationKey } from '../../localization'; import { Copilot } from '../../services/Copilot'; +import { getDescriptionField, getTitleField } from '../../utils'; export class TaxonomyListener extends BaseListener { /** @@ -73,10 +69,9 @@ export class TaxonomyListener extends BaseListener { } } - /** * Suggests a taxonomy for a given command, request ID, and tag type. - * + * * @param command - The command to execute. * @param requestId - The ID of the request. * @param type - The type of the tag. @@ -100,8 +95,8 @@ export class TaxonomyListener extends BaseListener { const extPath = Extension.getInstance().extensionPath; const panel = PanelProvider.getInstance(extPath); - 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 titleField = getTitleField(); + const descriptionField = getDescriptionField(); const tags = await Copilot.suggestTaxonomy( articleDetails.data[titleField], @@ -127,7 +122,7 @@ export class TaxonomyListener extends BaseListener { /** * Suggests taxonomy based on the provided command, request ID, and tag type. - * + * * @param command - The command to execute. * @param requestId - The ID of the request. * @param type - The type of tag. @@ -166,9 +161,8 @@ export class TaxonomyListener extends BaseListener { return; } - 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 titleField = getTitleField(); + const descriptionField = getDescriptionField(); const suggestions = await SponsorAi.getTaxonomySuggestions( githubAuth.accessToken, diff --git a/src/panelWebView/ViewPanel.tsx b/src/panelWebView/ViewPanel.tsx index 44f306f4..fd0c0941 100644 --- a/src/panelWebView/ViewPanel.tsx +++ b/src/panelWebView/ViewPanel.tsx @@ -137,7 +137,8 @@ export const ViewPanel: React.FunctionComponent = ( diff --git a/src/panelWebView/components/SeoStatus.tsx b/src/panelWebView/components/SeoStatus.tsx index 55b6b38d..1e85bc62 100644 --- a/src/panelWebView/components/SeoStatus.tsx +++ b/src/panelWebView/components/SeoStatus.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { SEO } from '../../models/PanelSettings'; +import { PanelSettings, SEO } from '../../models/PanelSettings'; import { TagType } from '../TagType'; import { ArticleDetails } from './ArticleDetails'; import { Collapsible } from './Collapsible'; @@ -8,49 +8,55 @@ import { SymbolKeywordIcon } from './Icons/SymbolKeywordIcon'; import { SeoFieldInfo } from './SeoFieldInfo'; import { SeoKeywords } from './SeoKeywords'; import { TagPicker } from './Fields/TagPicker'; -import * as l10n from '@vscode/l10n'; -import { LocalizationKey } from '../../localization'; +import { LocalizationKey, localize } from '../../localization'; import { VSCodeTable, VSCodeTableBody, VSCodeTableHead, VSCodeTableHeader, VSCodeTableRow } from './VSCode/VSCodeTable'; +import useContentType from '../../hooks/useContentType'; export interface ISeoStatusProps { seo: SEO; - data: any; + metadata: any; + settings: PanelSettings | undefined; focusElm: TagType | null; unsetFocus: () => void; } const SeoStatus: React.FunctionComponent = ({ - data, + metadata, seo, + settings, focusElm, unsetFocus }: React.PropsWithChildren) => { - const { title, slug } = data; + const contentType = useContentType(settings, metadata); + const { slug } = metadata; const { descriptionField, titleField } = seo; const tableContent = React.useMemo(() => { + const titleFieldName = contentType?.fields.find(f => f.name === titleField)?.title || titleField; + const descriptionFieldName = contentType?.fields.find(f => f.name === descriptionField)?.title || descriptionField; + return (
-

{l10n.t(LocalizationKey.panelSeoStatusTitle)}

+

{localize(LocalizationKey.panelSeoStatusTitle)}

- {l10n.t(LocalizationKey.panelSeoStatusHeaderProperty)} - {l10n.t(LocalizationKey.panelSeoStatusHeaderLength)} - {l10n.t(LocalizationKey.panelSeoStatusHeaderValid)} + {localize(LocalizationKey.panelSeoStatusHeaderProperty)} + {localize(LocalizationKey.panelSeoStatusHeaderLength)} + {localize(LocalizationKey.panelSeoStatusHeaderValid)} - {data[titleField] && seo.title > 0 ? ( + {metadata[titleField] && seo.title > 0 ? ( ) : null} @@ -58,25 +64,25 @@ const SeoStatus: React.FunctionComponent = ({ ) : null} - {data[descriptionField] && seo.description > 0 ? ( + {metadata[descriptionField] && seo.description > 0 ? ( ) : null} - {seo.content > 0 && data?.articleDetails?.wordCount > 0 ? ( + {seo.content > 0 && metadata?.articleDetails?.wordCount > 0 ? ( ) : null} @@ -84,20 +90,20 @@ const SeoStatus: React.FunctionComponent = ({
} - crntSelected={(data.keywords as string[]) || []} + crntSelected={(metadata.keywords as string[]) || []} options={[]} freeform={true} focussed={focusElm === TagType.keywords} @@ -106,17 +112,17 @@ const SeoStatus: React.FunctionComponent = ({ /> - +
); - }, [data, seo, focusElm, unsetFocus]); + }, [contentType, metadata, seo, focusElm, unsetFocus]); return ( - - {!title && !data[descriptionField] ? ( + + {!metadata[titleField] && !metadata[descriptionField] ? (

- {l10n.t(LocalizationKey.panelSeoStatusRequired, "Title", descriptionField)} + {localize(LocalizationKey.panelSeoStatusRequired, titleField, descriptionField)}

) : ( diff --git a/src/services/PagesParser.ts b/src/services/PagesParser.ts index 465e2629..50de93ec 100644 --- a/src/services/PagesParser.ts +++ b/src/services/PagesParser.ts @@ -9,8 +9,6 @@ import { DefaultFields, DEFAULT_CONTENT_TYPE_NAME, ExtensionState, - SETTING_SEO_DESCRIPTION_FIELD, - SETTING_SEO_TITLE_FIELD, SETTING_DATE_FORMAT } from '../constants'; import { Page } from '../dashboardWebView/models'; @@ -25,7 +23,7 @@ import { Notifications, Settings } from '../helpers'; -import { existsAsync } from '../utils'; +import { existsAsync, getDescriptionField, getTitleField } from '../utils'; import { Article, Cache } from '../commands'; import * as l10n from '@vscode/l10n'; import { LocalizationKey } from '../localization'; @@ -183,10 +181,8 @@ export class PagesParser { if (article?.data) { const wsFolder = Folders.getWorkspaceFolder(); - 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 titleField = getTitleField(); + const descriptionField = getDescriptionField(); const dateField = (await ArticleHelper.getPublishDateField(article)) || DefaultFields.PublishingDate; diff --git a/src/utils/getDescriptionField.ts b/src/utils/getDescriptionField.ts new file mode 100644 index 00000000..72b0a446 --- /dev/null +++ b/src/utils/getDescriptionField.ts @@ -0,0 +1,5 @@ +import { DefaultFields, SETTING_SEO_DESCRIPTION_FIELD } from '../constants'; +import { Settings } from '../helpers'; + +export const getDescriptionField = () => + Settings.get(SETTING_SEO_DESCRIPTION_FIELD) || DefaultFields.Description; diff --git a/src/utils/getTitleField.ts b/src/utils/getTitleField.ts new file mode 100644 index 00000000..65b4bb40 --- /dev/null +++ b/src/utils/getTitleField.ts @@ -0,0 +1,5 @@ +import { DefaultFields, SETTING_SEO_TITLE_FIELD } from '../constants'; +import { Settings } from '../helpers'; + +export const getTitleField = () => + Settings.get(SETTING_SEO_TITLE_FIELD) || DefaultFields.Title; diff --git a/src/utils/index.ts b/src/utils/index.ts index 22ef636f..5342fb5a 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -5,8 +5,10 @@ export * from './existsAsync'; export * from './fetchWithTimeout'; export * from './fieldWhenClause'; export * from './flattenObjectKeys'; +export * from './getDescriptionField'; export * from './getExtensibilityScripts'; export * from './getLocalizationFile'; +export * from './getTitleField'; export * from './ignoreMsgCommand'; export * from './isWindows'; export * from './joinUrl';