¿Cómo detener wordpress para realizar la consulta predeterminada?

4

Mi objetivo es una redirección a una plantilla personalizada basada en alguna nueva regla de reescritura, pero sin tener wordpress para hacer consultas inútiles.

mi código:

function add_rewrite_rules() {

    add_rewrite_rule(
        '^settore/([^/]*)/?$',
        'index.php?settore=$matches[1]',
        'top'
    );

  add_rewrite_tag('%settore%','(caldareria|tessile)');
}
add_action( 'init', 'add_rewrite_rules' );

function set_root_category_template($template){
    $settore = get_query_var('settore');
    if($settore != '') $template = locate_template('root-taxonomy.php');
    return $template;
}
add_filter('template_include','set_root_category_template',99);

Redirige a la perfección, pero si reviso $ wp_query- > publicaciones en root-taxonomy.php, veo una lista de publicaciones regulares. En su lugar, en esa página haré una consulta personalizada solicitando algunos datos específicos de términos de taxonomía, y por lo tanto, la consulta predeterminada es totalmente inútil. ¿Cómo puedo pararlo? Después de todo, no estoy pasando ninguna variable de consulta predeterminada a index.php, así que no puedo entender la razón por la que wp sigue haciendo una consulta ...

    
pregunta Stratboy 13.06.2014 - 11:35

2 respuestas

4

Detener WordPress para ejecutar la consulta principal es difícil: tienes que cavar dentro del corazón profundo de WordPress.

Flujo de trabajo del frontend de WordPress:

  1. wp-blog-header.php llame a la función wp()
  2. wp() crea una instancia de wp class , y llame al método main() en él
  3. main() código del método:

    public function main($query_args = '') {
      $this->init();
      $this->parse_request($query_args); // build query vars starting from url
      $this->send_headers();
      $this->query_posts();  // run main query via WP_Query using built query vars
      $this->handle_404(); // if query has no results set 404 headers and WP_Query props
      $this->register_globals();
    }
    
  4. wp-blog-header.php incluye template-loader.php que cargar el archivo de plantilla en función de la consulta

Entonces, la única forma de detener la consulta principal es evitar que se ejecute wp() .

Se puede hacer enganchando un gancho temprano, haz lo que necesites y, por último, exit() .

El problema de este enfoque es que al evitar que wp() se ejecute, también se evita que la clase wp analice la solicitud, por lo que las cosas de reescritura que agregue no se analizan.

Entonces, en lugar de agregar una etiqueta de reescritura y una regla de reescritura, es posible que desee mirar directamente a la url para elegir si es la que debe desencadenar su acción personalizada.

Primero de todo, escribamos una función que devuelva solo la parte relativa de la url, por ejemplo. si la url actual es algo así como example.com/wp/path/to/somewhere?foo=bar y su url local es example.com/wp/ la función devuelve path/to/somewhere :

function get_relative_url() {
  $home_path = rtrim( parse_url( home_url(), PHP_URL_PATH ), '/' );
  $path = trim( substr( add_query_arg( array() ), strlen( $home_path ) ), '/' );
  $qs = array_keys( $_GET );
  if ( ! empty( $qs ) ) {
    $path = remove_query_arg( $qs, $path );
  }
  return $path;
}

Ahora podemos usar un enlace inicial para ver la url, y solo si contiene la ruta deseada estableceremos la variable $settore , cargaremos la plantilla y saldremos:

add_action( 'wp_loaded', function() { // 'wp_loaded' hook happen before wp() is ran

  $path = get_relative_url();
  $url_parts = explode( '/', $path );
  if (
    isset( $url_parts[1] )
    && $url_parts[0] === 'settore'
    && in_array( $url_parts[1], array( 'caldareria', 'tessile' ), TRUE )
  ) {
    // ok the current url is something like example.com/settore/tessile
    // and 'tessile' is in the variable $url_parts[1]
    $template = locate_template( 'root-taxonomy.php' );
    if ( empty( $template ) ) return; // do nothing if template not found
    global $settore;
    $settore = $url_parts[1]; // in the template you can access to $settore variable.
    require_once $template;
    exit(); // prevent WordPress to do anything else
  }

} );

Eso es todo.

En el código anterior, entender si la url actual es la correcta y establecer la variable $settore fue fácil porque la estructura de la url era fácil, para estructuras de url más complejas, probablemente necesite una coincidencia de expresiones regulares, y tal vez use una herramienta como componente de enrutamiento de Symfony para hacer coincidir la url con algunas variables.

Este enfoque es el que he usado en Cortex , eche un vistazo si planea hacer algo así.

Gotchas

como puede ver, la consulta principal ( global $wp_query ) en el código que publiqué no se usa, en su plantilla será un objeto WP_Query vacío, por lo que cualquier cosa se referirá a la consulta principal, por ejemplo. las etiquetas de plantilla como is_tax() , is_archive() o similares, no funcionarán.

Esto también se aplicará al encabezado y al pie de página, porque muy probablemente en su 'root-taxonomy.php' usará get_header() y get_footer() .

También es posible que algunos complementos no funcionen correctamente, por ejemplo. Si está utilizando algún complemento SEO que establezca una etiqueta de título basada en la consulta, entonces tendrá problemas.

Una posible solución es configurar manualmente las propiedades de la consulta principal para acceder a global $wp_query o usar un encabezado personalizado, por ejemplo. get_header('root-tax') , para su plantilla personalizada y para el manejo en la etiqueta de título personalizada header-root-tax.php y / o cualquier otro problema.

    
respondido por el gmazzap 13.06.2014 - 13:11
0

¿Por qué no de esta manera?

add_action( 'pre_get_posts', 'my_post_queries' );
function my_post_queries( $query ) {
    if ($query->is_main_query() && !is_admin()) {
        // maybe check for specific page here
        // if (is_tax('your-taxonomy') { 
        $query = false;
        remove_all_actions ( '__after_loop');
        // }
    }
}

¿O entendí mal la pregunta?

    
respondido por el Web-Entwickler 19.04.2016 - 22:10

Lea otras preguntas en las etiquetas