Jump to content

Widget:UPDEvents: Difference between revisions

From Iskomunidad
No edit summary
No edit summary
 
(10 intermediate revisions by the same user not shown)
Line 1: Line 1:
<includeonly>
<includeonly>
<div id="upd-events-widget">
<div id="upd-events-widget" class="upd-events-widget">
   <div class="upd-events-loading">Loading upcoming events...</div>
   <div class="upd-events-loading">Loading upcoming events...</div>
   <ul class="upd-events-list" style="display:none;"></ul>
   <ul class="upd-events-list" style="display:none;"></ul>
</div>
</div>
<style>
.upd-events-widget {
  color: #000;
  font-size: 15px;
}
.upd-events-list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.upd-events-list li {
  margin: 0;
  padding: 10px 0;
  border-bottom: 1px solid #e5e5e5;
}
.upd-events-list li:last-child {
  border-bottom: none;
}
.upd-events-list a {
  color: #0E6021 !important;
  text-decoration: none;
  font-weight: 600;
}
.upd-events-list a:hover {
  text-decoration: underline;
}
.upd-events-loading,
.upd-events-empty {
  color: #555;
  font-size: 14px;
}
</style>


<script>
<script>
(function () {
(function () {
   var container = document.getElementById('upd-events-widget');
   var container = document.getElementById('upd-events-widget');
   if (!container || container.dataset.loaded === '1') return;
 
   if (!container || container.dataset.loaded === '1') {
    return;
  }
 
   container.dataset.loaded = '1';
   container.dataset.loaded = '1';


Line 14: Line 51:
   var list = container.querySelector('.upd-events-list');
   var list = container.querySelector('.upd-events-list');


   var feedUrl = 'https://upd.edu.ph/events-list/?ical=1';
  loading.textContent =
    'Widget JavaScript is running. Requesting UP Diliman...';
 
   var endpoint = new URL(
    'https://upd.edu.ph/wp-admin/admin-ajax.php'
  );
 
  var params = {
    action: 'search_events',
    id: '1',
    scope: 'future',
    orderby: 'event_start_date,event_start_time,event_name',
    view: 'list-grouped',
    pno: '1'
  };
 
  Object.keys(params).forEach(function (key) {
    endpoint.searchParams.set(key, params[key]);
  });


   function decodeICS(value) {
   var finished = false;
    return value
      .replace(/\\n/gi, '\n')
      .replace(/\\,/g, ',')
      .replace(/\\;/g, ';')
      .replace(/\\\\/g, '\\');
  }


   function parseDate(value) {
   var timeout = setTimeout(function () {
     if (!value) return null;
     if (finished) return;


     // All-day event: DTSTART;VALUE=DATE:20261106
     finished = true;
     if (/^\d{8}$/.test(value)) {
     loading.textContent =
       return new Date(
       'The UP Diliman request timed out or is blocked.';
        Date.UTC(
  }, 10000);
          Number(value.slice(0, 4)),
          Number(value.slice(4, 6)) - 1,
          Number(value.slice(6, 8))
        )
      );
    }


    // UTC date-time ending in Z
  fetch(endpoint.toString(), {
    if (/^\d{8}T\d{6}Z$/.test(value)) {
    method: 'GET',
      return new Date(
    mode: 'cors',
        value.slice(0, 4) + '-' +
    credentials: 'omit'
        value.slice(4, 6) + '-' +
  })
        value.slice(6, 8) + 'T' +
  .then(function (response) {
        value.slice(9, 11) + ':' +
    if (finished) return null;
        value.slice(11, 13) + ':' +
        value.slice(13, 15) + 'Z'
      );
    }


    // Date-time without Z: interpret as Philippine local time
     if (!response.ok) {
     if (/^\d{8}T\d{6}$/.test(value)) {
       throw new Error('HTTP ' + response.status);
       return new Date(
        value.slice(0, 4) + '-' +
        value.slice(4, 6) + '-' +
        value.slice(6, 8) + 'T' +
        value.slice(9, 11) + ':' +
        value.slice(11, 13) + ':' +
        value.slice(13, 15) + '+08:00'
      );
     }
     }


     return null;
     return response.text();
   }
   })
  .then(function (html) {
    if (finished || html === null) return;


  function showError() {
     finished = true;
     loading.textContent =
     clearTimeout(timeout);
      'Upcoming events could not be loaded. Please visit the UP Diliman Events page.';
     var link = document.createElement('a');
    link.href = 'https://upd.edu.ph/events-list/';
    link.textContent = ' View all events';
    link.target = '_blank';
    link.rel = 'noopener noreferrer';
    loading.appendChild(link);
  }


  fetch(feedUrl)
     var doc = new DOMParser().parseFromString(html, 'text/html');
     .then(function (response) {
      if (!response.ok) throw new Error('Calendar feed unavailable');
      return response.text();
    })
    .then(function (ics) {
      // Join folded iCalendar lines.
      ics = ics.replace(/\r?\n[ \t]/g, '');


      var blocks = ics.match(/BEGIN:VEVENT[\s\S]*?END:VEVENT/g) || [];
    var anchors = doc.querySelectorAll(
       var now = new Date();
      '#em-events-list-grouped-1 a[href*="/events/"], ' +
      var events = [];
       '.em-events-list a[href*="/events/"]'
      var seen = {};
    );


      blocks.forEach(function (block) {
    var seen = new Set();
        var startMatch = block.match(/^DTSTART(?:;[^:]*)?:(.+)$/m);
    var events = [];
        var titleMatch = block.match(/^SUMMARY(?:;[^:]*)?:(.+)$/m);
        var urlMatch = block.match(/^URL(?:;[^:]*)?:(.+)$/m);


        if (!startMatch || !titleMatch || !urlMatch) return;
    anchors.forEach(function (anchor) {
      var heading = anchor.querySelector('h4');
      if (!heading) return;


        var start = parseDate(startMatch[1].trim());
      var title = heading.textContent.trim();
        var title = decodeICS(titleMatch[1].trim());
      var url;
        var url = urlMatch[1].trim();


         if (!start || start <= now) return;
      try {
        if (!/^https:\/\/upd\.edu\.ph\/events\//i.test(url)) return;
         url = new URL(
          anchor.getAttribute('href'),
          'https://upd.edu.ph'
        ).href;
      } catch (e) {
        return;
      }


        // Keep only the nearest upcoming occurrence of each event page.
      if (!title || seen.has(url)) return;
        var key = url + '|' + title.toLowerCase();
        if (seen[key]) return;
        seen[key] = true;


        events.push({
      if (!/^https:\/\/upd\.edu\.ph\/events\//i.test(url)) {
          title: title,
         return;
          url: url,
       }
          start: start
         });
       });


       events.sort(function (a, b) {
      seen.add(url);
         return a.start - b.start;
       events.push({
        title: title,
         url: url
       });
       });
    });


      events = events.slice(0, 5);
    list.replaceChildren();


      if (!events.length) {
    if (events.length === 0) {
        loading.textContent = 'There are no upcoming events at this time.';
      loading.textContent =
        return;
        'The request succeeded, but no event titles were found.';
      }


       events.forEach(function (event) {
       return;
        var item = document.createElement('li');
    }
        var link = document.createElement('a');


        link.href = event.url;
    events.slice(0, 5).forEach(function (event) {
        link.textContent = event.title;
      var li = document.createElement('li');
        link.target = '_blank';
      var a = document.createElement('a');
        link.rel = 'noopener noreferrer';


        item.appendChild(link);
      a.href = event.url;
        list.appendChild(item);
      a.textContent = event.title;
       });
       a.target = '_blank';
      a.rel = 'noopener noreferrer';


       loading.style.display = 'none';
       li.appendChild(a);
       list.style.display = 'block';
       list.appendChild(li);
    })
    .catch(function (error) {
      console.error('UP Diliman Events widget:', error);
      showError();
     });
     });
    loading.style.display = 'none';
    list.style.display = 'block';
  })
  .catch(function (error) {
    if (finished) return;
    finished = true;
    clearTimeout(timeout);
    console.error('UPEvents widget error:', error);
    loading.textContent =
      'Request failed: ' +
      error.name + ' — ' + error.message;
  });
})();
})();
</script>
</script>
</includeonly>
</includeonly>

Latest revision as of 03:24, 29 October 2026