Live Server Side HTML/JavaScript Method

[HR][/HR] This is a PHP script. The same script in classic asp can be found here - http://www.sitepoint.com/forums/showthread.php?871345-Live-Server-Side-HTML-JavaScript-Method&p=5163068#post5163068
What do you people think of this method?

It’s just an example written from a question here [COLOR=#2968a1]http://www.sitepoint.com/forums/show…nt-Replacement[/COLOR] No animation though, which was one of the requests, but works with or without javascript.

The live method can work with ASP and PHP. I’m trying to do it in .NET but having problems.

It’s better if the CSS and JavaScript were in their seperate files, but I just wanted to show how it was done in one page.

Copy and save it in a default folder that runs php and it should work the same with or without javascript.

If you have dynamic data then you will need to add a nocache header. Adding this will also make it live if you use a setTimeout or setInterval.

<?php
//----is Live----//
$live=False;
if((isset($_GET["live"]))&&(($_GET["live"]==="1")||($_GET["live"]==="2"))){
    $live=(int)$_GET["live"];
}
//----write function----//
function write($s){
    global $live;
    if($live){
        echo str_replace("\\"","\\\\\\"",str_replace("\\r\
","",$s));
    }else{
        echo $s;
    }
}
//----product id (pid)----//

$pid=0;
if(isset($_GET["pid"])){
    $pid=(int)$_GET["pid"];
}
//----page headers----//
if($live){
    header("ContentType: application/x-javascript");
} else {
    echo "<!DOCTYPE html PUBLIC \\"-//W3C//DTD XHTML 1.0 Transitional//EN\\\\r\
\	\\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\\">\\r\
";
    echo "<html xmlns=\\"http://www.w3.org/1999/xhtml\\">\\r\
";
    echo "<head>\\r\
";
    echo "<title>".$title."</title>\\r\
";
    echo "<style type=\\"text/css\\">\\r\
";
        echo "img{width:200px;height:150px}\\r\
";
        echo "#sidecontent{display:block;width:200px;height:400px;background:gold;float:left;}\\r\
";
        echo "#maincontent{display:block;width:700px;height:400px;background:gold;float:left;}\\r\
";
        echo "#others img{width:100px;height:75px;}\\r\
";
    echo "</style>\\r\
";
    echo "<script type=\\"text/javascript\\">\\r\
";
    echo "function changeScript(s){";
        echo "var o=document.getElementsByTagName(\\"script\\")[0];";
        echo "var n=document.createElement('script');";
        echo "n.setAttribute('type', 'text/javascript');";
        echo "n.setAttribute('src',s);";
        echo "o.parentNode.replaceChild(n,o);";
    echo "};";
    echo "function init(){";
        echo "a=document.getElementsByTagName(\\"a\\");";
        echo "for(i=0;i<a.length;i++){";
            echo "a[i].onclick=function(){if(this.href.indexOf(\\"?\\")>-1) changeScript(this.href+\\"&live=1\\"); else changeScript(this.href+\\"?live=1\\"); return false;}";
        echo "}\\r\
";
    echo "}\\r\
";
    echo "window.onload=function(){init();}\\r\
";
    echo "</script>\\r\
";
    echo "</head>\\r\
";
    echo "<body>\\r\
";
    echo "<div id=\\"sidecontent\\"><a href=\\"\\" title=\\"Show All\\">Static side Content</a></div>\\r\
";
}
if($live){
    echo "document.getElementById(\\"maincontent\\").innerHTML=\\"";
} else {
    echo "<div id=\\"maincontent\\">\\r\
";
}
if($pid===0){
    for($i=5;$i<11;$i++){
        write("<a href=\\"?pid=".$i."\\" title=\\"Product #\\"".$i."\\"><img src=\\"\\" alt=\\"Egypt".$i.".jpg\\" /></a>\\r\
");
    }
    write("</div>\\r\
");
} else {
    //----get product info from db or text file----//
    write("<img src=\\"\\" alt=\\"Egypt".$pid.".jpg\\" />\\r\
");
    write("<div id=\\"info\\">\\r\
");
    write("<h1>Product Number ".$pid."</h1>\\r\
");
    write("<p>This is the info for product number ".$pid."</p>\\r\
");
    write("</div>\\r\
");
    write("<div id=\\"others\\">\\r\
");
    for($i=5;$i<11;$i++){
        if($i!==pid){
            write("<a href=\\"?pid=".$i."\\" title=\\"Product #".$i."\\"><img src=\\"\\" alt=\\"Egypt".$i.".jpg\\" /></a>\\r\
");
        }
    }
    write("</div>\\r\
");
}
if($live){
    echo "\\";init();";
} else {
    echo "</div>\\r\
";
}
?>

What are the benefits?

Works without javascript
URL on link can be copy/pasted
Lighter data, better for bandwidth (header, footer and common parts only loaded once)
Lighter execution, better for server, any included files can have if($live) die(); at the start
You can have a media file playing between page changes
You do not need to store info in cookies between page changes, the js variables stay active.
Pages can be made “live” with a simple setInterval or setTimeout and a no-cache header for the javascript
Site is seen without javascript by search engines and pages indexed as normal

I’ve been using the method for a long time. I called it the LiveScript method, although someone at github has started to use the name for one of their projects which has nothing to do with live javascript!

Forgot to mention why I use live=1 and live=2

Explanation here in asp forum

I think you need to do some clean up. Everything smashed together like it is makes it really hard to figure out what is going on. Should try and separate the Javascript from the HTML, the HTML from the PHP…etc. Right now it just looks like a giant mess.

I can’t. It’s livescript. Live JavaScript. It ouptuts either javascript or HTML depending on how it is requested. If I do what you say I need a file for HTML that does exactly the same but for the javascript. What’s the point of having multiple files that create the same output but just with different headers? I could output HTML, read it using HTTPXMLRequest, and then convert it to javascript but why go through all that when I can do it like this instead? That’s a waste of resources, IMO

I use the function write($string) to convert a HTML string to a javascript accepted string to be able to do this

if($live){
 echo "document.getElementById(\\"content\\").innerHTML=\\"";           //----start of javascript
} else {
echo "<div id=\\"content\\">\\r\
";           //----start of div in HTML
}

//---- uses write function to convert HTML with quotes and new lines to javascript with escaped quotes and removed new lines

write("<p>this is content</p>\\r\
");
write("<img src=\\"img.gif\\" alt=\\"an image\\" />\\r\
");

if($live){
echo "\\";"     //----end of javascript innerHTML
} else {
echo "</div>\\r\
";       //----closes the div in HTML
}

Err…okay…PHP is a lot more powerful then you give it credit for…give me one second…

Here, less example guff that lets us get to the meat so we can see what it all does.


<?php

// Template, Pure HTML Output
$output_html = <<<HTMLEOF
<!doctype html>
<!-- Lets not bother with the XHTML nonsense -->
<html>
  <head>
    <title>{:title:}<title>
    <script>
      function changeScript ( s ) {
        var o = document.getElementsByTagName( "script" )[0],
            n = document.createElement( "script" );
        
        n.setAttribute( "src", s ); // type="text/javascript" is implied.
        o.parentNode.replaceChild( n, o );
      };
      
      function init () {
        var a = document.getElementsByTagName( "a" ),
            i = 0;
            
        for ( i; i < a.length; i++ ) {
          a[ i ].onclick = function () {
            if ( this.href.indexOf( "?" ) > -1 )
              changeScript( this.href + "&live=1" );
            else
              changeScript( this.href + "?live=1" );
            
            return false;
          }
        }
      }
      
      windows.onload = init();
    </script>
  </head>
  <body>
    <div id="main_content">
      {:body_content:}
    </div>
  </body>
</html>
HTMLEOF;

#-------------------------------------------------------------------------------

// Template, Javascript Output
$output_js = 'document.getElementById( "{:container:}" ).innerHTML="{:body_content:}";init();';

#-------------------------------------------------------------------------------

$send_js = false;
if ( isset( $_GET[ 'live' ] ) )
  $send_js = (bool)$_GET[ 'live' ]; // Lets keep it simple for now.

$title   = 'Uninteresting title';
$content = 'Mary Poppins was here, <a href="?go=Supercalifragilisticexpialidocious">Supercalifragilisticexpialidocious</a>!!!';

#-------------------------------------------------------------------------------
// Javascript only output

if ( $send_js === true ) {
  header( 'content-type: application/x-javascript' );
  echo str_replace(
    [ '{:container:}', '{:body_content:}' ], // PHP 5.4 Array Sugar Syntax
    [ 'main_content', str_replace( '"', '\\\\"', $content ) ],
    $output_js
  );
  
  exit;
}

#-------------------------------------------------------------------------------
// No Javascript

echo str_replace(
  [ '{:title:}', '{:body_content:}' ],
  [ $title, $content ],
  $output_html
);

But you know you should just use XMLHttpRequest and pull in JSON…its a lot safer and easier. Almost all languages out there have a JSON en/decoder. (Despite its name XMLHttpRequest is not limited to only XML.)

I hope you’re not suggesting I concate massive strings? When I researched every place advised against this.

You can’t flush server coded javascript content as the files do not execute until they are finished, so there’s no problem with outputting it bit by bit. (which is a shame as this could get REALLY interesting)

(Despite its name XMLHttpRequest is not limited to only XML.)

Yes, I use XMLHttpRequest to pull data from non-live websites and make live pages from them. It worked with plentyoffish, but I didn’t publish it :slight_smile:

My HTML headers, when used in real projects, are in includes as well.

Something I like about php, is the fact you can use conditional includes which helps, although I try to keep the ASP and PHP ones as similar as possible so I can update either easily.

I don’t like the idea of using jquery, ajax, json or whatever. The output is here already, why do more work? It doesn’t have to be strings I output either, it can be javascript, so for pages that have a lot of similar data I create variables and arrays to shorten the javascript sent to the client, and use functions to rebuild and inject into the existing HTML page

Umm…No. I advising that you make things simpler when you offer examples so we can get the concepts without digging though guff. Being able to see the functions and concepts without running the logic though our heads and stripping out junk that is not currently important to the concept will allows us to grasp it FASTER. Thus simplifying the example.

Personally, I would never use this on production site. I’ll stick with a MVC-based pattern keep all my concerns separated from one another. My HTML view is separated from my JSON (AJAX) view, and so forth.

OK, each to their own, but my stats on http://www.unitingrhythms.com/home/statistics/ PROVE that my site works better with it. An average of 48ms for HTML, 21ms with live=1 and 7ms with live=2 :slight_smile: (working on it ATM moving from .co.uk on a rubbish server from streamline.net)
Even on my home site, asp classic which is very slow in comparrison, still makes the times better. http://www.livescript.co.uk/live/statistics/speed.asp (249ms,106ms,81ms)

So the javascript outputted pages are executed in over twice the speed :slight_smile:

Just had a glitchy request which increased the live=2 count. Added a function to click through the months in the asp one but haven’t done it in the PHP one as yet, but it was on 7, honest :slight_smile: