Commit 6da15198 authored by Erick Hitter's avatar Erick Hitter

Initial commit of version 0.4.4.1 from WP.org repository.

parents
<!DOCTYPE html>
<html>
<head>
<title><?php wp_title( '|', true, 'right' ); bloginfo( 'name' ); ?></title>
<link rel="canonical" href="<?php the_permalink(); ?>" />
<meta name="robots" content="noindex" />
</head>
<body <?php body_class(); ?>>
<?php
if( have_posts() ):
while( have_posts() ):
the_post();
?>
<div <?php post_class(); ?>>
<h1><?php the_title(); ?></h1>
<p>by <?php the_author(); ?> | <?php the_time( 'F j, Y g:i a' ); ?></p>
<?php
if( is_attachment() && wp_attachment_is_image() )
echo '<p>' . wp_get_attachment_image( $post->ID, 'large' ) . '</p>';
the_content();
?>
<?php
if( function_exists( 'wpf_the_page_numbers' ) )
wpf_the_page_numbers( false, '<p class="page_numbers">Page ', ' of ', '</p><!-- .page_numbers -->' );
?>
<p class="wpf-source"><strong>Source URL:</strong> <?php the_permalink(); ?></p>
<hr class="wpf-divider" />
</div>
<?php
endwhile;
endif;
?>
<p class="copyright">Copyright &copy;<?php echo date( 'Y' ); ?> <strong><?php bloginfo( 'name' ); ?></strong> unless otherwise noted.</p>
</body>
</html>
\ No newline at end of file
=== WP Print Friendly ===
Contributors: ethitter, thinkoomph
Donate link: http://www.thinkoomph.com/plugins-modules/wp-print-friendly/
Tags: print, template, printer, printable
Requires at least: 3.1
Tested up to: 3.4
Stable tag: 0.4.4.1
Extends WordPress' template system to support printer-friendly templates. Works with permalink structures to support nice URLs.
== Description ==
Extends WordPress' template system to support printer-friendly templates for posts, pages, and custom post types. Uses WP standard template naming to support templates on a post-type basis. Supports printing paged posts on single page. Adds nice URLs for printer-friendly pages.
**IMPORTANT**: There are certain plugins that may interfere with this plugin's functionality. See the **FAQ** for more information.
== Installation ==
1. Upload wp-print-friendly.php to /wp-content/plugins/.
2. Activate plugin through the WordPress Plugins menu.
3. Navigate to Options > Permalinks and click *Save Changes* to update navigation.
== Frequently Asked Questions ==
= Print links don't work =
First, navigate to Options > Permalinks in WP Admin, click *Save Changes*, and try again.
If clicking on a print link takes you back to the post or page where the link appeared, see the **Known Plugin Conflicts** item below.
If, after reviewing the remaining FAQ, you are still experiencing problems, visit [http://www.thinkoomph.com/plugins-modules/wp-print-friendly/](http://www.thinkoomph.com/plugins-modules/wp-print-friendly/) and leave a comment detailing the problem.
= How should I name print templates? =
Print templates should be prefixed with *wpf* and follow WordPress template conventions from there. To use one template for all contexts unless otherwise specified, name your template *wpf.php.*
For both built-in and custom post types, *wpf-[post type name].php* will be used for that post type. To use a template for a single post type object, name your template *wpf-[post type name]-[slug].php*.
For custom taxonomies, follow the naming conventions for post types.
Similarly, *wpf-home.php* will load that template for the front page of your site.
The plugin also includes a default template that may suit many needs.
= How do I add a print link to my templates? =
The function `wpf_the_print_link` will add a link to the print-friendly version of whatever page it appears on. This function accepts the following arguments:
* **$page_link**: Set to true to add a link to the current page in a paged post in addition a to a link for the entire post.
* **$link_text**: Set to text that should appear for the print link. Defaults to *Print this post*.
* **$class**: Specifies the CSS class for the print link. Defaults to *print_link*.
* **$page_link_separator**: If $page_link is true, specifies what separator will appear between the print link for the entire post and the print link for the current page of the post.
* **$page_link_text**: If $page_link is true, specifies what text will appear for the print link for the current page. Defaults to *Print this page*.
* **$link_target**: If set to "new", print links will open in a new window.
= Known Plugin Conflicts =
This plugin is known to conflict with certain plugins, many pertaining to SEO and permalinks. Conflicting plugins include, but are not limited to, the following:
* **WordPress SEO by Yoast:** This plugin's `Permalink` options, particularly *Redirect attachment URL's to parent post URL* and *Redirect ugly URL's to clean permalinks. (Not recommended in many cases!)*, interfere with WP Print Friendly's ability to display print templates. Both must be disabled, and the site's rewrite rules regenerated (by visiting Options > Permalinks and clicking *Save Changes*), for WP Print Friendly to function.
== Changelog ==
= 0.4.4.1 =
* Remove unnecessary query_var filter.
= 0.4.4 =
* Full support for child themes.
* Expand template choosing to fully support WordPress template hierarchy as described at [http://codex.wordpress.org/Template_Hierarchy](http://codex.wordpress.org/Template_Hierarchy).
* Simplify rewrite rules creation.
= 0.4.3.3 =
* Correct error that would display wrong page's content when printing a single page of a paged post.
* Correct error in link generation for page-specific print links.
* Increase compatibility with View All Post's Pages plugin.
= 0.4.3.2 =
* Resolve PHP notice in options retrieval.
* Add compatibility with View All Post's Pages plugin (release forthcoming).
= 0.4.3.1 =
* Fix bug in options retrieval that caused print links to be added to default post types if no post types were selected.
* Resolve PHP notice when using default permalinks.
= 0.4.3 =
* Fix bug in page number function.
* Rewrite endnote link processing, including a refined regex pattern.
* Introduce class property for print slug.
* Correct minor bug in print link generation.
* Add canonical link attribute and nofollow declaration to default template.
= 0.4.2.2 =
* Correct generation of custom post type rewrite rules.
= 0.4.2.1 =
* Version 0.4.2 omitted the default template.
= 0.4.2 =
* Correct page rewrite rules to accomodate situations necessitating verbose rules, such as when the permalink structure starts with `%postname%`. Thanks to Wes Herzik at ikonic for discovering and reporting this issue.
= 0.4.1 =
* Fix bug that displayed post links automatically on the wrong post types.
= 0.4 =
* Child pages now fully supported.
* Generates and registers rewrite rules more efficiently.
* Rewrite setting for all post types and taxonomies are now considered when adding print support.
* Add option to disable endnotes representing links found in content.
* Move copyright and other static elements from content filters to default template.
* Add function to display page numbers when printing single page of post.
* Options page is now fully translation-ready.
* Notices are translation-ready.
* Correct various other bugs, including many related to non-standard permalink structures, custom post types, and custom taxonomies.
= 0.3.2 =
* Add option to open print-friendly views in a new window.
= 0.3.1 =
* Correct PHP error in `is_print()`.
= 0.3 =
* Initial version.
== Upgrade Notice ==
= 0.4.4.1 =
Removes unnecessary query_var filter.
= 0.4.4 =
Adds full child theme and template hierarchy support for template selection. Simplifies rewrite rules.
= 0.4.3.3 =
Corrects a few errors related to paged posts and further enhances compatibility with View All Post's Pages plugin.
= 0.4.3.2 =
Fixes a minor bug in plugin's options retrieval and enhances compatibility with forthcoming View All Post's Pages plugin.
= 0.4.3.1 =
Fixes a bug in plugin's options retrieval that caused print links to be added to default post types if no post types were chosen. Also resolves a PHP notice encountered when using default permalinks.
= 0.4.3 =
Fixes various bugs in the print link, page numbering, and endnote generating functions. Also introduces a class variable for permalink component. Default template is updated to be more SEO friendly, now containing both canonical URL and nofollow declarations.
= 0.4.2.2 =
Rewrite rules for custom post types are now generated correctly.
= 0.4.2.1 =
Version 0.4.2 omitted the default template.
= 0.4.2 =
This release expands the plugin's page rewrite rules to accomodate permalink structures that necessitate verbose rules, such as when the structure begins with `%postname%`.
= 0.4.1 =
This release fixes bug that displayed post links automatically on the wrong post types.
= 0.4 =
This release addresses numerous bugs reported by the community, including print templates for child pages. All admin text, save the plugin's name, are now ready for translation. Templates are now completely customizable, and new template functions are included.
\ No newline at end of file
<?php
/*
Plugin Name: WP Print Friendly
Plugin URI: http://www.thinkoomph.com/plugins-modules/wp-print-friendly/
Description: Extends WordPress' template system to support printer-friendly templates. Works with permalink structures to support nice URLs.
Author: Erick Hitter (Oomph, Inc.)
Version: 0.4.4.1
Author URI: http://www.thinkoomph.com/
*/
class wp_print_friendly {
var $query_var = 'print';
var $ns = 'wp_print_friendly';
var $settings_key = 'wpf';
var $settings_defaults = array(
'auto' => false,
'placement' => 'below',
'post_types' => array( 'post', 'page' ),
'print_text' => 'Print this entry',
'print_text_page' => 'Print this page',
'css_class' => 'print_link',
'link_target' => 'same',
'endnotes' => true,
'endnotes_label' => 'Endnotes:'
);
var $notice_key = 'wpf_admin_notice_dismissed';
/*
* Register deactivation hook and filter.
* @uses register_deactivation_hook, add_filter
* @return null
*/
function __construct() {
register_deactivation_hook( __FILE__, array( $this, 'deactivation_hook' ) );
add_action( 'plugins_loaded', array( $this, 'action_plugins_loaded' ) );
}
/*
* Clean up after plugin deactivation.
* @uses flush_rewrite_rules, delete_option
* @action register_deactivation_hook
* @return null
*/
function deactivation_hook() {
flush_rewrite_rules();
delete_option( $this->settings_key );
delete_option( $this->notice_key );
}
/*
* Register actions and filters.
* @uses add_action, add_filter, get_option
* @action plugins_loaded
* @return null
*/
function action_plugins_loaded() {
add_action( 'init', array( $this, 'action_init' ), 20 );
add_action( 'admin_init', array( $this, 'action_admin_init' ) );
add_action( 'admin_menu', array( $this, 'action_admin_menu' ) );
add_filter( 'request', array( $this, 'filter_request' ) );
add_action( 'pre_get_posts', array( $this, 'action_pre_get_posts' ) );
add_filter( 'template_include', array( $this, 'filter_template_include' ) );
add_filter( 'body_class', array( $this, 'filter_body_class' ) );
add_filter( 'the_content', array( $this, 'filter_the_content' ), 0 );
add_filter( 'the_content', array( $this, 'filter_the_content_auto' ) );
add_filter( 'the_content', array( $this, 'filter_the_content_late' ), 99 );
if( !get_option( $this->notice_key ) )
add_action( 'admin_notices', array( $this, 'action_admin_notices_activation' ) );
}
/*
* Add print endpoint and rewrite rules for term taxonomy archives
* @uses add_rewrite_endpoint, $wp_rewrite, get_taxonomies, add_rewrite_rule
* @action init
* @return null
*/
function action_init() {
add_rewrite_endpoint( $this->query_var, EP_ALL );
//Taxonomies, since they aren't covered by add_rewrite_endpoint
global $wp_rewrite;
if( $wp_rewrite->permalink_structure ) {
$taxonomies = get_taxonomies( array(), 'objects' );
foreach( $taxonomies as $taxonomy => $args ) {
if( $args->rewrite == false )
continue;
$taxonomy_slug = '';
if( $args->rewrite[ 'with_front' ] && $wp_rewrite->front != '/' ) $taxonomy_slug .= $wp_rewrite->front;
$taxonomy_slug .= $args->rewrite[ 'slug' ];
$query_var = $args->query_var ? $args->query_var : 'taxonomy=' . $taxonomy . '&term';
add_rewrite_rule( $taxonomy_slug . '/([^/]+)?/' . $this->query_var . '(/(.*))?/?$', $wp_rewrite->index . '?' . $query_var . '=$matches[1]&' . $this->query_var . '=$matches[2]', 'top' );
}
}
}
/*
* Register plugin option and disable rewrite rule flush warning.
* @uses register_setting, update_option
* @action admin_init
* @return null
*/
function action_admin_init() {
register_setting( $this->settings_key, $this->settings_key, array( $this, 'admin_options_validate' ) );
if( isset( $_GET[ $this->notice_key ] ) )
update_option( $this->notice_key, 1 );
}
/*
* Determine if print template is being requested.
* @uses $wp_query
* @return bool
*/
function is_print() {
global $wp_query;
return is_array( $wp_query->query ) && array_key_exists( $this->query_var, $wp_query->query );
}
/*
* Select appropriate template based on post type and available templates.
* Returns an array with name and path keys for available template or false if no template is found.
* @uses get_queried_object, is_home, is_front_page, locate_template
* @return array or false
*/
function template_chooser() {
//Get queried object to check post type
$queried_object = get_queried_object();
//Get plugin path
$pluginpath = dirname( __FILE__ );
if( ( is_home() || is_front_page() ) && ( '' !== ( $path = locate_template( 'wpf-home.php', false ) ) ) ) {
$template = array(
'name' => 'wpf-home',
'path' => $path
);
}
elseif(
is_object( $queried_object ) &&
property_exists( $queried_object, 'taxonomy' ) &&
property_exists( $queried_object, 'slug' ) &&
( '' !== ( $path = locate_template( array( 'wpf-' . $queried_object->taxonomy . '-' . $queried_object->slug . '.php', 'wpf-' . $queried_object->taxonomy . '.php' ), false ) ) )
)
$template = array(
'name' => 'wpf-' . $queried_object->taxonomy,
'path' => $path
);
elseif(
is_object( $queried_object ) &&
property_exists( $queried_object, 'post_type' ) &&
property_exists( $queried_object, 'post_name' ) &&
( '' !== ( $path = locate_template( array( 'wpf-' . $queried_object->post_type . '-' . $queried_object->post_name . '.php', 'wpf-' . $queried_object->post_type . '.php' ), false ) ) )
)
$template = array(
'name' => 'wpf-' . $queried_object->post_type,
'path' => $path
);
elseif(
is_object( $queried_object ) &&
property_exists( $queried_object, 'post_name' ) &&
( '' !== ( $path = locate_template( 'wpf-' . $queried_object->post_name . '.php', false ) ) )
)
$template = array(
'name' => 'wpf-' . $queried_object->post_name,
'path' => $path
);
elseif( '' !== ( $path = locate_template( 'wpf.php', false ) ) )
$template = array(
'name' => 'wpf-default',
'path' => $path
);
elseif( file_exists( $pluginpath . '/default-template.php' ) )
$template = array(
'name' => 'wpf-plugin-default',
'path' => $pluginpath . '/default-template.php'
);
return isset( $template ) ? $template : false;
}
/*
* Detect request for print stylesheet on the homepage and reset query variables
* @param array $qv
* @filter request
* @return array
*/
function filter_request( $qv ) {
if( array_key_exists( 'pagename', $qv ) && $qv[ 'pagename' ] == $this->query_var ) {
$qv[ $this->query_var ] = '';
unset( $qv[ 'page' ] );
unset( $qv[ 'pagename' ] );
}
if( array_key_exists( $this->query_var, $qv ) && is_numeric( $qv[ $this->query_var ] ) )
$qv[ 'page' ] = intval( $qv[ $this->query_var ] );
return $qv;
}
/*
* Filter query when request to print specific page is made.
* @param object $query
* @action pre_get_posts
* @return object
*/
function action_pre_get_posts( $query ) {
if( array_key_exists( $this->query_var, $query->query_vars ) && !empty( $query->query_vars[ $this->query_var ] ) ) {
$qv = explode( '/', $query->query_vars[ $this->query_var ] );
if( array_key_exists( 1, $qv ) && is_numeric( $qv[ 1 ] ) )
$query->query_vars[ 'page' ] = (int)$qv[ 1 ];
}
return $query;
}
/*
* Filter template include to return print template if requested.
* @param string $template
* @filter template_include
* @return string
*/
function filter_template_include( $template ) {
if( $this->is_print() && ( $print_template = $this->template_chooser() ) )
$template = $print_template[ 'path' ];
return $template;
}
/*
* Filter body classes to include references to print template.
* @param array $classes
* @filter body_class
* @return array
*/
function filter_body_class( $classes ) {
if( $this->is_print() && ( $print_template = $this->template_chooser() ) ) {
if( $print_template[ 'name' ] == 'default' )
$classes[] = 'wpf';
else
$classes[] = $print_template[ 'name' ];
}
return $classes;
}
/*
* Filter post content to support printing entire post on one page.
* @param string $content
* @uses get_query_var
* @filter the_content
* @return string
*/
function filter_the_content( $content ) {
if( $this->is_print() ) {
$print = get_query_var( $this->query_var );
if( $print == 'all' || $print == '/all' || empty( $print ) ) {
global $post;
$content = $post->post_content;
$content = str_replace("\n<!--nextpage-->\n", "\n\n", $content);
$content = str_replace("\n<!--nextpage-->", "\n", $content);
$content = str_replace("<!--nextpage-->\n", "\n", $content);
$content = str_replace("<!--nextpage-->", ' ', $content);
}
}
return $content;
}
/*
* Filter the content if automatic inclusion is selected
* @param string $content
* @uses $this::get_options, $post, $this::print_url, get_query_var, apply_filters
* @filter the_content
* @return string
*/
function filter_the_content_auto( $content ) {
$options = $this->get_options();
global $post;
if( is_array( $options ) && array_key_exists( 'auto', $options ) && $options[ 'auto' ] == true && in_array( $post->post_type, $options[ 'post_types' ] ) && !$this->is_print() ) {
extract( $options );
//Basic URL
$print_url = $this->print_url();
//Page URL, if necessary
if( !empty( $print_text_page ) && strpos( $post->post_content, '<!--nextpage-->' ) !== false ) {
$page = get_query_var( 'page' );
$page = $page ? $page : 1;
$print_url_page = $this->print_url( false, $page );
}
//Build link(s)
$link = '<p class="wpf_wrapper"><a class="' . $css_class . '" href="' . $print_url . '"' . ( $link_target == 'new' ? ' target="_blank"' : '' ) . '>' . $print_text . '</a>';
if( isset( $print_url_page ) ) {
$link .= ' | ';
$link .= '<a class="' . $css_class . ' ' . $css_class . '_cur" href="' . $print_url_page . '"' . ( $link_target == 'new' ? ' target="_blank"' : '' ) . '>' . $print_text_page . '</a>';
}
$link .= '</p><!-- .wpf_wrapper -->';
//Place link(s)
if( $placement == 'above' )
$content = $link . $content;
elseif( $placement == 'below' )
$content = $content . $link;
elseif( $placement == 'both' )
$content = $link . $content . $link;
}
return $content;
}
/*
* Convert links to endnotes if desired
* @param string $content
* @uses $this::is_print, $this::get_options
* @filter the_content
* @return string
*/
function filter_the_content_late( $content ) {
if( $this->is_print() ) {
global $post;
$options = $this->get_options();
//Endnotes
if( $options[ 'endnotes' ] ) {
$links = array();
$i = 1;
//Build array of links
preg_match_all( '#<a href=(["\'{1}])([^"\']+)(["\'{1}])([^>]*)>(.*?)</a>#i', $content, $matches );
if(
isset( $matches ) && is_array( $matches ) &&
array_key_exists( 0, $matches ) && !empty( $matches[ 0 ] ) &&
array_key_exists( 2, $matches ) && !empty( $matches[ 2 ] ) &&
array_key_exists( 5, $matches ) && !empty( $matches[ 5 ] )
) {
//Format matches for replacement in content
$replacements = array();
foreach( $matches[ 0 ] as $key => $match ) {
$replacements[ $match ] = array(
'url' => $matches[ 2 ][ $key ],
'title' => $matches[ 5 ][ $key ]
);
}
//Replace links with endnote markers
foreach( $replacements as $match => $args ) {
$content = str_replace( $match, $args[ 'title' ] . '[' . $i . ']', $content );
$links[ $i ] = $args;
$i++;
}
//Output endnotes
$endnotes = '<div class="wpf-endnotes">';
$endnotes .= '<strong>' . $options[ 'endnotes_label' ] . '</strong>';
$endnotes .= '<ol>';
foreach( $links as $link ) {
$endnotes .= '<li>';
$endnotes .= preg_replace( '#<img(.*)>#', '[Image]', $link[ 'title' ] ) . ': ' . esc_url( $link[ 'url' ] );
$endnotes .= '</li>';
}
$endnotes .= '</ol></div><!-- .wpf-endnotes -->';
$content .= $endnotes;
}
}
}
return $content;
}
/*
* Generate URL for post's printer-friendly format
* @param int $post_id
* @param int $page
* @uses is_view_all, is_home, is_front_page, home_url, $post, get_permalink, is_category, get_category_link, is_tag, get_tag_link, is_date, get_query_var, get_day_link, get_month_link, get_year_link, is_tax, get_queried_object, get_term_link, $wp_rewrite, path_join, trailingslashit, add_query_arg
* @return string or bool
*/
function print_url( $post_id = false, $page = false ) {
if( $page === true )
return false;
if( function_exists( 'is_view_all' ) && is_view_all() )
$page = false;
$link = false;
//Get link base specific to page type being viewed
if( is_singular() || in_the_loop() ) {
if( $post_id == false ) {
global $post;
$post_id = $post->ID;
}
if( !$post_id )
return false;
$link = get_permalink( $post_id );
}
elseif( is_home() || is_front_page() )
$link = home_url( '/' );
elseif( is_category() )
$link = get_category_link( get_query_var( 'cat' ) );
elseif( is_tag() )
$link = get_tag_link( get_query_var( 'tag_id' ) );
/* DISABLED FOR NOW AS PRINTING OF DATE-BASED ARCHIVES DOESN'T WORK YET
elseif( is_date() ) {
$year = get_query_var( 'year' );
$monthnum = get_query_var( 'monthnum' );
$day = get_query_var( 'day' );
if( $day )
$link = get_day_link( $year, $monthnum, $day );
elseif( $monthnum )
$link = get_month_link( $year, $monthnum );
else
$link = get_year_link( $year );
}*/
elseif( is_tax() ) {
$queried_object = get_queried_object();
if( is_object( $queried_object ) && property_exists( $queried_object, 'taxonomy' ) && property_exists( $queried_object, 'term_id' ) )
$link = get_term_link( (int)$queried_object->term_id, $queried_object->taxonomy );
}
//If link base is set, build link
if( $link !== false ) {
global $wp_rewrite;
$page = intval( $page );
if( $wp_rewrite->using_permalinks() ) {
$link = path_join( $link, $this->query_var );
if( $page )
$link = path_join( $link, intval( $page ) );