¿Cómo puedo cargar una plantilla de página desde un plugin?

9 feb 2017, 15:21:00
Vistas: 23.5K
Votos: 13

Quiero agregar plantillas de página a un tema directamente desde el plugin. La idea es que la plantilla aparezca en el menú desplegable dentro de Atributos de página, y todo el código necesita estar en el plugin.

¿Algún consejo sobre cómo lograr esto?

0
Todas las respuestas a la pregunta 8
2
15

Puedes usar el filtro theme_page_templates para agregar plantillas al menú desplegable de plantillas de página de esta manera:

function wpse255804_add_page_template ($templates) {
    $templates['my-custom-template.php'] = 'Mi Plantilla';
    return $templates;
    }
add_filter ('theme_page_templates', 'wpse255804_add_page_template');

Ahora WordPress buscará el archivo my-custom-template.php en el directorio del tema, por lo que tendrás que redirigirlo al directorio de tu plugin usando el filtro page_template así:

function wpse255804_redirect_page_template ($template) {
    if ('my-custom-template.php' == basename ($template))
        $template = WP_PLUGIN_DIR . '/mypluginname/my-custom-template.php';
    return $template;
    }
add_filter ('page_template', 'wpse255804_redirect_page_template');

Lee más sobre esto aquí: Agregar plantilla de página personalizada programáticamente

9 feb 2017 16:23:16
Comentarios

¡Perfecto! Eso lo hace exactamente.

smartcat smartcat
9 feb 2017 17:53:27

Desde la versión 4.7 de WordPress, el código anterior no funcionará. Cambia esta línea de 'if ('my-custom-template.php' == basename ($template))' a $post = get_post(); $page_template = get_post_meta( $post->ID, '_wp_page_template', true ); if ('my-custom-template.php' == basename ($page_template ))

Nirmal Goswami Nirmal Goswami
9 dic 2017 11:47:01
0

Esta es una combinación de la respuesta anterior y los comentarios anteriores que terminaron funcionando para mí.

La función para agregar el plugin a la lista de plantillas disponibles:

function wpse255804_add_page_template ($templates) {
    $templates['my-custom-template.php'] = 'Mi Plantilla';
    return $templates;
    }
add_filter ('theme_page_templates', 'wpse255804_add_page_template');


La función para dirigir la plantilla al directorio apropiado dentro del plugin:

function wpse255804_redirect_page_template ($template) {
    $post = get_post();
    $page_template = get_post_meta( $post->ID, '_wp_page_template', true );
    if ('my-custom-template.php' == basename ($page_template))
        $template = WP_PLUGIN_DIR . '/mypluginname/my-custom-template.php';
    return $template;
    }
add_filter ('page_template', 'wpse255804_redirect_page_template');
9 oct 2018 22:29:45
1

Gracias por la ayuda. Modifiqué un poco el código para que funcione con la versión actual de WordPress. También lo cambié para que admita más de una plantilla personalizada.

Apuesto a que hay una mejor manera de hacer esto, pero funcionó para mí.

/**
 * Cargar plantilla con el Plugin
 */
function yourname_add_page_template ($templates) {
    $templates['page-one.php'] = 'título aquí Uno';
    $templates['page-two.php'] = 'título aquí Dos';
    $templates['page-three.php'] = 'título aquí Tres';
    return $templates;
}
add_filter ('theme_page_templates', 'yourname_add_page_template');

function yourname_redirect_page_template ($template) {
    $post = get_post();
    $page_template = get_post_meta( $post->ID, '_wp_page_template', true );
    if ('page-one.php' == basename ($page_template)) {
        $template = WP_PLUGIN_DIR . '/pluginname/templates/page-one.php';
        return $template;
    }
    elseif ('page-two.php' == basename ($page_template)) {
        $template = WP_PLUGIN_DIR . '/pluginname/templates/page-two.php';
        return $template;
    }
    elseif ('page-three.php' == basename ($page_template)) {
        $template = WP_PLUGIN_DIR . '/pluginname/templates/page-three.php';
        return $template;
    }
}
add_filter ('page_template', 'yourname_redirect_page_template');

1 jun 2019 07:55:55
Comentarios

Te falta un return $template si no coincide con ninguna de las páginas uno/dos/tres

Rup Rup
4 nov 2022 02:46:59
0

Del Codex:

<?php 
   $templates = get_page_templates();
   foreach ( $templates as $template_name => $template_filename ) {
       echo "$template_name ($template_filename)<br />";
   }
?>

Luego puedes utilizar las plantillas actuales y agregarlas programáticamente a lo que desees.

9 feb 2017 15:40:05
0

El siguiente fragmento de código está muy bien pensado, intentará buscar una plantilla en el plugin y si no la encuentra allí, intentará obtenerla del tema.

define( 'MY_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
define( 'MY_PLUGIN_TEMPLATE_DIR', MY_PLUGIN_DIR . '/templates/' );

add_filter( 'template_include', 'ibenic_include_from_plugin', 99 );

function ibenic_include_from_plugin( $template ) {

    $new_template = '';

    $provided_template_array = explode( '/', $template );

    // Esto nos dará archive.php
    $new_template = end( $provided_template_array );

    // Definir plantilla single y archive para el tipo de contenido personalizado 'portfolio'
    if( is_singular('portfolio') ) {
        $new_template = 'single-portfolio.php';
    }

    if( is_post_type_archive( 'portfolio' ) ) {
        $new_template = 'archive-portfolio.php';
    }

    $plugin_template = MY_PLUGIN_TEMPLATE_DIR . $new_template;

    if( file_exists( $plugin_template ) ) {
    return $plugin_template;
    }

    return $template;
}

Fuente: https://www.ibenic.com/include-or-override-wordpress-templates/

26 feb 2020 01:14:55
4

Aquí hay una actualización para 2022: A continuación, este código agregará una plantilla a la lista de plantillas de página y la registrará dentro de tus archivos de plugin

// ------------registrar plantilla de página en la lista de plantillas------------
function register_custom_template_list ($templates) {
  // ------------registrar nombre de visualización de la plantilla al nombre del archivo------------
  $templates['my-template.php'] = 'Mi Nombre de Plantilla';
  // ------------devolver lista de plantillas de página con la nueva adición------------
  return $templates;
}
// ------------conectar plantilla de página a la lista de plantillas------------
add_filter('theme_page_templates', 'register_custom_template_list');

// ------------registrar plantilla de página en el archivo------------
function render_custom_template_archive ($template) {
  // ------------obtener atributos de la página actualmente editada------------
  $post = get_post();
  $page_template = get_post_meta( $post->ID, '_wp_page_template', true );
  // ------------verificar si la plantilla seleccionada es para la plantilla personalizada------------
  if (basename ($page_template) == 'my-template.php'){
    // ------------registrar archivo de plantilla de página en la página------------
    $template = dirname(__DIR__).'/path_to/my-template.php';
    // ------------renderizar contenido de la plantilla personalizada------------
    return $template;
  } else {
    // ------------devolver plantilla seleccionada si no se eligió la plantilla personalizada------------
    return $template;
  }
}
// ------------conectar plantilla de página al archivo------------
add_filter('page_template', 'render_custom_template_archive');
3 nov 2022 06:43:38
Comentarios

Eso parece la respuesta de TKEz. ¿Qué tiene de diferente?

Rup Rup
4 nov 2022 02:45:10

@Rup He comentado el código para hacer la diferencia más clara. La principal diferencia está en la última parte de "render_custom_template_archive". La sentencia else asegura que otras plantillas de página también puedan cargarse. La respuesta aceptada/de TKEz rompió mi sitio WP y hacía que todas las páginas mostraran mi plantilla personalizada. Tuve que reiniciar completamente el sitio para que funcionara (afortunadamente era un sitio de pruebas).

sallycakes sallycakes
4 nov 2022 19:01:07

Ambas deberían funcionar bien tal cual, a menos que añadas llaves adicionales. Ambas funciones terminan con return $template que se ejecutará sin importar si la condición es verdadera o no.

Rup Rup
5 nov 2022 19:19:48

@Rup si miras la respuesta de TKEz; su declaración de retorno solo está dentro de la declaración if, lo que causó problemas en mi sitio

sallycakes sallycakes
5 nov 2022 22:32:38
0

Ahora que WordPress admite el uso de lo que tradicionalmente se conocía como Plantillas de Página con otros tipos de contenido, parece que un ejemplo actualizado que funcione para entradas, tipos de contenido personalizados y páginas podría ser útil.

/*
    Plugin Name: Ejemplo de Plantillas para Plugin
    Plugin URI: 
    Description: Carga plantillas de página (o tipo de contenido) desde un plugin
    Version: 0.1
    Requires at least: 6.0
    Requires PHP: 7
    Author: t31os
    Author URI: 
    License: GPL v2 or later
    License URI: https://www.gnu.org/licenses/gpl-2.0.html
*/
namespace t31os\Plugin;

if( !defined('ABSPATH') )
    exit;

class Plugin_Templates {
    
    private $types;
    private $args;
    private $folder;
    private $templates = [
         'template-name-1.php' => 'Plantilla de Plugin 1'
        ,'template-name-2.php' => 'Plantilla de Plugin 2'
        ,'template-name-3.php' => 'Plantilla de Plugin 3'
    ];
    
    public function __construct() {
        // Se ejecuta tarde para dar tiempo a que plugins/theme registren tipos de contenido
        add_action( 'init', [$this, 'on_init'], 5000 );
    }
    public function on_init() {
        
        // Filtros, ¡por qué no!
        $this->args      = apply_filters( 'my_plugin_template_type_args', [ 'public' => true ] );
        $this->folder    = apply_filters( 'my_plugin_template_directory', __DIR__ . '/templates/' );
        $this->templates = apply_filters( 'my_plugin_template_file_list', $this->templates );
        // Establecer los tipos de contenido
        $this->types     = get_post_types( $this->args );
        
        // No usamos plantillas con adjuntos
        unset( $this->types['attachment'] );
        
        // Añadir archivos personalizados a la lista de plantillas
        add_filter( 'theme_templates', [$this,'add_plugin_templates'], 1000, 4 );
        
        // Si la página es uno de los tipos
        if( isset( $this->types['page'] ) )
            add_filter( 'page_template', [$this,'set_plugin_page_template'], 1000, 3 );
        
        // Y manejar otros tipos de contenido
        add_filter( 'single_template', [$this,'set_plugin_type_template'], 1000, 3 );   
    }
    public function add_plugin_templates( $post_templates, $obj, $post, $post_type ) {
        
        if( !isset( $this->types[$post_type] ) )
            return $post_templates;
        
        foreach( $this->templates as $file => $name )
            $post_templates[$file] = $name;
        
        return $post_templates;
    }
    private function is_plugin_template( $file ) {
        return (bool) isset( $this->templates[$file] ) && file_exists( $this->folder . $file );
    }
    public function set_plugin_page_template( $template, $type, $templates ) {
        
        if( !isset( $templates[0] ) )
            return $template;
        
        if( $this->is_plugin_template( $templates[0] ) )
            return $this->folder . $templates[0];
        
        return $template;
    }
    public function set_plugin_type_template( $template, $type, $templates ) {
        
        if( !isset( $templates[0] ) || 'single' !== $type )
            return $template;
        
        if( $this->is_plugin_template( $templates[0] ) )
            return $this->folder . $templates[0];
        
        return $template;
    }
    // Función simple para depuración / verificación de valores
    private function pre( $s ) {
        printf( '<pre>%s</pre>', print_r( $s, true ) );
    }
}
new Plugin_Templates;

Intenté no ser demasiado abstracto y mantener la lógica bastante simple, cualquier problema, añade un comentario.

3 nov 2022 16:48:26
2
-4
<?php load_template( $_template_file, $require_once ) ?>

Eso proviene de los primeros resultados de búsqueda en Google para "cargar plantilla desde plugin". Por favor, haz un esfuerzo por encontrar las respuestas tú mismo antes de preguntar aquí.

9 feb 2017 15:39:28
Comentarios

Si no deseas que el tema o el tema hijo puedan sobrescribir la plantilla del plugin, simplemente usa require($template)

mrben522 mrben522
9 feb 2017 15:41:47

Por supuesto, lo he visto en Google. No creo que hayas entendido mi pregunta. Quiero que la plantilla aparezca en el desplegable de Atributos de página, para que el usuario pueda seleccionarla al crear/editar una página.

smartcat smartcat
9 feb 2017 15:45:03