Woocommerce – Alternativa para woocommerce_locate_template

5 minutos de lectura

Estoy desarrollando un complemento basado en woocommerce y, como parte del mismo, tuve que anular la ubicación predeterminada del archivo de plantilla de woocommerce. Quiero decir que estoy buscando tener una plantilla de woocommerce personalizada cargada desde mi complemento.

Para hacer esto, leí sobre woocommerce_locate_template en woocommerce basado en esto artículopero me di cuenta de que la misma función ha quedado obsoleta según este Enlace. Ahora me pregunto cuál podría ser una función alternativa para esto.

Toda mi intención era cambiar la ubicación de carga de la plantilla de WooCommerce predeterminada a mi carpeta de complementos. ¿Alguna ayuda para resolver esto? Gracias por adelantado.

avatar de usuario
lorenzo zotar

La función woocommerce_locate_template está en desuso en favor de wc_locate_template: puede leer el código aquí.

Sin embargo, si está buscando la filtrartodavía woocommerce_locate_template y toma tres argumentos:

  1. $plantilla ese es el resultado de la función core de wp locate_template
  2. $template_name ese es solo el nombre del archivo
  3. $plantilla_ruta ese es el camino de woocommerce para plantillas

Entonces puede verificar si $template_name es lo que desea interceptar y cambiar la ruta si es verdadero, así

function intercept_wc_template($template, $template_name, $template_path) {
    if ($template_name == 'that_template.php') {
        $template="the/path/of/your/plugin/template.php";
    }
    return $template;
}

add_filter('woocommerce_locate_template', 'intercept_wc_template', 20, 3);

No lo he probado, lo siento por cualquier posible error de sintaxis 🙂

¡Espero eso ayude!

— Actualización 1: olvidé un punto y coma 😛 —
— Actualización 2: ¡Cometí un error! —

  • Gracias por tu respuesta Lorenzo Zottar. Probé su código y debajo está el código, pero puedo ver que no hay cambios en la plantilla del producto.

    – krishna89

    07/09/2015 a las 22:40

  • aquí está el código que probé function intercept_wc_template($template, $template_name, $template_path) { if ($template_name == 'content-single-product.php') { //um_product_path is the plugin path $template = locate_template(um_product_path.'woocommerce/single-product/content-single-product.php'); } return $template; } add_filter('woocommerce_locate_template', 'intercept_wc_template', 20, 3);

    – krishna89

    7 sep 2015 a las 22:41


  • Intenta agregar var_dump($template); antes de devolver $template para depurar si la ruta es correcta y si las declaraciones if funcionan. La cadena aparecerá en la parte superior de su página cuando ingrese a una página de Woocommerce. El filtro funciona, por lo que podría ser un problema con su ruta o un problema en la declaración if 🙂

    – Lorenzo Zotar

    7 sep 2015 a las 22:54

  • Acabo de comprobar el var_dump en la página del producto. Noté que la cadena var_dump se refiere a la carpeta original de la plantilla de woocommerce o a la carpeta de mi tema woocommerce, pero no a la carpeta de mi complemento en ninguna parte.

    – krishna89

    07/09/2015 a las 23:00

  • Entonces, el problema está en la declaración if: cambie el var_dump en var_dump($template_name); y vaya a la página que desea interceptar y verifique el nombre exacto de la plantilla. Sin embargo, cometí un error, no es necesario que use localizar_plantilla, simplemente anule la variable $template: acabo de probarlo en mi máquina local. Editaré mi respuesta.

    – Lorenzo Zotar

    7 sep 2015 a las 23:22

Tuve que modificar el código anterior para que coincidiera correctamente con el archivo de plantilla que necesitaba, que en mi caso era “variable.php”.

$template_name debe ser la ruta raíz completa de woocommerce, consulte a continuación:

Consulte el código modificado a continuación:

function intercept_wc_template($template, $template_name, $template_path) {
    if ($template_name == 'single-product/add-to-cart/variable.php') {
        $template="wp-content/themes/theme-name/woocommerce/single-product/add-to-cart/variable.php";
    }

    return $template;
}

add_filter('woocommerce_locate_template', 'intercept_wc_template', 20, 3);

avatar de usuario
jonas lundman

Si alguien tiene problemas con esto a partir de 2021, vale la pena mencionar que el filtrar 'woocommerce_locate_template' no filtra todas las plantillas dentro de la carpeta de woocommerce. En su lugar, debe filtrar otras 2 funciones:

add_filter('wc_get_template', 'entex_wc_get_template', 20, 5);
add_filter('wc_get_template_part', 'entex_wc_get_template_part', 20, 3);

Por ejemplo, la plantilla raíz de woocommerce content-single-product.php debe filtrarse con wc_get_template_part.

Esto está funcionando para nuestro complemento:

function template_base(){
    return untrailingslashit(plugin_dir_path( __FILE__ )) .'/templates/';
}

function entex_wc_get_template($template, $template_name, $args, $template_path, $default_path){

    /* custom theme templates has priority */
    if(strpos($template, '/themes/') !== FALSE) return $template;

    static $cache = array();
    if(isset($cache[$template_name])) return $cache[$template_name];
    
    $plugin_template = wc_locate_template($template_name, WC()->template_path(), $this->template_base());
    if($plugin_template && file_exists($plugin_template)){
        $template = $plugin_template;
        $cache[$template_name] = $template;
    }
    return $template;
}

function entex_wc_get_template_part($template, $slug, $name){
    
    /* custom theme templates has priority */
    if(strpos($template, '/themes/') !== FALSE) return $template;
    
    $template_name="";
    if($name){
        $template_name = "{$slug}-{$name}.php";
    } else if($slug){
        $template_name = "{$slug}.php";
    }
    if(!$template_name) return $template;
    
    static $cache = array();
    if(isset($cache[$template_name])) return $cache[$template_name];
    
    $plugin_template = template_base().$template_name;
    if($plugin_template && file_exists($plugin_template)){
        $template = $plugin_template;
        $cache[$template_name] = $template;
    }
    return $template;
} 

Esto se arrancó de la clase PHP y se pegó aquí, así que espero que el código no esté roto.

Recomendamos registrar las plantillas para un rendimiento más limpio, si solo usa algunas, y agregue algo como esto al principio de las funciones:

if(!in_array($template_name, array(
    'archive-product.php',
    'content-product.php',
    'content-product-cat.php',
    'content-single-product.php',
    'content-widget-product.php',
    'checkout/form-checkout.php',
    'checkout/thankyou.php',
    'loop/loop-start.php',
    'loop/loop-end.php'
))) return $template;

¿Ha sido útil esta solución?