¿Plantillas de tipo de publicación personalizadas de la carpeta de complementos?

57

Me gustaría ofrecer mi tipo de publicación personalizada como un complemento, para que las personas puedan usarlo sin tocar su carpeta de temas. Pero las plantillas de tipo de publicación personalizadas, como single-movies.php, residen en la carpeta del tema. ¿Hay alguna manera de hacer que WP verifique un single-movies.php en la carpeta del complemento? ¿Enganchando una función en la Jerarquía de Filer ? O get_template_directory (); ?

nathanbweb
fuente

Respuestas:

90

Puedes usar single_templategancho de filtro.

/* Filter the single_template with our custom function*/
add_filter('single_template', 'my_custom_template');

function my_custom_template($single) {

    global $post;

    /* Checks for single template by post type */
    if ( $post->post_type == 'POST TYPE NAME' ) {
        if ( file_exists( PLUGIN_PATH . '/Custom_File.php' ) ) {
            return PLUGIN_PATH . '/Custom_File.php';
        }
    }

    return $single;

}
Bainternet
fuente
Es una respuesta asombrosa. Por favor, comparta dónde puedo obtener todos los ganchos de plantilla disponibles como single_template.
Gowri
66
@gowri El filtro es llamado por la get_query_template()función. Es un enlace variable, por lo que la primera parte {$type}_templatecambia según el parámetro que se pasa a esa función. Vea wp-includes / template.php para ver algunos comunes
shea
Este tutorial cubre el enlace single_template con una buena explicación. Una vez que comprenda los ganchos, el comentario de @ shea sugiere un enfoque más simple que la respuesta de @ Bainternet, utilizando add_filter( 'single-movies_template', 'my_custom_template' );como en el tutorial vinculado. (Esta pregunta está cerrada a nuevas respuestas, por lo que no puedo agregarla por sí sola.)
Greg Perham
2
Puede reemplazar PLUGIN_PATHcon plugin_dir_path( __FILE__ )y luego eliminar la primera barra diagonal de su nombre de archivo. El camino completo se vería así:return plugin_dir_path( __FILE__ ) . 'Custom_File.php';
Frits
1
PLUGIN_PATH arrojó un error, aquí hay una gran publicación que muestra cómo hacer esto y me funcionó de inmediato
Nathan
22

Respuesta actualizada

Versión más limpia y corta.

function load_movie_template( $template ) {
    global $post;

    if ( 'movie' === $post->post_type && locate_template( array( 'single-movie.php' ) ) !== $template ) {
        /*
         * This is a 'movie' post
         * AND a 'single movie template' is not found on
         * theme or child theme directories, so load it
         * from our plugin directory.
         */
        return plugin_dir_path( __FILE__ ) . 'single-movie.php';
    }

    return $template;
}

add_filter( 'single_template', 'load_movie_template' );

Vieja respuesta

Se agregó una verificación para una plantilla específica de tipo de publicación personalizada en la carpeta de temas a la respuesta @Brainternet.

function load_cpt_template($template) {
    global $post;

    // Is this a "my-custom-post-type" post?
    if ($post->post_type == "my-custom-post-type"){

        //Your plugin path 
        $plugin_path = plugin_dir_path( __FILE__ );

        // The name of custom post type single template
        $template_name = 'single-my-custom-post-type.php';

        // A specific single template for my custom post type exists in theme folder? Or it also doesn't exist in my plugin?
        if($template === get_stylesheet_directory() . '/' . $template_name
            || !file_exists($plugin_path . $template_name)) {

            //Then return "single.php" or "single-my-custom-post-type.php" from theme directory.
            return $template;
        }

        // If not, return my plugin custom post type template.
        return $plugin_path . $template_name;
    }

    //This is not my custom post type, do nothing with $template
    return $template;
}
add_filter('single_template', 'load_cpt_template');

Ahora puede permitir que los usuarios del complemento copien la plantilla de su complemento a su tema para anularlo.

Con este ejemplo, las plantillas deben estar en el directorio raíz tanto del complemento como del tema.

Campsjos
fuente
1
Usar en locate_templatelugar de get_stylesheet_directorysonidos como la opción más limpia para mí (que se encuentra aquí: code.tutsplus.com/tutorials/… ).
Felix
1
La respuesta actualizada no funcionó, la respuesta aceptada (o su respuesta anterior) funciona.
Edward
2
Tienes razón, @Edward, esa fue una actualización horrenda. Lo actualicé nuevamente con la sugerencia de Felix. También esta vez probé el código antes de publicarlo :)
campsjos
4

Me gustaría señalar que cuando utiliza el método de filtro para esto, es extremadamente importante priorizar el filtro de esta manera:

add_filter('single_template', 'my_custom_template', 99);

Si no hace esto, a veces WP intentará volver a verificar después de este filtro. Estuve arrancándome el pelo por eso durante 2 horas.

RBizzle
fuente
0

Hay una manera mucho mejor de hacerlo que estoy usando para mis complementos.

Como @campsjos menciona aquí , en lugar de verificar la existencia del archivo, puede verificar locate_templateque se registrará en el archivo de plantilla anulado del tema. Lo cual es bastante obvio.

function my_plugin_templates() {
    if (is_singular('movie')) {
        if (file_exists($this->template_dir . 'single-movie.php')) {
            return $this->template_dir . 'single-movie.php';
        }
    }
}

Use el template_includegancho de filtro para cargar el código anterior.

add_filter('template_include' , 'my_plugin_templates');
pixelngrain
fuente
0

Gracias a esta página pude resolver la misma pregunta para mí.

Como referencia, esto es lo que terminé con:

function pluginName_myposttype_single_template($single_template) {
  $myposttype_template = PLUGIN_DIR . 'templates/single-myposttype.php';
  return get_post_type() === 'myposttype' && file_exists($myposttype_template) ? $myposttype_template : $single_template;
}
add_filter('single_template', 'pluginName_myposttype_single_template');

el {$ type} _template filter hook no funcionó para mí

function pluginName_myposttype_single_template($single_template) {
  $myposttype_template = PLUGIN_DIR . 'templates/single-myposttype.php';

  if ( file_exists($myposttype_template) ) {
    $single_template = $myposttype_template;
  }
  return $single_template;
}
add_filter('single-myposttype_template', 'pluginName_myposttype_single_template');
Thomas Fellinger
fuente
-2

Lo anterior es una gran respuesta, pero la comprobación de $ single var permite que la plantilla anule una plantilla si el tema / tema secundario proporciona una.

/* Filter the single_template with our custom function*/
add_filter('single_template', 'your_cpt_custom_template');

function your_cpt_custom_template( $single ) {
    global $wp_query, $post;
    /* Checks for single template by post type */
    if ( !$single && $post->post_type == 'cpt' ) {
        if( file_exists( plugin_dir_path( __FILE__ ) . 'single-cpt.php' ) )
            return plugin_dir_path( __FILE__ ) . 'single-cpt.php';
    }
    return $single;
}
DigitalDesignDj
fuente
1
Esto no verifica si single-cpt.php está presente en un niño o en el tema. Solo se compara con single.php, que siempre estará presente en cualquier tema.
newpxsn
Así es, cuando escribí esto estaba usando un tema realmente desnudo, ¡tiene que haber una mejor manera!
DigitalDesignDj