Skip to content

Commit

Permalink
MWPW-135319 Init Tags Block (#15)
Browse files Browse the repository at this point in the history
* MWPW-135319 Init Tags Block

* taxonomyRoot

* pr

* early return
  • Loading branch information
meganthecoder authored Sep 13, 2023
1 parent 2c20931 commit 3fb4caa
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 3 deletions.
4 changes: 3 additions & 1 deletion scripts/scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* governing permissions and limitations under the License.
*/

import { setLibs } from './utils.js';
import { setLibs, buildAutoBlocks } from './utils.js';

// Add project-wide style path here.
const STYLES = '/styles/styles.css';
Expand Down Expand Up @@ -109,6 +109,7 @@ const CONFIG = {
// geoRouting: 'on',
productionDomain: 'business.adobe.com',
contentRoot: '/blog',
taxonomyRoot: '/tags',
};

// Load LCP image immediately
Expand Down Expand Up @@ -140,5 +141,6 @@ const miloLibs = setLibs(LIBS);
const { loadArea, setConfig } = await import(`${miloLibs}/utils/utils.js`);

setConfig({ ...CONFIG, miloLibs });
await buildAutoBlocks();
await loadArea();
}());
64 changes: 64 additions & 0 deletions scripts/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,67 @@ export const [setLibs, getLibs] = (() => {
* Edit above at your own risk.
* ------------------------------------------------------------
*/

/**
* Builds a block DOM Element from a two dimensional array
* @param {string} blockName name of the block
* @param {any} content two dimensional array or string or object of content
*/
function buildBlock(blockName, content) {
const table = Array.isArray(content) ? content : [[content]];
const blockEl = document.createElement('div');

blockEl.classList.add(blockName);
table.forEach((row) => {
const rowEl = document.createElement('div');
row.forEach((col) => {
const colEl = document.createElement('div');
const vals = col.elems || [col];
vals.forEach((val) => {
if (val) {
if (typeof val === 'string') {
colEl.innerHTML += val;
} else {
colEl.appendChild(val);
}
}
});
rowEl.appendChild(colEl);
});
blockEl.appendChild(rowEl);
});
return (blockEl);
}

function buildTagsBlock() {
const metadata = document.head.querySelectorAll('meta[property="article:tag"]');
if (!metadata.length) return;
const tagsArray = [...metadata].map((el) => el.content);
const tagsBlock = buildBlock('tags', tagsArray.join(', '));
const main = document.querySelector('main');
const recBlock = main.querySelector('.recommended-articles');
if (recBlock) {
// Put tags block before recommended articles block
if (recBlock.parentElement.childElementCount === 1) {
recBlock.parentElement.previousElementSibling.append(tagsBlock);
} else {
recBlock.before(tagsBlock);
}
} else {
main.lastElementChild.append(tagsBlock);
}
}

export async function buildAutoBlocks() {
const miloLibs = getLibs();
const { getMetadata } = await import(`${miloLibs}/utils/utils.js`);
const mainEl = document.querySelector('main');
try {
if (getMetadata('publication-date') && !mainEl.querySelector('.article-header')) {
buildTagsBlock(mainEl);
}
} catch (error) {
// eslint-disable-next-line no-console
console.error('Auto Blocking failed', error);
}
}
3 changes: 2 additions & 1 deletion styles/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ main p picture img {
font-size: var(--body-font-size-l);
}

main .section .content {
main .section .content,
main .section .tags {
max-width: var(--body-max-width);
margin-left: auto;
margin-right: auto;
Expand Down
6 changes: 6 additions & 0 deletions test/scripts/mocks/tagsBody.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<main>
<div>
<h1 id="connecting-external-data-sources-to-adobe-experience-manager-guides-is-now-a-breeze">Connecting external data sources to Adobe Experience Manager Guides is now a breeze</h1>
<p><em>Rohit Bansal is a principal product marketing manager at Adobe, leading global go-to-market strategy for Adobe Experience Manager Guides. With over 14 years of experience, Rohit has led marketing for product and services firms in the B2B domain — and managed key functions like product marketing, digital marketing, thought leadership, demand generation, and partner relations. A passionate data-driven marketer, he is also a big advocate of the customer experience.</em></p>
</div>
</main>
3 changes: 3 additions & 0 deletions test/scripts/mocks/tagsHead.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<meta name="publication-date" content="08-10-2023">
<meta property="article:tag" content="Customer Intelligence">
<meta property="article:tag" content="Customer Success">
15 changes: 15 additions & 0 deletions test/scripts/mocks/tagsWithRecBody.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<main>
<div>
<h1 id="customer-experience--what-it-is-why-its-important-and-how-to-deliver-it">Customer experience — what it is, why it’s important, and how to deliver it</h1>
<p><strong>See what Adobe Experience Cloud can do for you. <a href="https://business.adobe.com/request-consultation/experience-cloud.html">Request a demo</a> today.</strong></p>
<div class="recommended-articles">
<div>
<div>
<p><a href="https://business.adobe.com/blog/basics/ai-customer-experience">https://business.adobe.com/blog/basics/ai-customer-experience</a></p>
<p><a href="https://business.adobe.com/blog/how-to/cx-strategies">https://business.adobe.com/blog/how-to/cx-strategies</a></p>
<p><a href="https://business.adobe.com/blog/the-latest/creating-amazing-digital-experiences">https://business.adobe.com/blog/the-latest/creating-amazing-digital-experiences</a></p>
</div>
</div>
</div>
</div>
</main>
17 changes: 17 additions & 0 deletions test/scripts/mocks/tagsWithRecSectionBody.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<main>
<div class="before-rec">
<h1 id="customer-experience--what-it-is-why-its-important-and-how-to-deliver-it">Customer experience — what it is, why it’s important, and how to deliver it</h1>
<p><strong>See what Adobe Experience Cloud can do for you. <a href="https://business.adobe.com/request-consultation/experience-cloud.html">Request a demo</a> today.</strong></p>
</div>
<div>
<div class="recommended-articles">
<div>
<div>
<p><a href="https://business.adobe.com/blog/basics/ai-customer-experience">https://business.adobe.com/blog/basics/ai-customer-experience</a></p>
<p><a href="https://business.adobe.com/blog/how-to/cx-strategies">https://business.adobe.com/blog/how-to/cx-strategies</a></p>
<p><a href="https://business.adobe.com/blog/the-latest/creating-amazing-digital-experiences">https://business.adobe.com/blog/the-latest/creating-amazing-digital-experiences</a></p>
</div>
</div>
</div>
</div>
</main>
48 changes: 47 additions & 1 deletion test/scripts/utils.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { expect } from '@esm-bundle/chai';
import { setLibs } from '../../scripts/utils.js';
import { readFile } from '@web/test-runner-commands';
import sinon from 'sinon';
import { setLibs, buildAutoBlocks } from '../../scripts/utils.js';

describe('Libs', () => {
it('Default Libs', () => {
Expand Down Expand Up @@ -43,3 +45,47 @@ describe('Libs', () => {
expect(libs).to.equal('https://awesome--milo--forkedowner.hlx.live/libs');
});
});

const metadata = await readFile({ path: './mocks/tagsHead.html' });

describe('Auto Blocks', () => {
before(() => {
setLibs('/libs');
});

beforeEach(() => {
sinon.stub(console, 'error');
});

afterEach(() => {
console.error.restore();
});

it('catches errors', async () => {
document.head.innerHTML = metadata;
document.body.innerHTML = '';
await buildAutoBlocks();
expect(console.error.calledWith('Auto Blocking failed')).to.be.true;
});

it('builds the tags block', async () => {
document.head.innerHTML = metadata;
document.body.innerHTML = await readFile({ path: './mocks/tagsBody.html' });
await buildAutoBlocks();
expect(document.querySelector('.tags')).to.exist;
});

it('inserts the tags block before recommended articles if present', async () => {
document.head.innerHTML = metadata;
document.body.innerHTML = await readFile({ path: './mocks/tagsWithRecBody.html' });
await buildAutoBlocks();
expect(document.querySelector('.tags + .recommended-articles')).to.exist;
});

it('inserts the tags block in section before recommended articles if present', async () => {
document.head.innerHTML = metadata;
document.body.innerHTML = await readFile({ path: './mocks/tagsWithRecSectionBody.html' });
await buildAutoBlocks();
expect(document.querySelector('.before-rec .tags')).to.exist;
});
});

0 comments on commit 3fb4caa

Please sign in to comment.