#113 - RSS Feeds v0.2
Use a Webflow UI to display an RSS feed directly on your Website.
<!-- 💙 MEMBERSCRIPT #113 v0.2 💙 - RSS FEEDS IN WEBFLOW -->
<script>
(function() {
// console.log('RSS Feed Script starting...');
const CORS_PROXIES = [
'https://corsproxy.io/?',
'https://api.allorigins.win/raw?url=',
'https://cors-anywhere.herokuapp.com/',
'https://thingproxy.freeboard.io/fetch/',
'https://yacdn.org/proxy/'
];
function loadScript(src, onLoad, onError) {
const script = document.createElement('script');
script.src = src;
script.onload = onLoad;
script.onerror = onError;
document.head.appendChild(script);
}
async function fetchWithFallback(url) {
for (const proxy of CORS_PROXIES) {
try {
const response = await fetch(proxy + encodeURIComponent(url));
if (response.ok) {
return await response.text();
}
} catch (error) {
console.warn(`Failed to fetch with proxy ${proxy}:`, error);
}
}
throw new Error('All CORS proxies failed');
}
function initRSSFeed() {
if (typeof RSSParser === 'undefined') {
console.error('RSSParser is not defined.');
return;
}
const parser = new RSSParser({
customFields: {
item: [
['media:content', 'mediaContent', {keepArray: true}],
['media:thumbnail', 'mediaThumbnail', {keepArray: true}],
['enclosure', 'enclosure', {keepArray: true}],
]
}
});
document.querySelectorAll('[ms-code-rss-feed]').forEach(element => {
const url = element.getAttribute('ms-code-rss-url');
const limit = parseInt(element.getAttribute('ms-code-rss-limit')) || 5;
fetchWithFallback(url)
.then(str => parser.parseString(str))
.then(feed => {
renderRSSItems(element, feed.items.slice(0, limit), {
showImage: element.getAttribute('ms-code-rss-show-image') !== 'false',
showDate: element.getAttribute('ms-code-rss-show-date') !== 'false',
dateFormat: element.getAttribute('ms-code-rss-date-format') || 'short',
target: element.getAttribute('ms-code-rss-target') || '_self'
});
})
.catch(err => {
console.error('Error fetching or parsing RSS feed:', err);
element.textContent = `Failed to load RSS feed from ${url}. Error: ${err.message}`;
});
});
}
function renderRSSItems(element, items, options) {
const templateItem = element.querySelector('[ms-code-rss-item]');
if (!templateItem) return;
element.innerHTML = ''; // Clear existing items
items.forEach(item => {
const itemElement = templateItem.cloneNode(true);
const title = itemElement.querySelector('[ms-code-rss-title]');
if (title) {
const titleLength = parseInt(title.getAttribute('ms-code-rss-title-length')) || Infinity;
title.textContent = truncate(item.title, titleLength);
}
const description = itemElement.querySelector('[ms-code-rss-description]');
if (description) {
const descriptionLength = parseInt(description.getAttribute('ms-code-rss-description-length')) || Infinity;
description.textContent = truncate(stripHtml(item.content || item.description), descriptionLength);
}
const date = itemElement.querySelector('[ms-code-rss-date]');
if (date && options.showDate && item.pubDate) {
date.textContent = formatDate(new Date(item.pubDate), options.dateFormat);
}
const img = itemElement.querySelector('[ms-code-rss-image]');
if (img && options.showImage) {
const imgUrl = getImageUrl(item);
if (imgUrl) {
img.src = imgUrl;
img.alt = item.title;
img.removeAttribute('srcset');
}
}
const linkElement = itemElement.querySelector('[ms-code-rss-link]');
if (linkElement) {
linkElement.setAttribute('href', item.link);
linkElement.setAttribute('target', options.target);
}
element.appendChild(itemElement);
});
}
function getImageUrl(item) {
const sources = ['mediaContent', 'mediaThumbnail', 'enclosure'];
for (let source of sources) {
if (item[source] && item[source][0]) {
return item[source][0].$ ? item[source][0].$.url : item[source][0].url;
}
}
return null;
}
function truncate(str, length) {
if (!str) return '';
if (length === Infinity) return str;
return str.length > length ? str.slice(0, length) + '...' : str;
}
function stripHtml(html) {
const tmp = document.createElement('DIV');
tmp.innerHTML = html || '';
return tmp.textContent || tmp.innerText || '';
}
function formatDate(date, format) {
if (!(date instanceof Date) || isNaN(date)) return '';
const options = format === 'long' ?
{ weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' } :
undefined;
return format === 'relative' ? getRelativeTimeString(date) : date.toLocaleDateString(undefined, options);
}
function getRelativeTimeString(date, lang = navigator.language) {
const timeMs = date.getTime();
const deltaSeconds = Math.round((timeMs - Date.now()) / 1000);
const cutoffs = [60, 3600, 86400, 86400 * 7, 86400 * 30, 86400 * 365, Infinity];
const units = ['second', 'minute', 'hour', 'day', 'week', 'month', 'year'];
const unitIndex = cutoffs.findIndex(cutoff => cutoff > Math.abs(deltaSeconds));
const divisor = unitIndex ? cutoffs[unitIndex - 1] : 1;
const rtf = new Intl.RelativeTimeFormat(lang, { numeric: 'auto' });
return rtf.format(Math.floor(deltaSeconds / divisor), units[unitIndex]);
}
loadScript('https://cdn.jsdelivr.net/npm/rss-parser@3.12.0/dist/rss-parser.min.js', initRSSFeed, () => {
console.error('Error loading RSS Parser script');
loadScript('https://unpkg.com/rss-parser@3.12.0/dist/rss-parser.min.js', initRSSFeed, () => {
console.error('Error loading RSS Parser script from backup CDN');
});
});
})();
</script>
Erstellen des Make.com-Szenarios
1. Laden Sie den JSON-Blaupause unten, um angegeben zu bekommen.
2. Navigieren Sie zu Make.com und erstellen Sie ein neues Szenario...
3. Klicken Sie auf das kleine Kästchen mit den 3 Punkten und dann auf Blaupause importieren...
4. Laden Sie Ihre Datei hoch und voila! Sie sind bereit, Ihre eigenen Konten zu verknüpfen.
Brauchen Sie Hilfe mit diesem MemberScript?
Alle Memberstack-Kunden können im 2.0 Slack um Unterstützung bitten. Bitte beachten Sie, dass dies keine offiziellen Funktionen sind und der Support nicht garantiert werden kann.
Treten Sie dem 2.0 Slack beiv0.2 - CORS Proxy Rotation
Changed the script to try multiple different CORS proxies if one fails or is slow.
Autorisierung und Zahlungen für Webflow-Websites
Fügen Sie Ihrer Webflow-Website Logins, Abonnements, Gated Content und vieles mehr hinzu - einfach und vollständig anpassbar.