UNPKG

@skhemata/skhemata-blog

Version:

Skhemata Blog Web Component. This web component provides several sub components in addition to main component, allowing featured blogs, blog listing and blog post display.

223 lines (222 loc) 8.7 kB
/* eslint-disable lit-a11y/anchor-is-valid */ /** * * Lit Blog List Element * * */ import { __decorate } from "tslib"; // Import litelement base class, html helper function & typescript decorators import { SkhemataBase, html, property } from '@skhemata/skhemata-base'; // Import custom style elements import { faUser, faCalendarAlt } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@riovir/wc-fontawesome'; import { stringToHtml } from '@skhemata/skhemata-base/dist/directives/stringToHtml'; import { decodeHtmlEntities } from '@skhemata/skhemata-base/dist/directives/decodeHtmlEntities'; import { SkhemataBlogFeaturedStyle } from '../style/SkhemataBlogFeaturedStyle'; import { SkhemataBlogSharedStyle } from '../style/SkhemataBlogSharedStyle'; import { translationEngDefault } from '../translation/SkhemataBlogFeatured/eng'; // Import custom element directives // Import element dependencies import './SkhemataBlogSearch'; export class SkhemataBlogFeatured extends SkhemataBase { constructor() { // Always call super() first super(); // Property decorator (requires TypeScript or Babel) // Attributes that can be passed into different elements this.apiWordpress = { url: '' }; this.blogPagePath = ''; this.postsPerPage = 3; this.searchedBlogPosts = ''; this.blogPosts = []; this.totalPages = 0; this.totalCount = 0; this.translationData = { eng: translationEngDefault, }; this.formatDate = (date) => { const dateObj = new Date(date); const month = new Intl.DateTimeFormat('en-US', { month: 'short' }).format(dateObj); return `${month} ${dateObj.getDate()} ${dateObj.getFullYear()}`; }; window.addEventListener('hashchange', () => { this.getPosts(); }, false); } static get styles() { return [ ...super.styles, SkhemataBlogFeaturedStyle, SkhemataBlogSharedStyle, ]; } static get scopedElements() { return { 'fa-icon': FontAwesomeIcon, }; } navigate(slug) { this.dispatchEvent(new CustomEvent('navigate', { detail: { slug, }, })); } /** * Implement `render` to define a template for your element. * Use JS template literals */ render() { return html ` <div class="blog-list"> ${this.blogPosts.map((post) => html ` <div class="blog-item card"> <button class="featured" @click=${() => this.navigate(post.slug)}> <div class="card-content"> ${post._embedded['wp:featuredmedia'] ? html ` <figure class="image feature-img"> <img src="${post._embedded['wp:featuredmedia']['0'] .source_url}" alt="featured" /> </figure> ` : null} <div class="article-title-container p-lr"> <h2 class="blog-title title is-5 article-title"> ${decodeHtmlEntities(post.title.rendered)} </h2> </div> <div class="article-info p-lr"> <div class="article-author"> <fa-icon style="margin-right: 0.5rem;" .icon=${faUser} ></fa-icon> ${post._embedded.author['0'].name} </div> <div class="article-date"> <fa-icon style="margin-right: 0.5rem;" .icon=${faCalendarAlt} ></fa-icon> ${this.formatDate(post.date)} </div> </div> <div class="article-description p-lr"> ${post.excerpt.rendered.length > 250 ? stringToHtml(`${post.excerpt.rendered.substring(0, 200)}...`) : stringToHtml(post.excerpt.rendered.substring(0, 200))} </div> <div class="article-read-more"> <a class="has-text title is-6"> ${this.getStr('SkhemataBlogFeatured.readMore')} </a> </div> </div> </button> </div> `)} </div> `; } /** * Implement firstUpdated to perform one-time work after * the element’s template has been created. */ async firstUpdated() { await super.firstUpdated(); this.getPosts(); } /** * Fetch Posts from WP REST API */ getPosts() { // Use fetch method to make a request // https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch const params = new URLSearchParams(window.location.search); const search = params.get('s'); let searchParams = ''; let categoryParams = ''; if (search && search.length > 3) { searchParams = `&search=${search}`; } fetch(`${this.apiWordpress.url}/categories/?search=featured-article`) .then(response => { this.totalPages = Number(response.headers.get('X-WP-TotalPages')); this.totalCount = Number(response.headers.get('X-WP-Total')); const contentType = response.headers.get('Content-Type'); // Check if response header content type is json if (contentType && contentType.includes('application/json')) { return response.json(); } // Throw error if above condition isn't met throw new TypeError('The format is not JSON.'); }) .then(categories => { categoryParams = `&categories=${categories[0].id}`; fetch(`${this.apiWordpress.url}/posts?_embed${searchParams}${categoryParams}&per_page=${this.postsPerPage}`) .then(response => { this.totalPages = Number(response.headers.get('X-WP-TotalPages')); this.totalCount = Number(response.headers.get('X-WP-Total')); const contentType = response.headers.get('Content-Type'); // Check if response header content type is json if (contentType && contentType.includes('application/json')) { return response.json(); } // Throw error if above condition isn't met throw new TypeError('The format is not JSON.'); }) .then(data => { if (typeof data !== 'undefined') { // Loop through data // data.forEach((element: any) => // SkhemataBlogFeatured.formatCategories(element) // ); this.blogPosts = data.map(SkhemataBlogFeatured.formatCategories); } }); }); } /** * Format wp categories */ static formatCategories(data) { // Filter out all the categories of the post const formattedData = data; if (data && data._embedded) { const filteredCategories = data._embedded['wp:term'].filter((term, index) => term.length > 0 ? term[index].taxonomy === 'category' : false); [formattedData.categories] = filteredCategories; } return formattedData; } } __decorate([ property({ type: Object, attribute: 'api-wordpress' }) ], SkhemataBlogFeatured.prototype, "apiWordpress", void 0); __decorate([ property({ type: String, attribute: 'blog-page-path' }) ], SkhemataBlogFeatured.prototype, "blogPagePath", void 0); __decorate([ property({ type: Number, attribute: 'posts-per-page' }) ], SkhemataBlogFeatured.prototype, "postsPerPage", void 0); __decorate([ property({ type: String }) ], SkhemataBlogFeatured.prototype, "searchedBlogPosts", void 0); __decorate([ property({ type: Array }) ], SkhemataBlogFeatured.prototype, "blogPosts", void 0); __decorate([ property({ type: Number }) ], SkhemataBlogFeatured.prototype, "totalPages", void 0); __decorate([ property({ type: Number }) ], SkhemataBlogFeatured.prototype, "totalCount", void 0); __decorate([ property({ type: Object }) ], SkhemataBlogFeatured.prototype, "translationData", void 0); //# sourceMappingURL=SkhemataBlogFeatured.js.map