megclaypool
10/11/2018 - 7:56 AM

Insert Custom Post Type Landing Page into Yoast Breadcrumbs

[Insert Custom Post Type Landing Page into Yoast Breadcrumbs]

Once you've created a landing page for a custom post type, this is how to insert that landing page into the Yoast breadcrumbs for that post type.

Shamelessly adapted from Extending the functionality of Yoast breadcrumbs: https://jboullion.com/extending-the-functionality-of-yoast-breadcrumbs/

<?php

// Register custom post types and taxonomies here.

function radicati_theme_init() {

  // Destroy the default tags
  unregister_taxonomy_for_object_type( 'post_tag', 'post' );

  $labels = array(
    'name'                       => _x( 'Tags', 'Taxonomy General Name', 'radicati' ),
    'singular_name'              => _x( 'Tags', 'Taxonomy Singular Name', 'radicati' ),
    'menu_name'                  => __( 'Tags', 'radicati' ),
    'all_items'                  => __( 'All Tags', 'radicati' ),
    'parent_item'                => __( 'Parent Tag', 'radicati' ),
    'parent_item_colon'          => __( 'Parent Tag:', 'radicati' ),
    'new_item_name'              => __( 'New Tag Name', 'radicati' ),
    'add_new_item'               => __( 'Add New Tag', 'radicati' ),
    'edit_item'                  => __( 'Edit Tag', 'radicati' ),
    'update_item'                => __( 'Update Tag', 'radicati' ),
    'view_item'                  => __( 'View Tag', 'radicati' ),
    'separate_items_with_commas' => __( 'Separate tags with commas', 'radicati' ),
    'add_or_remove_items'        => __( 'Add or remove tags', 'radicati' ),
    'choose_from_most_used'      => __( 'Choose from the most used', 'radicati' ),
    'popular_items'              => __( 'Popular Tags', 'radicati' ),
    'search_items'               => __( 'Search Tags', 'radicati' ),
    'not_found'                  => __( 'Not Found', 'radicati' ),
  );
  register_taxonomy('post_tag_inm', ['post', 'faq'], [
    'labels'              => $labels,
    'hierarchical'        => true,
    'rewrite'             => false,
    'public'              => true,
    'show_ui'             => true,
    'show_admin_column'   => true,
    'show_in_rest'        => true,
    'show_in_nav_menus'   => true,
//    'capabilities'        => [
//      'manage_terms' => 'manage_tags'
//    ]
  ]);

  if(!taxonomy_exists('promotion_options')) {
    register_taxonomy('promotion_options', ['resource', 'post'], [
      'label' => __('Promotion Options'),
      'hierarchical' => true,
      'rewrite' => false,
      'public' => false,
      'show_ui' => true,
    ]);
  }

  if(!post_type_exists('faq')) {
    register_post_type('faq', [
      'label' => 'FAQs',
      'labels' => [
        'name' => 'FAQs',
        'singluar_name' => 'FAQ',
      ],
      'public' => true,
      'show_in_menu' => true,
      'show_in_rest' => true,
      'menu_position' => 5,
      'menu_icon' => 'dashicons-admin-tools',
      'supports' => [
        'title', 'editor', 'excerpt', 'page-attributes', 'thumbnail', 'custom-fields', 'author'
      ],
      'capability_type' => 'post',
      'taxonomies' => ['category', 'post_tag'],
    ]);
  }

	if(!post_type_exists('partner')) {
		register_post_type('partner', [
			'label' => 'Partners',
			'labels' => [
				'name' => 'Partners',
				'singluar_name' => 'Partner',
			],
			'public' => true,
			'show_in_menu' => true,
			'menu_position' => 5,
			'menu_icon' => 'dashicons-admin-tools',
			'supports' => [
				'title', 'editor', 'excerpt', 'page-attributes', 'thumbnail', 'custom-fields', 'author'
			],
			'capability_type' => 'post',
			'taxonomies' => ['category', 'post_tag'],
		]);
	}

  if(!taxonomy_exists('partner_type')) {
    register_taxonomy('partner_type', ['partner'], [
      'label' => __('Partner Type'),
      'hierarchical' => true,
      'rewrite' => false,
      'public' => false,
      'show_ui' => true,
    ]);
  }

  if(!term_exists('promoted_to_front_page', 'promotion_options')) {
    wp_insert_term('Promoted to Front Page', 'promotion_options', [
      'description' => 'Content that should displayed on the front page',
      'slug' => 'promoted_to_front_page',
    ]);

    // Add other default promotion options here.
  }


  if(!taxonomy_exists('person_role')) {
    register_taxonomy('person_role', ['person'], [
      'label' => __('Person Role'),
      'hierarchical' => true,
      'rewrite' => false,
      'public' => true,
      'show_ui' => true,
    ]);
  }

  if(!post_type_exists('person')) {
    register_post_type('person', [
      'label' => 'People',
      'labels' => [
        'name' => 'People',
        'singluar_name' => 'person',
      ],
      'public' => true,
      'publicly_queryable' => true,
      'show_in_menu' => true,
      'menu_position' => 5,
      'menu_icon' => 'dashicons-groups',
      'supports' => [
        'title', 'editor', 'excerpt', 'page-attributes', 'thumbnail', 'custom-fields', 'author'
      ],
      'capability_type' => 'post',
      'taxonomies' => ['person_role'],
    ]);
  }

  // If you view a custom post type item and get a 404 page, uncomment this and
  // reload the page a few times.
  //flush_rewrite_rules();

}

add_action('init', 'radicati_theme_init');


// Add Resources to category archive pages

//function radicati__pre_get_posts($query) {
//  if( (is_category() || is_tag()) && $query->is_archive() && empty( $query->query_vars['suppress_filters'] ) ) {
//    $query->set( 'post_type', array(
//      'post', 'resource'
//    ));
//  }
//  return $query;
//}
//add_filter('pre_get_posts', 'radicati__pre_get_posts');

add_filter( 'wpseo_breadcrumb_links', 'jb_wpseo_breadcrumb_links' );
function jb_wpseo_breadcrumb_links( $links ) {
  // if we nee

  
  if ( is_single() && get_post_type() == 'faq') {
    $cpt_object = get_post_type_object( get_post_type() );
    
    if ( ! $cpt_object->_builtin ) {

      // this is redundant, but we could add other custom post types that need breadcrumbs someday...
      if (get_post_type() == 'faq') {
        $landing_page = get_page_by_path( '/faqs' );
      }
      

      $oldest_parent = $landing_page;
      $safty = 0; //remove the safety at your own risk :)
      while($oldest_parent->post_parent != 0) {
        
        $oldest_parent = get_post($oldest_parent->post_parent);
        array_splice( $links, -1, 0, array(
          array(
            'id'    => $oldest_parent->ID
          )
        ));

        if($safty++ > 5) break;
      }

      array_splice( $links, -1, 0, array(
        array(
          'id'    => $landing_page->ID
        )
      ));
    }
  }

  return $links;
}
  1. Create your custom post type. (That's a whole different ball of wax, but I'll attach an example of a file (which we require_once in functions.php) at the end in case you need an example...)
  2. Create your landing page.
  3. Add the following code to your post type creation page (or anywhere in functions.php or a php document included/required therein, but let's be organized, shall we?):
add_filter( 'wpseo_breadcrumb_links', 'jb_wpseo_breadcrumb_links' );
function jb_wpseo_breadcrumb_links( $links ) {

  // below, add as many post_types as you want custom breadcrumbs for
  if ( is_single() && get_post_type() == 'POST_TYPE_SLUG') {
    $cpt_object = get_post_type_object( get_post_type() );
    
    if ( ! $cpt_object->_builtin ) {

      // make a new condition and new $landing_page for each post_type getting a custom breadcrumb
      if (get_post_type() == 'POST_TYPE_SLUG') {
        $landing_page = get_page_by_path( 'LANDING_OR_LISTING_PAGE_FOR_THAT_POST_TYPE' );
      }
      

      $oldest_parent = $landing_page;
      $safty = 0; //remove the safety at your own risk :)
      while($oldest_parent->post_parent != 0) {
        
        $oldest_parent = get_post($oldest_parent->post_parent);
        array_splice( $links, -1, 0, array(
            array(
                'id'    => $oldest_parent->ID
            )
        ));

        if($safty++ > 5) break;
      }

      array_splice( $links, -1, 0, array(
          array(
              'id'    => $landing_page->ID
          )
      ));
    }
  }
  return $links;
}

Warning:

If your breadcrumb is redirecting to a listing page, the page slug cannot be the same as your custom post type slug. Found this out when I was using the more automated version of this script described in Extending the functionality of Yoast breadcrumbs. It works ok for landing pages, but listing pages can't paginate properly and everything after page 1 returns a 404 :( Solution: set landing/listing page breadcrumb manually for each post type :)