diff --git a/blocks/author-box/author-box.css b/blocks/author-box/author-box.css
new file mode 100644
index 00000000..530ee56b
--- /dev/null
+++ b/blocks/author-box/author-box.css
@@ -0,0 +1,122 @@
+/* author box */
+
+main .author-box-container {
+ padding-top: 0;
+}
+
+main .author-box-container > div {
+ max-width: unset;
+ padding: 0;
+ margin: 0 auto;
+ }
+
+ main .author-box {
+ visibility: unset;
+ max-width: unset;
+ }
+
+ main .author-box-info {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ margin-top: 40px;
+ margin-bottom: 40px;
+ padding: 0 2rem;
+ }
+
+ main .author-box-info .sharing-details {
+ margin-left: auto;
+ }
+
+ main .author-box-info .blog-author-image,
+ main .author-box-info .blog-author-image img {
+ flex: 0 0 64px;
+ margin: 0;
+ margin-right: 16px;
+ height: 64px;
+ width: 64px;
+ border-radius: 50%;
+ object-fit: cover;
+ }
+
+ main .author-box-info .blog-author-name {
+ margin-bottom: 0;
+ }
+
+ main .author-box-info a {
+ text-decoration: none;
+ cursor: pointer;
+ }
+
+ main .author-box-info p,
+ main .author-box-info p a {
+ margin: 0;
+ }
+
+ main .author-box-info .sharing-details svg {
+ width: 40px;
+ height: 40px;
+ }
+
+ main .author-box-info .blog-author-blurb {
+ font-style: italic;
+ color: grey;
+ padding-left: 15px;
+ display: none;
+ }
+
+ main .author-box-info .publication-date-invalid {
+ display: none;
+ }
+
+ @media (min-width: 600px) {
+ main .author-box {
+ margin-left: auto;
+ margin-right: auto;
+ padding-left: 0;
+ padding-right: 0;
+ }
+
+ main .author-box .author-box-info {
+ max-width: 900px;
+ margin-left: auto;
+ margin-right: auto;
+ }
+
+ main .author-box-info .blog-author-blurb {
+ max-width: 300px;
+ margin-left: 10px;
+ border-left: 1px solid grey;
+ display: block;
+ font-size: 15px;
+ }
+
+ main .author-box-info .blog-author-details {
+ font-size: 16px;
+ }
+ }
+
+ @media (min-width: 768px) {
+ main .author-box-info .blog-author-blurb {
+ max-width: 380px;
+ margin-left: 20px;
+ font-size: 18px;
+ }
+
+ main .author-box-info .blog-author-details {
+ font-size: 18px;
+ }
+ }
+
+ @media (min-width: 900px) {
+ main .author-box-info .blog-author-blurb {
+ max-width: 450px;
+ font-size: 20px;
+ margin-left: 30px;
+ padding-left: 30px;
+ }
+
+ main .author-box-info .blog-author-details {
+ font-size: 20px;
+ }
+ }
diff --git a/blocks/author-box/author-box.js b/blocks/author-box/author-box.js
new file mode 100644
index 00000000..b6ca4af6
--- /dev/null
+++ b/blocks/author-box/author-box.js
@@ -0,0 +1,86 @@
+import {
+ getMetadata,
+} from '../../scripts/lib-franklin.js';
+
+function openPopup(e) {
+ const target = e.target.closest('a');
+ const href = target.getAttribute('data-href');
+ const type = target.getAttribute('data-type');
+ window.open(
+ href,
+ type,
+ 'popup,top=233,left=233,width=700,height=467',
+ );
+}
+
+async function buildSharing(githubId) {
+ const authorName = getMetadata('author');
+ const sharing = document.createElement('div');
+ sharing.classList.add('sharing-details');
+ const scriptUrl = new URL(import.meta.url);
+ const iconsPath = new URL('../../icons/icon-github.svg', scriptUrl).href;
+ // Fetch SVG content
+ const response = await fetch(iconsPath);
+ const svgContent = await response.text();
+ sharing.innerHTML = `
+
+ ${svgContent}
+
+ `;
+ sharing.querySelectorAll('[data-href]').forEach((link) => {
+ link.addEventListener('click', openPopup);
+ });
+ return sharing;
+}
+
+async function addProfileLinkToImage(authorImage, githubId) {
+ const authorLink = document.createElement('a');
+ authorLink.classList.add('blog-author-link');
+ authorLink.setAttribute('data-href', githubId);
+ authorLink.append(authorImage);
+ authorLink.addEventListener('click', openPopup);
+ return authorLink;
+}
+
+async function createAuthorBlurb(blurb) {
+ const authorBlurb = document.createElement('div');
+ authorBlurb.classList.add('blog-author-blurb');
+ authorBlurb.append(blurb);
+ return authorBlurb;
+}
+
+function validateDate(dateTag, dateString) {
+ const regex = /^[A-Z][a-z]+\s\d{1,2}(st|nd|rd|th),?\s\d{4}$/;
+ if (!regex.test(dateString)) {
+ dateTag.classList.add('publication-date-invalid');
+ dateTag.setAttribute('title', 'invalid-date');
+ console.error('Invalid publication date format. Please use a format like Month DDth, YYYY (e.g., January 30th, 2024)');
+ }
+}
+
+export default async function decorateAuthorBox(blockEl) {
+ const githubId = getMetadata('github');
+ const childrenEls = Array.from(blockEl.children);
+ const bylineContainer = childrenEls[0];
+ bylineContainer.classList.add('author-box-info');
+ // author image
+ const authorImage = bylineContainer.firstElementChild;
+ authorImage.classList.add('blog-author-image');
+ const addAuthorLink = await addProfileLinkToImage(authorImage, githubId);
+ bylineContainer.prepend(addAuthorLink);
+ // author name
+ bylineContainer.lastElementChild.classList.add('blog-author-details');
+ const authorDetails = bylineContainer.lastElementChild;
+ authorDetails.firstElementChild.classList.add('blog-author-name');
+ // publication date
+ const date = authorDetails.lastElementChild;
+ date.classList.add('blog-publication-date');
+ validateDate(date, date.textContent.trim());
+ // author blurb
+ const blurb = getMetadata('author-blurb');
+ const authorBlurb = await createAuthorBlurb(blurb);
+ bylineContainer.append(authorBlurb);
+ // sharing
+ const shareBlock = await buildSharing(githubId);
+ bylineContainer.append(shareBlock);
+}
diff --git a/icons/icon-github.svg b/icons/icon-github.svg
new file mode 100644
index 00000000..95992ac8
--- /dev/null
+++ b/icons/icon-github.svg
@@ -0,0 +1,6 @@
+
+
diff --git a/scripts/scripts.js b/scripts/scripts.js
index b9361542..044297c9 100644
--- a/scripts/scripts.js
+++ b/scripts/scripts.js
@@ -425,7 +425,7 @@ function addBlockLevelInViewAnimation(main) {
}
function decorateBreadcrumb(main) {
- if (!document.body.classList.contains('guides-template')) {
+ if (!document.body.classList.contains('guides-template') && !document.body.classList.contains('blog-template')) {
return;
}
@@ -448,6 +448,7 @@ function decorateBreadcrumb(main) {
main.prepend(wrapper);
const isDocumentationLanding = window.location.pathname === '/docs/';
+ const blogTemplate = document.body.classList.contains('blog-template');
const list = createTag('ul');
const home = createTag('li', {}, 'Home');
@@ -458,6 +459,7 @@ function decorateBreadcrumb(main) {
const category = getMetadata('category');
const title = getMetadata('og:title');
+ const template = getMetadata('template');
if (category) {
const section = createTag(
@@ -468,17 +470,28 @@ function decorateBreadcrumb(main) {
list.append(section);
}
+ if (template) {
+ const section = createTag(
+ 'li',
+ {},
+ `${template}`,
+ );
+ list.append(section);
+ }
+
if (!isDocumentationLanding) {
const article = createTag('li', {}, `${title}`);
list.append(article);
- const backBtn = createTag('div', { class: 'guides-back-btn desktop' }, `
-
-
- Back
-
- `);
- document.querySelector('.default-content-wrapper').prepend(backBtn);
+ if (!blogTemplate) {
+ const backBtn = createTag('div', { class: 'guides-back-btn desktop' }, `
+
+
+ Back
+
+ `);
+ document.querySelector('.default-content-wrapper').prepend(backBtn);
+ }
}
// make the last item to be unclickable as already on the page
@@ -533,6 +546,21 @@ function decorateSVGs(main) {
});
}
+function buildAuthorBox(main) {
+ const div = document.createElement('div');
+ const author = getMetadata('author');
+ const publicationDate = getMetadata('publication-date');
+ const authorImage = getMetadata('author-image');
+
+ const authorBoxBlockEl = buildBlock('author-box', [
+ [``,
+ `
${author}
+${publicationDate}
`], + ]); + div.append(authorBoxBlockEl); + main.append(div); +} + // --------------- Main functions here ---------------- // /** @@ -541,6 +569,9 @@ function decorateSVGs(main) { */ export function buildAutoBlocks(main) { try { + if (getMetadata('author') && !main.querySelector('.author-box')) { + buildAuthorBox(main); + } buildEmbeds(main); } catch (error) { // eslint-disable-next-line no-console diff --git a/styles/styles.css b/styles/styles.css index 594e3d8b..c302bd8e 100644 --- a/styles/styles.css +++ b/styles/styles.css @@ -312,6 +312,10 @@ aside { padding-left: var(--side-navigation-bar-gap); margin-right: 0; } + + .blog-template .default-content-wrapper { + max-width: 70%; + } } @media screen and (min-width: 1250px) { @@ -323,6 +327,11 @@ aside { .franklin .gnav .submenu-content { max-width: var(--grid-desktop-container-width); } + + .blog-template .default-content-wrapper { + max-width: 60%; + height: 50%; + } } [class$="-"], @@ -1801,6 +1810,10 @@ body.guides-template .guides-back-btn span.icon { body.guides-template main.without-full-width-hero .doc-detail-hero-image { border-radius: var(--image-border-radius-xxl); } + + body.blog-template img { + max-width: 90%; + } } @media screen and (min-width: 900px) { @@ -1878,6 +1891,10 @@ body.guides-template .guides-back-btn .icon-icon-arrow { brightness(94%) contrast(92%); } +body.blog-template aside { + display: none; +} + /* bumper template */ body.bumper-template { text-align: center;