document.write("
<?php if(!defined('ABSPATH')) { die(); }
/**
* Plugin Name: Improved Template Hierarchy
* Plugin URI: https://gschoppe.com/wordpress/better-template-hierarchy/
* Description: Implementation of suggested improvements to the WordPress Template Heirarchy
* Author: Greg Schoppe
* Author URI: https://gschoppe.com
* Version: 1.1.0
**/
if( !class_exists('GJSImprovedTemplateHierarchy') ) {
class GJSImprovedTemplateHierarchy {
private static $persistently_cache;
private static $cache_expiration = 1800;
private $was_404 = false;
private $custom_path_templates;
private $current_template_path;
private $theme;
private $cache_hash;
public static function Instance() {
static $instance = null;
if ($instance === null) {
$instance = new self();
}
return $instance;
}
private function __construct() {
add_filter( 'init', array( $this, 'init') );
add_filter( 'pre_handle_404', array( $this, 'prevent_404_on_custom_path_templates' ) );
add_filter( 'redirect_canonical', array( $this, 'prevent_redirecting_custom_path_templates' ), 10, 2 );
add_filter( 'template_include', array( $this, 'insert_template_overrides' ), 0 );
}
public function init() {
// Initialize caching on first run.
if ( ! isset( self::$persistently_cache ) ) {
self::$persistently_cache = apply_filters( 'cache_custom_path_templates_persistently', false );
}
$this->theme = wp_get_theme();
$this->cache_hash = md5( 'GJSImprovedTemplateHierarchy: ' . $this->theme->theme_root . '/' . $this->theme->stylesheet );
$this->populate_custom_path_templates();
}
public function insert_template_overrides( $template ) {
if( !apply_filters( 'disable_front_page_templates', false ) ) {
if( is_front_page() && is_page() ) {
$page_template = get_page_template_slug( get_the_ID() );
if( $page_template ) {
$path = locate_template( $page_template );
if( $path ) {
return $path;
}
}
}
}
if( !apply_filters( 'disable_blog_template_file', false ) ) {
if( is_home() ) {
$path = locate_template( 'blog.php' );
if( $path ) {
return $path;
}
}
}
if( !apply_filters( 'disable_custom_path_templates', false ) ) {
if( $this->was_404 || apply_filters( 'force_custom_path_templates', false ) ) {
$template_path = $this->get_current_template_path();
if( $template_path ) {
add_filter( 'body_class', array( $this, 'add_template_body_classes' ) );
return $template_path;
}
}
}
return $template;
}
public function prevent_404_on_custom_path_templates( $short_circuit ) {
global $wp_query;
$template_path = $this->get_current_template_path();
if( $template_path ) {
if( $wp_query->is_404 || ( property_exists( $wp_query, 'posts' ) && count( $wp_query->posts ) == 0 ) ) {
$this->was_404 = true;
}
$wp_query->is_404 = false;
status_header( 200 );
return true;
}
return $short_circuit;
}
public function prevent_redirecting_custom_path_templates( $new_url, $original_url ) {
global $wp;
if( $new_url ) {
$request = add_query_arg( array(), $wp->request );
$request = trim( $request, '/' );
$slashed_request = '/' . $request . '/';
$canonical = get_site_url( null, $slashed_request);
if( $canonical === $new_url ) {
return $new_url;
}
$template_path = $this->get_current_template_path();
if( $template_path ) {
if( $canonical !== $original_url ) {
return $canonical;
} else {
return false;
}
}
}
return $new_url;
}
public function add_template_body_classes( $classes ) {
$template_class = 'path-template-' . $this->get_current_template_slug();
$class_no_php = $template_class;
if( substr( $class_no_php, -4 ) === '-php') {
$class_no_php = substr( $class_no_php, 0, -4 );
}
$new_classes = array( 'path-template', $template_class, $class_no_php );
return array_merge( $classes, $new_classes );
}
// private functions
private function populate_custom_path_templates() {
$path_templates = $this->cache_get( 'custom_path_templates' );
if ( ! is_array( $path_templates ) ) {
$path_templates = array();
$files = (array) wp_get_theme()->get_files( 'php', 1 );
foreach( $files as $file => $full_path ) {
$header_template = array(
'path' => "Custom Path",
'subdirs' => "Parse Subdirectories"
);
$header = get_file_data( $full_path, $header_template, 'custom_paths');
if( $header['path'] ) {
$path = trim( $header['path'], '/' );
$path_templates[ $path ] = array(
'file' => $file,
'subdirs' => $this->is_truthy( $header['subdirs'] )
);
}
}
$this->cache_add( 'custom_path_templates', $path_templates );
}
$this->custom_path_templates = $path_templates;
}
private function get_current_template_slug() {
$path = $this->get_current_template_path();
$base = basename( $path );
$slug = sanitize_title( $base );
return $slug;
}
private function get_current_template_path() {
global $wp;
if( $this->current_template_path === null ) {
$request = add_query_arg( array(), $wp->request );
$template_path = $this->get_matching_custom_template( $request );
$this->current_template_path = $template_path;
}
return $this->current_template_path;
}
private function get_matching_custom_template( $request ) {
$request = trim( $request, '/' );
$path_parts = explode( '/', $request );
$templates = $this->custom_path_templates;
$ancestor = false;
while( $path_parts ) {
$temp = implode( '/', $path_parts );
if( isset( $templates[$temp] ) ) {
if( !$ancestor || $templates[$temp]['subdirs'] ) {
$path = locate_template( $templates[$temp]['file'] );
if( $path ) {
return $path;
}
}
}
$ancestor = true;
array_pop( $path_parts );
}
return false;
}
private function cache_get( $key ) {
return wp_cache_get( $key . '-' . $this->cache_hash, 'GJSImprovedTemplateHierarchy' );
}
private function cache_add( $key, $data ) {
return wp_cache_add( $key . '-' . $this->cache_hash, $data, 'GJSImprovedTemplateHierarchy', self::$cache_expiration );
return false;
}
private function is_truthy( $value ) {
$truthy_vals = array( 'true', 'yes' );
$truthy_vals = apply_filters( 'improved_template_hierarchy_truthy_values', $truthy_vals );
$value = trim( strtolower( $value ) );
$value = apply_filters( 'improved_template_hierarchy_truthy_test_value', $value );
return in_array( $value, $truthy_vals );
}
}
GJSImprovedTemplateHierarchy::Instance();
}
gjs-improved-template-hierarchy.php - Snippet hosted by \"Cacher\"
");