Sometimes you need to have some custom code rendered on a template page or within a collection list where the code it unique to the CMS page / item.
The Issue
Webflow encodes the HTML contained in a field that is placed into a Embed Element, when the page is rendered out to the hosting servers as HTML.
The encoded HTML will render as code, not as HTML in your Collection template or within a collection list.
Example HTML placed in your collection item field; <p>I am a paragraph. Whoohoo!</p>
The same HTML encoded by Webflow on rendering the page; <p> I am a paragraph. Whoohoo!</p>
The web page will show <p>I am a paragraph. Whoohoo!</p>
instead of;
I am a paragraph. Whoohoo!
Ok, so you understand the problem. Lets fix it.
The Solution
Decoding all the possible HTML entities </p>
is not trivial.
Fortunately, we can leverage someone else's hard work to do it. Thanks to
Mathias Bynens, https://mathiasbynens.be, and his he repo on github, we can.
We will use this robust HTML entity encoder/decoder along with some custom JavaScript to handle the targeting and replacement.
Read the details about using he at the projects Github page. We will be using just the decode method for our purposes.
Assumptions / Steps
Create Your Fields
Create two text fields (multiline) in your collection. I named mine "custom styles" and "custom code". I want to use the styles field to include unique CSS styles when I need to. If you were using the same styles for your custom HTML, then you could just embed a style block in your page head or along with your HTML.
Add Custom Fields to your Collection Template Page
Add an Embed element (in the Webflow designer) into your Collection template page, where you want the CODE to render. Assign it an ID called "custom-code". You can change this value to be whatever you want, just make sure to change the code provided below. Just remember the ID has to be unique on the page, period.
Cool now we have a target to fix with he, in our JavaScript.
I added the "custom styles" field binding to the Head, as well as a CDN version of the he script.
You can grab a CDN version of he from jsDelivr.com. You can copy the script tag below and from inside the Designer, open the Page's settings, enter your code in the head code section, and save the settings. See instructions at Webflow here.
Note: You only need it on pages where you are trying to render embedded html from a collection.
<script src="https://cdn.jsdelivr.net/npm/[email protected]/he.min.js"></script>
Now lets add some JavaScript to our page. If you are doing this on the Collection template page, lets add it to the before body close custom code area in the template's page settings. Why? To let some Webflow Dom manipulations finish first so you don't get an error.https://share.getcloudapp.com/6quk1neW?embed=true
Here is my code.
<script>
// if you use a different value for the ID of your embed
// then change it below - I used "custom-code"
var embedId = "custom-code";
var target = document.getElementById(embedId);
var targetText = target.innerHTML;
function decodeField(target) {
var dText = he.decode(target);
document.getElementById(embedId).innerHTML = dText;
}
// run the function to decode the target field content
decodeField(targetText);
</script>
Save and Publish
Boom. That's all that's needed. This will work on all HTML in your field. That means CSS and Javascript too.
If it's not working for you, I suspect you failed to follow instructions. I don't offer support for free, but you can book me for work.
How About Collection lists?
Here is the jQuery way. Makes it simpler to iterate over elements. The entire code block below could be added to the page settings -> custom code -> before body close area.
<!-- If you already loaded HE then you don't need this line-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/he/1.2.0/he.min.js"></script>
<!-- decode CMS collection item embed -->
<script type="text/javascript">
$(document).ready(function () {
// targeting class of .podcast-embed
$(".podcast-embed").each(function () {
$(this).hide(); // hide so code is not displayed (better to hide in CSS)
$(this).html(he.decode($(this).html())); // decode the text
$(this).show(); // show the decoded element
});
});
</script>
jQuery approach to decode an embed with HE from a collection list where the embed has a class of .podcast-embed
More Options
Now if you took some time to read the he docs, you might realize that this could be used to display code on a page using the encode method. Yep. Even dynamically with the click of a button and some JS. That is a different story.