I’m working on a client site that has two different custom post types: artist
and portfolio
. I’m using the posts-to-posts plugin to create a relationship from each artist to their portfolios.
Artist URL’s are setup as {siteUrl}/artist
, while portfolio URL’s are setup to receive the artist name: {siteUrl}/artist/%artistname%
I wrote the following to check if the portfolio
is connected to an artist
, and if so, change the URL of that portfolio
to {siteUrl}/artist/artist-name/portfolio-name
. If it doesn’t have an artist connected, it directs changes the URL to {siteUrl}/portfolio/portfolio-name
.
function filter_portfolio_link( $post_link, $post ) {
if ( $post->post_type === 'portfolio' ) {
$connected = new WP_query( array(
'post_type' => 'artist',
'connected_type' => 'portfolios_to_artists',
'connected_items' => $post,
'nopaging' => true,
) );
if ($connected->have_posts() ) {
foreach ( $connected as $connectedPost ) {
setup_postdata($connectedPost);
if ($connectedPost->post_type === 'artist') {
$artistName = $connectedPost->post_name;
$first = false;
}
}
$post_link = str_replace( '%artist_name%', $artistName, $post_link );
}
else {
$post_link = str_replace( 'artist/%artist_name%', 'portfolio', $post_link);
}
}
return $post_link;
}
add_filter( 'post_type_link', 'filter_portfolio_link', 10, 2);
This pulls the correct data and inserts it in the URL correctly, but with lots of PHP notices. I’m not so worried about those at the moment.
So while this changes the slug correctly, it isn’t changing the permalink and I’m getting 404 errors on the front-end. I imagine this needs a rewrite function to be paired with it? Just not sure where to go from here.
So after a lot of time spent and a lot of trying different things, I finally figured out the right way to do this. I used MonkeyMan Rewrite Analyzer and the WP Debug Bar to help figure out how to construct the rewrite.
So first, my custom post type URLs are rewritten as such:
Then, I register a rewrite tag
%artistname%
for the artist name, which we’ll grab via aWP_Query
function, as well as a rewrite rule to fill in the slug to be occupied by the artist’s name, which will come before the slug of the portfolio being shown.Next, I refined the URL filter to check if it’s a portfolio post, and if so, pull the slug of the first connected
artist
, and then plop that slug into the post link string.So that’s it! While I didn’t use the same plugin as discussed in the thread Nested custom post types with permalinks, the whole thread was super helpful in arriving at this conclusion.