Desarrollando un tema infantil, ¿cómo deshabilitar las plantillas de los padres?

2

Estoy desarrollando un tema infantil simple basado en veinte y nueve. Pero observo que twentyeleven tiene una plantilla de escaparate y barra lateral cuando agrega una nueva página. ¿Cómo puedo deshabilitar estas plantillas de functions.php? Quiero mostrar solo las plantillas del tema hijo

saludos

    
pregunta alex 19.04.2013 - 11:02

3 respuestas

3

Como lo mencionó @toscho es complicado. Pero es factible.

Básicamente, necesita encontrar enlaces de acción llamados antes y después de que se genere el menú desplegable de la plantilla y llamar a ob_start() para iniciar el almacenamiento en búfer de salida y ob_get_clean() para capturar el HTML almacenado en búfer. Los ganchos 'submitpage_box' y 'edit_page_form' funcionarán para esto, respectivamente.

Después de capturar el HTML almacenado en búfer, debe obtener la lista de plantillas de páginas secundarias que, desafortunadamente, requiere que duplique una gran cantidad de código de WordPress porque Core no hace que el código sea reutilizable para obtener la lista de plantillas de páginas para solo la plantilla secundaria. Puede encontrar el código necesario en el método get_child_page_templates() en el código siguiente, que es casi completamente una composición del código necesario del núcleo de WordPress.

Una vez que tenga tanto el HTML almacenado en el búfer, necesita obtener la lista de plantillas de páginas secundarias necesarias para eliminar <options> s de <select> que no son plantillas de página del tema secundario, pero asegúrese de incluir la opción 'default' . Puede hacerlo a través de un par complejo de expresiones regulares, las funciones preg_match() y preg_match_all() y un bucle foreach() donde agrega solo el HTML para las plantillas del tema secundario a su lista y luego las combina de nuevo en el HTML que llegó antes y después de la lista de <option> s

Empaquete todo eso en un I call llamado Omit_Parent_Theme_Page_Templates que puede colocar en el archivo functions.php de su tema o incluirlo en un complemento que está creando y viola, ya no están las plantillas de la página principal.

Aquí está el código fuente para mi clase Omit_Parent_Theme_Page_Templates que necesita:

<?php
class Omit_Parent_Theme_Page_Templates {
  function __construct() {
    add_action( 'submitpage_box', array( $this, '_submitpage_box' ) );
    add_action( 'edit_page_form', array( $this, '_edit_page_form' ) );
  }
  function _submitpage_box() {
    ob_start();
  }
  function _edit_page_form() {
    $html = ob_get_clean();
    $select_regex = '<select\s*name="page_template"\s*id="page_template".*?>';
    preg_match( "#^(.*{$select_regex})(.*?)(</select>.*)$#sm", $html, $outer_match );
    preg_match_all( "#(<option\s*value='([^']+)'.*?>(.*?)</option>)#sm", $outer_match[2], $inner_matches, PREG_SET_ORDER );
    $child_page_templates = $this->_get_child_page_templates();    
    foreach( $inner_matches as $index => $matches )
      if ( isset( $child_page_templates[$matches[2]] ) )
        $child_page_templates[$matches[2]] = $inner_matches[$index][0];

    $html = $outer_match[1] . implode( "\n", $child_page_templates ). $outer_match[3];
    echo $html;
  }
  private function _get_child_page_templates() {
    $child_page_templates = array( 'default' => true );
    $files = wp_get_theme()->get_files( 'php', 1 );
    foreach ( $files as $file => $full_path ) {
      if ( ! preg_match( '|[^]]Template Name:(.*)$|mi', file_get_contents( $full_path ), $header ) )
        continue;
      $child_page_templates[ $file ] = true;
    }
    return $child_page_templates;
  }

}
new Omit_Parent_Theme_Page_Templates();

Debido a que WordPress no proporciona enlaces para lo que desea, este código es mucho más complejo de lo que nos gustaría. Utiliza una técnica, la modificación de HTML capturado en el búfer de salida, que generalmente es "un hack". Pero dada la naturaleza de lo que estamos cambiando, no creo que sea muy probable que se rompa a menos que WordPress reorganice los atributos id o name de <select> o cambie fundamentalmente cómo funcionan las plantillas de página, ninguna de las cuales es muy probable.

Por supuesto, si algún otro complemento decide modificar las plantillas de página también utilizando la misma técnica, pero de una manera incompatible, ese complemento podría romper este código o viceversa.

Pero dudo que algo de eso sea demasiado probable y si lo está utilizando para su propio sitio, no me preocuparía en absoluto, sin embargo, estaría un poco más preocupado por la publicación del código en un complemento ampliamente distribuido, pero solo un poco. :)

ACTUALIZACIÓN:

Ah, qué diablos. Decidió convertir esto en un complemento y publicarlo en el repositorio de complementos de WordPress, haga clic en aquí para acceder a él. Supongo que no estaba lo suficientemente preocupado como para no publicarlo. :)

    
respondido por el MikeSchinkel 24.04.2013 - 02:16
3

Desde 3.9 puedes hacerlo fácilmente, usando el filtro theme_page_templates .

Solo necesitas usar algo como esto:

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

Lectura adicional:

respondido por el andrezrv 17.06.2014 - 22:45
0

Para generar el menú desplegable, WordPress llama a page_template_dropdown() , que llama a get_page_templates() , que (desde al menos WP 3.4) llama a wp_get_theme()->get_page_templates() (es decir, WP:Theme::get_page_templates() para el tema activo).

El último método recorre los archivos de tema real .php para encontrar cualquier archivo con un encabezado Template Name: y almacena en caché el resultado. Hasta el momento, no se han proporcionado acciones ni filtros.

Como alternativa a la respuesta de Mike, podríamos modificar el caché. Menos piratería que la expresión regular, pero aún así piratea. Lo enganchamos en la acción admin_head-post.php , por lo que solo se ejecuta cuando se muestra el editor de publicación.

En el ejemplo a continuación, la plantilla page-home.php se elimina de la lista.

add_action("admin_head-post.php", "my_admin_head_post");

function my_admin_head_post() {
    // Run template fetching once so the template list is cached.
    $templates = wp_get_theme()->get_page_templates();

    // Generate cache hash, just like WP_Theme::__construct() does.
    $cache_hash = md5(WP_CONTENT_DIR."/themes/".get_stylesheet());
    $cache_key  = "page_templates-".$cache_hash;

    // Remove unwanted templates from the list and save changes.
    unset($templates['page-home.php']);
    wp_cache_replace($cache_key, $templates, "themes", 1800);
}

Para su problema específico, donde desea eliminar las plantillas del tema principal de la lista, afortunadamente, existe un método público WP_Theme::parent() que recupera el elemento primario del tema como otro objeto WP_Theme . El siguiente código (no probado) debería hacer el truco:

function my_admin_head_post() {
    $theme  = wp_get_theme();
    $parent = $theme->parent();

    if(!is_a($parent, "WP_Theme"))
        return;

    $templates        = $theme->get_page_templates();
    $parent_templates = $parent->get_page_templates();

    $cache_hash = md5(WP_CONTENT_DIR."/themes/".get_stylesheet());
    $cache_key  = "page_templates-".$cache_hash;

    foreach($templates as $id => $template) {
        if(isset($parent_templates[$id]))
            unset($templates[$id]);
    }

    wp_cache_replace($cache_key, $templates, "themes", 1800);
}

Nota: dado que una plantilla eliminada ya no se puede elegir desde el menú desplegable, la actualización / publicación de una página existente que usó anteriormente la plantilla restablecerá la plantilla de la página.

    
respondido por el Robbert 08.03.2014 - 16:45

Lea otras preguntas en las etiquetas