Source: dist/extras/cms-pagelist/init.js

/**
 * Extra - CMS Pagelist
 *
 * Provide a block of content from a collection, eg: a list of blog posts or a list of authors.
 *
 * @module Extras/CMS-Pagelist
 * @license The MIT License (MIT)
 * @copyright (c) 2025 eVAL Agency
 * @author Charlie Powell
 * @see https://markdownmaster.com/docs/extras/cms-pagelist.html
 * @since 3.0.0
 */

/**
 * Provides `<cms-pagelist>` tag functionality.
 */
class CMSPagelistElement extends HTMLElement {
	constructor() {
		// Always call super first in constructor
		super();
	}

	/**
	 * Called when the element is added to the DOM.
	 */
	connectedCallback() {
		this.render();
	}

	/**
	 * Execute the plugin on a given node to render the requested content inside it
	 */
	render() {
		let type = this.getAttribute('type'),
			layout = this.getAttribute('layout'),
			sort = this.getAttribute('sort'),
			limit = this.getAttribute('limit'),
			filters = {},
			has_filters = false,
			collection;

		if (type === null) {
			this.innerHTML = 'ERROR: No type specified';
			return;
		}

		collection = window.CMS.getCollection(type);
		if (collection === null) {
			CMS.log.Error('cms-pagelist', 'Collection ' + collection + ' not located in CMS');
			this.parentElement.removeChild(this);
			return;
		}

		// To allow the user to specify multiple attributes for the same field,
		// ie: author = ['bob', 'alice']
		for (let i = 0; i < this.attributes.length; i++) {
			let ak = this.attributes[i].name, av = this.attributes[i].value;
			if (ak.indexOf('filter-') === 0) {
				// Starts with "filter-..., denotes a filter to add to the query"
				// Trim the prefix, so we have just the field the user is filtering
				ak = ak.replace(/^filter-/, '');
				has_filters = true;

				if (av.indexOf(',') !== -1) {
					// Value contains a comma, split into an array
					filters[ak] = [];
					av.split(',').forEach(v => {
						if (v.trim() !== '') {
							filters[ak].push(v.trim());
						}
					});
				}
				else {
					filters[ak] = av;
				}
			}
		}

		if (layout === null) {
			// Default for this collection
			layout = collection.layout.list;
		}

		// Reset any filters previously set on this collection
		collection.resetFilters();

		// User-request sort and filter parameters
		if (sort !== null) {
			collection.filterSort(sort);
		}
		if (has_filters) {
			collection.filterAttributeSearch(filters);
		}
		if (limit !== null) {
			collection.paginate(parseInt(limit), 1);
		}

		window.CMS.fetchLayout(layout, collection)
			.then(html => {
				this.innerHTML = html;
			})
			.catch(error => {
				console.error('Unable to render <cms-pagelist> template [' + layout + ']', error);
			});
	}
}

customElements.define('cms-pagelist', CMSPagelistElement);