Site logo

[Resolved] Best way to customize Archives templates?

Home Forums Support [Resolved] Best way to customize Archives templates?

Home Forums Support Best way to customize Archives templates?

Viewing 14 posts - 1 through 14 (of 14 total)
  • Author
    Posts
  • #2447419
    John

    Hi GP team,

    I’m using GP Pro and GB Pro. I have created several Custom Post Types (CPT) and several custom Taxonomies. I have used the awesome “Loop Template” Element from GB Pro to create a custom archives page. Very powerful Element, I love it, but it’s not helping me achieve what I want to do.

    I would like my Archive pages to display the pieces of content grouped by CPT or by Taxonomy. More specifically, I would like my Taxonomy archive pages to group the content by CPT, and I would like my CPT archive pages to group the content by some specific custom taxonomy (by a different taxonomy depending on the CPT). So something like this:

    Topic taxonomy term archive page: content would be grouped by CPT:
    – All Posts with that term
    – All Events with that term (Event is a CPT)
    – All Resources with that term (Resources is a CPT)

    Resources CPT archive page: content would be grouped by Topic taxonomy term (and not by the Language taxonomy or any other):
    – All Resources with the term “HR”
    – All Resources with the term “Leadership”
    – All Resources with the term “Sales”
    Etc.

    Consultant CPT archive page: content would be grouped by Country taxonomy term (and not by the Topic taxonomy or any other):
    – All Consultants with the term “USA”
    – All Consultants with the term “Germany”
    – All Consultants with the term “Australia”
    Etc.

    Is that possible to achieve?

    I have created a child theme and I’m now looking at the archive.php file content in the Theme Editor. And I’m a bit lost… I looked up some php templates online, but they’re not designed for GeneratePress specifically, and I want that file to stay GeneratePress-compatible.

    Thank you for any guidance you may have

    #2447423
    John

    Thinking about it further: I can probably create an archive page manually for each CPT, that way I can control exactly which taxonomy they are grouped by. However, I still need a way to generate the Taxonomy archive pages grouped by CPT dynamically, since there are too many taxonomy terms and they may change more frequently.

    #2448917
    David
    Staff
    Customer Support

    Hi there,

    if i understand correctly, then for those to operate as proper archive pages then you would need to create a nested loop.
    e.g a Parent Loop that loops through the current object terms, and foreach term a nested loop that queries posts for just those terms.

    But its not something that can be done with Block Element Loop Templates at this time, as the GB Query Loop Block can’t do nested loops yet. So you would need to create custom PHP templates. See my reply here:

    https://generatepress.com/forums/topic/file-page-that-organizes-posts-listed-in-subcategory/#post-2371271

    As a note, the example code i provided will work with a Block Element – Content Template as it uses generate_do_template_part( 'archive' ) function.

    #2457643
    John

    Thank you David. I have read your response and looked at the other post, but I am bit lost with customizing the php for my needs.

    I’m thinking about going about it a different way, and I wonder if GP (+ GB Pro) can help me. I’m using WP Gridbuilder to add filters to some posts, and I can use it on my taxonomy pages too.

    So if I was able to display a taxonomy page that lists all the posts tagged with that taxonomy (all terms included), I could add a filter and users would be able to use that filter, instead of having to leave the page to look at the results for a different term.

    For example, I have a Country custom taxonomy and when I click on a country term, it opens the archive page for that term (default behavior). Instead, I would like to create a page with a query that lists all posts using the Country taxonomy (regardless of which country term), and I will filter it with WP Gridbuilder.

    But when I use GB Pro to create a Query Loop, it asks me to select a Post Type. Instead, I would like to select a Taxonomy (and no specific term). So I thought maybe I can use the “inherit query from template” feature, but then I need a template that queries all post types based on the Country taxonomy. (Right?)

    Does this query template exist anywhere in GP? If not, is it possible to (easily) create it?
    Side question: does GB Pro 1.7 add anything that might be useful for my use-case here?

    I hope I am being clear – thank you!

    #2458854
    David
    Staff
    Customer Support

    Heres the WP codex on taxonomy templates for reference:

    https://developer.wordpress.org/themes/template-files-section/taxonomy-templates/

    We can try using that like so:

    1, Make a copy of the GP archive.php template and add it in your Child Theme.
    2. Rename that templates filename using this naming rule taxonomy-{taxonomy}.php ( taken from the doc above ).
    For example your country tax would be: taxonomy-country.php

    Then you should have a /country archive page that will list all posts found within that taxonomy.

    If that works, then the option for Inherit query from Template will do exactly that.

    The Pro version of GB will add convenience to building and allow more access to the Blocks HTML as well as some advanced query features, but it won’t do anything different in regards to this challenge.

    #2459651
    John

    David,

    That’s a great idea! Unfortunately I tried it following your instructions, but /country still gives me a 404 page :/ Any idea why? I tried to purge the cache and “resave” permalinks, just in case, alas no chance.

    Re GB Pro: I already use it, it’s great — I was wondering if the upcoming version which I’ve seen previews of — GB 1.7 I believe — had any feature that could help me in this case.

    EDIT: I also tried disabling all the active Elements on the archive pages, just to make sure nothing interferes even though I don’t imagine they would cause an issue. Still not working.

    #2460373
    David
    Staff
    Customer Support

    Ah, my bad, forgot this age old trac:

    https://core.trac.wordpress.org/ticket/13816

    TLDR: Bottom line, /{taxonomy} without any terms will 404. As the query for those templates rely on terms not the taxonomy So if you go to /{taxonomy}/{term} then you should see those results and it will be using your taxonomy template.

    So to get around that would require custom development.
    You may want to ask the question – is it necessary to have separate index pages for each taxonomy ? Would they show all the same posts as each other ?

    #2460736
    John

    David, I see thank you. It’s surprising to me that there isn’t an easier solution to this.

    To your questions: my thinking was mostly that having one page per taxonomy to navigate said taxonomy is much simpler than having one page per taxonomy term, where the user has to backtrack to find other terms. For instance, I have a Language and a Country taxonomy (I have more, but for the sake of the example that’s enough). I would rather have one page for Languages and one page for Countries (total = 2 pages, 2 URLs) instead of 300+ pages for each language and each country.

    I don’t have a budget for custom development so I will need to get around the problem. Maybe there is a way to create a taxonomy dropdown selector on each term archive page so users can navigate the taxonomy more easily. I appreciate your help.

    #2461409
    David
    Staff
    Customer Support

    How many CPTs are we dealing with ? Is it just one CPT with many custom taxonomies ?

    #2461914
    John

    I currently have 3 CPT and 6 custom taxonomies, in addition to the defaults of course.

    I have found a way to add a little taxonomy term dropdown “switcher” on the Archive page for each taxonomy, which I consider a workable workaround even if it’s not perfect.

    However as of now, I’m displaying it via a shortcode inserted in an Element hook, and the taxonomy is passed by a shortcode attribute. That means I have to create a different Element hook for each category, which I’m not really excited about for maintenance. Instead I’d love to make it dynamic so that wherever the shortcode is placed, it picks up the taxonomy of the archive page it’s on. That way I could use only 1 Element for all archive pages.

    If you are willing, would you mind sharing how I could modify the following snippet to achieve this? I have adapted a shortcode found online in a PHP snippet:

    /**
     * Shortcode to create a list or dropdown link to taxonomy archives
     *
     * @author Joshua David Nelson, josh@jdn.im
     **/
    
    function hol_taxonomy_list( $atts ) {
        $a = shortcode_atts( array(
    		'taxonomy' => '',
    		'post-type' => 'event', 'licensee', 'post', 'page',
            	'type' => 'list',
    		'title' => '',
        ), $atts );
    	$filter_text = '';
    	// Make sure the taxonomy field is valid and it exists
    	if( $a['taxonomy'] !== '' && taxonomy_exists( $a['taxonomy'] ) ) {
    		$taxonomy = get_taxonomy( $a['taxonomy'] );
    		$tax_url = get_post_type_archive_link( $a['post-type'] ) . '?' . $taxonomy->name . '=';
    		$taxonomy_name = ucfirst( $taxonomy->labels->name );
    	
    		if( $a['type'] == 'list' ) {
    			
    			$filter_text .= '<div class="hol-taxonomy-list taxonomy-' . $taxonomy->name . '">';
    
    			$filter_text .= '<ul>';
    			
    			$args = array(
    			    'orderby'       => 'name', 
    			    'order'         => 'ASC',
    			);
    			$terms = get_terms( $taxonomy->name, $args );
    			foreach( $terms as $term ) {
    				$filter_text .= '<li><a href="' . get_term_link( $term, $taxonomy->name ) . '" title="' . $term->name . '">' . $term->name . '</a></li>';
    			}
    			
    			$filter_text .= '</ul></div>';
    			
    		} elseif( $a['type'] == 'dropdown' ) {
    			
    			$filter_text .= '<div class="hol-taxonomy-dropdown taxonomy-' . $taxonomy->name . '"><form name="type_jump">';
    			
    			$filter_text .= '<select class="input-block-level select" name="' . $taxonomy->name . '"  OnChange="window.location=this.options[this.selectedIndex].value;">';
    			
    			$args = array(
    			    'orderby'       => 'count', 
    			    'order'         => 'DESC',
    			);
    			
    			$filter_text .=  '<option value="">Change ' . $taxonomy->labels->singular_name . '</option>';
    			
    			$terms = get_terms( $taxonomy->name, $args );
    			foreach( $terms as $term ) {
    				$filter_text .=  '<option value="' . $tax_url . $term->slug . '">' . $term->name . '</option>';
    			}
    			
    			$filter_text .= '</select></form></div>';          
    			
    		}
    	}
    
        return $filter_text;
    }
    add_shortcode( 'hol_taxonomy_list', 'hol_taxonomy_list' );

    I’m aware my question goes beyond the scope of the theme support and I don’t want to abuse your time. However I’m hoping that my workaround solution can be useful to others facing the same issue. If you don’t consider it a waste your time, I’d love your suggestion. I’ll be happy to post a more generic version of the shortcode.

    Thank you!

    #2461952
    John

    Well, I think I figured it out by simply adding get_query_var('taxonomy') as the taxonomy instead of an empty field.

    Given this modification, my understanding is that the snippet could be significantly simplified but I’m not knowledgeable enough with PHP to do it confidently, so I’ll just post what I’m using (though modified to be more generic) for others to tweak if desired (if so, I’d appreciate if you post your change!)

    /**
     * Shortcode to create a list or dropdown link to taxonomy archives
     *
     * Adapted from initial @author Joshua David Nelson, josh@jdn.im
     **/
    
    function jdn_taxonomy_list( $atts ) {
        $a = shortcode_atts( array(
    		'taxonomy' => get_query_var('taxonomy'), // Replace get_query_var('taxonomy') by '' for an empty field that you can customize via shortcode attribute
    		'post-type' => 'post', // Add your own post types if desired, e.g. 'post', 'movie', 'actor',
            	'type' => 'list',
    		'title' => '', // I've removed the code that makes use of the title attribute, so I think it's irrelevant
        ), $atts );
    	$filter_text = '';
    	// Make sure the taxonomy field is valid and it exists
    	if( $a['taxonomy'] !== '' && taxonomy_exists( $a['taxonomy'] ) ) {
    		$taxonomy = get_taxonomy( $a['taxonomy'] );
    		$tax_url = get_post_type_archive_link( $a['post-type'] ) . '?' . $taxonomy->name . '=';
    		$taxonomy_name = ucfirst( $taxonomy->labels->name );
    	
    		if( $a['type'] == 'list' ) {
    			
    			$filter_text .= '<div class="jdn_taxonomy_list taxonomy-' . $taxonomy->name . '">';
    
    			$filter_text .= '<ul>';
    			
    			$args = array(
    			    'orderby'       => 'name', 
    			    'order'         => 'ASC',
    			);
    			$terms = get_terms( $taxonomy->name, $args );
    			foreach( $terms as $term ) {
    				$filter_text .= '<li><a href="' . get_term_link( $term, $taxonomy->name ) . '" title="' . $term->name . '">' . $term->name . '</a></li>';
    			}
    			
    			$filter_text .= '</ul></div>';
    			
    		} elseif( $a['type'] == 'dropdown' ) {
    			
    			$filter_text .= '<div class="jdn_taxonomy_ dropdown taxonomy-' . $taxonomy->name . '"><form name="type_jump">';
    			
    			$filter_text .= '<select class="input-block-level select" name="' . $taxonomy->name . '"  OnChange="window.location=this.options[this.selectedIndex].value;">';
    			
    			$args = array(
    			    'orderby'       => 'count', 
    			    'order'         => 'DESC',
    			);
    			
    			$filter_text .=  '<option value="">Change ' . $taxonomy->labels->singular_name . '</option>';
    			
    			$terms = get_terms( $taxonomy->name, $args );
    			foreach( $terms as $term ) {
    				$filter_text .=  '<option value="' . $tax_url . $term->slug . '">' . $term->name . '</option>';
    			}
    			
    			$filter_text .= '</select></form></div>';          
    			
    		}
    	}
    
        return $filter_text;
    }
    add_shortcode( 'jdn_taxonomy_list', 'jdn_taxonomy_list' ); // Use the shortcode with [jdn_taxonomy_list] or [jdn_taxonomy_list type="dropdown"]
    #2462635
    David
    Staff
    Customer Support

    That looks great, i can’t see much room for improvement. It loops through the terms, gets the links and outputs the Select HTML. Nothing surplus to requirements there.

    #2463430
    John

    Thanks David!

    #2463821
    David
    Staff
    Customer Support

    You’re welcome

Viewing 14 posts - 1 through 14 (of 14 total)
  • You must be logged in to reply to this topic.