0

I have code displaying related posts (to the selected post in the single.php file) based on tags. Posts displayed are those with the same tags as the single post, the selected one.

I realize that tags are ordered alphabetically (maybe not true?) so I can't go around and select only based on the first/last entered tag. I want to base it on only one tag, a "main" tag.

Is it possible to make one tag per post the "main" tag?

I'm honestly a bit lost here. It's hard to search for since HTML (and others) use "tag"...

EDIT in an attempt to clarify:
Imagine the following:
You've a post.
The post have three tags: cat, dog, tree.
The post is mostly related to the tag "dog".
You want to select other posts based on the most important tag (aka dog).
How would you make "dog" more important then the rest of the tags?
It should be possible as content editor to change which tag's the most important.

closed as off-topic by Mark Kaplun, Dave Romsey, cjbj, bueltge, TheDeadMedic Sep 20 '16 at 10:10

This question appears to be off-topic. The users who voted to close gave this specific reason:

If this question can be reworded to fit the rules in the help center, please edit the question.

  • Please edit your question and include all relevant code, and explain better what is it that you get now and what do you want to achieve. Right now I personally have no idea what is the question here, what have tag order have anything to do with getting related posts – Mark Kaplun Sep 13 '16 at 8:45
  • There's no code. I'm asking for a way to set a "main tag" or something similar. I've nothing to work with because I've trouble searching this :/ I'll try to clarify it. – TheZeph Sep 13 '16 at 8:58
  • 1
    so when you say "I have code", what does it mean? – Mark Kaplun Sep 13 '16 at 9:00
  • I guess nothing, just my way of speaking. I've searched quite some and I keep going in circles. It's obvious that I don't really know how to ask it. I know what I want but not how to ask it, it that makes sense... – TheZeph Sep 13 '16 at 9:11
  • well, then it is time you actually tried to write that code and ask specific questions about the code you have written :( – Mark Kaplun Sep 13 '16 at 9:16
1

You can't make a main tag per post. Tags are a not hyerarchycal taxonomy, and by definition, not hyerarchycal taxonomies have no hyerarchy, none of the terms can be more important than each other.

In order to accomplish your task, most WP developers would suggest yo to make some custom field to store your "main tag", and then use it to retrieve your related posts. Something like this in your functions.php would construct your custom field metabox:

/**
 * Generated by the WordPress Meta Box Generator at http://goo.gl/8nwllb

 */
class Custom_Meta_Box {
private $screens = array(
    'post',
);
private $fields = array(
    array(
        'id' => 'main-tag',
        'label' => 'Main tag',
        'type' => 'text',
    ),
);

/**
 * Class construct method. Adds actions to their respective WordPress hooks.
 */
public function __construct() {
    add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
    add_action( 'save_post', array( $this, 'save_post' ) );
}

/**
 * Hooks into WordPress' add_meta_boxes function.
 * Goes through screens (post types) and adds the meta box.
 */
public function add_meta_boxes() {
    foreach ( $this->screens as $screen ) {
        add_meta_box(
            'main-tag',
            __( 'Main Tag', 'your-textdomain' ),
            array( $this, 'add_meta_box_callback' ),
            $screen,
            'side',
            'default'
        );
    }
}

/**
 * Generates the HTML for the meta box
 * 
 * @param object $post WordPress post object
 */
public function add_meta_box_callback( $post ) {
    wp_nonce_field( 'main_tag_data', 'main_tag_nonce' );
    echo 'Use this field to set the main tag:';
    $this->generate_fields( $post );
}

/**
 * Generates the field's HTML for the meta box.
 */
public function generate_fields( $post ) {
    $output = '';
    foreach ( $this->fields as $field ) {
        $label = '<label for="' . $field['id'] . '">' . $field['label'] . '</label>';
        $db_value = get_post_meta( $post->ID, 'main_tag', true );
        switch ( $field['type'] ) {
            default:
                $input = sprintf(
                    '<input id="%s" name="%s" type="%s" value="%s">',
                    $field['id'],
                    $field['id'],
                    $field['type'],
                    $db_value
                );
        }
        $output .= '<p>' . $label . '<br>' . $input . '</p>';
    }
    echo $output;
}

/**
 * Hooks into WordPress' save_post function
 */
public function save_post( $post_id ) {
    if ( ! isset( $_POST['main_tag_nonce'] ) )
        return $post_id;

    $nonce = $_POST['main_tag_nonce'];
    if ( !wp_verify_nonce( $nonce, 'main_tag_data' ) )
        return $post_id;

    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
        return $post_id;

    foreach ( $this->fields as $field ) {
        if ( isset( $_POST[ $field['id'] ] ) ) {
            switch ( $field['type'] ) {
                case 'email':
                    $_POST[ $field['id'] ] = sanitize_email( $_POST[ $field['id'] ] );
                    break;
                case 'text':
                    $_POST[ $field['id'] ] = sanitize_text_field( $_POST[ $field['id'] ] );
                    break;
            }
            update_post_meta( $post_id, 'main_tag', $_POST[ $field['id'] ] );
        } else if ( $field['type'] === 'checkbox' ) {
            update_post_meta( $post_id, 'main_tag', '0' );
        }
    }
}
}
new Custom_Meta_Box;

Once you have your custom field metabox, you should fill it with a valid tag slug (I suggest slug better than a name or term ID) and use it to retrieve your related posts by making this kind of query inside single.php:

$args = array(
    'meta_key'   => 'main_tag',
    'meta_value' => get_post_meta($post->ID, 'main_tag', true);
);
$query = new WP_Query( $args );
  • That's a cool generator! Cheers. Care to explain the last step? I don't understand the "fill it with a valid tag slug"-part. I need the "main tag" inside my own function to query with my custom query so that I can match normal tags and main tag with each other. Also, English is not my native tongue. – TheZeph Sep 13 '16 at 8:55
  • Just a question, but would it not be easier to just register a new custom taxonomy (custom_tags) and use that instead, as a custom tax, you can make it hierarchical.? – Malisa Sep 13 '16 at 10:05
  • It would be easier? Maybe, but also it will generate custom taxonomy archives, sitemaps, it would interfere with taxonomies-related plugins, etc. Storing a single text field is a tidy, simple way to fetch posts. – David Navia Sep 13 '16 at 11:26
  • @TheZeph With this solution, you could use the "Main tag" slug to query your posts this way: $args = array( 'tag' => get_post_meta($post->ID, 'main_tag', true); ); $query = new WP_Query( $args ); That's why I told you to use a valid tag slug name, in order to match with tags of other posts – David Navia Sep 13 '16 at 11:31
  • Right, right. Seems to be working great at the moment. I realized one thing though; with normal tags you get an ID which means if you search for a specific ID then it doesn't matter what it's named. This main tag system lack connection to the standard tags which makes it unreliable when trying to find only posts based of the main tag if you look through main and normal tags for a specific tag. I guess I just want to copy one of the picked normal tags, with all its info, to the "main tag" part. Any suggestion where I should look to accomplish that? – TheZeph Sep 13 '16 at 13:23

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