I'm currently working on a custom loop/query where I need to add the permalink of a post to the array of posts I'm retrieving from the DB.
Sadly get_permalink()
produces one additional DB request for every call, which can get pretty intense as I'm listing all posts on one page.
I first thought it might be that calls to get_option( 'permalink_structure' );
or get_option( 'default_category' );
are no auto loaded options, but both are auto loaded. Proof here:
function wpse_list_autoloaded_opts()
{
$results = $wpdb->get_results( "
SELECT option_name, option_value
FROM $wpdb->options
WHERE autoload = 'yes'
" );
echo '<pre>';
foreach( $results as $result )
if ( 'permalink_structure' === $result->option_name OR 'default_category' === $result->option_name )
echo "Name: {$result->option_name}, Value: {$result->option_value}<br />";
echo '<pre>';
}
add_action( 'shutdown', 'wpse_list_autoloaded_opts' );
EDIT: Ok, I managed to track it down to the following lines inside the get_permalink()
function.
if ( is_object($id) && isset($id->filter) && 'sample' == $id->filter ) {
$post = $id;
$sample = true;
} else {
$post = &get_post($id);
$sample = false;
}
So my Q is now: How would I avoid running the else
part, which calls get_post()
and does the additional query?
EDIT 2: Now found out that the docBlock of get_permalink()
is as wrong as the Codex. You can pass the whole $post
object into the function too. This solves the if ( is_object($id)
part.
Still open: From where the heck would I retrieve $post->filter
with a value of 'sample'
?
EDIT 3: Adding $post->filter = 'sample'
to each post object solves the problem. But what remains is a bad feeling that I might break something. The 'sample'
in $id/$post->filter
seems pretty strange and I can't find out where it comes from.