Discussion:
is_single() includes attachments
Bart Schouten
2014-09-02 01:38:20 UTC
Permalink
(I wrote this two weeks ago).

Hi all,

There seems to be a bit of a confusion all around about the "is_single()"
template function.
"This conditional tag checks if a single post of any post type except
attachment and page post types is being displayed. (...). To check for all
the post types, use the is_singular() function."

However when you check the code it is clear attachments are included, not
excluded:

(Talking about 3.9.2 now)..

query.php: WP_Query::init_query_flags() initializes $this->is_single to
false.

query.php: WP_Query::parse_query() then does:

if ( ('' != $qv['attachment']) || !empty($qv['attachment_id']) ) {
$this->is_single = true;
$this->is_attachment = true;
}

Also, further down:

} elseif ( '' != $qv['static'] || '' != $qv['pagename'] ||
!empty($qv['page_id']) ) {
$this->is_page = true;
$this->is_single = false;
}

This "is_single = false" is pointless since is_single was already false in
all conditions. But that's beside the point really. From the code you can
see that "pages" are excluded but "attachments" are included in
"is_single".

There is other code that depends on this:

E.g. post-template.php, get_body_class(), line 536:

if ( is_attachment() ) {

...only runs if is_single() is also true, ie. it is situated inside an if
( is_single() ) block.

But this code in query.php is meaningless now:

$this->is_singular = $this->is_single || $this->is_page ||
$this->is_attachment;

because is_single already includes is_attachment at this point.

It seems to me that the intent of this design was for is_single to NOT
include is_attachment.

In 3.9.2 the offending line is at query.php:1500, in trunk it is at
query.php:1590.

(There is a lot more documentation for that function (parse_query) in
trunk...?)

--------
There is this function in link-template.php:

function adjacent_posts_rel_link_wp_head() {
if ( !is_singular() || is_attachment() )
return;
adjacent_posts_rel_link();
}

That could also be written as:

function adjacent_posts_rel_link_wp_head() {
if ( is_single() || is_page() ) {
adjacent_posts_rel_link();
}
}

provided that is_single would actually work as intended.

(!is_singular || is_attachment) is equivalent to !(is_singular &&
!is_attachment) which means you could also write:

function adjacent_posts_rel_link_wp_head() {
if ( is_singular() && !is_attachment ) {
adjacent_posts_rel_link();
}
}

and that would currently also work.)

---
This code:

function get_boundary_post( $in_same_term = false, $excluded_terms = '',
$start = true, $taxonomy = 'category' ) {
$post = get_post();
if ( ! $post || ! is_single() || is_attachment() || ! taxonomy_exists(
$taxonomy ) )
return null;
}

actually only tests for is_attachment because of the is_single() flaw.

It ought to be covered by !is_single() but that doesn't work, so an
additional test is needed.

Of course there is many more references to is_single() and you'd need to
check them all. Many templates may also have been designed around this
aberrant code. Any template that checks for is_single expecting it to only
cover single posts, would find to (its) surprise that attachments are also
covered by that code. So e.g. some sidebar code that does different things
depending on query/page type would need to test for is_attachment first or
as a form of "if (is_single && !is_attachment)".

I encountered it because I have some buggy sidebar code that bugs out on
any anomaly of this kind. Canary in the coalmine kinda thing :p.

I am not any regular contributor, nor have I ever contributed any code to
anything, but instead of writing this as a bug in TRAC I thought I would
(first) post it here.

I guess I could submit a bug and then start modifying files, make patch
files out of them, then attach them to the bug, but it is still a
modification that can affect a lot of files (potentially) so I guess I
just want to offer this just as a suggestion for now.

Regards,

Bart Schouten, NL.
Mark E
2014-09-05 17:14:34 UTC
Permalink
Looking for some specific code:

There is, or was, a drop-in database lib tool for WordPress that can
allow a site to have multiple read/write database servers.
If I recall correctly this was developed years ago in the earlier days
of WP.org and I believe this was built and made available as open source
to by Automattic.

Basically what it does is the you configure the site so the any number
of database servers can be used for ultra high traffic scenarios, and
each DB server in the config can be set for reads or writes. Then when
WP needs to do a query it determines which server to send the request
to. Something like that.

Anyone know where that code is located?

Mark
Mark E
2014-09-05 17:20:24 UTC
Permalink
Doh - found it!

https://wordpress.org/plugins/hyperdb/
Post by Mark E
There is, or was, a drop-in database lib tool for WordPress that can
allow a site to have multiple read/write database servers.
If I recall correctly this was developed years ago in the earlier days
of WP.org and I believe this was built and made available as open
source to by Automattic.
Basically what it does is the you configure the site so the any number
of database servers can be used for ultra high traffic scenarios, and
each DB server in the config can be set for reads or writes. Then when
WP needs to do a query it determines which server to send the request
to. Something like that.
Anyone know where that code is located?
Mark
_______________________________________________
wp-hackers mailing list
http://lists.automattic.com/mailman/listinfo/wp-hackers
Bart Schouten
2014-09-06 00:22:35 UTC
Permalink
Thanks! That should prove useful some day.
From what I see it is not a real parallel computing thing in the sense of
it being really advanced but it seems to rely on partitions of the data
set in order to simply say "this part gets stored there" and "this other
part gets stored elsewhere". But perhaps that only makes sense because
full redundancy would obviate any advantages; then again, we are talking
about db-reads mostly so any regular 'load balancing' strategy should be
sufficient or perfect for this as well... (?) . Actually, it seems pretty
awesome.

Regards,

Bart.
Doh - found it!
https://wordpress.org/plugins/hyperdb/
There is, or was, a drop-in database lib tool for WordPress that can allow
a site to have multiple read/write database servers.
If I recall correctly this was developed years ago in the earlier days of
WP.org and I believe this was built and made available as open source to by
Automattic.
Basically what it does is the you configure the site so the any number of
database servers can be used for ultra high traffic scenarios, and each DB
server in the config can be set for reads or writes. Then when WP needs to
do a query it determines which server to send the request to. Something
like that.
Anyone know where that code is located?
Mark
_______________________________________________
wp-hackers mailing list
http://lists.automattic.com/mailman/listinfo/wp-hackers
_______________________________________________
wp-hackers mailing list
http://lists.automattic.com/mailman/listinfo/wp-hackers
Loading...