Background
Many methods exist to creating printer versions. A few of these include:
- creating a separate HTML page for every page on your website
that is formatted to print well.
- using a database to hold the page content and display the
content via either the normal template or the stripped-down printer template.
- including a header.php file above your content and footer.php
below your content.
The method I will describe here is different from the usual
methods and is used on websites like CNN.
The basic idea is to put a hidden html comment tag at the
beginning of the main content of your webpage, and another
hidden html comment tag at the end of your content.
<!--startclickprintinclude-->
The content you want to print goes here.
<!--endclickprintinclude-->
The Printer Version script will open the webpage, grab
only that which is between the hidden tags, and display
it within the Printer Version template.
Bells & Whistles
A few extra features are included to provide additional
functionality:
- Ability to exclude some text within the printable region.
- Ability to optionally cache the grabbed pages in a
MySQL database to improve performance.
- Ability to extend script to accommodate multiple
websites with each using its own Printer Version template.
- Optional javascript to add Printer Version button to webpages.
Set up MySQL database tables
The first table to create will hold member settings. If you
create an interface for members to manage their own data, then
username and password will be useful. Name and email may be
useful for you to contact your users or notify them with custom
email messages via an error subroutine. The "activeyn"
field should be set to "y" if you want the users printer
version to work. You may specify a different template file such
as "customername.html" in the "template" field.
The "subject", "logo", and "emailbody"
fields field are added in anticipation of having an "Email
This Page To A Friend" script to interact with this same data
in the future. The "domain" field is the allowed domain
name for this user. The "sitename" field should be
the name of the users company and will be available for
integration with templates.
CREATE TABLE `member` (
`id` tinyint(7) NOT NULL auto_increment,
`username` varchar(25) NOT NULL default '',
`password` varchar(25) default NULL,
`name` varchar(50) default NULL,
`email` varchar(50) default NULL,
`activeyn` char(1) default NULL,
`template` varchar(50) default NULL,
`subject` varchar(100) default NULL,
`domain` varchar(50) default NULL,
`logo` varchar(100) default NULL,
`emailbody` mediumtext,
`sitename` varchar(100) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
) TYPE=MyISAM AUTO_INCREMENT=1 ;
Here is an example SQL statement used to set up a user:
INSERT INTO `member` VALUES (1, 'yourdomain.com', 'yourpassword',
'Your Company Name', 'yourname@yourdomain.com', 'y',
'customtemplate.html', 'Website Page From !MAILFROMNAME!',
'yourdomain.com', 'yourlogo.jpg',
'The following page from the Your Company Name
website\r\n(YourDomain.com) was suggested to you by:
!MAILFROMNAME!.\r\nPage Title: !TITLE!\r\nLink:
!URL!\r\nNote from !MAILFROMNAME!:\r\n!MESSAGE!',
'Your Company Name');
Next we create the cache table. It is relational to the
member table via the username field. Each record will
store the URL of the respective webpage in all lowercase,
the timestamp of when it was added to the table for use in
expiration, the <head> title of the webpage, and the
printable content.
CREATE TABLE `cache` (
`id` tinyint(7) NOT NULL auto_increment,
`username` varchar(25) NOT NULL default '',
`url` varchar(100) default NULL,
`date` varchar(20) default NULL,
`title` varchar(50) default NULL,
`body` blob,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
) TYPE=MyISAM AUTO_INCREMENT=1 ;
Create the template
The default template name for the printable version will
be 1.html . You may define a different default template
for a domain in the MySQL settings for that member.
The most basic template will use 3 tokens: Page Title is !TITLE!,
URL to original page is !URL!, and the printable content is !CONTENT!
A more fully-featured template which includes both "Print"
and "Close This Window" buttons is included in the
download version of this script.
<html><head>
<title>!TITLE!</title>
<base href="!URL!"></head>
<body>!CONTENT!
<br><br>Page printed from: !URL!
</body>
</html>
Beginning the Printer Version script
Create a new file called print.php and start the file with:
<?
A few options need to be set in the beginning.
First are the MySQL server connections.
<?php
//Server Settings
$mysv="localhost"; #your server name
$myun="your MySQL username";
$mypw="your MySQL password";
$mydb="your MySQL database name";
//Connection
$db = mysql_connect($mysv, $myun, $mypw);
mysql_select_db($mydb,$db);
?>
Next we tell the script how many days to cache the printable
HTML content of a webpage. After this many days the script
will go spider the webpage again. If your webpages change
frequently, you may wish to make this a lower number.
<?php
$daystocache = 5;
?>
Next we define what hidden comment tags we will use to grab
the printable content.
<?php
$GrabStart = "<!--startclickprintinclude-->";
$GrabEnd = "<!--endclickprintinclude-->";
?>
You have the option of excluding certain content that is
inside of the printable region. Define the comment tags here.
<?php
$ExcludeStart = "<!--startclickprintexclude-->";
$ExcludeEnd = "<!--endclickprintexclude-->";
?>
This defines what tags we will use to find the webpage title.
<?php
$TitleStart = "<title>";
$TitleEnd = "</title>";
?>
Determine the original webpage
Depending on your implementation, you may pass a variable to the
script telling it what URL to spider. If the script does not
receive this variable, it will try to determine the URL using the
$HTTP_REFERER variable.
<?php
//Get The URL to spider
if (!$url) {
$url=$HTTP_REFERER;
}
?>
Verify user
This script is designed for you to set up multiple domain names
which are allowed to use the Printer Version script. No other
domain names will be allowed to use the script.
To accomplish these we will first extract the domain name from the URL:
<?php
$url2 = strtolower($url);
$url2 = str_replace("http://", "", $url2);
$url2 = str_replace("www.", "", $url2);
$path = explode ("/", $url2);
$domainname = $path[0];
?>
Next we will query the MySQL database to look for a match for any
users which match the domainname just parsed. If the user is
active, then the settings for that user will be available later in the
script in an array called $myrow.
<?php
$sql = "SELECT * FROM member WHERE domain='$domainname'";
$result = mysql_query($sql);
$myrow = mysql_fetch_array($result);
?>
Even if a user exists, does not mean that they are active. If the user
does not exist or is not active, we will return an error message.
<?php
if ($myrow["activeyn"]!="y"){
echo "This domain $domainname is not active";
exit;
}
?>
Retrieve the template
You can specify different template filenames for different users
in their database record. The default template is 1.html . Templates
should be stored in the same directory as the print.php script.
Once opened, the template code is stored in the variable $body.
<?php
//Get template filename for this user from database
$filename = $myrow["template"];
//Show the default template if necessary
if ( !file_exists($filename) ) {
$filename = "1.html";
}
//Open template file and store in variable $body
$fd = fopen ($filename, "rb");
$body = fread ($fd, filesize ($filename));
fclose ($fd);
?>
Search the cache for page content
Here we will build a function to see if this page is already in the MySQL
cache of page content. If it is in the cache, the function will only
return the data if it is not older than the number of days specified in the
options above.
Step 0: Define the function
<?php
function cachesearch($url,$daystocache)
{?>
Step 1: Calculate the maximum timestamp available
<?php
$expiredate = strtotime ("-$daystocache days");
?>
Step 2: Query database for matching URL and timestamp below the maximum allowed
<?php
$sql = "SELECT * FROM cache WHERE url='$url' and date > '$expiredate'";
$result = mysql_query($sql);
$myrow = mysql_fetch_array($result);
?>
Step 3: If matching content is in the cache, return it
<?php
if (mysql_numrows($result)==1) {
$answer[0] = $myrow["title"];
$answer[1] = $myrow["body"];
return $answer;
}
?>
Step 4: If no match is found in the cache, return false
<?php
else {
return false;
}
?>
Step 5: End the function definition
<?php
} # end of cachesearch
?>
Step 6: Execute the function
<?php
$cacheurl = strtolower($url);
$resultb = cachesearch($cacheurl,$daystocache);
?>
Note: Any returned title will now be in variable $result[0]
and any returned body content will now be in variable $result[1] .
Retrieve webpage content if not in cache
Here we will check to see if we successfully retrieved any content from
the cache. If the cache was empty or expired for this URL, we will go
grab the webpage.
<?php
if ($resultb[1]==) {
?>
First we grab the entire webpage and store in variable $rf.
<?php
$file = fopen("$url", "r");
$rf = fread($file, 20000);
fclose($file);
?>
Next we parse out the printable content using the tags defined in the
options above.
<?php
$grab = eregi("$GrabStart(.*)$GrabEnd", $rf, $printing);
?>
Next we delete any content chosen to be excluded. The printable
content is now ready and stored in variable $showme.
<?php
$showme = eregi_replace("$ExcludeStart[^>.]*$ExcludeEnd","",$printing[1]);
?>
Next we parse out the page title, but only if a title has not been sent
to the script via a variable.
<?php
if (!$title) {
$grab = eregi("$TitleStart(.*)$TitleEnd", $rf, $thetitle);
$title = $thetitle[1];
} #end if no title
?>
Add grabbed data to MySQL cache. First delete any old cached data.
<?php
$sql = "DELETE FROM cache where url='$cacheurl'";
$resulta = mysql_query($sql);
?>
Next Create the new datas timestamp.
<?php
$date=time();
?>
Next format the new data for the database.
<?php
$titleb = mysql_escape_string($title);
$contentb = mysql_escape_string($showme);
?>
Finally insert the new data into the database.
<?php
$sql = "INSERT INTO cache (id,username,url,date,title,body) VALUES
('','$company','$cacheurl','$date','$titleb','$contentb')";
$resultc = mysql_query($sql);
?>
Finish up by closing the if expression.
<?php
} #end if cache is empty
?>
If the page is in the cache, then set the $showme and $title variables
based on the returned data.
<?php
else {
$showme = $resultb[1];
$title = $resultb[0];
}
?>
Integrate printable content with template
The template content is in the $body variable. We will replace
the tokens in the template with the variables in this script.
<?php
$body2 = str_replace("!TITLE!", $title, $body);
$body2 = str_replace("!URL!", $url, $body2);
$body2 = str_replace("!COMPANY!", $company, $body2);
$body2 = str_replace("!HTTP_REFERER!", $HTTP_REFERER, $body2);
$body2 = str_replace("!CONTENT!", $showme, $body2);
$body2 = str_replace("!LOGO!", $myrow["logo"], $body2);
$body2 = str_replace("!SITENAME!", $myrow["sitename"], $body2);
?>
Show the result
Print the resulting printer version of the webpage and end the print.php script.
<?php
echo $body;
?>
Adding Printer Version button via HTML
This method involves hard-coding the link to the printer version.
You can hard code ALL of the data this way:
<a href=http://www.yourdomain.com/print/print.php?company=yourdomain.com
&url=http://www.yourdomain.com/pagebeinggrabbed.html&title=Title+Of+Page+Being+Grabbed>
<img src=http://www.yourdomain.com/print/printerversionbutton.jpg border=0></a>
Alternatively, you can let the print.php script determine the
URL of the page to be grabbed using $HTTP_REFERER. In this case,
your may use the same link throughout your website.
<a href=http://www.yourdomain.com/print/print.php?company=yourdomain.com>
<img src=http://www.yourdomain.com/print/button.jpg border=0></a>
Adding Printer Version button via Javascript
This method is an alternative to the HTML method, and allows you to
control the HTML for the Printer Version button and link in a central
javascript file.
1. Add the following javascript to your webpage template in the place
that you want the Printer Version button to appear:
<script language="javascript"
src="http://www.yourdomain.com/print/print.js">
</script>
<script language=javascript>showbutton
("yourdomain.com","main");</script>
The script allows you to specify a particular "Printer Version"
button. The default button is "printmain.gif" but you can
override this for a particular webpage by changing the word "main"
to some other word. (e.g. if you want to use "printblack.gif"
button instead, change the word "main" to "black")
2. Create a file called print.js.
The showbutton() function creates the HTML to show the printer version
button and link to the printer version.
The showprinterversion() function opens a new window to show the printer
version. You can customize the size and features of the window here.
This function automatically URL encodes the URL of the page to be grabbed,
and uses javascript to complete the title of the page.
The randomname() function creates a random name for the opened window.
This helps prevent some cache issues.
function randomname(str)
{
var ret = new String("");
var ch;
for (var i = 0; i < str.length; i++)
{
ch = str.charAt(i);
if (ch == ".")
ret += "X";
else
ret += ch;
}
return ret;
}
function showprinterversion(company, button)
{
var name = randomname(Math.random().toString());
var url = "http://www.yourdomain.com/print/print.php?company="
+ company + "&url=" +escape(location.href) + "&title="
+ escape(document.title);
window.open(url, name,
'height=580,width=530,toolbar=0,menubar=no,directories=no,resizable=1,
scrollbars=1,status=0');
return;
}
function showbutton(company, button)
{
document.write('<br>');
document.write('<table border="0" cellspacing="0"
cellpadding="0"');
document.write('<tr><td align="middle" valign="top">');
var link = "<a name='printerversionlink' href='#'
onClick='javascript:showprinterversion(\"" + company
+ "\", \"" + button + "\");
' target='_self'>";
document.write (link);
var btn = "<img name='printerversionbutton'
src='http://www.yourdomain.com/print/print" + button
+ ".gif' border=0>";
document.write (btn);
document.write('</table>');
}
Testing it out
In the end you should have the following files:
/print/print.php
/print/print.js
/print/1.html
/print/printmain.gif
I also include some images to use in the template:
/print/clickheretoprint.gif
/print/closewindow.gif
the sample SQL needed to set up your database:
SQLsetup.txt
and an example page that shows how to use the include and exclude tags:
example.html
Good luck!