Meta_Query as a way how to setup CPT permalinks – is it a good thing?

Since it is a performance question, you might be able to avoid using meta keys at all by storing/getting that data another way and not having to set a separate meta field to match with…

a. You could get the year from the published $post->post_date… So that when doing the query just use the date argument:

$args = array(
    'post_type' => $wp_query->query['post_type'],
    'date_query' => array( array('year' => $wp_query->query['year']) ),
    'posts_per_page' => -1
);
$posts = get_posts($args);

b. You could set the issue number using the page attributes $post->menu_order field. This would have the added advantage of giving it’s own post writing screen metabox (and even the quick edit on the post list screen) without any additional code, and sits well with the purpose of the field (ordering issues like you would pages.) Just add support to the post type when registering it, or you can also do:

add_post_type_support('issue','page-attributes');

…then following the code above you would have:

if (!empty($posts)) {
    foreach ($posts as $post) {
        if ($post->menu_order == $wp_query->query['cibulka_val']) {
            $data['id'] = $post->ID;
        }
    }
}

The advantage is both post_date and menu_order are both in the row of the posts table (and thus the $post object automatically too) so no need for SQL to access the postmeta table this way to match the data… though it is probably a pretty small gain if multipled by thousands who knows… you could still be getting hundreds of posts for that year and looping them this way.

So instead, you could use the menu_order and post_date as mentioned, but do you own custom query just to get the Post ID – which truly is a super-efficient way of doing it – there is really nothing faster here. eg:

if (isset($wp_query->query['cibulka_key'])) {
    global $wpdb;
    $query = "SELECT ID FROM ".$wpdb->prefix."posts 
              WHERE YEAR(post_date) = '".$wp_query->query['year']."' 
              AND menu_order="".$wp_query->query["cibulka_val']."' 
              AND post_status="publish"";
    $postid = $wpdb->get_var($query);
    if ($postid) {
        $data['id'] = $postid;
        // if this is really needed here?
        $data['post'] = get_post($postid);
    } else {$data = array();}
    include_template_with_var('single.php', $data);
}

Leave a Comment