To get the posts from a post type you can use get_posts()
$posts = get_posts(
array (
'numberposts' => -1,
'posts_per_page' => -1,
'post_type' => 'store'
)
);
Be aware, the -1
is dangerous: If there are millions of stores, the query might run into a time-out.
Here is a very basic example for such a meta box. You will find much more examples and explanations in our tag metabox.
<?php # -*- coding: utf-8 -*-
/* Plugin Name: Store metabox */
add_action( 'add_meta_boxes_post', 'wpse_98184_register_store_metabox' );
add_action( 'save_post', 'wpse_98184_save_store_metabox' );
function wpse_98184_register_store_metabox()
{
add_meta_box( 'post_store', 'Store', 'wpse_98184_render_store_metabox', NULL, 'side' );
}
function wpse_98184_render_store_metabox( $object, $box )
{
$nonce = wp_create_nonce( __FILE__ );
echo "<input type='hidden' name='nonce_store_mbox' value='$nonce' />";
$posts = get_posts(
array (
'numberposts' => -1,
'posts_per_page' => -1,
'post_type' => 'store',
)
);
if ( ! $posts )
return print 'No store found';
$meta = get_post_meta( $object->ID, '_store', TRUE );
$selected = $meta ? $meta : 0;
$html = '<select name="_store"><option value="0">Select a store</option>';
foreach ( $posts as $post )
$html .= sprintf(
'<option value="%1$d" %2$s>%3$s</option>',
esc_attr( $post->ID ),
selected( $post->ID, $selected, FALSE ),
esc_html( $post->post_title )
);
$html .= '</select>';
echo $html;
}
function wpse_98184_save_store_metabox( $id )
{
if ( defined( 'DOING_AJAX' ) && DOING_AJAX )
return;
if ( ! isset ( $_POST[ 'nonce_store_mbox' ] ) )
return;
if ( ! wp_verify_nonce( $_POST[ 'nonce_store_mbox' ], __FILE__ ) )
return;
if ( ! current_user_can( 'edit_post', $id ) )
return;
if ( ! isset ( $_POST['_store'] ) )
return delete_post_meta( $id, '_store' );
update_post_meta( $id, '_store', $_POST['_store'] );
}
To list all these associated posts in a store page, use a function that queries for post meta fields:
function wpse_98184_list_store_posts()
{
$args = array(
'post_type' => 'post',
'numberposts' => -1,
'posts_per_page' => -1,
'meta_query' => array (
array (
'key' => '_store',
'value' => get_the_ID(),
'compare' => '==',
),
)
);
$posts = get_posts( $args );
if ( ! $posts )
return '';
$output = '<ul class="store-posts">';
foreach ( $posts as $post )
$output .= sprintf(
'<li><a href="%1$s">%2$s</a></li>',
get_permalink( $post->ID ),
esc_html( get_the_title( $post->ID ) )
);
$output .= '</ul>';
return $output;
}
You could use this function as a shortcode handler:
add_shortcode( 'storeposts', 'wpse_98184_list_store_posts' );
Then just add [storeposts]
wherever you need that list in your store.