Using JavaScript For Web Syndication
JavaScript is a useful tool for syndicating content to other websites. For example, this page displays ads by Google using JavaScript. When you viewed this page, your browser fetched a script from Google then ran the script and displayed ads on the page.
This article examines the pros and cons of JavaScript syndication, explains how to implement it, and demonstrates a technique using PHP to make it even easier.
Pros and Cons of JavaScript Syndication
JavaScript has some inherent weaknesses:
- JavaScript depends on the user's browser: if JavaScript is not enabled your content will not appear. People with disabilities will not have access to the content, and search engines will not index the content.
- JavaScript is not efficient -- the content must be loaded from a central location for every user. This might lead to bandwidth problems when serving the content, as shown in Figures 1 & 2.
If you are syndicating to websites that are not under your control, you don't know that the webmaster will have the expertise to implement a syndication strategy using XML. You might be syndicating to a small company that used FrontPage to make the website; they certainly can't set up a dynamic process to fetch an XML feed from your site, cache it, and integrate the data into their site.
Using JavaScript has the following benefits:
- For the target website, implementation is simple: just add one line of HTML to the target page. It works for any web server environment -- you don't need server-side technologies such as PHP, Perl, Python, or Java.
- When you update the content on your site, changes are immediately reflected on syndication sites. With cached solutions such as RSS there is typically a self-imposed delay of up to an hour.
- You can control how your content is presented, or you can allow partners to customize the presentation.
- You can log information about the end-users that see your syndicated content, as shown in Figure 3. You can log each user that fetches your JavaScript file, then compare those results to the number of clicks-throughs you receive in your syndicated content.
To achieve the widest adoption for content syndication, you should use JavaScript in addition to other syndication methods such as RSS.
A Simple Example
Let's assume that you run a network of websites, each on a different server, and you want to put a common element at the top of each page:
First you would create a JavaScript file topbar.js
like the following:
document.write('<div class="topbar">'); document.write('The Fubar Network: '); document.write('<a href="http://web1.net">Web1<\/a>,'); document.write('<a href="http://web2.net">Web2<\/a>,'); document.write('<a href="http://web3.net">Web3<\/a>'); document.write('</div>');
Then on each of your websites, at the top of each page, you would add the following to fetch and execute the JavaScript:
<script type="text/javascript" src="http://web1.com/topbar.js"> </script>
The JavaScript program displays your HTML on the page. Let's try it right here to see it in action:
Encoding Your Data
Even with the simple example above, some problems might occur.
Since everything in topbar.js
must be valid
JavaScript, you must be careful to escape and encode the data
correctly. For example, since the document.write()
function is printing a single-quoted string, you must be sure to
"escape" any single quotes within that string.
JavaScript is also very picky about the characters
"</
" -- older browsers have been known to abort when
encountering this sequence -- so you must escape that as well.
As an alternative to worrying about which characters to escape, I
recommend encoding all of your data,
then using the JavaScript unescape()
function to decode
it prior to writing. So our file topbar.js
becomes the following (the encoded data has been abbreviated in this example):
document.write(unescape('%3Cdiv%20style...'));
Making It Dynamic
In the example above, we displayed static HTML, but what if we want to display dynamic information? For example, we might want to query a database and display the time of the next live event.
We can't really do that in JavaScript, since JavaScript runs in the user's browser. Instead, we need a server-side script to do the work for us. Let's use PHP since that's widely available (but you could just as easily use Java, Perl, or Python).
The only caveat is this: our server-side script can't just output HTML, it must output a JavaScript program. The JavaScript program will then write the data onto the page.
A Dynamic Example
First we'll write our PHP page:
<?php // Simulate fetching the live event $event = sprintf('%s: <a href="%s">%s</a>', 'Tuesday', 'http://web1.net/events/', 'Internet Security Webcast'); // This is the content we want to display $data = <<<EOT <div class="topbar"> The Fubar Network: <a href="http://web1.net">Web1</a>, <a href="http://web2.net">Web2</a>, <a href="http://web3.net">Web3</a> <div>Upcoming event: $event</div> </div> EOT; // Output JavaScript code to write the data printf('document.write(unescape("%s"));', rawurlencode($data)); ?>
When we view this PHP page, we should see a JavaScript program like the following (the data is truncated to fit on this page). Notice that the content has been properly encoded -- no matter what content we use, the JavaScript program will be valid.
document.write(unescape("%3Cdiv%20class..."));
Now we need to syndicate this JavaScript program as we did before. Luckily, the <script>
element can be used to fetch any URL, even if it's not a .js
file, so we'll tell it to fetch topbar.php
instead of topbar.js
:
<script type="text/javascript" src="http://web1.com/topbar.php"> </script>
Let's try it right here to see it in action:
I Can Name That Tune in One Line of PHP...
Everything we've done so far works, but doesn't look too fun to maintain. It would be much easier if we could just take any PHP page, and magically syndicate it with JavaScript.
Luckily, PHP makes this possible. By including one simple file, you can turn any page into a JavaScript syndication script:
<?php include("makejavascript.php"); ?>
makejavascript.php
<?php function ob_makejavascripthandler($output) { return sprintf('document.write(unescape("%s"));', rawurlencode($output)); } ob_start("ob_makejavascripthandler"); ?>
Here is how it works:
- When you include
makejavascript.php
, it callsob_start()
, to start output buffering.While output buffering is active no output is sent from the script (other than headers), instead the output is stored in an internal buffer. -- PHP documentation
- When your script finishes, PHP automatically calls the function
ob_makejavascripthandler()
and passes it all the buffered output from your script. - The
ob_makejavascripthandler()
function takes the output and turns it into a JavaScript program.
Putting It All Together
So here is the workflow for syndicating content using PHP and JavaScript:- Design the content you want to syndicate - it can be plain HTML or dynamic PHP. We'll call the file
content.php
<?php // Simulate fetching the live event $event = sprintf('%s: <a href="%s">%s</a>', 'Tuesday', 'http://web1.net/events/', 'Internet Security Webcast'); ?> <div class="topbar"> The Fubar Network: <a href="http://web1.net">Web1</a>, <a href="http://web2.net">Web2</a>, <a href="http://web3.net">Web2</a> <div>Upcoming event: <?= $event ?></div> </div>
- Create the syndication file
content-syndicate.php
. This file displays a JavaScript program.<?php include('makejavascript.php'); include('content.php'); ?>
- To display your syndicated content, add the following to any HTML page:
<script type="text/javascript" src="http://web1.com/content-syndicate.php"> </script>
Bells and Whistles
Button, button... who's got the button?
Of course it wouldn't be fair if the syndicators were the only ones to get a cool button, so we should have one for JavaScript syndication as well. I suggest using .Adding Parameters
The examples so far assume that every website would display the same syndicated content, but you can use parameters to customize the output for each of your syndication partners.
For example, if your PHP script accepted a parameter n
, then you could specify n=5
when you fetch the JavaScript syndication file:
<script type="text/javascript" src="http://web1.com/content-syndicate.php?n=5"> </script>
Adding a Web Wizard
You can even go the extra mile and provide a web interface for configuring the parameters. An excellent example is topics_anywhere for PHPBB, which implements the JavaScript syndication techniques described here. In fact, I'm using it to display the discussion groups below.
Sending JavaScript Data
The examples above assume that your syndicated JavaScript program
writes content to the page using document.write()
, but
you can do more than that in your script.
To allow greater flexibility, you can set JavaScript variables, provide custom JavaScript functions, or execute any JavaScript code that you choose. For example, you could convert your RSS data into a JavaScript data structure:
// Array of headlines // Each headline is a JavaScript object var rss_items = [ { title:unescape("..."), link:unescape("..."), description:unescape("...") }, { title:unescape("..."), link:unescape("..."), description:unescape("...") }, ];Your syndication partners can then use that data in JavaScript functions, or you can provide the functions to manipulate the data.
Links
- Web services to convert an RSS feed into a JavaScript syndication format:
- Feedroll ← Recommended
- Feed2JS
- Media Scooper
- XML::RSS::JavaScript
A Perl module to convert RSS data into a JavaScript syndication format. - MagpieRSS: RSS for
PHP
PHP module to fetch and parse RSS feeds. Use with makejavascript.php to convert an RSS feed to JavaScript syndication format. - XML button created via CSS
Clever technique for creating an XML button without using a graphic.