Opened 13 years ago
Closed 10 years ago
#22110 closed enhancement (wontfix)
Check for current conditional
| Reported by: |
|
Owned by: | |
|---|---|---|---|
| Milestone: | Priority: | normal | |
| Severity: | normal | Version: | 3.4 |
| Component: | Query | Keywords: | needs-patch |
| Focuses: | Cc: |
Description
More than once I've needed a programmatic way to determine what page is being displayed, for example when implementing event tracking recently:
add_action( 'wp_enqueue_scripts', function() {
wp_enqueue_script( 'my-site', get_template_directory_uri() . '/js/mysite.js', array( 'jquery' ), '1', true );
// Figure out what type of page we're on
$is = '';
foreach ( $GLOBALS['wp_query'] as $key => $value ) {
if ( true === $value && 'is_' === substr( $key, 0, 3 ) ) {
$is = substr( $key, 3, strlen($key) );
break;
}
}
wp_localize_script( 'my-site', 'event_tracking', array(
'category' => $is,
) );
} );
And then used like:
<a onclick="_gaq.push(['_trackEvent', event_tracking.category, 'more-stories', 'click']);">Action</a>
Now granted the above way to determine the current page is a little janky, and has at least one flaw (on custom post type archives because both "is_archive" and "is_post_type_archive" are set, and it will find "is_archive" first, every time). TBH this was me with a bowl of chili in one hand trying to avoid typing out "if ( is_* ) { } elseif ( is_* ) { } elseif ( is_* ) {} ...".
A saner function would probably explicitly check each conditional, which would make it a little more tedious but also more maintainable:
function where_am_i( $return = 'simple' ) {
global $wp_query;
if ( ! isset( $wp_query ) ) {
_doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.5' );
return false;
}
$primary = null;
$secondary = null;
$tertiary = null;
// Tried to maintain the hierarchy from query.php
if ( true === $wp_query->is_robots ) {
$primary = 'robots';
} elseif ( true === $wp_query->is_attachment ) {
$primary = 'attachment';
$secondary = 'single';
$tertiary = 'singular';
} elseif ( true === $wp_query->is_page ) {
$primary = 'page';
$tertiary = 'singular';
} elseif ( true === $wp_query->is_single ) {
$primary = 'single';
$secondary = 'singular';
} elseif ( true === $wp_query->is_search ) {
$primary = 'search';
} elseif ( true === $wp_query->is_time ) {
$primary = 'time';
$secondary = 'date';
$tertiary = 'archive';
} elseif ( true === $wp_query->is_day ) {
$primary = 'day';
$secondary = 'date';
$tertiary = 'archive';
} elseif ( true === $wp_query->is_month ) {
$primary = 'month';
$secondary = 'date';
$tertiary = 'archive';
} elseif ( true === $wp_query->is_year ) {
$primary = 'year';
$secondary = 'date';
$tertiary = 'archive';
} elseif ( true === $wp_query->is_date ) {
$primary = 'date';
$secondary = 'archive';
} elseif ( true === $wp_query->is_category ) {
$primary = 'category';
$secondary = 'archive';
} elseif ( true === $wp_query->is_tag ) {
$primary = 'tag';
$secondary = 'archive';
} elseif ( true === $wp_query->is_tax ) {
$primary = 'custom_taxonomy';
$secondary = 'archive';
} elseif ( true === $wp_query->is_author ) {
$primary = 'author';
$secondary = 'archive';
} elseif ( true === $wp_query->is_post_type_archive ) {
$primary = 'post_type';
$secondary = 'archive';
} elseif ( true === $wp_query->is_feed ) {
$primary = 'feed';
} elseif ( true === $wp_query->is_trackback ) {
$primary = 'trackback';
} elseif ( true === $wp_query->is_comments_popup ) {
$primary = 'comments_popup';
$secondary = 'comments';
} elseif ( true === $wp_query->is_preview ) {
$primary = 'preview';
$secondary = 'singular';
} elseif ( true === $wp_query->is_admin ) {
$primary = 'admin';
} elseif ( true === $wp_query->is_comment_feed ) {
$primary = 'comment_feed';
$secondary = 'comments';
$tertiary = 'feed';
} elseif ( true === $wp_query->is_404 ) {
$primary = '404';
$secondary = 'singular';
} elseif ( true === $wp_query->is_home ) {
$primary = 'home';
if ( true === $wp_query->is_posts_page ) {
$secondary = 'posts_page';
$tertiary = 'page';
} else {
$secondary = 'static_page';
}
}
if ( 'detailed' === $return ) {
$details = compact( $primary, $secondary, $tertiary );
$details = array_filter( $details ); // Remove empty
return $details;
}
// 'simple' === $return
return $primary;
}
Should it use $wp_the_query so that it always acts on the main query?
Change History (11)
#2
in reply to:
↑ 1
@
13 years ago
Replying to scribu:
Can't you just use get_body_class()?
Honestly I hadn't considered that, I was mostly aware of body_class() which of course just outputs a space-delimited string.
get_body_class() looks like it would mostly work, but there are some core differences:
- rtl is the first element of the array when is_rtl() is set, so if I wanted to use this to a theme (for example) I would have to do some funky workarounds to account for rtl support — the first element of the array wouldn't always be the primary section of the site.
- it wouldn't work if you needed to programmaticallly find "where am I" in a feed, or anywhere that's not really user-facing.
- no clear identifier that you're on a custom taxonomy, e.g. the second element is "tax-<taxonomy name>" so when you just want to know whether you're on a custom taxonomy page you have to do some custom parsing.
You're right that get_body_class() would work better than the hacky way I currently get the current section, for the most part.
#3
follow-up:
↓ 6
@
13 years ago
Off the top of my head, I can think of four supersets of other flags: is_time, is_date, is_archive, is_singular. So, is_time is true when is_hour, is_minute, or is_second is true. is_date is true when is_day, is_month, or is_year. is_singular when is_single or is_page. (Also is_attachment, but when is_attachment is true, is_single XOR is_page is always true.) is_archive is a superset of a whole bunch of conditionals, such as is_tag, is_category, is_tax, is_post_type_archive, etc.
I would probably just code around those supersets. It can probably be much saner than a giant if/elseif/elseif/... statement.
#4
follow-up:
↓ 5
@
13 years ago
it wouldn't work if you needed to programmaticallly find "where am I" in a feed, or anywhere that's not really user-facing.
Why not?
#5
in reply to:
↑ 4
@
13 years ago
Replying to scribu:
it wouldn't work if you needed to programmaticallly find "where am I" in a feed, or anywhere that's not really user-facing.
Why not?
Using feeds as an example, in the default feed:
var_dump(get_body_class()); array (size=0) empty
In a custom feed:
var_dump(get_body_class()); array (size=3) 0 => string 'logged-in' (length=9) 1 => string 'admin-bar' (length=9) 2 => string 'no-customize-support' (length=20)
#6
in reply to:
↑ 3
@
13 years ago
Replying to nacin:
Off the top of my head, I can think of four supersets of other flags: is_time, is_date, is_archive, is_singular. So, is_time is true when is_hour, is_minute, or is_second is true. is_date is true when is_day, is_month, or is_year. is_singular when is_single or is_page. (Also is_attachment, but when is_attachment is true, is_single XOR is_page is always true.) is_archive is a superset of a whole bunch of conditionals, such as is_tag, is_category, is_tax, is_post_type_archive, etc.
I would probably just code around those supersets. It can probably be much saner than a giant if/elseif/elseif/... statement.
If I weren't trying to make it "everything for everybody" it would look more like this:
function where_am_i() {
global $wp_query;
if ( ! isset( $wp_query ) ) {
_doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.5' );
return false;
}
// Tried to maintain the hierarchy from query.php
if ( true === $wp_query->is_robots ) {
return 'robots';
} elseif ( true === $wp_query->is_attachment ) {
return 'attachment';
} elseif ( true === $wp_query->is_page ) {
return 'page';
} elseif ( true === $wp_query->is_single ) {
return 'single';
} elseif ( true === $wp_query->is_search ) {
return 'search';
} elseif ( true === $wp_query->is_time ) {
return 'time';
} elseif ( true === $wp_query->is_date ) {
return 'date';
} elseif ( true === $wp_query->is_category ) {
return 'category';
} elseif ( true === $wp_query->is_tag ) {
return 'tag';
} elseif ( true === $wp_query->is_tax ) {
return 'custom_taxonomy';
} elseif ( true === $wp_query->is_author ) {
return 'author';
} elseif ( true === $wp_query->is_post_type_archive ) {
return 'post_type';
} elseif ( true === $wp_query->is_feed ) {
return 'feed';
} elseif ( true === $wp_query->is_trackback ) {
return 'trackback';
} elseif ( true === $wp_query->is_admin ) {
return 'admin';
} elseif ( true === $wp_query->is_404 ) {
return '404';
} elseif ( true === $wp_query->is_home ) {
return 'home';
}
return null;
}
#8
@
13 years ago
After a bit more testing, get_blog_class() could work but:
1) It should use in-memory caching to store the resulting body class (e.g., putting it in a global and returning the global if ! empty())
2) the first two elements of the array should be reversed in some cases. Any kind of archive-type page (author, date, etc) return "archive" as the 0th element when the useful value is held in the 1st element, while non-archive pages return the desired value (single, home, etc) in the 0th element.
3) I'd kinda want to wrap it in a helper, like: function where_am_i() { return get_body_class()[0]; }
I know I'm not the only person who would find this useful, but if you all disagree then I'll happily keep using our local copy.
Can't you just use get_body_class()?