Aggiungere programmaticamente una pagina con template personalizzato

29 mar 2011, 14:14:31
Visualizzazioni: 24.6K
Voti: 7

Sto cercando di aggiungere un template di pagina da un plugin, e il mio file template si trova nella cartella del plugin. È possibile? Ecco il mio codice:

global $user_ID;
    $new_post = array(
        'post_title' => 'Pagina Template di Test',
        'post_content' => 'Un po\' di testo',
        'post_status' => 'publish',
        'post_date' => date('Y-m-d H:i:s'),
        'post_author' => $user_ID,
        'post_type' => 'page',
        'post_category' => array(0)
    );
    $post_id = wp_insert_post($new_post);
    if (!$post_id) {
        wp_die('Errore nella creazione della pagina template');
    } else {
        update_post_meta($post_id, '_wp_page_template', 'tp-file.php');
    }

tp-file.php è la mia pagina template personalizzata. Quando metto quel file nella cartella my-theme, funziona bene, ma voglio farlo con il file dalla cartella del plugin così non devo costringere gli utenti a copiare quel file dalla cartella del plugin alla cartella del template. È possibile? Qualche idea?

4
Commenti

http://www.unfocus.com/2010/08/10/including-page-templates-from-a-wordpress-plugin/ Sembra trattare questo problema. Non sono molto familiare con esso, quindi non posso dire se funziona o meno.

Rev. Voodoo Rev. Voodoo
29 mar 2011 14:45:02

Grazie @Rev.Voodoo darò un'occhiata.

user1147 user1147
29 mar 2011 15:11:20

@Rev.Voodoo no, non ha aiutato

user1147 user1147
30 mar 2011 00:54:26

qual è il contenuto di tp-file.php?

User User
1 gen 2012 11:27:46
Tutte le risposte alla domanda 3
15
13

L'articolo linkato è sulla strada giusta, ma lo semplificherò per te.. ;)

add_filter( 'page_template', 'catch_plugin_template' );

function catch_plugin_template( $template ) {
    if( 'tp-file.php' == basename( $template ) )
        $template = WP_PLUGIN_DIR . '/yourpluginname/tp-file.php';
    return $template;
}

Il filtro fondamentalmente verifica se il tuo template di pagina speciale è impostato per la pagina corrente, se lo è, aggiorna il percorso per puntare al template del tuo plugin.

Assicurati solo che il percorso sia corretto, altrimenti vedrai errori di inclusione... :)

Follow-up #1

Ok, il primo problema è che WordPress convalida qualsiasi template impostato come template di pagina, cioè verifica se il file si trova nella cartella del tema ed è un file di template valido, altrimenti lo salta e include un template più generico, come page.php...

Tuttavia, questo non cambia il fatto che il campo meta conservi ancora il valore del tuo template personalizzato, e anche is_page_template( 'tp-file.php' ) restituirà correttamente true se usato al posto della mia precedente condizione, ad esempio..

// Filtra il template di pagina
add_filter('page_template', 'catch_plugin_template');

// Callback del filtro per il template di pagina
function catch_plugin_template($template) {
    // Se tp-file.php è il template impostato
    if( is_page_template('tp-file.php') )
        // Aggiorna il percorso (deve essere un percorso, usa WP_PLUGIN_DIR e non WP_PLUGIN_URL) 
        $template = WP_PLUGIN_DIR . '/tp-test/tp-file.php';
    // Restituisci
    return $template;
}

NOTA: Ho modificato il codice per usare WP_PLUGIN_DIR poiché la costante WP_PLUGIN_URL non è adatta per i percorsi... (gli include devono usare un percorso, non un URL).

Un problema, e questo non è qualcosa che puoi risolvere, è che quando visualizzi la pagina dall'area di amministrazione, durante la modifica della pagina, il template non sarà elencato come template attivo, e salvare le modifiche potrebbe ovviamente cambiare il template attivo. Non c'è molto che possiamo fare lì, il menu a discesa dei template di pagina è generato da una funzione che scandisce i file del tema, non ci sono hook che permetterebbero di estendere la lista con i template dei plugin.

Personalmente, quello che suggerirei, come soluzione alternativa, sarebbe salvare un campo meta aggiuntivo per ogni pagina creata usando la tua pagina speciale del plugin, poi aggiungere un hook su save_post o wp_insert_post_data e verificare se questo campo meta esiste, se esiste, verificare anche che il template di pagina sia impostato su tp-file.php, e se non lo è, aggiornarlo a tp-file.php. Il campo meta aggiuntivo sarebbe solo un flag, per indicare quali pagine devono avere il template del plugin associato.

Ecco il tuo plugin che funziona nella sua forma più basilare (sì, l'ho testato)... :)

<?php
/*
  Plugin Name: TP Test Plugin
  Plugin URI: 
  Description: TP Test Plugin
  Version: 1.0.0
  Author: 
  Author URI: 
*/

global $wp_version;

if( version_compare( $wp_version, "2.9", "<" ) )
    exit( 'Questo plugin richiede WordPress 2.9 o più recente. <a href="http://codex.wordpress.org/Upgrading_WordPress">Aggiorna per favore!</a>' );

// Aggiungi callback al menu di amministrazione
add_action('admin_menu', 'create_tp_menu');

// Callback per aggiungere voci di menu
function create_tp_menu() {
    add_management_page('TP Test', 'TP Test', 'manage_options', 'tp-teste', 'wp_tp_test_fnc' );
}

function wp_tp_test_fnc() {

    //include('tp-form-file.php');

    if( !empty( $_POST['tp_name'] ) ) {
        $tp_name = $_POST['tp_name'];

        global $user_ID;
        $new_post = array(
            'post_title' => $tp_name,
            'post_content' => 'Qualche testo',
            'post_status' => 'publish',
            'post_date' => date('Y-m-d H:i:s'),
            'post_author' => $user_ID,
            'post_type' => 'page',
        );
        $post_id = wp_insert_post($new_post);

        if( !$post_id )
            wp_die('Errore nella creazione della pagina template');
        else
            update_post_meta( $post_id, '_wp_page_template', 'tp-file.php' );
        /*
        $pt = get_page_templates();

        $pt['TP file test'] = WP_PLUGIN_URL . '/tp-test/tp-file.php';

        echo "<pre>";
        print_r($pt);
        echo "</pre>";
        */
    }   
    ?>
    <fieldset style="margin: 50px 100px;background-color: #cccccc;padding: 30px;border: 1px solid #ccc">
         <legend style="background-color: #ccccff;padding: 20px;font-weight: bold;font-size: 18px">Crea Pagina Template</legend>
         <form name="frm_main" action="" method="POSt">
              <input class="text" type="text" name="tp_name" size="50" />
              <br />
              <input class="button" type="submit" value="Crea Pagina Template" name="btn_submit" />
         </form>
    </fieldset>
    <?php

}


// Filtra il template di pagina
add_filter('page_template', 'catch_plugin_template');

// Callback del filtro per il template di pagina
function catch_plugin_template($template) {
    // Se tp-file.php è il template impostato
    if( is_page_template('tp-file.php') )
        // Aggiorna il percorso (deve essere un percorso, usa WP_PLUGIN_DIR e non WP_PLUGIN_URL) 
        $template = WP_PLUGIN_DIR . '/tp-test/tp-file.php';
    // Restituisci
    return $template;
}

Spero che questo aiuti a chiarire le cose.. :)

30 mar 2011 02:21:03
Commenti

Grazie @t31os ho provato ma non ha funzionato, poi ho trovato questo http://adambrown.info/p/wp_hooks/hook/page_template che è deprecato, qualche altra idea?

user1147 user1147
30 mar 2011 02:31:51

Ho anche provato qualcosa del genere, ma non ha funzionato: $pt = get_page_templates(); $pt['TP testing'] = WP_PLUGIN_URL . '/tp-test/tp-file.php';

user1147 user1147
30 mar 2011 02:38:15

Per me funziona perfettamente... avrei bisogno di più dettagli oltre a "non ha funzionato"..

t31os t31os
30 mar 2011 02:46:51

Sembra che i file template non siano abilitati nella sottocartella, ho trovato questo nella funzione get_page_templates in theme.php, altre idee?

user1147 user1147
30 mar 2011 02:48:09

Non è rilevante, il codice che ho fornito funzionerà perfettamente purché il percorso sia impostato correttamente e la pagina richiesta abbia _wp_page_template impostato su tp-file.php... L'ho appena ritestato per sicurezza, e ho confermato nuovamente che funziona (dovrò vedere più del tuo codice se vuoi che ti aiuti a capire perché non funziona nel tuo setup).

t31os t31os
30 mar 2011 02:53:31

Grazie per il tuo tempo, il mio codice non è cambiato, l'unica cosa è che ho aggiunto il tuo codice al mio file principale del plugin, dai un'occhiata qui: http://pastebin.com/sNR9s0sP

user1147 user1147
30 mar 2011 03:05:20

Ho anche ricontrollato la mia tabella wp_postmeta, sembra tutto a posto

user1147 user1147
30 mar 2011 03:07:58

Ok, ma cosa succede quando carichi una pagina che ha _wp_page_template impostato su tp-file.php? Vedi un errore di inclusione, vedi una pagina bianca, vedi qualcos'altro? Aiutami ad aiutarti... ;)

t31os t31os
30 mar 2011 03:08:39

Vedo "Qualche testo" come se fosse una pagina normale, e se vado nel backend vedo che il template della pagina è impostato su predefinito, e non c'è nella lista il mio file template

user1147 user1147
30 mar 2011 03:10:34

Tra qualche minuto vado a letto, ma domani ti chiarirò il problema. Finché il campo meta _wp_page_template rimane impostato correttamente dovrebbe funzionare, indipendentemente dal fatto che non venga visualizzato nella parte amministrativa (cosa che ci si aspetta - spiegherò meglio nell'aggiornamento della risposta domani).

t31os t31os
30 mar 2011 03:17:41

ok, grazie @t31os per l'aiuto

user1147 user1147
30 mar 2011 03:19:33

Prego... e ho appena aggiornato la mia risposta.. ;)

t31os t31os
30 mar 2011 12:56:21

Ehi, è strano, il codice non funziona quando il modulo è in un file separato, ma se è tutto insieme, allora funziona.

user1147 user1147
30 mar 2011 13:49:03

Prova a impostare un'azione nel tuo modulo, ad es. action="<?php admin_url( '/?page=tp-teste' ) ?>", per assicurarti che venga inviato correttamente alla pagina del tuo plugin.

t31os t31os
30 mar 2011 13:54:56

Aaaaaaa, oddio, quello era il problema. Grazie @t31os per il tuo tempo.

user1147 user1147
30 mar 2011 14:09:51
Mostra i restanti 10 commenti
2

Il filtro page_template è ora deprecato. (http://adambrown.info/p/wp_hooks/hook/page_template)

Prova a utilizzare single_template (o archive_template per i template di archivio) invece.

Basato sulla risposta di @t31os:

// Filtro per il template della pagina
add_filter('single_template', 'catch_plugin_template');

// Callback per il filtro del template
function catch_plugin_template($template) {
    // Se tp-file.php è il template impostato
    if( is_page_template('tp-file.php') )
        // Aggiorna il percorso (deve essere un percorso, usa WP_PLUGIN_DIR e non WP_PLUGIN_URL)
        $template = WP_PLUGIN_DIR . '/tp-test/tp-file.php';
    // Restituisci
    return $template;
}
23 giu 2016 17:20:10
Commenti

se il filtro single_template non ha funzionato, puoi utilizzare questo filtro; add_filter('template_include', 'catch_plugin_template');

preso da qui; https://www.pradipdebnath.com/2019/08/17/how-to-add-page-template-from-plugin-in-wordpress/

ewroman ewroman
18 apr 2020 07:59:47

Non sono sicuro se sia deprecato, è cambiato dalla versione 4.7. https://developer.wordpress.org/reference/hooks/type_template/.L'argomento è vuoto se il/i tema/i non forniscono il template, non se la pagina lo ha selezionato (memorizzato) nel database dal menu a discesa di selezione.

Jonas Lundman Jonas Lundman
4 dic 2021 10:49:31
0

Un problema, e questo non è qualcosa che puoi risolvere, è che quando visualizzi la pagina dall'area di amministrazione, durante la modifica della pagina, il template non verrà elencato come quello attivo, e salvare le modifiche potrebbe naturalmente cambiare il template attivo. Non c'è molto che possiamo fare lì, il menu a discesa dei template di pagina è generato da una funzione che scansiona i file del tema, non ci sono hook disponibili che io possa vedere che ci permettano di estendere la lista con template di plugin.

In realtà ho trovato un hook in un'altra discussione che fa esattamente questo:

WordPress: È possibile creare template di pagina programmaticamente?

Incollerò il codice qui per comodità:

CONST CUSTOM_PAGE_TEMPLATES = array(
  array('slug' => 'home', 'label' => 'Home'),
  array('slug' => 'content-page', 'label' => 'Pagina Contenuti'),
  array('slug' => 'ordering', 'label' => 'Ordini'),
  array('slug' => 'reviews', 'label' => 'Recensioni')
); 

/**
 * Aggiunge template di pagina senza file al menu a discesa dei template 
 */
add_filter('theme_page_templates', function($page_templates, $wp_theme, $post) {
  foreach(CUSTOM_PAGE_TEMPLATES as $template) {
    // Aggiunge se non esiste già
    if (!isset($page_templates[$template['slug']])) {
      $page_templates[$template['slug']] = $template['label'];
    }
  }
  return $page_templates;
}, PHP_INT_MAX, 3);

Spero che questo possa essere utile a qualcuno.

20 apr 2021 10:06:53