This is a relatively simple technique that allows you to create print-ready versions of archives, taxonomies, taxonomy term archives etc, with the site header and footer removed or simplified.
Third party (plugin) solutions often don’t respect the formatting that you’ve set up for screen, and require to to restyle all your content to fit within their templates. The following approach loads a similar page template, with all styles, but missing headers / sidebars/ footer elements that you don’t want in printed results.
The basic premise is to use a query string parameter to change the template file being loaded, to in turn remove the headers and footer. The basic premise is
- Generate a print URL from the current URL (including query string params such a search terms, pagination numbers etc):
$print_url = '//' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . ($_SERVER['QUERY_STRING'] ? "&template=print": "?template=print");
- Place a print button on the page, set to open in a new window:
<a class='btn-print' target='_blank' href='<?= $print_url ?>'>Print</a>
- At the very top of the template file in question (ie
archive.php
,taxonomy.php
,search.php
etc), add a snippet of code that loads the alternative version of the current template, and then exits. So, forarchive.php
:
123if (isset($_GET['template']) && $_GET['template'] == 'print') {include 'archive-print.php'; die();}
archive-print.php
can be based onarchive.php
with a few key print-ready modifications.archive-print.php
should be a full-width layout, with no sidebars or other elements- It should load an alternative header and footer.
get_header()
is replaced byget_header('empty')
which changes the header file loaded. The empty header file, calledheader-empty.php
contains all the<head>
elements, but the body should be pared back (so strip all navigation and other elements). Same forfooter-empty.php
.
- Finally, in order to print, en-queue a javascript to check whether we are on a print template (by the presence of the query string parameter), and trigger the print dialog on page load.
1234567891011121314151617181920212223242526(function($) {$(document).ready(function() {if ($_GET('template') == 'print') {$('.btn-print').hide();setTimeout(function() {window.print();}, 500);}});})(jQuery);function $_GET(param) {var vars = {};window.location.href.replace( location.hash, '' ).replace(/[?&]+([^=&]+)=?([^&]*)?/gi, // regexpfunction( m, key, value ) { // callbackvars[key] = value !== undefined ? value : '';});if ( param ) {return vars[param] ? vars[param] : null;}return vars;}
It is also worth adding some@media print
style hints to your css to make sure that individual posts in your list view don’t span pages when printed. For this, use thepage-break-inside: avoid;
directive, and make sure all floats are disabled (took me some time to debug this).