Pym.js Tips & Tricks - kavyasukumar/shenanigans GitHub Wiki
For creating embed.txt, we highly recommend using Pym.js, a Javascript library for responsively embedding iframes.
Here are a few easy ways to use Pym.js to add functionality to your embedded projects.
NOTE: In Pym.js parlance, the parent page is the page you embed the iframe in. And the child frame is the page that is embedded. For more info read Pym.js documentation.
The following is a simple embed.txt.erb
for your blueprint that makes the embed responsive.
<div data-analytics-class="embed" data-analytics-viewport="autotune" id="<%=data.autotune.slug %>__graphic"></div>
<%=javascript_include_tag('pym') %>
<script type="text/javascript">
new pym.Parent('<%=data.autotune.slug %>__graphic', '<%=asset_url('/') %>');
</script>
Make sure that the file is saved as
embed.txt.erb
In the blueprint's javascript add this
var pymChild = pym.Child();
Anytime you add or remove content to the blueprint's DOM, send the new height to the parent page like this
pymChild.sendHeight();
For Pym.Js to function correctly, make sure that the following css is applied to the child page.
html, body { width:auto; height:auto; }
When a user clicks a share button from your blueprint, you often want to share the parent page's url and not the link to the child directly. Security concerns restrict communication between the parent and its embedded iframes. But Pym.Js's sendMessage
function can be used to send the parent page's url to the blueprint.
Save the snippet below as embed.txt.erb
<div data-analytics-class="embed" data-analytics-viewport="autotune" id="<%= slug %>__graphic"></div>
<%=javascript_include_tag('pym') %>
<script>
var pymParent = new pym.Parent('<%= slug %>__graphic', '<%= absolute_page_url %>');
pymParent.onMessage('childLoaded', function() {
pymParent.sendMessage('setShareUrl', document.URL);
});
</script>
The script above waits for the child page to send a childLoaded
message. Then it attempts to send its URL to the child.
The child blueprint first has to notify the parent that it has finished loading. For this in the blueprint's javascript add the following
Create a Pym Child and send childLoaded
message
var parentPageUrl = document.URL,
pymChild = new pym.Child();
pymChild.sendMessage('childLoaded', 'ready');
Don't forget to continue to call
sendHeight()
when content height changes
Add a listener for the setShareUrl
message as follows
pymChild.onMessage('setShareUrl', function(Url) {
parentPageUrl = Url;
});
When the height of the content in the child iframe changes drastically, sometimes you are left with a scroll position on the parent that is not ideal. You can use Pym.js to scroll the parent page.
In this example, we will scroll the parent page to the start of the iframe
For this let's use the example above, but instead of sending just the parent page's url, let's also send the id
of the div
that contains the iframe.
The new embed.txt.erb
looks like this
<div data-analytics-class="embed" data-analytics-viewport="autotune" id="<%= slug %>__graphic"></div>
<%=javascript_include_tag('pym') %>
<script>
var data = {};
data['url'] = document.URL;
data['slug'] = '<%= slug %>__graphic';
var pymParent = new pym.Parent('<%= slug %>__graphic', '<%= absolute_page_url %>', {xdomain: '.*\.voxmedia\.com'});
pymParent.onMessage('childLoaded', function() {
pymParent.sendMessage('shareInfo', JSON.stringify(data));
});
</script>
The shareInfo
handler stores the slug
in addition to the parent page URL like this
pymChild.onMessage('shareInfo', function(data) {
data = JSON.parse(data);
parentPageSlug = data.slug;
parentPageUrl = data.url;
});
Now for the actual scrolling, just call
pymChild.scrollParentTo(parentPageSlug);