mirror of
https://github.com/fleetdm/fleet
synced 2026-05-22 08:28:52 +00:00
Website: Add sidebar nav to article template. (#22992)
Closes: #22037 Closes: #21281 Changes: - Added a sidebar nav to article pages with - links to headings (h2) in the article - links to /guides, /docs, and the REST API documentation - links to share the article on Twitter, LinkedIn, and Hacker News. --------- Co-authored-by: Mike Thomas <78363703+mike-j-thomas@users.noreply.github.com>
This commit is contained in:
parent
726889bed1
commit
0ec10c4e71
6 changed files with 176 additions and 41 deletions
BIN
website/assets/images/social-share-icon-hacker-news-20x20@2x.png
vendored
Normal file
BIN
website/assets/images/social-share-icon-hacker-news-20x20@2x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 498 B |
BIN
website/assets/images/social-share-icon-linkedin-20x20@2x.png
vendored
Normal file
BIN
website/assets/images/social-share-icon-linkedin-20x20@2x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 649 B |
BIN
website/assets/images/social-share-icon-twitter-20x20@2x.png
vendored
Normal file
BIN
website/assets/images/social-share-icon-twitter-20x20@2x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
|
|
@ -5,6 +5,7 @@ parasails.registerPage('basic-article', {
|
|||
data: {
|
||||
articleHasSubtitle: false,
|
||||
articleSubtitle: undefined,
|
||||
subtopics: [],
|
||||
},
|
||||
|
||||
// ╦ ╦╔═╗╔═╗╔═╗╦ ╦╔═╗╦ ╔═╗
|
||||
|
|
@ -14,7 +15,16 @@ parasails.registerPage('basic-article', {
|
|||
//…
|
||||
},
|
||||
mounted: async function() {
|
||||
//…
|
||||
this.subtopics = (() => {
|
||||
let subtopics = $('[purpose="article-content"]').find('h2.markdown-heading').map((_, el) => el);
|
||||
subtopics = $.makeArray(subtopics).map((subheading) => {
|
||||
return {
|
||||
title: subheading.innerText,
|
||||
url: $(subheading).find('a.markdown-link').attr('href'),
|
||||
};
|
||||
});
|
||||
return subtopics;
|
||||
})();
|
||||
// If the article has a subtitle (an H2 immediatly after an H1), we'll set articleSubtitle to be the text of that heading
|
||||
this.articleHasSubtitle = $('[purpose="article-content"]').find('h1 + h2');
|
||||
if(this.articleHasSubtitle.length > 0 && this.articleHasSubtitle[0].innerText) {
|
||||
|
|
@ -25,6 +35,9 @@ parasails.registerPage('basic-article', {
|
|||
let startValue = parseInt(ol.getAttribute('start'), 10) - 1;
|
||||
ol.style.counterReset = 'custom-counter ' + startValue;
|
||||
});
|
||||
// Add an event listener to add a class to the right sidebar when the header is hidden.
|
||||
window.addEventListener('scroll', this.handleScrollingInArticle);
|
||||
|
||||
if(this.algoliaPublicKey) {// Note: Docsearch will only be enabled if sails.config.custom.algoliaPublicKey is set. If the value is undefined, the handbook search will be disabled.
|
||||
docsearch({
|
||||
appId: 'NZXAYZXDGH',
|
||||
|
|
@ -60,5 +73,19 @@ parasails.registerPage('basic-article', {
|
|||
window.open('https://fleetdm.com/rss/'+articleCategory, '_blank');
|
||||
}
|
||||
},
|
||||
handleScrollingInArticle: function () {
|
||||
let rightNavBar = document.querySelector('div[purpose="right-sidebar"]');
|
||||
let scrollTop = window.pageYOffset;
|
||||
let windowHeight = window.innerHeight;
|
||||
// Add/remove the 'header-hidden' class to the right sidebar to scroll it upwards with the website's header.
|
||||
if (rightNavBar) {
|
||||
if (scrollTop > this.scrollDistance && scrollTop > windowHeight * 1.5) {
|
||||
rightNavBar.classList.add('header-hidden');
|
||||
} else {
|
||||
rightNavBar.classList.remove('header-hidden');
|
||||
}
|
||||
}
|
||||
this.scrollDistance = scrollTop;
|
||||
},
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#basic-article {
|
||||
padding: 0px 24px 0px 24px;
|
||||
h1 {
|
||||
font-size: 36px;
|
||||
}
|
||||
|
|
@ -9,9 +8,12 @@
|
|||
border-top: 2px solid @core-vibrant-blue-15;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
[purpose='page-container'] {
|
||||
max-width: 1200px;
|
||||
padding: 64px;
|
||||
}
|
||||
[purpose='breadcrumbs-and-search'] {
|
||||
padding-top: 64px;
|
||||
// padding-top: 64px;
|
||||
max-width: 1072px;
|
||||
margin: auto;
|
||||
font-size: 14px;
|
||||
|
|
@ -119,14 +121,56 @@
|
|||
[purpose='breadcrumbs-title'] {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
}
|
||||
[purpose='right-sidebar'] {
|
||||
position: sticky;
|
||||
margin-top: 64px;
|
||||
top: 144px;
|
||||
width: 256px;
|
||||
font-size: 14px;
|
||||
transition-property: transform;
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
transition-duration: 500ms;
|
||||
a:not([purpose='edit-button']) {
|
||||
margin-bottom: 8px;
|
||||
display: block;
|
||||
color: #515774;
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
color: @core-fleet-black;
|
||||
}
|
||||
}
|
||||
}
|
||||
[purpose='docs-links'] {
|
||||
a {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
[purpose='social-share-buttons'] {
|
||||
padding-bottom: 24px;
|
||||
margin-bottom: 24px;
|
||||
border-bottom: 1px solid #E2E4EA;
|
||||
a {
|
||||
margin-right: 16px;
|
||||
}
|
||||
img {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
}
|
||||
[purpose='subtopics'] {
|
||||
padding-bottom: 24px;
|
||||
margin-bottom: 24px;
|
||||
border-bottom: 1px solid #E2E4EA;
|
||||
}
|
||||
.header-hidden { // For scrolling the sidebar with the sticky header
|
||||
transform: translateY(-80px);
|
||||
}
|
||||
[purpose='article-container'] {
|
||||
max-width: 800px;
|
||||
margin: auto;
|
||||
padding-right: 64px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
}
|
||||
[purpose='article-title'] {
|
||||
padding-top: 64px;
|
||||
|
|
@ -141,7 +185,6 @@
|
|||
line-height: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
[purpose='rss-button'] {
|
||||
padding: 4px 8px;
|
||||
display: inline;
|
||||
|
|
@ -190,22 +233,24 @@
|
|||
}
|
||||
|
||||
[purpose='edit-button'] {
|
||||
margin-left: 24px;
|
||||
margin-top: 16px;
|
||||
img {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: inline;
|
||||
margin-right: 8px;
|
||||
}
|
||||
padding: 4px 8px;
|
||||
padding: 6px 8px;
|
||||
display: block;
|
||||
color: @core-fleet-black-75;
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
line-height: 21px;
|
||||
border-radius: 6px;
|
||||
width: 102px;
|
||||
background: rgba(25, 33, 71, 0.05);
|
||||
&:hover {
|
||||
background-color: rgba(25, 33, 71, 0.05);
|
||||
background-color: rgba(25, 33, 71, 0.1);
|
||||
}
|
||||
&:active {
|
||||
background-color: rgba(25, 33, 71, 0.1);
|
||||
|
|
@ -546,6 +591,24 @@
|
|||
}
|
||||
|
||||
@media (max-width: 991px) {
|
||||
[purpose='page-container'] {
|
||||
max-width: 1200px;
|
||||
padding: 64px 32px;
|
||||
}
|
||||
[purpose='right-sidebar'] {
|
||||
margin-top: 48px;
|
||||
width: 100%;
|
||||
}
|
||||
.header-hidden {
|
||||
transform: translateY(0);
|
||||
}
|
||||
[purpose='article-container'] {
|
||||
max-width: 100%;
|
||||
padding-right: 0px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
}
|
||||
[purpose='article-title'] {
|
||||
padding-top: 60px;
|
||||
}
|
||||
|
|
@ -575,6 +638,9 @@
|
|||
line-height: 38px;
|
||||
}
|
||||
}
|
||||
[purpose='right-sidebar'] {
|
||||
margin-top: 40px;
|
||||
}
|
||||
[purpose='article-content'] {
|
||||
img {
|
||||
padding-bottom: 0px;
|
||||
|
|
@ -584,13 +650,12 @@
|
|||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
[purpose='breadcrumbs-and-search'] {
|
||||
padding-top: 32px;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@media (max-width: 576px) {
|
||||
@media (max-width: 575px) {
|
||||
[purpose='page-container'] {
|
||||
padding: 32px 24px;
|
||||
}
|
||||
[purpose='bottom-cta'] {
|
||||
[purpose='next-steps-button'] {
|
||||
width: 100%;
|
||||
|
|
|
|||
93
website/views/pages/articles/basic-article.ejs
vendored
93
website/views/pages/articles/basic-article.ejs
vendored
|
|
@ -1,5 +1,5 @@
|
|||
<div id="basic-article" v-cloak>
|
||||
<div class="container-fluid px-0">
|
||||
<div purpose="page-container" class="container-fluid">
|
||||
<div purpose="breadcrumbs-and-search" class="d-flex flex-lg-row flex-column justify-content-between align-items-lg-center align-items-start">
|
||||
<div purpose="breadcrumbs" class="d-flex flex-row align-items-start">
|
||||
<div>
|
||||
|
|
@ -26,34 +26,77 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div purpose="article-container">
|
||||
<div purpose="article-title">
|
||||
<h1><%=thisPage.meta.articleTitle %></h1>
|
||||
<h2 v-if="articleHasSubtitle && articleSubtitle !== undefined">{{articleSubtitle}}</h2>
|
||||
</div>
|
||||
<div class="d-flex flex-sm-row flex-column justify-content-between align-items-sm-center">
|
||||
<div purpose="article-details" class="d-flex flex-row align-items-center">
|
||||
<span><js-timestamp format="billing" :at="thisPage.meta.publishedOn"></js-timestamp></span>
|
||||
<span class="px-2">|</span>
|
||||
<img style="height: 28px; width: 28px; border-radius: 100%;" alt="The author's GitHub profile picture" :src="'https://github.com/'+thisPage.meta.authorGitHubUsername+'.png?size=200'">
|
||||
<p class="pl-2 font-weight-bold"><%=thisPage.meta.authorFullName %></p>
|
||||
<div purpose="article-and-sidebar" class="d-flex flex-lg-row-reverse flex-column justify-content-lg-between">
|
||||
<div purpose="article-title-and-author" class="d-lg-none d-block">
|
||||
<div purpose="article-title">
|
||||
<h1><%=thisPage.meta.articleTitle %></h1>
|
||||
<h2 v-if="articleHasSubtitle && articleSubtitle !== undefined">{{articleSubtitle}}</h2>
|
||||
</div>
|
||||
<div class="d-flex flex-row align-items-center justify-content-sm-end pt-3 pt-sm-1">
|
||||
<a purpose="rss-button" @click="clickCopyRssLink(articleCategorySlug)"><span>Subscribe</span></a>
|
||||
<a purpose="edit-button" class="d-flex flex-row align-items-center text-nowrap" target="_blank" :href="'https://github.com/fleetdm/fleet/edit/main/articles/'+thisPage.sectionRelativeRepoPath"><img alt="A pencil icon" src="/images/pencil-16x16@2x.png">Edit page</a>
|
||||
<div class="d-flex flex-sm-row flex-column justify-content-between align-items-sm-center">
|
||||
<div purpose="article-details" class="d-flex flex-row align-items-center">
|
||||
<span><js-timestamp format="billing" :at="thisPage.meta.publishedOn"></js-timestamp></span>
|
||||
<span class="px-2">|</span>
|
||||
<img style="height: 28px; width: 28px; border-radius: 100%;" alt="The author's GitHub profile picture" :src="'https://github.com/'+thisPage.meta.authorGitHubUsername+'.png?size=200'">
|
||||
<p class="pl-2 font-weight-bold"><%=thisPage.meta.authorFullName %></p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div purpose="article-content" class="d-flex flex-column" parasails-has-no-page-script>
|
||||
<%- partial(path.relative(path.dirname(__filename), path.resolve( sails.config.appPath, path.join(sails.config.builtStaticContent.compiledPagePartialsAppPath, thisPage.htmlId)))) %>
|
||||
|
||||
<div purpose="sidebar-container">
|
||||
<div purpose="right-sidebar" class="d-flex flex-column">
|
||||
<div purpose="social-share-buttons" class="d-flex flex-column order-lg-2 order-1">
|
||||
<p><strong>Share</strong></p>
|
||||
<div class="d-flex flex-row">
|
||||
<a :href="`https://news.ycombinator.com/submitlink?u=https://fleetdm.com${encodeURIComponent(thisPage.url)}&t=${encodeURIComponent(thisPage.meta.articleTitle)}`"><img src="/images/social-share-icon-hacker-news-20x20@2x.png" alt="Share this article on Hacker News"></a>
|
||||
<a :href="`https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent('https://fleetdm.com'+thisPage.url)}`"><img src="/images/social-share-icon-linkedin-20x20@2x.png" alt="Share this article on LinkedIn"></a>
|
||||
<a :href="`https://twitter.com/intent/tweet?url=${encodeURIComponent('https://fleetdm.com'+thisPage.url)}`"><img src="/images/social-share-icon-twitter-20x20@2x.png" alt="Share this article on Twitter"></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div purpose="subtopics" id="subtopics" class="d-flex nav flex-column order-lg-1 order-2">
|
||||
<p><strong>On this page</strong></p>
|
||||
<a v-for="topic in subtopics" :href="topic.url" class="nav-link p-0">{{topic.title}}</a>
|
||||
</div>
|
||||
<div purpose="docs-links" class="order-3">
|
||||
<a href="/docs">Docs</a>
|
||||
<a href="/docs/rest-api">REST API</a>
|
||||
<a href="/guides">Guides</a>
|
||||
<a purpose="edit-button" class="d-inline-block text-nowrap" target="_blank" :href="'https://github.com/fleetdm/fleet/edit/main/articles/'+thisPage.sectionRelativeRepoPath"><img alt="A pencil icon" src="/images/pencil-16x16@2x.png">Edit page</a>
|
||||
</div>
|
||||
<!-- <div class="d-flex flex-row align-items-center justify-content-start pt-3 pt-sm-1">
|
||||
<a purpose="rss-button" @click="clickCopyRssLink(articleCategorySlug)"><span>Subscribe</span></a>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div purpose="bottom-cta" class="d-block">
|
||||
<h3 style="font-size: 24px; line-height: 32px;">Get started</h3>
|
||||
<div class="d-flex flex-sm-row flex-column align-items-center">
|
||||
<a href="/register" class="d-flex btn btn-primary justify-content-center align-items-center" purpose="next-steps-button">
|
||||
Start now
|
||||
</a>
|
||||
<animated-arrow-button class="ml-sm-4" href="/contact">Talk to us</animated-arrow-button>
|
||||
<div purpose="article-container">
|
||||
<div purpose="article-title-and-author" class="d-none d-lg-block">
|
||||
<div purpose="article-title">
|
||||
<h1><%=thisPage.meta.articleTitle %></h1>
|
||||
<h2 v-if="articleHasSubtitle && articleSubtitle !== undefined">{{articleSubtitle}}</h2>
|
||||
</div>
|
||||
<div class="d-flex flex-sm-row flex-column justify-content-between align-items-sm-center">
|
||||
<div purpose="article-details" class="d-flex flex-row align-items-center">
|
||||
<span><js-timestamp format="billing" :at="thisPage.meta.publishedOn"></js-timestamp></span>
|
||||
<span class="px-2">|</span>
|
||||
<img style="height: 28px; width: 28px; border-radius: 100%;" alt="The author's GitHub profile picture" :src="'https://github.com/'+thisPage.meta.authorGitHubUsername+'.png?size=200'">
|
||||
<p class="pl-2 font-weight-bold"><%=thisPage.meta.authorFullName %></p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div purpose="article-content" class="d-flex flex-column" parasails-has-no-page-script>
|
||||
<%- partial(path.relative(path.dirname(__filename), path.resolve( sails.config.appPath, path.join(sails.config.builtStaticContent.compiledPagePartialsAppPath, thisPage.htmlId)))) %>
|
||||
</div>
|
||||
<hr>
|
||||
<div purpose="bottom-cta" class="d-block">
|
||||
<h3 style="font-size: 24px; line-height: 32px;">Get started</h3>
|
||||
<div class="d-flex flex-sm-row flex-column align-items-center">
|
||||
<a href="/register" class="d-flex btn btn-primary justify-content-center align-items-center" purpose="next-steps-button">
|
||||
Start now
|
||||
</a>
|
||||
<animated-arrow-button class="ml-sm-4" href="/contact">Talk to us</animated-arrow-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in a new issue