diff --git a/components/article/ToolPicker.tsx b/components/article/ToolPicker.tsx index 4392bdac8799..ad64fe29aae9 100644 --- a/components/article/ToolPicker.tsx +++ b/components/article/ToolPicker.tsx @@ -12,35 +12,10 @@ import { useArticleContext } from 'components/context/ArticleContext' // Nota bene: tool === application // Nota bene: picker === switcher -const supportedTools = [ - 'cli', - 'desktop', - 'webui', - 'curl', - 'codespaces', - 'vscode', - 'importer_cli', - 'graphql', - 'powershell', - 'bash', -] -const toolTitles = { - webui: 'Web browser', - cli: 'GitHub CLI', - curl: 'cURL', - desktop: 'Desktop', - codespaces: 'Codespaces', - vscode: 'Visual Studio Code', - importer_cli: 'GitHub Enterprise Importer CLI', - graphql: 'GraphQL API', - powershell: 'PowerShell', - bash: 'Bash', -} as Record - // Imperatively modify article content to show only the selected tool // find all platform-specific *block* elements and hide or show as appropriate // example: {% webui %} block content {% endwebui %} -function showToolSpecificContent(tool: string) { +function showToolSpecificContent(tool: string, supportedTools: Array) { const markdowns = Array.from(document.querySelectorAll('.extended-markdown')) markdowns .filter((el) => supportedTools.some((tool) => el.classList.contains(tool))) @@ -77,7 +52,8 @@ type Props = { } export const ToolPicker = ({ variant = 'subnav' }: Props) => { const { asPath } = useRouter() - const { defaultTool, detectedTools } = useArticleContext() + // allTools comes from the ArticleContext which contains the list of tools available + const { defaultTool, detectedTools, allTools } = useArticleContext() const [currentTool, setCurrentTool] = useState(getDefaultTool(defaultTool, detectedTools)) const sharedContainerProps = { @@ -100,7 +76,7 @@ export const ToolPicker = ({ variant = 'subnav' }: Props) => { // Whenever the currentTool is changed, update the article content useEffect(() => { preserveAnchorNodePosition(document, () => { - showToolSpecificContent(currentTool) + showToolSpecificContent(currentTool, Object.keys(allTools)) }) }, [currentTool, asPath]) @@ -137,7 +113,7 @@ export const ToolPicker = ({ variant = 'subnav' }: Props) => { onClickTool(tool) }} > - {toolTitles[tool]} + {allTools[tool]} ))} diff --git a/components/context/ArticleContext.tsx b/components/context/ArticleContext.tsx index 966d99c665d9..bd2d198ebc69 100644 --- a/components/context/ArticleContext.tsx +++ b/components/context/ArticleContext.tsx @@ -29,6 +29,7 @@ export type ArticleContextT = { currentLearningTrack?: LearningTrack detectedPlatforms: Array detectedTools: Array + allTools: Record } export const ArticleContext = createContext(null) @@ -70,5 +71,6 @@ export const getArticleContextFromRequest = (req: any): ArticleContextT => { currentLearningTrack: req.context.currentLearningTrack, detectedPlatforms: page.detectedPlatforms || [], detectedTools: page.detectedTools || [], + allTools: page.allToolsParsed || [], // this is set at the page level, see lib/page.js } } diff --git a/contributing/content-markup-reference.md b/contributing/content-markup-reference.md index 7d8fe5dd2e0f..632507dc4fd7 100644 --- a/contributing/content-markup-reference.md +++ b/contributing/content-markup-reference.md @@ -128,7 +128,7 @@ You can define a default platform in the frontmatter. For more information, see ## Tool tags -We occasionally need to write documentation for different tools (GitHub UI, GitHub CLI, GitHub Desktop, cURL, Codespaces, VS Code, GitHub Enterprise Importer CLI, GraphQL API). Each tool may require a different set of instructions. We use tool tags to demarcate information for each tool. +We occasionally need to write documentation for different tools (GitHub UI, GitHub CLI, GitHub Desktop, cURL, Codespaces, VS Code, GitHub Enterprise Importer CLI, GraphQL API). Each tool may require a different set of instructions. We use tool tags to demarcate information for each tool. To modify the list of possible tools, edit [`lib/all-tools.js`](../lib/all-tools.js). ### Usage diff --git a/lib/all-tools.js b/lib/all-tools.js new file mode 100644 index 000000000000..9cb24ff39f38 --- /dev/null +++ b/lib/all-tools.js @@ -0,0 +1,13 @@ +// all the tools available for the Tool Picker +export const allTools = { + bash: 'Bash', + cli: 'GitHub CLI', + codespaces: 'Codespaces', + curl: 'cURL', + desktop: 'Dekstop', + importer_cli: 'GitHub Enterprise Importer CLI', + graphql: 'GraphQL API', + powershell: 'PowerShell', + vscode: 'Visual Studio Code', + webui: 'Web browser', +} diff --git a/lib/frontmatter.js b/lib/frontmatter.js index 97bded646780..fdf7d3d8a9bf 100644 --- a/lib/frontmatter.js +++ b/lib/frontmatter.js @@ -3,6 +3,7 @@ import path from 'path' import parse from './read-frontmatter.js' import semver from 'semver' import { allVersions } from './all-versions.js' +import { allTools } from './all-tools.js' const layoutNames = [ 'default', @@ -20,6 +21,7 @@ const semverRange = { message: 'Must be a valid SemVer range', } const versionObjs = Object.values(allVersions) + const guideTypes = ['overview', 'quick_start', 'tutorial', 'how_to', 'reference'] const featureVersions = fs .readdirSync(path.posix.join(process.cwd(), 'data/features')) @@ -177,21 +179,11 @@ export const schema = { type: 'string', enum: ['mac', 'windows', 'linux'], }, - // Tool-specific content preference + // Tool-specific content preference, the list of tools are kept in + // make it easier to update in a single place defaultTool: { type: 'string', - enum: [ - 'webui', - 'cli', - 'desktop', - 'curl', - 'codespaces', - 'vscode', - 'importer_cli', - 'graphql', - 'powershell', - 'bash', - ], + enum: Object.keys(allTools), }, // Documentation contributed by a third party, such as a GitHub Partner contributor: { diff --git a/lib/liquid-tags/extended-markdown.js b/lib/liquid-tags/extended-markdown.js index 20eec546592a..f44ebeb67d60 100644 --- a/lib/liquid-tags/extended-markdown.js +++ b/lib/liquid-tags/extended-markdown.js @@ -1,17 +1,12 @@ -export const tags = { +import { allTools } from '../all-tools.js' + +// we do this to get an object that combines all possible liquid tags +const toolTags = Object.fromEntries(Object.keys(allTools).map((tool) => [tool, ''])) + +const subsetTags = { mac: '', windows: '', linux: '', - cli: '', - desktop: '', - webui: '', - curl: '', - codespaces: '', - vscode: '', - importer_cli: '', - graphql: '', - powershell: '', - bash: '', all: '', tip: 'border rounded-1 mb-4 p-3 color-border-accent-emphasis color-bg-accent f5', note: 'border rounded-1 mb-4 p-3 color-border-accent-emphasis color-bg-accent f5', @@ -19,6 +14,8 @@ export const tags = { danger: 'border rounded-1 mb-4 p-3 color-border-danger color-bg-danger f5', } +export const tags = Object.assign({}, subsetTags, toolTags) + export const template = '
{{ output }}
' diff --git a/lib/page.js b/lib/page.js index 1bc8f7b950cc..4e952d9b07a4 100644 --- a/lib/page.js +++ b/lib/page.js @@ -17,6 +17,7 @@ import readFileContents from './read-file-contents.js' import getLinkData from './get-link-data.js' import getDocumentType from './get-document-type.js' import { union } from 'lodash-es' +import { allTools } from './all-tools.js' // We're going to check a lot of pages' "ID" (the first part of // the relativePath) against `productMap` to make sure it's valid. @@ -261,18 +262,13 @@ class Page { this.includesPlatformSpecificContent = this.detectedPlatforms.length > 0 // set flags for webui, cli, etc switcher element - this.detectedTools = [ - 'cli', - 'desktop', - 'webui', - 'curl', - 'codespaces', - 'vscode', - `importer_cli`, - `graphql`, - 'powershell', - 'bash', - ].filter((tool) => html.includes(`extended-markdown ${tool}`) || html.includes(`tool-${tool}`)) + this.detectedTools = Object.keys(allTools).filter( + (tool) => html.includes(`extended-markdown ${tool}`) || html.includes(`tool-${tool}`) + ) + + // pass the list of all possible tools around to components and utilities that will need it later on + this.allToolsParsed = allTools + this.includesToolSpecificContent = this.detectedTools.length > 0 return html diff --git a/lib/schema-event.js b/lib/schema-event.js index ec9564573eba..02345185ee81 100644 --- a/lib/schema-event.js +++ b/lib/schema-event.js @@ -1,7 +1,7 @@ import { languageKeys } from './languages.js' import { allVersionKeys } from './all-versions.js' import { productIds } from './all-products.js' - +import { allTools } from './all-tools.js' const context = { type: 'object', additionalProperties: false, @@ -146,18 +146,7 @@ const context = { }, application_preference: { type: 'string', - enum: [ - 'webui', - 'cli', - 'desktop', - 'curl', - 'codespaces', - 'vscode', - 'importer_cli', - 'graphql', - 'powershell', - 'bash', - ], + enum: Object.keys(allTools), description: 'The application selected by the user.', }, color_mode_preference: { @@ -451,17 +440,7 @@ const preferenceSchema = { }, preference_value: { type: 'string', - enum: [ - 'webui', - 'cli', - 'desktop', - 'curl', - 'codespaces', - 'vscode', - 'importer_cli', - 'graphql', - 'powershell', - 'bash', + enum: Object.keys(allTools).concat( 'dark', 'light', 'auto', @@ -469,8 +448,8 @@ const preferenceSchema = { 'auto:light', 'linux', 'mac', - 'windows', - ], + 'windows' + ), description: 'The application, color_mode, or os selected by the user.', }, },