DOC 2.0 API PostMessage Support For Dynamic IFrame Resizing

When it comes to embedding the output of our new 2.0 APIs in other websites via iframes, we've tried to make that process as easy as possible, from the CORS ACAO header to offering HTTPS endpoints. All display modes of our GEO 2.0 API automatically resize to fit whatever sized iframe they are displayed in, meaning you can chose the map size that works best for you. The same is true for most of our DOC 2.0 API output formats, with the exception of the article and image lists.

When you embed the DOC 2.0 API in an iframe using "ArtList", "ArtGallery", "ImageCollage", "ImageCollageInfo" or "ImageCollageShare" modes, the width of the results display automatically adapts to the width of the browser window, dynamically moving elements or even generating a completely new layout (in the case of ArtGallery and ImageGallery modes) to achieve the best fit. However, when it comes to the height of the iframe, the content height of the results is entirely dependent on the number of results. A search with few results will yield a page that is fairly short in terms of pixel height, while a page with many results will be very tall. In the case of the Gallery modes, images which fail to load are discarded from the layout, meaning the final height may vary over time as not all images load for every user.

When it comes to automatically adjusting the height of an iframe to its embedded contents, most approaches require both the embedded and embedding pages to be hosted on the same domain and thus don't work cross-origin. Other techniques only work with selected browsers or are extremely fragile or exploit undocumented nuances of how a given browser functions and thus are not sustainable or portable.

One of the few fully portable techniques, supported by nearly all modern browsers and fully cross-origin, is based on postMessage, in which the embedded content (in this case the output of the DOC 2.0 API) sends an update via JavaScript to the embedding page every time its content height changes, allowing the embedding page (your page) to include a small snippet of JavaScript code that receives those height updates and dynamically resizes the iframe accordingly to precisely fit the embedded content.

In short, with a brief snippet of a few lines of JavaScript, you can now embed these five output modes of the DOC 2.0 API in an iframe in your page and have the iframe dynamically resize its height to precisely fit the content, making it appear to be perfectly inline in your page.

Embedding A Single Iframe

To embed a single iframe – a gallery of the latest coverage of hurricanes, you would embed the following code in your page. Just change the URL of the iframe to your own search and copy-paste into your own page – no additional code is needed! (You can remove the <STYLE></STYLE> block – it simply ensures that the output stretches all the way to the right and left edges of your browser window without border whitespace).

<script>
    window.addEventListener("message", function(e){
	var gallery1 = document.getElementById("gallery1");
	if (gallery1.contentWindow === e.source) {
	    gallery1.height = e.data.height + "px";
            gallery1.style.height = e.data.height + "px";
	}
    });
</script>

<style>
body { margin: 0; padding: 0; }
</style>

Here are some articles about hurricanes
<iframe ID="gallery1" src="https://api.gdeltproject.org/api/v2/doc/doc?query=hurricane&mode=artgallery" scrolling="no" width=100% frameborder="0"></iframe>

Embedding Multiple Iframes

To embed multiple iframes, we just give each iframe a different name and repeat the inner "gallery" code in the JavaScript block for each iframe. Here's an example that embeds three iframes.

<script>
    window.addEventListener("message", function(e){
	var gallery1 = document.getElementById("gallery1");
	if (gallery1.contentWindow === e.source) {
	    gallery1.height = e.data.height + "px";
            gallery1.style.height = e.data.height + "px";
	}
	var gallery2 = document.getElementById("gallery2");
	if (gallery2.contentWindow === e.source) {
	    gallery2.height = e.data.height + "px";
            gallery2.style.height = e.data.height + "px";
	}
	var gallery3 = document.getElementById("gallery3");
	if (gallery3.contentWindow === e.source) {
	    gallery3.height = e.data.height + "px";
            gallery3.style.height = e.data.height + "px";
	}
    });
</script>

<style>
body { margin: 0; padding: 0; }
</style>


The basic GDELT ImageCollage mode:
<iframe ID="gallery1" src="https://api.gdeltproject.org/api/v2/doc/doc?query=hurricane&mode=imagecollage" scrolling="no" width=100% frameborder="0"></iframe>

The basic GDELT ArtList mode:
<iframe ID="gallery2" src="https://api.gdeltproject.org/api/v2/doc/doc?query=hurricane&mode=artlist" scrolling="no" width=100% frameborder="0"></iframe>

The new GDELT ArtGallery mode:
<iframe ID="gallery3" src="https://api.gdeltproject.org/api/v2/doc/doc?query=hurricane&mode=artgallery" scrolling="no" width=100% frameborder="0"></iframe>

 

That's all there is to it! Happy embedding!