• Skip to main content
  • Skip to primary sidebar
  • Skip to footer

nSiteful Web Builders

Building a Better Web - One Site at a Time.

  • Home
  • About
    • Testimonials
    • Resources
  • Web Sites
  • Online Marketing
  • WordPress Support
    • Customized WordPress Training
    • 60-for-60 Sessions
  • Web Applications
  • Blog
    • Archive Listing Minimalistic
    • Blog Articles Grouped by Category
    • Case Studies
    • General
    • Portfolio
    • Reviews
    • Snippets
    • Techniques
  • Contact Jeff
    • Purchase Retainer Consulting Hours
    • About Retainer Consulting Hours

By Jeff Cohan, March 10, 2023

Use Case for Custom Post Type: “In The News”

On This Page...

  • Websites like to display news
  • My Rule of Thumb Test for Custom Post Types:
  • Problems…
  • Conversion to Custom Post Type
    • Register Custom Post Type Code
    • Register Custom Taxonomies Code
  • How the Posts are Added and Edited
  • How the Posts Display on the Website Front End
    • Main Rendering Code
    • Getting the Data for Each Individual “In The News” Post
  • In Closing
  • Related Posts
This post assumes you have a basic familiarity with WordPress Custom Post Types. For an introduction or refresher, check out my multipart series of posts about Custom Post Types, starting here. The original version of this post includes code snippets, but I have not explained most of the code. If you have questions about what the code is doing, post those quesions in the comments.

Websites like to display news

Many websites include an “In The News” section — content related to articles, videos, podcasts, etc., that other publishers have published about them. It might be called “News”, “Press”, “Media” or something else.

Here’s a screenshot of the “In The News” section of the wanderBOX website.

Archive page for News custom post type

My Rule of Thumb Test for Custom Post Types:

An “In The News” post is a good use case for a custom post type. This is because it passes my rule-of-thumb test:

  1. All posts share a unique set of properties.
  2. You want to efficiently create and maintain these posts.
  3. You want to uniformly and consistently display these posts.

We can see from the above screenshot that there is a unique set of properties these posts share. They are Publication Name, Publication Date, Author Name, Article Title, and URL of the online article. There are also two “optional” properties: a brief description of the article, and an excerpt from the article.

When my client first started publishing In-The-News content, he created them as blog posts. By assigning these blog posts the category of “News”, we were able to isolate them so that they stood apart from all other blog posts.

Problems…

But adding these news items as blog posts created some problems.

In order to display these posts consistently and uniformly, the authors had to remember exactly where to place the various “properties” as well as how each one is formatted.

What’s more, if the client decided at some time in the future that, for example, all the author names should be displayed differently (different font size, weight, or style; different color; etc.), then someone would have to go back into each “in The News” post and make the appropriate changes.

Conversion to Custom Post Type

Because of these issues — and because “In The News” content is a perfect use case for a Custom Post Type — I recently converted all the “In The News” posts to posts of the custom post type “News”.

The code for registering the News CPT and the custom taxonomies for the News CPT are in a file named cpt-news.php and stored in the /mu-plugins/ folder.

Register Custom Post Type Code

Here is the code for registering the CPT:

function wb_register_news_cpt() {

	$labels = array(
		'name'                  => _x( 'News Post', 'Post Type General Name', 'news_domain' ),
		'singular_name'         => _x( 'News Posts', 'Post Type Singular Name', 'news_domain' ),
		'menu_name'             => __( 'News', 'news_domain' ),
		'name_admin_bar'        => __( 'News', 'news_domain' ),
		'archives'              => __( 'News Archives', 'news_domain' ),
		'attributes'            => __( 'News Attributes', 'news_domain' ),
		'parent_item_colon'     => __( 'Parent Item:', 'news_domain' ),
		'all_items'             => __( 'All News Items', 'news_domain' ),
		'add_new_item'          => __( 'Add New News Item', 'news_domain' ),
		'add_new'               => __( 'Add New', 'news_domain' ),
		'new_item'              => __( 'New News Item', 'news_domain' ),
		'edit_item'             => __( 'Edit News Item', 'news_domain' ),
		'update_item'           => __( 'Update News Item', 'news_domain' ),
		'view_item'             => __( 'View News Item', 'news_domain' ),
		'view_items'            => __( 'View News Items', 'news_domain' ),
		'search_items'          => __( 'Search News Items', 'news_domain' ),
		'not_found'             => __( 'Not found', 'news_domain' ),
		'not_found_in_trash'    => __( 'Not found in Trash', 'news_domain' ),
		'featured_image'        => __( 'Featured Image', 'news_domain' ),
		'set_featured_image'    => __( 'Set featured image', 'news_domain' ),
		'remove_featured_image' => __( 'Remove featured image', 'news_domain' ),
		'use_featured_image'    => __( 'Use as featured image', 'news_domain' ),
		'insert_into_item'      => __( 'Insert into News', 'news_domain' ),
		'uploaded_to_this_item' => __( 'Uploaded to this News Item', 'news_domain' ),
		'items_list'            => __( 'News list', 'news_domain' ),
		'items_list_navigation' => __( 'News list navigation', 'news_domain' ),
		'filter_items_list'     => __( 'Filter News list', 'news_domain' ),
	);
	$args = array(
		'label'                 => __( 'News', 'news_domain' ),
		'description'           => '',
		'labels'                => $labels,
		'supports'              => array( 'title', 'page-attributes' ),
		'taxonomies'            => array( 'news_cats', 'news_tags' ),
		'hierarchical'          => true,
		'public'                => true,
		'show_ui'               => true,
		'show_in_menu'          => true,
		'menu_position'         => 5,
		'show_in_admin_bar'     => true,
		'show_in_nav_menus'     => true,
		'can_export'            => true,
		'has_archive'           => true,
		'exclude_from_search'   => false,
		'publicly_queryable'    => true,
		'capability_type'       => 'page',
	);
	register_post_type( 'news', $args );

}
add_action( 'init', 'wb_register_news_cpt', 0 );

Register Custom Taxonomies Code

Here is the code for registering the news_cats taxonomy:

function wb_register_news_cats() {

	$labels = array(
		'name'                       => _x( 'News Categories', 'Taxonomy General Name', 'text_domain' ),
		'singular_name'              => _x( 'News Category', 'Taxonomy Singular Name', 'text_domain' ),
		'menu_name'                  => __( 'News Categories', 'text_domain' ),
		'all_items'                  => __( 'All News Categories', 'text_domain' ),
		'parent_item'                => __( 'Parent Item', 'text_domain' ),
		'parent_item_colon'          => __( 'Parent Item:', 'text_domain' ),
		'new_item_name'              => __( 'New News Category Name', 'text_domain' ),
		'add_new_item'               => __( 'Add New News Category', 'text_domain' ),
		'edit_item'                  => __( 'Edit News Category', 'text_domain' ),
		'update_item'                => __( 'Update News Category', 'text_domain' ),
		'view_item'                  => __( 'View News Category', 'text_domain' ),
		'separate_items_with_commas' => __( 'Separate News Categories with commas', 'text_domain' ),
		'add_or_remove_items'        => __( 'Add or remove News Categories', 'text_domain' ),
		'choose_from_most_used'      => __( 'Choose from the most used', 'text_domain' ),
		'popular_items'              => __( 'Popular News Categories', 'text_domain' ),
		'search_items'               => __( 'Search News Catetories', 'text_domain' ),
		'not_found'                  => __( 'Not Found', 'text_domain' ),
		'no_terms'                   => __( 'No News Categories', 'text_domain' ),
		'items_list'                 => __( 'News Categories list', 'text_domain' ),
		'items_list_navigation'      => __( 'News Categories list navigation', 'text_domain' ),
	);
	$args = array(
		'labels'                     => $labels,
		'hierarchical'               => true,
		'public'                     => true,
		'show_ui'                    => true,
		'show_admin_column'          => true,
		'show_in_nav_menus'          => true,
		'show_tagcloud'              => true,
	);
	register_taxonomy( 'news_cats', array( 'news' ), $args );

}
add_action( 'init', 'wb_register_news_cats', 0 );

Here is the code for registering the news_tags taxonomy:

function wb_register_news_tags() {

	$labels = array(
		'name'                       => _x( 'News Tags', 'Taxonomy General Name', 'text_domain' ),
		'singular_name'              => _x( 'News Tag', 'Taxonomy Singular Name', 'text_domain' ),
		'menu_name'                  => __( 'News Tags', 'text_domain' ),
		'all_items'                  => __( 'All News Tags', 'text_domain' ),
		'parent_item'                => __( 'Parent News Tag', 'text_domain' ),
		'parent_item_colon'          => __( 'Parent News Tag:', 'text_domain' ),
		'new_item_name'              => __( 'New News Tag', 'text_domain' ),
		'add_new_item'               => __( 'Add New News Tag', 'text_domain' ),
		'edit_item'                  => __( 'Edit News Tag', 'text_domain' ),
		'update_item'                => __( 'Update News Tag', 'text_domain' ),
		'view_item'                  => __( 'View News Tag', 'text_domain' ),
		'separate_items_with_commas' => __( 'Separate News Tags with commas', 'text_domain' ),
		'add_or_remove_items'        => __( 'Add or remove News Tags', 'text_domain' ),
		'choose_from_most_used'      => __( 'Choose from the most used', 'text_domain' ),
		'popular_items'              => __( 'Popular News Tags', 'text_domain' ),
		'search_items'               => __( 'Search News Tags', 'text_domain' ),
		'not_found'                  => __( 'Not Found', 'text_domain' ),
		'no_terms'                   => __( 'No News Tags', 'text_domain' ),
		'items_list'                 => __( 'News Tag list', 'text_domain' ),
		'items_list_navigation'      => __( 'News Tag list navigation', 'text_domain' ),
	);
	$args = array(
		'labels'                     => $labels,
		'hierarchical'               => false,
		'public'                     => true,
		'show_ui'                    => true,
		'show_admin_column'          => true,
		'show_in_nav_menus'          => true,
		'show_tagcloud'              => true,
	);
	register_taxonomy( 'news_tags', array( 'news' ), $args );

}
add_action( 'init', 'wb_register_news_tags', 0 );

How the Posts are Added and Edited

Using Advanced Custom Fields Pro (but the free version would have sufficed for this implementation), I created a form group for “News”. News items are added and edited from the WordPress back end using this form, based on that form group:

Form for inputting posts for the News custom post type

How the Posts Display on the Website Front End

The nature of these “In The News” posts obviates the need for single post pages. Therefore, the only code that matters is that which renders the News archive.
All of the code that follows in this section is in a file named cpt-news-functions.php in the /mu-plugins/ folder.

Main Rendering Code

<?php
function wb_news_render_archive() {
	if ( ! ( is_post_type_archive( 'news' ) || is_tax('news_cats') || is_tax('news_tags') ) ) return;
	
	/* Call */
	$data = wb_news_get_single(get_the_ID());
	extract($data);
	$pub_date_cos = date('F j, Y', strtotime($data['publication_date']));
	/* Assemble the Categoy Links */
	$cats = $data['news_cat_terms']; /* md array of term stuff for link_cats */
	/* Assemble Category Archive permalinks (for THIS post) into an array that will be imploded for the nav */
	$news_cats_archives = array();
	foreach ( $cats as $cat ) {
		$news_cats_archives[] = '<a href="/' . $cat->taxonomy . '/' . $cat->slug . '/">' . $cat->name . '</a>';
	}
	$news_cats_archives_nav = 
	'<span class="terms">' . implode(' | ', $news_cats_archives) . '</span>';
?>
<div class="news-item-container">
	<div class="publication-name">
		<?php echo $data['publication_name'];?>
	</div>
	<div class="news-item">
		<div class="article-title">
			<?php echo $data['article_title'];?>
		</div>
		<div class="publication-date">
			<span class="prompt">Date Published: </span>
			<?php echo $pub_date_cos;?>
		</div>
		<div class="author-name">
			<span class="prompt">Author: </span>
			<?php echo $data['author_name'];?>
		</div>
		<?php if ( $data['about_this_article'] ) : ?>
			<div class="about-this-article">
				<span class="prompt">About this article: </span>
				<span class="text"><?php echo $data['about_this_article'];?></span>
			</div>
		<?php endif; ?>
		
		<?php if ( $data['money_quote'] ) : ?>
			<div class="money-quote">
				<span class="prompt">Excerpt: </span>
				<blockquote><?php echo $data['money_quote'];?></blockquote>
			</div>
		<?php endif; ?>
		<?php if ( !empty($cats) ) : ?>
		<nav class="cat-links">
			<span class="prompt">Filed Under: </span>
			<?php echo $news_cats_archives_nav;?>
		</nav>
		<?php endif; ?>
		<div class="article-url">
			<?php echo $data['article_url'];?>
		</div>
		<div class="permalink">
			<a class="external button" target="_blank" title="Visit <?php echo $article_url;?>" href="<?php echo $article_url;?>">Read More >></a>
		</div>
	</div>
</div><!-- / .news-item-container -->
<?php
}
add_action('generate_after_entry_title', 'wb_news_render_archive');

Getting the Data for Each Individual “In The News” Post

Here is the code for retrieving the data for each individual News item. This function is called on line 6 of the above code. Notice that even though I’m using Advanced Custom Fields to generate the custom fields, I’m using the native WordPress get_post_meta() function instead of ACF’s the_field() function. I do this to avoid problems in the event that the ACF plugin is ever removed from the website. If the plugin were to be removed, all the “post_meta” content would remain in the database, but any code using ACF functions would fail.

<?php
function wb_news_get_single($id) {
	$data = array(); // init
	$data['news_cat_terms'] 	= wp_get_post_terms($id, 'news_cats', array('fields' => 'all'));	
	$data['news_tag_terms'] 	= wp_get_post_terms($id, 'news_tags', array('fields' => 'all'));	
	$data['publication_name'] 	= get_post_meta($id, 'wbnews_publication_name', true);
	$data['publication_date'] 	= get_post_meta($id, 'wbnews_publication_date', true);
	$data['article_url'] 		= get_post_meta($id, 'wbnews_article_url', true);
	$data['article_title'] 		= get_post_meta($id, 'wbnews_article_title', true);
	$data['author_name'] 		= get_post_meta($id, 'wbnews_author_name', true);
	$data['money_quote'] 		= get_post_meta($id, 'wbnews_money_quote', true);
	$data['about_this_article']	= get_post_meta($id, 'wbnews_about_this_article', true);
	return $data;
}

In Closing

I hope someone finds this post helpful. If you have questions, please ask in the comments section below. Thanks for listening.

Related Posts

  1. Dive Into WordPress Custom Post Types – Part 2
  2. How to Create a Simple Custom Events Plugin
  3. Use Custom Fields to Hide Stale Posts
  4. How to use Advanced Custom Fields with Genesis
  5. Dive Into WordPress Custom Post Types – Part 3
  • Choose the best match.

Written by Jeff Cohan · Categorized: Techniques · Tagged: Advanced Custom Fields, Custom Fields, Custom Post Types, WordPress

  • Choose the best match.

Reader Interactions

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Primary Sidebar

mailchimp signup

Subscribe to get notified when new articles are published. Unsubscribe any time. No spam. I promise. Check out my newsletter archives.

social

Twitter Facebook LinkedIn

Recent Articles

  • Use Case for Custom Post Type: “In The News” March 10, 2023
  • Create a Custom Shortcode to Display a MemberPress Membership Price ANYWHERE on Your Website February 5, 2023
  • Avoid Direct Styling; Use CSS Instead September 21, 2022
  • Blog Tags: What They Are (and What They’re Not) August 5, 2022
  • How to Create a Simple Custom Events Plugin May 24, 2022

Filter By Category/Tag

Categories

  • Case Studies (7)
  • General (61)
  • Portfolio (5)
  • Reviews (12)
  • Snippets (16)
  • Techniques (38)

Popular Tags

Advanced Custom Fields Blogging Child Themes Content Marketing CSS CSS Grid Customer Service Custom Fields Custom Post Types Diagnostics Facebook FooGallery Genesis Gutenberg HTML Images iPhone Libra Live Chat Marketing Media MemberPress MemberPress Courses mu-plugins MySQL Photo Gallery php Pinterest Plugins Post Formats Pricing Project Management Security SEO Seth Godin Shortcodes Social Networking Surveys Taxonomies Trello Twitter Video Web design Web forms WordPress

siteground wp hosting

Web Hosting

wp101

EasyWordPresstutorialvideosforbeginners.
MemberPress CTA

Footer

Background

Web Sites | WordPress Support | Web Applications.

Formally trained in liberal arts and education (I have a B.A. in Government from Harvard and studied Secondary Education at Rutgers Graduate School), I have honed my skills in the communication arts and sciences as a teacher, trainer, instructional designer, writer, photographer, calligrapher, helpdesk manager, database programmer, and multimedia developer.

(I've also been a group counselor, waiter, bartender, bicycle messenger boy, computer salesman, carpenter's helper, financial analyst, and school board president.)

Tech

Systems since 1983.
Web sites since 1994.
PHP since 2001.
WordPress since 2007.

Contact

770-772-5134
Email Jeff
Send Money
All Ways

Copyright 2023, nSiteful Web Builders, Inc.

 

Subscribe

Pardon the interruption. I know popups can be annoying. But I’d love to have you as a subscriber.

Sign up to be notified when new articles are published. Unsubscribe any time.

* indicates required

Powered by MailChimp

×