Cum să *elimini* un șablon de pagină din tema părinte într-o temă copil?
Folosesc tema TwentyTen pentru a crea o temă copil, dar nu reușesc să scap de șablonul de pagină 'O coloană, fără sidebar' care se află în tema părinte TwentyTen.
Am crezut că dacă îl copiez și șterg conținutul va funcționa, dar se pare că nu. Știe cineva cum să fac acest lucru? Sunt sigur că e foarte simplu.
Mulțumesc
osu

WordPress 3.9 introducează un filtru theme_page_templates
.
Exemplul de mai jos, din fișierul functions.php
al unui child theme Twenty Fourteen, arată cum să elimini template-ul "Contributor Page":
function tfc_remove_page_templates( $templates ) {
unset( $templates['page-templates/contributors.php'] );
return $templates;
}
add_filter( 'theme_page_templates', 'tfc_remove_page_templates' );
Pentru toate celelalte tipuri de postări (cum ar fi "post" și tipuri personalizate de postări), poți folosi filtrul mai generic theme_{$post_type}_templates
(vezi documentația).
add_filter('theme_page_templates', 'tfc_remove_page_templates');
add_filter('theme_post_templates', 'tfc_remove_page_templates');
add_filter('theme_mycustomposttype_templates', 'tfc_remove_page_templates');

Suprascrierea acelui șablon ar fi mult mai ușoară decât înlăturarea lui. Doar așa merge logica.
Nu susțin că e o idee eficientă (e târziu aici), dar asta ar elimina șablonul din ecranul de editare:
add_action('admin_head-post.php','remove_template');
function remove_template() {
global $wp_themes;
get_themes();
$templates = &$wp_themes['Twenty Ten']['Template Files'];
$template = trailingslashit( TEMPLATEPATH ).'onecolumn-page.php';
$key = array_search($template, $templates);
unset( $templates[$key] );
}

Mulțumesc pentru asta, pare o soluție bună - când spui suprascrierea template-ului, te referi la includerea unui template cu o singură coloană oricum? Sau te referi la suprascrierea lui cu un template pe care chiar vreau să îl folosesc (adică să îl numesc One Column dar să aibă de fapt 2 sau 3 coloane?)?

@Osu Mă refeream la suprascrierea cu propriul tău template similar. Din punct de vedere logic, este ușor pentru un child theme să schimbe și să adauge la template-urile parent theme-ului, dar este greu să le dezactivezi. Practic, un child theme ar trebui să facă mai mult decât parent theme-ul, nu mai puțin. Și logica codului urmează acest principiu.

Ah, ok. Mulțumesc pentru clarificare. O să creez un template cu o coloană pentru ei atunci. Noroc

Pentru cei care doresc să elimine tema din lista derulantă folosind jQuery, iată o altă abordare (nu sunt sigur că este cea mai bună metodă totuși): http://pastie.org/3710683

@Rarst : Ai vreo idee de ce global $wp_themes
nu acceptă unset
în versiunea 3.4.1?

Extinzând răspunsul lui @Rarst, iată o abordare mai generică care nu este legată de un anumit temă, dar poate fi folosită în fișierul functions.php al propriului child theme pentru a elimina orice șabloane de pagină din tema părinte pe care doriți să le înlăturați.
function remove_template( $files_to_delete = array() ){
global $wp_themes;
// Pentru comoditate, permite utilizarea unei singure valori ca scalar fără a o înfășura într-un array() inutil
if ( is_scalar( $files_to_delete ) ) $files_to_delete = array( $files_to_delete );
// elimină extensia fișierului dacă a fost furnizată
$files_to_delete = preg_replace( "/\.[^.]+$/", '', $files_to_delete );
// Populează array-ul global $wp_themes
get_themes();
$current_theme_name = get_current_theme();
// Observă că luăm o referință la $wp_themes pentru a o putea modifica in-place
$template_files = &$wp_themes[$current_theme_name]['Template Files'];
foreach ( $template_files as $file_path ){
foreach( $files_to_delete as $file_name ){
if ( preg_match( '/\/'.$file_name.'\.[^.]+$/', $file_path ) ){
$key = array_search( $file_path, $template_files );
if ( $key ) unset ( $template_files[$key] );
}
}
}
}
Deci puteți utiliza această funcție în fișierul functions.php al child theme-ului dvs. astfel:
add_action( 'admin_head-post.php', 'remove_parent_templates' );
function remove_parent_templates() {
remove_template( array( "showcase.php", "sidebar-page" ) );
}
Aici ilustrez doar că nu trebuie să includeți extensia ".php" dacă nu doriți.
Sau: remove_template( "sidebar-page" );
- nu este nevoie să transmiteți un array dacă doriți să modificați un singur fișier.

Există un nou filtru în nucleul WordPress (3.9) pentru a elimina șabloanele de pagină. Acesta poate fi utilizat din temele copil.
Iată cum poți realiza acest lucru în TwentyTen (testat pe WP 3.9):
add_filter( 'theme_page_templates', 'my_remove_page_template' );
function my_remove_page_template( $pages_templates ) {
unset( $pages_templates['onecolumn-page.php'] );
return $pages_templates;
}
https://core.trac.wordpress.org/changeset/27297
http://boiteaweb.fr/theme_page_templates-hook-semaine-16-8033.html

Deoarece răspunsurile anterioare nu mai funcționează în versiunile actuale de WordPress și a existat o întrebare înrudită la care tocmai am răspuns (aprilie 2013) folosind un buffer de ieșire PHP, am considerat că voi posta un link către acel răspuns.
De asemenea, tocmai am publicat plugin-ul Omit Parent Theme Page Templates care filtrează toate șabloanele de pagină ale temei părinte din lista derulantă de șabloane din metabox-ul Page Attributes atunci când adăugați sau editați o "Pagină" WordPress.

10 iulie 2012 - WordPress 3.4.1
Răspunsurile anterioare nu funcționează și, după cum a menționat Rarst într-un comentariu:
componentele interne legate de teme au trecut printr-o refactorizare majoră și modificări de API în versiunea 3.4, așa că multe metode mai vechi nu vor funcționa
Soluție Rapidă jQuery
add_action('admin_head', 'wpse_13671_script_enqueuer');
function wpse_13671_script_enqueuer() {
global $current_screen;
/**
* /wp-admin/edit.php?post_type=page
*/
if('edit-page' == $current_screen->id)
{
?>
<script type="text/javascript">
jQuery(document).ready( function($) {
$("a.editinline").live("click", function () {
var ilc_qe_id = inlineEditPost.getId(this);
setTimeout(function() {
$('#edit-'+ilc_qe_id+' select[name="page_template"] option[value="showcase.php"]').remove();
}, 100);
});
$('#doaction, #doaction2').live("click", function () {
setTimeout(function() {
$('#bulk-edit select[name="page_template"] option[value="showcase.php"]').remove();
}, 100);
});
});
</script>
<?php
}
/**
* /wp-admin/post.php?post=21&action=edit
*/
if( 'page' == $current_screen->id )
{
?>
<script type="text/javascript">
jQuery(document).ready( function($) {
$('#page_template option[value="showcase.php"]').remove();
});
</script>
<?php
}
}
Niciun Hook Disponibil?
Dacă am urmărit calea corectă, acesta este locul unde se întâmplă "acțiunea" (/wp-includes/class-wp-theme.php
), și se pare că nu există niciun hook disponibil aici...
/**
* Returnează șabloanele de pagină ale temei.
*
* @since 3.4.0
* @access public
*
* @return array Array cu șabloanele de pagină, indexate după numele fișierului, cu valoarea numelui din header tradus.
*/
public function get_page_templates() {
// Dacă ai greșit ceva în tema curentă și invalidăm tema părinte, majoritatea lucrurilor încă funcționează. Lasă așa.
if ( $this->errors() && $this->errors()->get_error_codes() !== array( 'theme_parent_invalid' ) )
return array();
$page_templates = $this->cache_get( 'page_templates' );
if ( ! is_array( $page_templates ) ) {
$page_templates = array();
$files = (array) $this->get_files( 'php', 1 );
foreach ( $files as $file => $full_path ) {
$headers = get_file_data( $full_path, array( 'Template Name' => 'Template Name' ) );
if ( empty( $headers['Template Name'] ) )
continue;
$page_templates[ $file ] = $headers['Template Name'];
}
$this->cache_add( 'page_templates', $page_templates );
}
if ( $this->load_textdomain() ) {
foreach ( $page_templates as &$page_template ) {
$page_template = $this->translate_header( 'Template Name', $page_template );
}
}
if ( $this->parent() )
$page_templates += $this->parent()->get_page_templates();
return $page_templates;
}

Tichet Trac: http://core.trac.wordpress.org/ticket/21891
