HTML Widget for RSS Feeds
I have successfully embedded a live RSS feed on the homepage using a custom HTML widget.
Our Vision is to have the Widget to disappear when there is no content in the RSS Feed, and display the contents when an announcement is entered - so it automatically appears when someone enters anRSS feed altert. The good news is, AI helped me write the code to successfully implement this. See pictures below.
You'll notice the yellow alert at the top of the page. It lines up perfectly with the widget on the right.
However, when there is no content in the feed, the widget successfully shrinks but a small space is consumed pushing down the widget by one space. It's not very noticeable, but I'd like to get rid of it completely when no RSS Alert is available.
So, using AI I got this code created.
<!DOCTYPE html>
<html><head>
<meta charset="utf-8">
<title>Campus Alerts</title>
<style>
html, body {
margin: 0 !important;
padding: 0 !important;
background-color: transparent !important;
font-family: Lato, sans-serif;
}
#alert-container {
background-color: #FFF9C4;
padding: 14px 16px;
border-radius: 10px;
box-shadow: 0 2px 6px rgba(0,0,0,0.12);
font-size: 0.95rem;
color: #202122;
max-height: 250px;
overflow-y: auto;
margin: -8px 0 -16px !important;
}
.alert-title { font-weight: bold; color: #b30000; margin-bottom: 6px; font-size: 1.1em; }
.alert-desc { margin-bottom: 12px; }
#alert-container:empty { display: none !important; }
.placeholder { height: 1px; opacity: 0; visibility: hidden; }
</style>
</head><body><p></p>
<div id="alert-container"></div>
<div id="empty-placeholder">No alerts</div>
<p><script>
const RSS_URL = 'https://rss.icmobile.singlewire.com/outbound-rss-feed/c3d722a2-c57f-11f0-9a2f-d7e6357975dd';
async function loadAlert() {
try {
const res = await fetch(RSS_URL);
const text = await res.text();
const parser = new DOMParser();
const xml = parser.parseFromString(text, "application/xml");
const items = xml.querySelectorAll("item");
const container = document.getElementById('alert-container');
const placeholder = document.getElementById('empty-placeholder');
if (items.length === 0) {
container.innerHTML = '';
placeholder.style.display = 'block';
return;
}
container.innerHTML = Array.from(items).map(item => `
<div >${item.querySelector("title").textContent}</div>
<div >${item.querySelector("description").textContent}</div>
`).join('');
placeholder.style.display = 'none';
} catch (e) {
document.getElementById('alert-container').innerHTML = 'Error loading alerts';
document.getElementById('empty-placeholder').style.display = 'none';
}
}
loadAlert();
setInterval(loadAlert, 30 * 1000); // Faster refresh for testing
</script></p></body></html>
But when I paste the code in the Source area of the widget, D2L inserts some codes that I didn't include. You will notice after the </head><body> tags, D2L adds <p></p>.
This may be the cause of the extra space ???
So, to try and take away this automatic formatting I tried to redefine what the <p> tag was defined as, but it didn't work.
p {
margin: 0 !important;
padding: 0 !important;
line-height: 1 !important; /* Optional: also should tightens line height if needed */
}
Q: Is there any way to get it to stop inserting extra code to see if this is the cause of the extra space? (I think D2L support is saying NO to this now :-( )
Q: Any other work around to make sure the widget completely collapses.
If I can get it to completely collapse, then I can add many different RSS feed options for other applications. But if I can't get rid of the small space adding multiple RSS Feed widgets would keep pushing the below widgets lower each time, making this solution not very usable to extended purposes.
I reached out to D2L support first, and they redirected me to this space. Hopefully there are some success stories out there that will help me :-)
D2L support has told me that they said they "confirmed that the behavior you’re seeing—where an empty <p></p> tag is automatically inserted—is expected. This is part of a safeguard in the Brightspace editor to ensure valid HTML is saved and prevent rendering issues. One workaround is to use CSS to hide empty paragraph tags. This will remove the visual space caused by the empty tag without affecting other content."
I've redefined the <P> tag but the issue got worse. I will try again with CSS but am wondering if you have any other thoughts to assist?
Much thanks,
Randy
Answers
-
Hi Randy,
I don't do much coding with widgets but I am 99.9% sure you cannot put a whole .html page in the source editor, just body elements, and yes the injected <p></p> is likely a feature, not a bug. It is easy enough to inspect the widget in the devtools console and add a style="display: none;" to make it disappear, and would be nice write code like this:
document.getElementById('widget_id').style.display = 'none';
…but trying to target the widget itself is also difficult because the top-level widget div doesn't have a unique id or class. I was able to achieve this effect though with a widget I gave the name "Test Collapse" and with the following widget source code to find that name and then the top-level widget div to hide:
<p></p>
<p><script>
document.addEventListener('DOMContentLoaded', function() {
Array.from(document.querySelectorAll('h2.d2l-heading.vui-heading-4')).find(el => el.textContent.trim() === 'Test Collapse').closest('.d2l-custom-widget').style.display = 'none';
});
</script></p>Seems to have the desired effect with no extra space where the widget would be, as the whole widget is hidden, at least in my testing. Hope this helps!
Josh.
