Adaugă pagină cu șablon personalizat programatic

29 mar. 2011, 14:14:31
Vizualizări: 24.6K
Voturi: 7

Încerc să adaug o pagină cu șablon dintr-un plugin, iar fișierul șablonului se află în folderul plugin-ului. Este posibil acest lucru? Iată codul meu:

global $user_ID;
    $new_post = array(
        'post_title' => 'Pagină Șablon Test', // Titlul paginii de test
        'post_content' => 'Un text oarecare', // Conținutul
        'post_status' => 'publish', // Status publicat
        '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('Eroare la crearea paginii șablon');
    } else {
        update_post_meta($post_id, '_wp_page_template', 'tp-file.php');
    }

tp-file.php este pagina mea șablon personalizată. Când pun acel fișier în folderul temei (my-theme), funcționează bine, dar vreau să fac acest lucru cu fișierul din folderul plugin-ului astfel încât să nu fie nevoie ca utilizatorii să copieze acel fișier din folderul plugin-ului în folderul șablonului. Este posibil acest lucru? Aveți vreo idee?

4
Comentarii

http://www.unfocus.com/2010/08/10/including-page-templates-from-a-wordpress-plugin/ Se pare că se ocupă de această problemă. Nu sunt foarte familiarizat cu asta, așa că nu pot spune dacă funcționează sau nu.

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

Mulțumesc @Rev.Voodoo, o să arunc o privire.

user1147 user1147
29 mar. 2011 15:11:20

@Rev.Voodoo nu, asta nu a ajutat

user1147 user1147
30 mar. 2011 00:54:26

ce conține fișierul tp-file.php?

User User
1 ian. 2012 11:27:46
Toate răspunsurile la întrebare 3
15
13

Articolul menționat este pe drumul cel bun, dar voi simplifica lucrurile pentru tine.. ;)

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;
}

Filtrul verifică în esență dacă șablonul tău special este setat pentru pagina curentă și, dacă da, actualizează calea pentru a indica către șablonul din pluginul tău.

Doar asigură-te că calea este corectă, altfel vei întâmpina erori de includere... :)

Urmărire #1

Prima problemă este că WordPress validează orice șablon setat ca șablon de pagină, adică verifică dacă fișierul se află în directorul temei și dacă este un fișier de șablon valid. Dacă nu, trece peste el și include un șablon mai generic, cum ar fi page.php...

Totuși, acest lucru nu schimbă faptul că câmpul meta păstrează valoarea șablonului tău personalizat, iar is_page_template( 'tp-file.php' ) va returna corect „true” dacă este folosit în locul condiției mele anterioare, de exemplu...

// Filtrează șablonul paginii
add_filter('page_template', 'catch_plugin_template');

// Callback pentru filtrul de șablon
function catch_plugin_template($template) {
    // Dacă tp-file.php este șablonul setat
    if( is_page_template('tp-file.php') )
        // Actualizează calea (trebuie să fie o cale, folosește WP_PLUGIN_DIR și nu WP_PLUGIN_URL)
        $template = WP_PLUGIN_DIR . '/tp-test/tp-file.php';
    // Returnează
    return $template;
}

NOTĂ: Am modificat codul să folosească WP_PLUGIN_DIR, deoarece constanta WP_PLUGIN_URL nu este potrivită pentru căi... (includerile trebuie să folosească o cale, nu un URL).

O problemă, și aceasta nu este ceva ce poți repara, este că atunci când vizualizezi pagina din zona de administrare, în timpul editării, șablonul nu va fi listat ca activ, iar salvarea modificărilor ar putea schimba șablonul activ. Nu putem face prea multe în acest sens, deoarece dropdown-ul pentru șabloane este generat de o funcție care scanează fișierele temei și nu există hook-uri care să ne permită extinderea listei cu șabloane din plugin.

Personal, aș sugera ca soluție alternativă să salvezi un câmp meta suplimentar pentru fiecare pagină creată folosind pluginul tău special, apoi să adaugi un hook la save_post sau wp_insert_post_data pentru a verifica dacă acest câmp meta există. Dacă există, verifică și dacă șablonul paginii este setat la tp-file.php, iar dacă nu, îl actualizează. Câmpul meta suplimentar ar funcționa ca un „flag” pentru a indica care pagini necesită șablonul din plugin.

Iată pluginul tău funcționând în forma sa cea mai simplă (da, l-am testat)... :)

<?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( 'Acest plugin necesită WordPress 2.9 sau mai nou. <a href="http://codex.wordpress.org/Upgrading_WordPress">Te rog actualizează!</a>' );

// Adaugă callback pentru meniul de administrare
add_action('admin_menu', 'create_tp_menu');

// Callback pentru adăugarea elementelor de meniu
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' => 'Text exemplu',
            '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('Eroare la crearea paginii de șablon');
        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">Creează Pagină de Șablon</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="Creează Pagină de Șablon" name="btn_submit" />
         </form>
    </fieldset>
    <?php

}


// Filtrează șablonul paginii
add_filter('page_template', 'catch_plugin_template');

// Callback pentru filtrul de șablon
function catch_plugin_template($template) {
    // Dacă tp-file.php este șablonul setat
    if( is_page_template('tp-file.php') )
        // Actualizează calea (trebuie să fie o cale, folosește WP_PLUGIN_DIR și nu WP_PLUGIN_URL)
        $template = WP_PLUGIN_DIR . '/tp-test/tp-file.php';
    // Returnează
    return $template;
}

Sper că acest lucru clarifică lucrurile.. :)

30 mar. 2011 02:21:03
Comentarii

Mulțumesc @t31os Am încercat și nu a funcționat, apoi am găsit acest http://adambrown.info/p/wp_hooks/hook/page_template care este învechit, ai alte idei?

user1147 user1147
30 mar. 2011 02:31:51

Am încercat și ceva de genul acesta, dar nu a funcționat: $pt = get_page_templates(); $pt['TP testing'] = WP_PLUGIN_URL . '/tp-test/tp-file.php';

user1147 user1147
30 mar. 2011 02:38:15

Funcționează perfect la mine... Am nevoie de mai multe detalii decât "nu a funcționat"...

t31os t31os
30 mar. 2011 02:46:51

Se pare că fișierele de șablon nu sunt activate în subdirector, am observat asta în funcția get_page_templates din theme.php, ai alte idei?

user1147 user1147
30 mar. 2011 02:48:09

Nu este relevant, codul pe care l-am furnizat va funcționa perfect, cu condiția ca calea să fie setată corect și ca pagina solicitată să aibă _wp_page_template setat la tp-file.php... Tocmai l-am testat din nou pentru a fi sigur și am confirmat că funcționează (va trebui să văd mai multe detalii din codul tău dacă vrei să te ajut să înțelegi de ce nu funcționează în configurația ta).

t31os t31os
30 mar. 2011 02:53:31

Mulțumesc pentru timpul acordat, codul meu nu s-a schimbat, singurul lucru este că am adăugat codul tău în fișierul principal al plugin-ului meu, aruncă o privire aici: http://pastebin.com/sNR9s0sP

user1147 user1147
30 mar. 2011 03:05:20

De asemenea, am verificat din nou tabelul wp_postmeta, pare în regulă

user1147 user1147
30 mar. 2011 03:07:58

Ok, dar ce se întâmplă când încarci o pagină care are _wp_page_template setat la tp-file.php? Vezi vreo eroare de include, vezi o pagină goală sau vezi altceva? Ajută-mă să te ajut... ;)

t31os t31os
30 mar. 2011 03:08:39

Văd "Un text" ca pe o pagină normală, iar dacă merg în backend, văd că șablonul paginii este setat la cel implicit și nu apare în listă fișierul meu de șablon

user1147 user1147
30 mar. 2011 03:10:34

Mă pregătesc să merg la culcare în următoarele minute, dar voi clarifica problema mâine pentru tine. Atâta timp cât câmpul meta _wp_page_template rămâne setat corect, ar trebui să funcționeze, indiferent că nu apare în partea de administrare (ceea ce este de așteptat - voi explica în actualizarea răspunsului mâine).

t31os t31os
30 mar. 2011 03:17:41

ok, mersi @t31os pentru ajutor

user1147 user1147
30 mar. 2011 03:19:33

Cu plăcere... și tocmai am actualizat răspunsul meu.. ;)

t31os t31os
30 mar. 2011 12:56:21

Hei, este ciudat, codul nu funcționează când formularul este într-un fișier separat, dar dacă este împreună, atunci funcționează.

user1147 user1147
30 mar. 2011 13:49:03

Încearcă să setezi o acțiune pe formularul tău, de ex. action="<?php admin_url( '/?page=tp-teste' ) ?>", pentru a te asigura că se trimite corect către pagina ta de plugin.

t31os t31os
30 mar. 2011 13:54:56

Aaaaa, doamne, asta era problema. Mulțumesc @t31os pentru timpul acordat.

user1147 user1147
30 mar. 2011 14:09:51
Arată celelalte 10 comentarii
2

Filtrul page_template este acum învechit. (http://adambrown.info/p/wp_hooks/hook/page_template)

Încercați să utilizați single_template (sau archive_template pentru șabloanele de arhivă) în schimb.

Bazat pe răspunsul lui @t31os:

// Filtru pentru șablonul de pagină
add_filter('single_template', 'catch_plugin_template');

// Funcția de callback pentru filtrul de șablon
function catch_plugin_template($template) {
    // Dacă tp-file.php este șablonul setat
    if( is_page_template('tp-file.php') )
        // Actualizează calea (trebuie să fie o cale, folosește WP_PLUGIN_DIR și nu WP_PLUGIN_URL)
        $template = WP_PLUGIN_DIR . '/tp-test/tp-file.php';
    // Returnează
    return $template;
}
23 iun. 2016 17:20:10
Comentarii

dacă filtrul single_template nu a funcționat, poți folosi acest filtru; add_filter('template_include', 'catch_plugin_template');

luat de aici; https://www.pradipdebnath.com/2019/08/17/how-to-add-page-template-from-plugin-in-wordpress/

ewroman ewroman
18 apr. 2020 07:59:47

Nu sunt sigur dacă este învechit, doar s-a schimbat începând cu versiunea 4.7. https://developer.wordpress.org/reference/hooks/type_template/.Argumentul este gol dacă tema(ele) nu oferă șablonul, nu dacă pagina l-a selectat (l-a salvat) în baza de date din meniul dropdown.

Jonas Lundman Jonas Lundman
4 dec. 2021 10:49:31
0

O problemă, și aceasta nu este ceva ce poți repara, este că atunci când vizualizezi pagina din zona de administrare, în timpul editării paginii, șablonul nu va fi listat ca șablonul activ, iar salvarea modificărilor ar putea, desigur, să schimbe șablonul activ. Nu prea putem face ceva în acest sens, meniul derulant cu șabloane de pagină este generat de o funcție care scanează fișierele temei, nu există hook-uri disponibile care să ne permită să extindem lista cu șabloane din plugin-uri.

De fapt, am găsit un hook într-un alt thread care face exact asta:

WordPress: Poți crea șabloane de pagină programatic?

Lipesc codul aici pentru comoditate:

CONST CUSTOM_PAGE_TEMPLATES = array(
  array('slug' => 'home', 'label' => 'Acasă'),
  array('slug' => 'content-page', 'label' => 'Pagină de conținut'),
  array('slug' => 'ordering', 'label' => 'Comandă'),
  array('slug' => 'reviews', 'label' => 'Recenzii')
); 

/**
 * Adaugă șabloane de pagină fără fișiere în meniul derulant de șabloane 
 */
add_filter('theme_page_templates', function($page_templates, $wp_theme, $post) {
  foreach(CUSTOM_PAGE_TEMPLATES as $template) {
    // Adaugă dacă nu există deja
    if (!isset($page_templates[$template['slug']])) {
      $page_templates[$template['slug']] = $template['label'];
    }
  }
  return $page_templates;
}, PHP_INT_MAX, 3);

Sper că acest lucru ajută pe cineva.

20 apr. 2021 10:06:53