Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Newsletters: New Newsletter List Block and Newsletter Archive. Summary field added to Newsletter: Email #1476

Merged
merged 10 commits into from
Nov 19, 2024
8 changes: 8 additions & 0 deletions boulder_base.libraries.yml
Original file line number Diff line number Diff line change
Expand Up @@ -525,3 +525,11 @@ colorbox-image:
css/block/image-gallery.css: {}
css/colorbox-image.css: {}
js/glightbox/glightbox.min.css: {}

ucb-newsletter-list-block:
version: 1.x
js:
js/ucb-newsletter-list-block.js: {}
css:
theme:
css/block/ucb-newsletter-list-block.css: {}
14 changes: 14 additions & 0 deletions css/block/ucb-newsletter-list-block.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.ucb-newsletter-list-text{
font-weight: bold;
margin-bottom: 0px;
}

.ucb-newsletter-row{
margin-bottom: 20px;
border-bottom: 1px solid rgba(128, 128, 128, 0.333);
padding-bottom: 20px;
}

.ucb-newsletter-list-summary{
margin-bottom: 0px;
}
20 changes: 20 additions & 0 deletions css/ucb-taxonomy-page.css
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,23 @@
.feed-icon {
display: none;
}


.ucb-newsletter-list-text{
font-weight: bold;
margin-bottom: 0px;
}

.ucb-newsletter-row{
margin-bottom: 20px;
border-bottom: 1px solid rgba(128, 128, 128, 0.333);
padding-bottom: 20px;
}

.ucb-newsletter-list-summary{
margin-bottom: 0px;
}

.ucb-newsletter-row .row p{
margin-bottom: 0;
}
170 changes: 170 additions & 0 deletions js/ucb-newsletter-list-block.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
(function (customElements) {
class NewsletterListElement extends HTMLElement {
constructor() {
super();
this._baseURI = this.getAttribute('baseURI');
this.count = parseInt(this.getAttribute('count'));
this.newsletterType = this.getAttribute('newsletter-type');
this.taxonomyMap;
this.taxonomyName;
// Fetch taxonomy terms to build the map first
fetch(`${this._baseURI}/jsonapi/taxonomy_term/newsletter`)
.then(response => {
if (!response.ok) throw new Error("Network response was not ok");
return response.json();
})
.then(data => {
// Create the ID-to-name map
this.taxonomyMap = data.data.reduce((map, term) => {
map[term.id] = term.attributes.name;
return map;
}, {});

// Now that the taxonomyMap is ready, fetch newsletters
this.fetchNewsletters();
})
.catch(error => {
console.log("Failed to fetch taxonomy terms:", error);
});
}

fetchNewsletters() {
const publishedParams = '&filter[published][group][conjunction]=AND'
+ '&filter[publish-check][condition][path]=status'
+ '&filter[publish-check][condition][value]=1'
+ '&filter[publish-check][condition][memberOf]=published';

fetch(`${this._baseURI}/jsonapi/node/newsletter?include=field_newsletter_section_block.field_newsletter_section_select.field_newsletter_article_select${publishedParams}&filter[field_newsletter_type.meta.drupal_internal__target_id][value]=${this.newsletterType}&sort=-created`)
.then(this.handleError)
.then((data) => this.build(data, this.count))
.catch(error => {
console.log(error);
});
}

handleError = response => {
if (!response.ok) {
throw new Error("Network response was not ok");
} else {
return response.json();
}
};

// Traverses through nested paragraphs to grab the first one Newsletter -> First Section -> First Newsletter Article or First Newsletter Content. If first article -> get the article
build(data, count) {
const newsletters = data["data"];
const references = data["included"];
const newsletterElements = []; // Array to hold newsletter elements

// Loop through newsletters up to the specified count
for (let i = 0; i < Math.min(newsletters.length, count); i++) {
const newsletter = newsletters[i];
const newsletterTitle = newsletter.attributes.title;

// Get the path using taxonomy and title
const taxonomyId = newsletter.relationships.field_newsletter_type?.data.id;
this.taxonomyName = this.taxonomyMap[taxonomyId];
const path = newsletter.attributes.path.alias
? newsletter.attributes.path.alias
: `/node/${newsletter.attributes.drupal_internal__nid}`;

// Check for a summary field in the newsletter
let summary = newsletter.attributes.field_newsletter_summary;
// If no summary is present, fall back to content processing
if (!summary) {
const sectionBlockRef = newsletter.relationships.field_newsletter_section_block?.data[0];
if (sectionBlockRef) {
const sectionBlock = references.find(
ref => ref.id === sectionBlockRef.id && ref.type === 'paragraph--newsletter_section'
);

if (sectionBlock) {
// Access the array of section items in the section block
const sectionSelectRefs = sectionBlock.relationships?.field_newsletter_section_select?.data;

if (sectionSelectRefs && sectionSelectRefs.length > 0) {
// Loop through section items and find the first valid content
for (const sectionSelectRef of sectionSelectRefs) {
const sectionContent = references.find(ref => ref.id === sectionSelectRef.id);

if (sectionContent) {
// Check if the section content is a paragraph or article and get the title
if (sectionContent.type === 'paragraph--newsletter_section_content') {
summary = sectionContent.attributes.field_newsletter_content_title;
} else if (sectionContent.type === 'paragraph--newsletter_section_article') {
const articleRef = sectionContent.relationships?.field_newsletter_article_select?.data;

if (articleRef) {
const article = references.find(
ref => ref.id === articleRef.id && ref.type === 'node--ucb_article'
);
if (article) {
summary = article.attributes.title;
}
}
}

// Exit the loop once a valid summary is found
if (summary) {
break;
}
}
}
}
}
}
}

// Store the newsletter information
newsletterElements.push({ title: newsletterTitle, summary, path });
}

// Build DOM elements for each newsletter
this.renderNewsletters(newsletterElements);
this.renderButton(this.taxonomyName);
}


// This will create the Newsletter Rows
renderNewsletters(newsletterElements) {
newsletterElements.forEach(newsletter => {
const newsletterElement = document.createElement('div');
newsletterElement.classList.add('ucb-newsletter-row');

const linkElement = document.createElement('a');
linkElement.href = newsletter.path;
linkElement.classList.add('ucb-newsletter-list-link');


const titleElement = document.createElement('p');
titleElement.textContent = newsletter.title;
titleElement.classList.add('ucb-newsletter-list-text');

linkElement.appendChild(titleElement);

const summaryElement = document.createElement('p');
summaryElement.textContent = newsletter.summary;
summaryElement.classList.add('ucb-newsletter-list-summary');

newsletterElement.appendChild(linkElement);
newsletterElement.appendChild(summaryElement);
this.appendChild(newsletterElement);
});
}

// This will create the Archive Link
renderButton(taxonomyName){
const buttonElement = document.createElement('a');
const urlName = taxonomyName
.toLowerCase() // lower
.replace(/[^\w\s-]/g, '') // remove special chars
.replace(/\s+/g, '-'); // spaces => -
buttonElement.href = `${this._baseURI}/newsletter/${urlName}`;
buttonElement.innerText = `${taxonomyName} Archive`;
this.appendChild(buttonElement);
}
}

customElements.define('ucb-newsletter-list', NewsletterListElement);

})(window.customElements);
23 changes: 23 additions & 0 deletions templates/block/block--ucb-newsletter-list-block.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{% set classes = [
'block',
'container',
'block-' ~ configuration.provider|clean_class,
'block-' ~ plugin_id|clean_class,
bundle ? 'block--type-' ~ bundle|clean_class,
view_mode ? 'block--view-mode-' ~ view_mode|clean_class,
] %}

{% extends '@boulder_base/block/styled-block.html.twig' %}

{% set baseurlJSON = url('<front>')|render|trim('/') %}

{% block content %}
{{ attach_library('boulder_base/ucb-newsletter-list-block') }}
{{ content.body }}
<ucb-newsletter-list
baseURI="{{baseurlJSON}}"
count="{{content.field_ucb_newsletter_list_count|render|striptags|trim}}"
newsletter-type="{{content.field_select_newsletter_lis_type|render|striptags|trim}}"
>
</ucb-newsletter-list>
{% endblock %}
17 changes: 17 additions & 0 deletions templates/content/node--newsletter--email-html.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -341,11 +341,28 @@ h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6 {
display: block;
}
}
/* Preheader Style -- this appears after the subject line */
.preheader{
display: none !important;
visibility: hidden;
opacity: 0;
height: 0;
width: 0;
}
</style>
</head>
{# END VARIABLE TESTS #}
{# BIG Wrapper #}
<div id="email" style="align-items:center;{{emailBackground}}">
<!--PRE-HEADER TEXT-->
{% if node.field_newsletter_summary.value %}
<span
style="display: none !important;visibility: hidden;opacity: 0;height: 0;width: 0;"
class="preheader">
{{ node.field_newsletter_summary.value }}
</span>
{% endif %}
<div id="ucb-email-body" style="margin: auto;{{divStyles}}" data-url="{{base_url}}">
{# HEADER -- to do: might need to be different tables for styling purposes #}
<!-- Header -->
Expand Down