#113 - RSS Feeds v0.1

Use a Webflow UI to display an RSS feed directly on your Website.

View demo project
Voir la démo

<!-- 💙 MEMBERSCRIPT #113 v0.1 💙 - RSS FEEDS IN WEBFLOW -->
<script>
  (function() {
    console.log('RSS Feed Script starting...');

    const CORS_PROXY = 'https://cors-anywhere.herokuapp.com/';

    function loadScript(src, onLoad, onError) {
      const script = document.createElement('script');
      script.src = src;
      script.onload = onLoad;
      script.onerror = onError;
      document.head.appendChild(script);
    }

    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;

        parser.parseURL(CORS_PROXY + url, (err, feed) => {
          if (err) {
            console.error('Error parsing RSS feed:', err);
            element.textContent = `Failed to load RSS feed from ${url}. Error: ${err.message}`;
          } else {
            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'
            });
          }
        });
      });
    }

    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);
        }

        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>

Création du scénario Make.com

1. Téléchargez le modèle JSON ci-dessous pour commencer.

2. Naviguez jusqu'à Make.com et créez un nouveau scénario...

3. Cliquez sur la petite boîte avec trois points, puis sur Import Blueprint...

4. Téléchargez votre fichier et voilà ! Vous êtes prêt à relier vos propres comptes.

Besoin d'aide avec ce MemberScript ?

All Memberstack customers can ask for assistance in the 2.0 Slack. Please note that these are not official features and support cannot be guaranteed.

Join the 2.0 Slack
Version notes
Attributs
Description
Attribut
Aucun élément n'a été trouvé.
Tutorial