-
-
Save scribu/2865132 to your computer and use it in GitHub Desktop.
/** | |
* Helper class for controlling all aspects of a view. | |
* | |
* Supported methods (automatically hooked): | |
* - init() - for registering post types, taxonomies, rewrite rules etc. | |
* - parse_query() - for correcting query flags | |
* - pre_get_posts() - for altering the query, without affecting the query flags | |
* - posts_search(), posts_clauses(), posts_request() - for direct SQL manipulation | |
* - the_posts() - for various other manipulations | |
* - template_redirect() - for enqueuing scripts etc. | |
* - template_include( $path ) - for loading a different template file | |
* - title_parts( $parts ) - for changing the title | |
* - breadcrumbs( $trail ) - for changing the breadcrumbs | |
* - notices() - for displaying notices | |
*/ | |
abstract class APP_View { | |
/** | |
* Test if this class should handle the current view. | |
* | |
* Use is_*() conditional tags and get_query_var() | |
* | |
* @return bool | |
*/ | |
abstract function condition(); | |
function __construct() { | |
// 'init' hook (always ran) | |
if ( method_exists( $this, 'init' ) ) | |
add_action( 'init', array( $this, 'init' ) ); | |
// $wp_query hooks | |
$actions = array( 'parse_query', 'pre_get_posts' ); | |
$filters = array( 'posts_search', 'posts_clauses', 'posts_request', 'the_posts' ); | |
foreach ( $actions as $method ) { | |
if ( method_exists( $this, $method ) ) | |
add_action( $method, array( $this, '_action' ) ); | |
} | |
foreach ( $filters as $method ) { | |
if ( method_exists( $this, $method ) ) | |
add_filter( $method, array( $this, '_filter' ), 10, 2 ); | |
} | |
// other hooks | |
add_action( 'template_redirect', array( $this, '_template_redirect' ) ); | |
} | |
final function _action( $wp_query ) { | |
if ( $wp_query->is_main_query() && $this->condition() ) { | |
$method = current_filter(); | |
// debug( get_class( $this ) . '->' . $method . '()' ); | |
$this->$method( $wp_query ); | |
} | |
} | |
final function _filter( $value, $wp_query ) { | |
if ( $wp_query->is_main_query() && $this->condition() ) { | |
$method = current_filter(); | |
// debug( get_class( $this ) . '->' . $method . '()' ); | |
$value = $this->$method( $value, $wp_query ); | |
} | |
return $value; | |
} | |
final function _template_redirect() { | |
if ( !$this->condition() ) | |
return; | |
if ( method_exists( $this, 'template_redirect' ) ) | |
$this->template_redirect(); | |
$filters = array( | |
'template_include' => 'template_include', | |
'appthemes_title_parts' => 'title_parts', | |
'appthemes_notices' => 'notices', | |
'breadcrumb_trail_items' => 'breadcrumbs', | |
); | |
foreach ( $filters as $filter => $method ) { | |
if ( method_exists( $this, $method ) ) | |
add_filter( $filter, array( $this, $method ) ); | |
} | |
} | |
} |
The main idea of the class isn't to have an easy way to add hooks; it's to control a single part of a site from a single place in the codebase.
Another idea is that you take this class and make it your own. It's a parent class, but the mechanism itself is not meant to be extensible, since then you get a mess of figuring out if a particular method should/n't automatically be hooked.
I got it. Maybe I'm wrong when implement add_filter
in the code above. My main idea is just stripping out the list of default actions, filters to a function, that will make child class easier to add more automatic hooks, just in case we want to use it in another framework (for ex. the list of hooks in _template_redirect
is appthemes-specific, and we want to change it).
Yes, and what I'm saying is that you should change them directly in the class; and also change the APP_
prefix while you're at it. :)
Oh, got it. I'm too greedy when I want a class-for-all ;)
@scribu: I don't think restricting actions & filters is a good idea. It makes the class less extendable in the future when WP (or we) adds more query actions. Of course we can do the way you suggested but it won't use the benefits of the class (the easy way to implement hooks).
I think we can do something like this: