Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

On my site, users can view content on the blog or on a cartoon index page. Both these pages aggregate posts and custom post-types. The cartoon index differs in that it has an image slider before blog-style content. We want to create tag.php pages that take into account whether a person is in the cartoon archive or in the blog in general when clicking a tag link.

I couldn't attach images of each page (I don't have enough reputation), but message me if you want to see examples.

Right now every call to tag.php results in the same page, regardless of if that call came from the blogstream or elsewhere. How could I produce a tag page that is sensitive to where the visitor was when being called. Or can anyone see any alternatives?

Regards, --

EDIT:

Thank you George for suggesting custom taxonomies. That has almost got me to a solution. Before nailing myself to that path, however, I want to think about alternatives. I'll post the alternatives as answers below.

To try to clarify, my problem is that I want to display tag results using two or three unique templates. One template is a blogstream, and the other two have an image slider with a blogstream beneath it. These last two differ in that they display different categories of images. And when a person is viewing, for example, the blogstream when they click a tag link, I want them to be given a tag page that looks only like a blogstream (meaning without an image slider).

share|improve this question
add comment

6 Answers 6

If you really want to use a singular tag.php file, you can run a regex on your $_SERVER['HTTP_REFERER'] value to determine where you're coming from and then load a template part depending on the result, just be sure to have a default in there. Sorry, I can't be more specific on the regex without knowing your URL structure.

If there's just a specific part of the template - like the slider - that you want to display conditionally I would wrap that in an if statement rather than swapping out the entire template for maintainability.

share|improve this answer
    
Thanks for the suggestion. I'll be able to figure out the regex so no problem on being vague about it. –  nanoo_k Aug 8 '13 at 2:20
    
I do worry about which page will be indexed by Google tho--the version with the image slider or without. Similarly, I worry about what happens when the page is shared. So I'd like to hear if you know how to create multiple tag.php pages. If I could, I would like URLs looking something like site.com/cartoon-tag/[tag] and site.com/blog/[tag]. I'm currently looking at how Wordpress assigns a query to a specific page. Again, thanks a lot for your suggestion. –  nanoo_k Aug 8 '13 at 2:49
    
To be clear, I'm looking at functions related to WP_Rewrite: codex.wordpress.org/Class_Reference/WP_Rewrite –  nanoo_k Aug 8 '13 at 2:58
    
It's true, you might see a duplicate content SEO hit. Do you want to maintain the mix of the blog content and the image content? If not, you might want to look into creating a custom taxonomy for one or the other. –  George Yates Aug 8 '13 at 20:51
add comment

You could add a rewrite endpoint, so normal tag view has URLs like /tag/apple/, and links from your other view has the endpoint appended like /tag/apple/blogstream/:

function wpa_tag_enpoint(){
    add_rewrite_endpoint( 'blogstream', EP_TAGS );
}
add_action( 'init', 'wpa_tag_enpoint' );

Then you can filter tag_template and check for the presence of that query var and load a different template:

function wpa_tag_template( $templates = '' ){
    global $wp_query;
    if( array_key_exists( 'blogstream', $wp_query->query_vars ) ){
        $templates = locate_template( 'stream-tag.php', false );
    }
    return $templates;
}
add_filter( 'tag_template', 'wpa_tag_template' );
share|improve this answer
    
Wow this is exciting! Thank you Milo. I tried modifying your code to more closely fit what I need. Would you tell me if this looks right to you? –  nanoo_k Aug 27 '13 at 1:14
    
Instead of filling out several comments, I'm just going to post the code as an answer. –  nanoo_k Aug 27 '13 at 1:15
add comment

Solutions using category-$slug and archive-$posttype template pages:

First, some background. My posts are divided into categories: "playground," "treasury," "articles," etc. "Playground" and "treasury" are the categories that need tag result pages with an image slider at the top. But I want all categories present on all tag result pages. By default Wordpress offers category-$slug.php pages, so I can have category-playground.php and category-treasury.php in addition to tag.php (which would display blogstream styled tag results).

Alternatively, "playground" and "treasury" posts could be moved into custom post types of the same name. I could then have archive-treasury.php and archive-playground.php in addition to tag.php.

Both these solutions leave me with the same question: can category or archive pages be filtered by tag term? Let me use these URLs to illustrate:

I want site.com/treasury/$term to point to category-treasury.php and show in the image slider only posts that have been tagged $term. (Below the slider I would write a custom query to grab posts of other categories and display them in a blogstream). The same goes for site.com/playground/$term.

If I could do that, then I would just need to create links to these pages. Again, blogstream links to return to blogstream styled pages (tag.php in this case). Tag links in category-playground.php should lead to category-plaground styled pages. I'm thinking I could use RegEx to find the /tag/ in tag links and replace it with /playground/.

I would be terminally grateful for advice about either this or my previous solution. ('Terminally' grateful... because we are mortal... heh heh).

Regards,

share|improve this answer
add comment

Solution using custom taxonomies:

If I create two custom taxonomies then Wordpress by default lets me create term-links to unique taxonomy pages. It can be done with the wp_get_object_terms($post->ID, $taxonomy) and get_term_link($term->slug, $taxonomy) functions.

My URL structure winds up looking like this:

site.com/$taxonomy-1/%term%
site.com/$taxonomy-2/%term%
site.com/tag/%term%

My problem now is that I want all three taxonomies to be identical. So if a post is tagged "apples, oranges, fruit" in one taxonomy, it should be tagged "apples, oranges, fruit" in the other two taxonomies. I would do this manually but I'm working with over two thousand posts.

share|improve this answer
add comment

Code below is an extension of Milo's answer.

function wpa_tag_enpoint(){

    // Add /treasury/ to end of tag links on treasury-tag.php and the treasury index page
    if ( is_page_template( 'treasury-tag.php' ) && is_page_template( 'treasury-index.php' ) ){
    add_rewrite_endpoint( 'treasury', EP_TAGS );
    }
    // Add /playground/ to end of tag links on playground-tag.php and the playground index page
    if ( is_page_template( 'playground-tag.php' ) && is_page_template( 'playground-index.php' ) ){
    add_rewrite_endpoint( 'playground', EP_TAGS );
    }

    // Nothing is added to tag links elsewhere, so those go to tag.php which displays in blogstream format.
}
add_action( 'init', 'wpa_tag_enpoint' );


// Why is $templates defined as an empty string?
function wpa_tag_template( $templates = '' ){
    global $wp_query;

    // If 'treasury' exists as a key in the $wp_query array, load treasury-tag.php
    if( array_key_exists( 'treasury', $wp_query->query_vars ) ){
        $templates = locate_template( 'treasury-tag.php', false );
    }

    // If 'playground' exists as a key in the $wp_query array, load playground-tag.php
    if( array_key_exists( 'playground', $wp_query->query_vars ) ){
        $templates = locate_template( 'playground-tag.php', false );
    }
    return $templates;
}

// I couldn't find an entry in the codex for the tag_template filter, but I'm guessing this just hooks the above function when a template is being chosen.   
add_filter( 'tag_template', 'wpa_tag_template' );

I'm wondering whether the new URLs can be rewritten again without changing the functionality so visitors see site.com/playground/tag/apple instead of site.com/tag/apple/playground.

share|improve this answer
    
I tried my code but it didn't work. After adding it to functions.php I flushed my rewrite rules (by going to Settings > Permalinks > Save). Not only are URLs not modified to include /playground/ or /treasury/ at the end but if I manually type a URL of the type site.com/tag/apples/treasury/, I reach a 404 page. Reading the codex. –  nanoo_k Aug 27 '13 at 2:47
    
you can't wrap add_rewrite_endpoint in if conditionals, they'll never be added because those conditions are never met on the admin side, where that init has to be executed. also, you won't see the URLs modified automatically. rewrite rules only handle incoming requests, not the output of URLs. for that you'll have to add a filter to tag_link, to check which page you're currently on and append the correct endpoint if necessary. –  Milo Aug 27 '13 at 3:14
add comment
up vote 0 down vote accepted

Thanks again Milo and George for your help. I finally decided to use custom taxonomies. Here was my procedure.

// 1. Create the two taxonomies I need.
function  create_playground_taxonomy() {
    register_taxonomy( 'cartoon-playground', 'post', array (
            'rewrite' => array( 'slug' => 'Cartoon-Playground'),
            'hierarchical' => false,
            'labels' => array(
                'name' => _x( 'Cartoon Playground Tags', 'taxonomy general name' ),
                'all_items' => __( 'All Playground Cartoons' ), 
                'singular_name' => _x( 'Cartoon Playground Tag', 'taxonomy singular name' )
            )
        )
    );
}
add_action( 'init', 'create_playground_taxonomy' );
function  create_treasury_taxonomy() {
    register_taxonomy( 'cartoon-treasury', 'post', array (
            'rewrite' => array( 'slug' => 'Cartoon-Treasury' ),
            'hierarchical' => false,
            'labels' => array(
                'name' => _x( 'Cartoon Treasury Tags', 'taxonomy general name' ),
                'all_items' => __( 'All Treasury Cartoons' ), 
                'singular_name' => _x( 'Cartoon Treasury Tag', 'taxonomy singular name' )
            )
        )
    );
}
add_action( 'init', 'create_treasury_taxonomy' );


// 2. Copies terms from post_tag to the two new taxonomies.
// After updating functions.php, refresh any non-admin page
// on your site——that's what activates the function.
function replicateTaxonomyTerms() {
    $terms = get_terms( 'post_tag' );
    $count = count($terms);
    if ( $count > 0 ){
        foreach ( $terms as $term ) {
            wp_insert_term( $term->name, 'cartoon-treasury', array( 'slug' => $term->slug) );
            wp_insert_term( $term->name, 'cartoon-playground', array( 'slug' => $term->slug) );
        }
    }
}
add_action('init', 'replicateTaxonomyTerms');


// 3. Identifies post_tag terms that are associated with one post
// and associates that post with terms in the other taxonomies.
// 
// I needed this code because I invented these taxonomies AFTER
// the posts were imported. If you define the taxonomies before
// importing, you should work with your import functions instead.
// This code was used only to initially update all my posts. Below
// is a different function that I use update the posts every day.
// 
// So for example post1 is originally associated with the post_tag
// term 'green-bean.' After running this code, post1 will also be
// associated with the treasury taxonomy term 'green-bean.'
// 
// Refresh a non-admin page once this code is in functions.php.
// Increment the offset by 500 (or whatever your server can handle)
// until you modify all your posts.
// 
// When you've updated all your posts, comment-out or delete the code.
function updatePostsTerms() {
    global $post;  
    $args = array(  
        'posts_per_page' => 500,
        'offset' => 0,
        'post_type' => 'post',
        'cat' => 953
        );  
    $the_query = get_posts( $args );  // Should grab ALL posts
    if ($the_query) {  
        foreach ($the_query as $post) {
            $post_id = $post->ID;
            $args = array( 'orderby' => 'name', 'order' => 'ASC', 'fields' => 'names' );
            $tags = wp_get_post_tags( $post_id, $args ); // Gets existing tags. The array is a list af arguments used to grab only the term IDs and order them.
            $new_terms = implode(', ', $tags);
            $append = false;
            wp_set_post_terms( $post_id, $new_terms, 'cartoon-treasury', $append );
            wp_set_post_terms( $post_id, $new_terms, 'cartoon-playground', $append );
        }
    }
    wp_reset_query();  
}
add_action('wp_head', 'updatePostsTerms'); */


// Duplicates post_tag terms when post is saved. So for example user
// inputs 'chocolate' as a new tag term. When saved, 'chocolate' is
// saved to the other taxonomies as well.
// 
// To maintain accurate tag clouds, I need some posts to NOT be
// associated with all taxonomies, and so I check the posts' category
// to see if it's one that should have the post_tag term duplicated.
// 
// Keep this code in functions.php.
function duplicateTerms(  ){
    $post_id = $_POST['post_ID'];
    $new_terms = $_POST['adv-tags-input'];
    $categories = $_POST['post_category'];
    $new_terms = explode(',', $new_terms);
    foreach ($new_terms as $term){
        wp_insert_term( $term, 'cartoon-treasury', array( 'slug' => $term) );
        wp_insert_term( $term, 'cartoon-playground', array( 'slug' => $term) );
    }
    $append = false;
    foreach ( $categories as $category ) {
        if ( $category == 953 ) {
            wp_set_post_terms( $post_id, $new_terms, 'cartoon-treasury', $append );
        }
    }
    foreach ( $categories as $category ) {
        if ( $category == 4074 ) {
            wp_set_post_terms( $post_id, $new_terms, 'cartoon-playground', $append );
        }
    }
}
add_action( 'save_post', 'duplicateTerms' );

// With these taxonomies, I have control over tag clouds and template pages.
// When looking at cartoons via the slider, a user can click a tag from
// the tag cloud and be directed to another slider page. These slider pages
// have URLs that look like this: site.com/taxonomy-name/term , and I can 
// modify these pages by modifying the taxonomy's template.
// 
// When looking at cartoons on the blog, a user can click a tag from the tag
// cloud and be directed to posts in blog-format. URLs look like this: site.com
// /blog/term.
// 
// I'm still running into some problems with this setup, by most things
// are working. :)

Thanks everyone for all your help.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.