mirror of
https://github.com/silverstripe/doc.silverstripe.org
synced 2024-10-22 15:05:50 +00:00
NEW Add version banners at the top of docs pages
This commit is contained in:
parent
4b9c88219b
commit
4a08724c29
@ -14,7 +14,7 @@ class IconExtractor {
|
|||||||
const matches = content.match(/icon(Brand)?: ([a-zA-Z0-9_-]+)/);
|
const matches = content.match(/icon(Brand)?: ([a-zA-Z0-9_-]+)/);
|
||||||
if (matches) {
|
if (matches) {
|
||||||
const isBrand = typeof matches[1] !== 'undefined';
|
const isBrand = typeof matches[1] !== 'undefined';
|
||||||
selectors.push(isBrand ? `fab` : `fas`);
|
selectors.push(isBrand ? 'fab' : 'fas');
|
||||||
selectors.push(`fa-${matches[2]}`);
|
selectors.push(`fa-${matches[2]}`);
|
||||||
}
|
}
|
||||||
return selectors;
|
return selectors;
|
||||||
@ -29,6 +29,12 @@ const whitelist = [
|
|||||||
// Syntax highlighting
|
// Syntax highlighting
|
||||||
'pre',
|
'pre',
|
||||||
'code',
|
'code',
|
||||||
|
|
||||||
|
// Icon classes used in nodes.ts
|
||||||
|
'far',
|
||||||
|
'fa-calendar',
|
||||||
|
'fa-check-circle',
|
||||||
|
'fa-times-circle',
|
||||||
];
|
];
|
||||||
|
|
||||||
const whitelistPatterns = [
|
const whitelistPatterns = [
|
||||||
|
@ -11,13 +11,14 @@ interface LayoutProps {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const Layout: StatelessComponent<LayoutProps> = ({ children, pageContext: { slug } }) => {
|
const Layout: StatelessComponent<LayoutProps> = ({ children, pageContext: { slug } }) => {
|
||||||
const { setCurrentPath, getVersionPath, getCurrentVersion, getCurrentNode, getDefaultVersion } = useHierarchy();
|
const { setCurrentPath, getVersionPath, getCurrentVersion, getCurrentNode, getDefaultVersion, getVersionMessage } = useHierarchy();
|
||||||
const [isToggled, setSidebarOpen] = useState(false);
|
const [isToggled, setSidebarOpen] = useState(false);
|
||||||
const handleNavigate = () => setSidebarOpen(false);
|
const handleNavigate = () => setSidebarOpen(false);
|
||||||
|
|
||||||
setCurrentPath(slug);
|
setCurrentPath(slug);
|
||||||
const ver = getCurrentVersion();
|
const ver = getCurrentVersion();
|
||||||
const currentNode = getCurrentNode();
|
const currentNode = getCurrentNode();
|
||||||
|
const versionMessage = getVersionMessage();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -37,7 +38,10 @@ const Layout: StatelessComponent<LayoutProps> = ({ children, pageContext: { slug
|
|||||||
<div className="docs-content">
|
<div className="docs-content">
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<article role="main" className="docs-article">
|
<article role="main" className="docs-article">
|
||||||
|
<>
|
||||||
|
{versionMessage}
|
||||||
{children}
|
{children}
|
||||||
|
</>
|
||||||
</article>
|
</article>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -15,6 +15,7 @@ import {
|
|||||||
getVersionPath,
|
getVersionPath,
|
||||||
setCurrentPath,
|
setCurrentPath,
|
||||||
getDefaultVersion,
|
getDefaultVersion,
|
||||||
|
getVersionMessage,
|
||||||
} from '../utils/nodes';
|
} from '../utils/nodes';
|
||||||
|
|
||||||
const NodeProvider: StatelessComponent<{}> = ({ children, pageContext: { slug } }): ReactElement => {
|
const NodeProvider: StatelessComponent<{}> = ({ children, pageContext: { slug } }): ReactElement => {
|
||||||
@ -61,6 +62,7 @@ const NodeProvider: StatelessComponent<{}> = ({ children, pageContext: { slug }
|
|||||||
getVersionPath,
|
getVersionPath,
|
||||||
setCurrentPath,
|
setCurrentPath,
|
||||||
getDefaultVersion,
|
getDefaultVersion,
|
||||||
|
getVersionMessage,
|
||||||
}}>
|
}}>
|
||||||
{children}
|
{children}
|
||||||
</NodeContext.Provider>
|
</NodeContext.Provider>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { useContext } from 'react';
|
import { useContext, ReactElement } from 'react';
|
||||||
import NodeContext from '../contexts/NodeContext';
|
import NodeContext from '../contexts/NodeContext';
|
||||||
import { SilverstripeDocument } from '../types';
|
import { SilverstripeDocument } from '../types';
|
||||||
|
|
||||||
@ -15,6 +15,7 @@ interface NodeFunctions {
|
|||||||
getVersionPath(currentNode: SilverstripeDocument, version: number|string): string;
|
getVersionPath(currentNode: SilverstripeDocument, version: number|string): string;
|
||||||
setCurrentPath(slug: string): undefined;
|
setCurrentPath(slug: string): undefined;
|
||||||
getDefaultVersion(): string;
|
getDefaultVersion(): string;
|
||||||
|
getVersionMessage(): ReactElement | ReactElement[] | string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const useHierarchy = (): NodeFunctions => {
|
const useHierarchy = (): NodeFunctions => {
|
||||||
|
@ -384,6 +384,60 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.callout-block--version {
|
||||||
|
border-left-width: 6px;
|
||||||
|
padding-top: 1rem;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
|
||||||
|
.callout-version-title {
|
||||||
|
display: flex;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: $font-weight-bold;
|
||||||
|
color: lighten($theme-text-color-primary, 15%);
|
||||||
|
|
||||||
|
.callout-version-stability {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-left: auto;
|
||||||
|
font-size: 1.125rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.callout-version-stability-text {
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.callout-version-content {
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.callout-block-success {
|
||||||
|
.callout-version-stability {
|
||||||
|
color: darken($theme-success-color, 15%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.callout-block-info {
|
||||||
|
.callout-version-stability {
|
||||||
|
color: darken($theme-info-color, 15%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.callout-block-warning {
|
||||||
|
.callout-version-stability {
|
||||||
|
color: darken($theme-warning-color, 15%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.callout-block-danger {
|
||||||
|
.callout-version-stability {
|
||||||
|
color: darken($theme-danger-color, 15%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.cta-section {
|
.cta-section {
|
||||||
.container {
|
.container {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
|
import parse from 'html-react-parser';
|
||||||
|
import { ReactElement } from 'react';
|
||||||
import { SilverstripeDocument } from '../types';
|
import { SilverstripeDocument } from '../types';
|
||||||
import sortFiles from './sortFiles';
|
import sortFiles from './sortFiles';
|
||||||
import { node } from 'prop-types';
|
|
||||||
|
|
||||||
let __nodes: SilverstripeDocument[];
|
let __nodes: SilverstripeDocument[];
|
||||||
let __currentVersion: string | null = null;
|
let __currentVersion: string | null = null;
|
||||||
@ -149,17 +150,65 @@ const getDefaultVersion = (): string => '4';
|
|||||||
*/
|
*/
|
||||||
const getCurrentVersion = (): string => __currentVersion || getDefaultVersion();
|
const getCurrentVersion = (): string => __currentVersion || getDefaultVersion();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a message to display for all pages on this version's docs
|
||||||
|
*/
|
||||||
|
const getVersionMessage = (): ReactElement | ReactElement[] | string | null => {
|
||||||
|
const EOL = [
|
||||||
|
'3',
|
||||||
|
];
|
||||||
|
const PRE_RELEASE = [
|
||||||
|
'5',
|
||||||
|
];
|
||||||
|
const version = getCurrentVersion();
|
||||||
|
const stablePath = getVersionPath(getCurrentNode(), getDefaultVersion());
|
||||||
|
|
||||||
|
// Output the appropriate message and styling
|
||||||
|
function makeMessage(style: string, icon: string, stability: string, message: string|null): string {
|
||||||
|
let template = `<div id="version-callout" class="callout-block callout-block--version callout-block-${style}">
|
||||||
|
<div class="callout-version-title">Version ${version}<span class="callout-version-stability">
|
||||||
|
<i class="far fa-${icon}"></i><span class="callout-version-stability-text">${stability}</span></span>
|
||||||
|
</div>`;
|
||||||
|
if (message) {
|
||||||
|
template += `<div class="callout-version-content">
|
||||||
|
This version of Silverstripe CMS ${message}.
|
||||||
|
<a href="${stablePath}">Go to documentation for the most recent stable version.</a>
|
||||||
|
</div>`;
|
||||||
|
}
|
||||||
|
template += '</div>';
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the correct message for the current version
|
||||||
|
if (EOL.includes(version)) {
|
||||||
|
return parse(makeMessage('danger', 'times-circle', 'end of life', 'will not recieve any additional bug fixes or documentation updates'));
|
||||||
|
}
|
||||||
|
if (PRE_RELEASE.includes(version)) {
|
||||||
|
return parse(makeMessage(
|
||||||
|
'warning',
|
||||||
|
'calendar',
|
||||||
|
'pre-stable',
|
||||||
|
'has not yet been given a stable release. See <a target="_blank" href="https://www.silverstripe.org/software/roadmap/">the release roadmap</a> for more information'
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return parse(makeMessage('success', 'check-circle', 'supported', null));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the path in another version
|
* Gets the path in another version
|
||||||
* @param currentNode
|
* @param currentNode
|
||||||
* @param version
|
* @param version
|
||||||
*/
|
*/
|
||||||
const getVersionPath = (currentNode: SilverstripeDocument, version: number): string => {
|
const getVersionPath = (currentNode: SilverstripeDocument|null, version: number|string): string => {
|
||||||
const newPath = currentNode.slug.replace(/^\/en\/[0-9]+\//, `/en/${version}/`);
|
const basePath = `/en/${version}`;
|
||||||
|
if (!currentNode) {
|
||||||
|
return basePath;
|
||||||
|
}
|
||||||
|
const newPath = currentNode.slug.replace(/^\/en\/[0-9]+\//, `${basePath}/`);
|
||||||
const otherNode = getNodes().find(n => n.slug === newPath);
|
const otherNode = getNodes().find(n => n.slug === newPath);
|
||||||
|
|
||||||
return otherNode ? otherNode.slug : `/en/${version}`;
|
return otherNode ? otherNode.slug : basePath;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -185,4 +234,5 @@ export {
|
|||||||
getVersionPath,
|
getVersionPath,
|
||||||
setCurrentPath,
|
setCurrentPath,
|
||||||
getDefaultVersion,
|
getDefaultVersion,
|
||||||
|
getVersionMessage,
|
||||||
};
|
};
|
@ -65,6 +65,13 @@ const rewriteHeaders = (domNode: DomElement): ReactElement | false => {
|
|||||||
|
|
||||||
domNode.children?.push(anchor);
|
domNode.children?.push(anchor);
|
||||||
|
|
||||||
|
if (domNode.name === 'h1') {
|
||||||
|
if (!domNode.attribs) {
|
||||||
|
domNode.attribs = {};
|
||||||
|
}
|
||||||
|
domNode.attribs['aria-details'] = 'version-callout';
|
||||||
|
}
|
||||||
|
|
||||||
return domToReact([domNode]);
|
return domToReact([domNode]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user