web-dev-qa-db-fra.com

Dites à wordpress d'afficher une seule page au lieu d'une archive

J'ai donc plusieurs paramètres personnalisés dans l'URL et, à un moment donné, lorsque la requête atteint 3 paramètres (par exemple, index.php?post_type=foo&<param-1>=<val-1>&<param-2>=<val-2>&<param-3>=<val-3>), il peut y avoir un message ou aucun. Au lieu d’afficher archive (archive-foo.php) avec cet article, je souhaite que wordpress affiche le message lui-même (par exemple, single-foo.php). Bien sûr, je peux vérifier tout cela dans le archive-foo.php et le rediriger vers un article correspondant à partir de là, mais dans ce cas, je "gaspille" toute la requête d'affichage de l'archive.

Donc, y a-t-il un moyen de forcer le chargement d'une seule page par wordpress lorsque l'archive ne contient qu'un seul enregistrement en manipulant la requête principale (en utilisant une fonction personnalisée dans functions.php et en l'attachant via add_action('pre_get_posts', '<func-name>'))?

Exemple approximatif:

add_action('pre_get_posts', 'custom_func')
function custom_func($query) {
    if($query->get('param-1')) {
        // Change some $query params, but still show archive
        if($query->get('param-2')) {
            // Change some $query params, but still show archive
            if($query->get('param-3')) {
                // There is 1 post or none for sure
                // Alter the query to something like
                $wpdb->query('SELECT * FROM wp_posts WHERE param1=val1 AND param2=val2 ...');
                // force to load a single page with the results passed to $post object
            }
        }
    }
}
1
somebody

Voici un filtre grossier:

add_filter(
  'template_include',
  function($template) {
    global $wp_query;
    if (1 == $wp_query->found_posts) {
      global $wp_query;
      $type = $wp_query->get('post_type') ?: false;
      $template_type = $type ? 'single-' . $type. '.php' : 'single.php';
      if ( locate_template($template_type) ) {
        return locate_template($template_type);
      } elseif ( $type && locate_template('single.php') ) {
        return locate_template('single.php');
      }
    }
    return $template;
  }
);

Vous devrez le modifier pour qu'il traite correctement les modèles single-{*}.php personnalisés. (Édité par G.M.)

Je vais peut-être modifier le code un peu plus tard, mais je pensais pouvoir vous aider à démarrer.

2
s_ha_dum

Je pense que vous pouvez faire quoi en utilisant la fonction template_include():

 add_filter('template_include','alter_template');
 function alter_template($template){

     global $wp_query;

     if($wp_query->found_posts == 1) {
         $template = get_stylesheet_directory().'/single.php';
     }

     return $template;
  }

Ou si vous souhaitez rediriger vers la publication, utilisez template_direct():

add_action( 'template_redirect', 'my_page_template_redirect' );
function my_page_template_redirect()
{
    global $wp_query;
    if($wp_query->found_posts == 1)
    {
        wp_redirect( 'URL_of_the_post );
        exit();
    }
}
1
cybmeta