Last active
June 10, 2023 14:51
-
-
Save krystyna93/e909a5d50e96ed237a10b5eb7bb1d976 to your computer and use it in GitHub Desktop.
Custom WordPress Metabox: Relationship Between Two CPT's
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
a general overview of how to create a WordPress metabox that establishes a relationship between two custom post types and shares | |
details between them both, then output the data to the front end. | |
You will need to first register your custom post types using the register_post_type() function in your WordPress theme's functions.php | |
file. | |
Create a metabox for one of the custom post types using the add_meta_box() function. Within the metabox callback function | |
you can use the metadata API to retrieve data related to the other custom post type. | |
Use a custom field to store the relationship between the two custom post types. | |
This can be done using the add_post_meta() and update_post_meta() functions. | |
Retrieve the related data from the other custom post type using the get_posts() function and the meta_query parameter to filter | |
by the custom field value. You can also use WP_Query to retrieve posts and filter them based on custom field values. | |
Output the related data in the metabox using HTML and/or PHP. | |
To display the data on the front end, you can create a custom template for your custom post type or use a shortcode to display | |
the related data on a post or page. | |
For example, let's say you have two custom post types: "Books" and "Authors". You want to establish a relationship between them so | |
that each book can have one author and each author can write multiple books. Here's how you might set this up: | |
Register the custom post types In your functions.php file, register the "Books" custom post type: | |
*/ | |
function create_books_post_type() { | |
$args = array( | |
'labels' => array( | |
'name' => __( 'Books' ), | |
'singular_name' => __( 'Book' ) | |
), | |
'public' => true, | |
'has_archive' => true, | |
'supports' => array( 'title', 'editor', 'thumbnail' ) | |
); | |
register_post_type( 'books', $args ); | |
} | |
add_action( 'init', 'create_books_post_type' ); | |
/*Then, register the "Authors" custom post type: */ | |
function create_authors_post_type() { | |
$args = array( | |
'labels' => array( | |
'name' => __( 'Authors' ), | |
'singular_name' => __( 'Author' ) | |
), | |
'public' => true, | |
'has_archive' => true, | |
'supports' => array( 'title', 'editor', 'thumbnail' ) | |
); | |
register_post_type( 'authors', $args ); | |
} | |
add_action( 'init', 'create_authors_post_type' ); | |
/* Create a metabox for the "Books" custom post type Create a metabox for the "Books" custom post type using the add_meta_box() | |
function. Within the metabox callback function, use the metadata API to retrieve data related to the "Authors" custom post type.*/ | |
function books_author_metabox() { | |
add_meta_box( | |
'books-author-metabox', | |
__( 'Author Details' ), | |
'books_author_metabox_callback', | |
'books' | |
); | |
} | |
add_action( 'add_meta_boxes', 'books_author_metabox' ); | |
function books_author_metabox_callback( $post ) { | |
// Add a nonce field to the books author metabox | |
wp_nonce_field( basename( __FILE__ ), 'books_author_nonce' ); | |
// Retrieve the author ID from the custom field | |
$author_id = get_post_meta( $post->ID, 'book_author', true ); | |
// Retrieve the author name from the "Authors" custom post type | |
$author_name = ''; | |
if ( $author_id ) { | |
$author_post = get_post( $author_id ); | |
$author_name = $author_post->post_title; | |
} | |
// Output the author name in the metabox | |
echo 'Author: ' . $author_name; | |
// Add a select dropdown for choosing the author | |
$args = array( | |
'post_type' => 'authors', | |
'orderby' => 'title', | |
'order' => 'ASC', | |
'posts_per_page' => -1, | |
); | |
$authors = get_posts( $args ); | |
echo '<label for="book_author">Select Author:</label>'; | |
echo '<select name="book_author">'; | |
echo '<option value="">-- Select --</option>'; | |
foreach ( $authors as $author ) { | |
$selected = ''; | |
if ( $author->ID == $author_id ) { | |
$selected = 'selected'; | |
// Add the selected attribute if the author is already set for the book | |
echo '<option value="' . $author->ID . '" ' . $selected . '>' . $author->post_title . '</option>'; | |
} | |
echo '</select>'; | |
} | |
/* | |
Use a custom field to store the relationship between the two custom post types Add a custom field to the "Books" custom post type | |
to store the relationship between the book and author. You can use the add_post_meta() function to add the custom field, and the | |
update_post_meta() function to update it. | |
*/ | |
function save_books_author_metabox( $post_id ) { | |
// Verify the nonce before saving data | |
if ( !isset( $_POST['books_author_nonce'] ) || !wp_verify_nonce( $_POST['books_author_nonce'], basename( __FILE__ ) ) ) { | |
return $post_id; | |
} | |
// Save the author ID to the custom field | |
if ( isset( $_POST['book_author'] ) ) { | |
$author_id = sanitize_text_field( $_POST['book_author'] ); | |
update_post_meta( $post_id, 'book_author', $author_id ); | |
} | |
} | |
add_action( 'save_post_books', 'save_books_author_metabox' ); | |
/* | |
Retrieve the related data from the "Authors" custom post type Retrieve the related data from the "Authors" custom post type | |
using the get_posts() function and the meta_query parameter to filter by the custom field value. | |
*/ | |
function get_books_by_author( $author_id ) { | |
$args = array( | |
'post_type' => 'books', | |
'orderby' => 'title', | |
'order' => 'ASC', | |
'posts_per_page' => -1, | |
'meta_query' => array( | |
array( | |
'key' => 'book_author', | |
'value' => $author_id, | |
), | |
), | |
); | |
$books = get_posts( $args ); | |
return $books; | |
} | |
/*Output the related data in the metabox and on the front end Output the related data in the metabox using HTML and/or PHP. | |
To display the data on the front end, you can create a custom template for your custom post type or use a shortcode to display the | |
related data on a post or page. | |
For example, to display a list of books by an author on the front end, you could create a shortcode that accepts the author ID | |
as a parameter, then uses the get_books_by_author() function to retrieve the books and output them in a list. | |
*/ | |
function books_by_author_shortcode( $atts ) { | |
$atts = shortcode_atts( array( | |
'author_id' => '', | |
), $atts ); | |
$books = get_books_by_author( $atts['author_id'] ); | |
if ( ! empty( $books ) ) { | |
echo '<ul>'; | |
foreach ( $books as $book ) { | |
echo '<li>' . $book->post_title . '</li>'; | |
} | |
echo '</ul>'; | |
} | |
} | |
add_shortcode( 'books_by_author', 'books_by_author_shortcode' ); | |
/*You can then use the [books_by_author] shortcode in any post or page, like this: */ | |
[books_by_author author_id="123"] | |
/*This will display a list of books with the "book_author" custom field set to 123. | |
Additionally, if you want to display the related data on a custom template for your custom post type, you can create a new file | |
called single-books.php in your theme directory. This file will be used to display single entries of the "Books" custom post type. | |
Within this file, you can use the get_post_meta() function to retrieve the author ID from the custom field and then use | |
the get_post() function to retrieve the author name from the "Authors" custom post type. You can then output the author name | |
and any other related data within the template. | |
Here's an example single-books.php file: | |
*/ | |
<?php get_header(); ?> | |
<?php while ( have_posts() ) : the_post(); ?> | |
<article class="entry"> | |
<header class="entry-header"> | |
<h1 class="entry-title"><?php the_title(); ?></h1> | |
<?php | |
// Retrieve the author ID from the custom field | |
$author_id = get_post_meta( get_the_ID(), 'book_author', true ); | |
// Retrieve the author name from the "Authors" custom post type | |
$author_name = ''; | |
if ( $author_id ) { | |
$author_post = get_post( $author_id ); | |
$author_name = $author_post->post_title; | |
} | |
?> | |
<p class="entry-meta">By <?php echo $author_name; ?></p> | |
</header> | |
<div class="entry-content"> | |
<?php the_content(); ?> | |
</div> | |
</article> | |
<?php endwhile; ?> | |
<?php get_footer(); | |
/* | |
In this example, we retrieve the author ID from the "book_author" custom field using the get_post_meta() function, | |
and then use the get_post() function to retrieve the author name from the "Authors" custom post type. | |
We then output the author name within the entry header using PHP. | |
This is just one example of how you can display related data from two custom post types in WordPress. | |
The implementation may vary depending on your specific use case and requirements, but this should give you a general idea of | |
how to establish a relationship between two custom post types and output the related data in a metabox and on the front end. */ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment