Skip to content

Instantly share code, notes, and snippets.

@bennadel
Created February 22, 2023 13:28
Show Gist options
  • Save bennadel/c453890313584761daa5f1e4cc1a297c to your computer and use it in GitHub Desktop.
Save bennadel/c453890313584761daa5f1e4cc1a297c to your computer and use it in GitHub Desktop.
Persisting An IFrame-Based Video Player Across Page Visits With Hotwire And Lucee CFML
<cfmodule template="./tags/page.cfm" section="home">
<cfoutput>
<h2>
Welcome to This Site
</h2>
<ul>
<li>
<a href="video.htm?id=meghan-trainor" data-turbo-frame="player">
Play <strong>Meghan Trainor</strong> - Me Too
</a>
</li>
<li>
<a href="video.htm?id=dojo-cat" data-turbo-frame="player">
Play <strong>Dojo Cat</strong> - Go To Down
</a>
</li>
</ul>
</cfoutput>
</cfmodule>
// Import core modules.
import { Application } from "@hotwired/stimulus";
import { Controller } from "@hotwired/stimulus";
import * as Turbo from "@hotwired/turbo";
// ----------------------------------------------------------------------------------- //
// ----------------------------------------------------------------------------------- //
class PlayerTemplateController extends Controller {
/**
* I get called whenever this controller instance is bound to a host element.
*/
connect() {
// On page load, there is no turbo-frame since it's embedded within a content
// template. The only goal of this controller is to ensure that a SINGLE instance
// of said template exists (and is injected in between the HEAD and BODY tags
// where it won't be affected by Turbo Drive's full-body content replacement).
if ( ! document.querySelector( "#player" ) ) {
document.body
.before( this.element.content.cloneNode( true ) )
;
}
}
}
// ----------------------------------------------------------------------------------- //
// ----------------------------------------------------------------------------------- //
window.Stimulus = Application.start();
// When not using the Ruby On Rails asset pipeline / build system, Stimulus doesn't know
// how to map controller classes to data-controller attributes. As such, we have to
// explicitly register the Controllers on Stimulus startup.
Stimulus.register( "player-template", PlayerTemplateController );
<!doctype html>
<html lang="en">
<head>
<!--- Truncated for snippet. --->
</head>
<body>
<h1>
ColdFusion + Hotwire IFrame Video Player Demo
</h1>
<!--- Truncated for snippet. --->
<template data-controller="player-template">
<turbo-frame id="player" class="player">
<!---
This Turbo-Frame is inert and cannot be targeted until the
template is cloned and the resultant element is injected into the
document.
--->
</turbo-frame>
</template>
</body>
</html>
<cfscript>
param name="url.id" type="string" default="";
switch ( url.id ) {
case "dojo-cat":
src = "https://www.youtube.com/embed/TLiGA_wrNp0?autoplay=1";
break;
case "meghan-trainor":
src = "https://www.youtube.com/embed/qDRORgoZxZU?autoplay=1";
break;
default:
src = "";
break;
}
</cfscript>
<cfoutput>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<base href="#request.appPath#/hotwire.cfm/" />
<link rel="stylesheet" type="text/css" href="#request.appPath#/dist/main.css"></link>
</head>
<body>
<h1>
Video Player
</h1>
<turbo-frame id="player">
<!---
Only show the IFRAME when the SRC is defined. If there is no SRC, just
return empty content, which will - for all intents and purposes - "close"
the player. This isn't technically closing the player (ie, clearing the
Turbo-Frame "src" attribute); but, it's good enough for this demo.
--->
<cfif src.len()>
<iframe
width="355"
height="200"
src="#src#"
title="YouTube video player"
frameborder="0"
allow="autoplay; encrypted-media; picture-in-picture; web-share"
allowfullscreen>
</iframe>
<!--- Hidden by default, only shows when inside injected player. --->
<p class="player__close">
<a href="video.htm?id=">
Close Player
</a>
</p>
</cfif>
</turbo-frame>
<p>
<a href="index.htm">Back to Home</a>
</p>
</body>
</html>
</cfoutput>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment