Support

Account

Home Forums General Issues CPT with single CPT template. Can I 404 conditionally with ACF true/false field?

Solved

CPT with single CPT template. Can I 404 conditionally with ACF true/false field?

  • Hello, I have a new CPT called “person”. This will have ACF fields containing the name, thumbnail, bio and further info of each person at my client’s company.

    I’m also creating a team member grid element where individual people can be chosen from the people CPT using an ACF Post Object field, displaying the thumbnail and name.

    BUT some of these people will have their own page showing all their details, while other will not have a page at all, just the thumbnail and name with no link. I will create a single-person.php template to show all their details but I need to make sure that this only used when conditionally chosen in the person’s admin screen.

    What I need to do is have a conditional true/false field in the person’s admin screen which is called “Has own page?”. I want to 404 any attempt to land at a page where this conditional has not been set.

    Good: /people/the-boss/ Has own page?: Y
    404: /people/the-intern/ Has own page?: N

    I was wondering if I should place the logic for this inside the single-person.php template, or if it’s better to do it earlier somehow so that this single page template isn’t touched and the 404.php template is used immediately.

    Another concern I have is for things like Yoast sitemap which could ignore the page templates completely and create links for people I do not want.

    What is my best approach for conditionally setting a 404 for some people and not others?

    Thanks in advance.

  • In the time-honoured tradition I have managed to solve this after writing the question.

    For anybody who also needs the answer this is how I excluded certain CPT entries from having their own page and appearing in the Yoast XML Sitemap if they did NOT have the “has_page” conditional field checked:

    class CPT_Person
    {
    	public static $CPT_PERSON = 'person';
    
    	public function __construct()
    	{
    		$this->hook_actions();
    		$this->hook_filters();
    	}
    
    	private function hook_actions()
    	{
    		add_action('template_redirect', array($this, 'people_404'));
    	}
    
    	private function hook_filters()
    	{
    		add_filter('wpseo_exclude_from_sitemap_by_post_ids', array($this, 'hide_people_from_yoast_sitemap'));
    	}
    
    	public function people_404_ids()
    	{
    		// Returns array of people CPT IDs where 'has page' has not been set to true
    		$exclude_args = array(
    			'post_type' => self::$CPT_PERSON,
    			'posts_per_page' => -1,
    			'meta_query' => array(
    				'relation' => 'OR',
    				array(
    					'key'   => 'has_page',
    					'value' =>  0,
    					'compare' => '='
    				),
    				array(
    					'key'   => 'has_page',
    					'compare' => 'NOT EXISTS'
    				)
    			),
    			'fields' => 'ids'
    		);
    		$the_query = new WP_Query($exclude_args);
    		return $the_query->posts;
    	}
    
    	public function hide_people_from_yoast_sitemap()
    	{	// Exclude some people from Yoast XML Sitemap
    		$exclude_ids = $this->people_404_ids();
        return $exclude_ids;
    	}
    
    	public function people_404()
    	{
    		// Exclude some people from having single CPT page
    		if(is_singular(self::$CPT_PERSON))
    		{
    			$exclude_ids = $this->people_404_ids();
    			if (in_array(get_the_ID(), $exclude_ids))
    			{
    				global $wp_query;
    				$wp_query->set_404();
    				http_response_code(404);
    				get_template_part(404);
    				exit();
    			}
    		}
    	}
    
    }
    new CPT_Person();
Viewing 3 posts - 1 through 3 (of 3 total)

You must be logged in to reply to this topic.