<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Perplexed Labs &#187; SCRIPT</title>
	<atom:link href="http://blog.perplexedlabs.com/tag/script/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.perplexedlabs.com</link>
	<description>web development war stories from the frontlines to the backend</description>
	<lastBuildDate>Mon, 16 May 2011 14:19:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>PHP Dynamic JavaScript SCRIPT Insertion for Embedding</title>
		<link>http://blog.perplexedlabs.com/2009/02/05/dynamic-javascript-script-insertion-for-embedding/</link>
		<comments>http://blog.perplexedlabs.com/2009/02/05/dynamic-javascript-script-insertion-for-embedding/#comments</comments>
		<pubDate>Thu, 05 Feb 2009 20:21:34 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[embed]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[SCRIPT]]></category>

		<guid isPermaLink="false">http://www.perplexedlabs.com/?p=136</guid>
		<description><![CDATA[For an internal project I've been working on I have to provide embeddable versions of internal tools for deployment on remote partner sites. I achieved this in my framework through, what I call, output format filters. Let's say you have an action "cloud" in a controller "markets". The URL to access this resource in its [...]


Related posts:<ol><li><a href='http://blog.perplexedlabs.com/2009/05/04/php-jquery-ajax-javascript-long-polling/' rel='bookmark' title='Permanent Link: PHP jQuery AJAX Javascript Long Polling'>PHP jQuery AJAX Javascript Long Polling</a></li>
<li><a href='http://blog.perplexedlabs.com/2008/11/07/real-time-ajax-javascript-progress-bar/' rel='bookmark' title='Permanent Link: Real-time &#8220;AJAX&#8221; JavaScript Progress Bar'>Real-time &#8220;AJAX&#8221; JavaScript Progress Bar</a></li>
<li><a href='http://blog.perplexedlabs.com/2009/02/06/javascript-roundto-nearest-thousandth-hundredth-tenth/' rel='bookmark' title='Permanent Link: JavaScript roundTo Nearest Thousandth, Hundredth, Tenth, *'>JavaScript roundTo Nearest Thousandth, Hundredth, Tenth, *</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>For an internal project I've been working on I have to provide embeddable versions of internal tools for deployment on remote partner sites.</p>
<p>I achieved this in my framework through, what I call, output format filters.  Let's say you have an action "cloud" in a controller "markets".  The URL to access this resource in its full glory would be:</p>
<blockquote>
<p>http://www.domainname.com/markets/cloud</p>
</blockquote>
<p>Pretty standard stuff.  Let's say we want to offer an embeddable version of this resource.  I can append an "output format filter" on this resource:</p>
<blockquote>
<p>http://www.domainname.com/markets/cloud/embed</p>
</blockquote>
<p>Alright, again, pretty standard stuff.  How on earth does this relate to dynamic javascript SCRIPT insertion?</p>
<p>On the remote partner site, I ask them to place the following HTML fragment in the desired location they want the resource to appear:</p>
<pre class="brush: xml; title: ;">
&lt;script language=&quot;javascript&quot; type=&quot;text/javscript&quot; src=&quot;http://www.domainname.com/markets/cloud/embed&quot;&gt;&lt;/script&gt;
</pre>
<p>One line of HTML.</p>
<p>How does this work under the hood?  It simply takes the view's content and prepares it as a valid javascript document.write.  It also specifies certain HTML headers, notably:</p>
<blockquote><p><strong>Content-Type: application/x-javascript</strong></p></blockquote>
<pre class="brush: php; title: ;">
function prepJS($js)
{
	// prepare the output as valid javascript
	$js = str_replace(&quot;\\&quot;, &quot;\\\\&quot;, $js);
	$js = preg_replace(&quot;/[\r\n]+/&quot;, '\n', $js);
	$js = str_replace('&quot;', '\&quot;', $js);
	$js = preg_replace(&quot;/&lt;script/i&quot;, '&lt;scr&quot;+&quot;ipt', $js);
	$js = preg_replace(&quot;/&lt;\/script/i&quot;, '&lt;/scr&quot;+&quot;ipt', $js);

	return $js;
}
</pre>
<pre class="brush: jscript; title: ;">
document.write(&quot;&lt;?php echo prepJS($viewContent); ?&gt;&quot;);
</pre>
<p>It should be fairly obvious what the function does.  It escapes double quotes, adds slashes, and replaces newlines and carriage returns with their inline equivalent.  Additionally and VERY important, it splits SCRIPT tag elements (if your view had inline SCRIPT's) into SCR"+"IPT so that the browser treats these as pure strings and doesn't cause JavaScript parsing errors.</p>
<p>What if the resource you are embedding depends upon the availability of certain JavaScript libraries or external source files?  The first response usually is, myself included, to simply document.write more SCRIPT tags!</p>
<pre class="brush: jscript; title: ;">
document.write(&quot;
&lt;?php prepJS('&lt;script type=&quot;text/javascript&quot; language=&quot;javascript&quot; src=&quot;http://www.domainname.com/path/to/jquery.js&quot;&gt;&lt;/script&gt;'); ?&gt;
&quot;);
document.write(&quot;
&lt;?php prepJS('&lt;script type=&quot;text/javascript&quot; language=&quot;javascript&quot; src=&quot;http://www.domainname.com/path/to/morejs.js&quot;&gt;&lt;/script&gt;'); ?&gt;
&quot;);
document.write(&quot;&lt;?php echo prepJS($viewContent); ?&gt;&quot;);
</pre>
<p>The problem is of course that in IE, <a href="http://stackoverflow.com/questions/94141/javascripts-document-write-inline-script-execution-order">there's no telling what order those SCRIPT tags will get executed</a>.  Furthermore, if your resource depends on them, they need to be executed <strong>before</strong> you document.write the content.</p>
<p>My solution to this problem was two-fold.  For other reasons not worth going into here, it's generally a good idea to concatenate all your JavaScript source files into one larger file, minify (if desired), cache, and serve the result.  Taking advantage of this we can reduce the above to a single additional SCRIPT insertion.  Tack this snippet onto the end of that file:</p>
<pre class="brush: jscript; title: ;">
if(typeof(embedReady) != 'undefined') {
	embedReady();
}
</pre>
<p>And we come up with this:</p>
<pre class="brush: jscript; title: ;">
document.write(&quot;
&lt;?php prepJS('&lt;script type=&quot;text/javascript&quot; language=&quot;javascript&quot; src=&quot;http://www.domainname.com/path/to/cached_combined_js.js&quot;&gt;&lt;/script&gt;'); ?&gt;
&quot;);
var embedReady = function() {
    document.write(&quot;&lt;?php echo prepJS($viewContent); ?&gt;&quot;);
}
</pre>
<p>Now we're only concerned with a single SCRIPT load.  We've safely placed our document.write of content inside a function that's called at the end of our dependency SCRIPT.  In an elegant, browser agnostic fashion our resource will have it's dependencies loaded before it executes.</p>
<p>Yay?</p>


<p>Related posts:<ol><li><a href='http://blog.perplexedlabs.com/2009/05/04/php-jquery-ajax-javascript-long-polling/' rel='bookmark' title='Permanent Link: PHP jQuery AJAX Javascript Long Polling'>PHP jQuery AJAX Javascript Long Polling</a></li>
<li><a href='http://blog.perplexedlabs.com/2008/11/07/real-time-ajax-javascript-progress-bar/' rel='bookmark' title='Permanent Link: Real-time &#8220;AJAX&#8221; JavaScript Progress Bar'>Real-time &#8220;AJAX&#8221; JavaScript Progress Bar</a></li>
<li><a href='http://blog.perplexedlabs.com/2009/02/06/javascript-roundto-nearest-thousandth-hundredth-tenth/' rel='bookmark' title='Permanent Link: JavaScript roundTo Nearest Thousandth, Hundredth, Tenth, *'>JavaScript roundTo Nearest Thousandth, Hundredth, Tenth, *</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.perplexedlabs.com/2009/02/05/dynamic-javascript-script-insertion-for-embedding/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

