Forzar a WordPress a Mostrar Páginas en Lugar de Categorías
Estoy tratando de crear una estructura SILO en uno de mis sitios WordPress.
Siempre he marcado esta opción en el plugin Yoast SEO "Eliminar la base de categoría (usualmente /category/) de la URL de categoría."
Así que mis páginas de categoría tienen esta URL: sitename.com/apple/ (donde "apple" es la página de categoría)
Ahora quiero crear una nueva "página" con el mismo slug, apple.
Puedo crear una nueva página "apple" fácilmente, sin embargo, cuando voy a sitename.com/apple/ se muestra la página de categoría -- en lugar de la página recién creada.
Mi pregunta: ¿Hay alguna manera de "anular" la prioridad predeterminada de categoría sobre una página? Me gustaría mostrar la página porque tendré control sobre ella -- puedo personalizarla, agregar más contenido y cambiarla fácilmente (además, las páginas me ayudarán a estructurar mejor mi sitio)
¡Agradezco su ayuda!

Una posible solución es no cambiar la base de categoría y dejarla como está, pero en su lugar modificar cualquier salida de un enlace de categoría para eliminar la base de categoría mediante un filtro. Por supuesto, esto resultará en un error 404 si no has creado una página en lugar de donde apuntan estos enlaces, por lo que se requiere crear una página para cada categoría.
function wpa_alter_cat_links( $termlink, $term, $taxonomy ){
if( 'category' != $taxonomy ) return $termlink;
return str_replace( '/category', '', $termlink );
}
add_filter( 'term_link', 'wpa_alter_cat_links', 10, 3 );
Probablemente querrás probar esto exhaustivamente para detectar posibles efectos secundarios, ¡úsalo bajo tu propio riesgo!
EDITADO - modificando solo enlaces de categorías de nivel superior:
function wpa_alter_cat_links( $termlink, $term, $taxonomy ){
if( 'category' == $taxonomy && 0 == $term->parent ){
return str_replace( '/category', '', $termlink );
}
return $termlink;
}
add_filter( 'term_link', 'wpa_alter_cat_links', 10, 3 );

¡Milo, esto es exactamente lo que quería! No puedo creer que fuera tan fácil y posible. ¡Muchas gracias!
Sin embargo, hay un problema. Las páginas de subcategorías están apuntando a error 404. ¿Hay alguna forma de solucionar esto?
Detalles adicionales: Para mis sitios, se requieren migas de pan. Así que este es el formato: Inicio -> Cat 1 -> Sub cat 2 -> publicación. La cat 1 ahora es una PÁGINA, pero sub-cat 2 apunta a una página 404.

tendrías que crear páginas hijas bajo las páginas principales para las subcategorías.

Eres un genio, eso es lo que eres. Muchas gracias. Esto sí que lleva mucho tiempo y esfuerzo. Creo que lo haré de todos modos. Aún así, me gustaría saber si puedo hacer que solo la categoría padre apunte a una PÁGINA mientras que la subcategoría muestre la página de categoría predeterminada.

en la función anterior, verifica si $term->parent
es igual a 0
. Las categorías hijas tendrán un ID de categoría como $term->parent
, en las categorías de nivel superior simplemente será cero.

Entiendo que debo usar if ($term->parent == 0) pero no estoy seguro de dónde colocar este código. He pasado un tiempo buscando en Google pero no encuentro la manera de hacer que funcione. Realmente agradecería si puedes revisar el código. :)

Creé la siguiente función bastante simple para darle mayor importancia a las páginas que a las categorías al cargar el contenido.
(Nota: puede que no sea la mejor, pero es una forma sencilla. Encontré un problema al usar el plugin Advanced Custom Fields, que por defecto no inserta los campos personalizados ni de la página antigua ni de la nueva. Añadir get_queried_object()->ID
como segundo parámetro de get_field()
de ACF resolvió esto. Pruébalo cuidadosamente en tu entorno de WP).
function loadPageFirst() {
// obtener la categoría actual
$actualCategory = get_category( get_query_var('cat') );
// obtener la página con el mismo slug
$matchingPage = get_page_by_path( $actualCategory->slug );
// Si no hay coincidencia, cargar la plantilla de listado normal y salir (editar si usas una plantilla de listado personalizada, ej. category.php)
if (!$matchingPage) {
include( get_template_directory() . '/archive.php');
die();
}
// Hacer una nueva consulta con el ID de la página y cargar la plantilla de página
query_posts( 'page_id=' . $matchingPage->ID );
include( get_template_directory() . '/page.php');
die();
}
add_filter( 'category_template', 'loadPageFirst' );
Puedes incluirla en el functions.php de tu tema. Esto parece funcionar bien con el plugin Yoast SEO.

Creo que no necesitas incluir archive.php y die() — dependiendo de tu tema, esto no funcionará. Puedes simplemente retornar en su lugar. (¡Pero muchísimas gracias por el código!)

Aquí hay una respuesta súper simple y que funciona perfectamente: https://stackoverflow.com/questions/32310453/make-wordpress-use-the-page-instead-of-category
Por el bien de la completitud:
Contexto
- example.com es el dominio
- Tengo una página en WP llamada "foobar" con contenido
- Tengo una categoría de entradas en WP llamada "foobar"
- Tengo una entrada en WP titulada "cosas divertidas que hacer con foobars", y la categoría está asignada a "foobar"
Expectativas
- Cuando voy a example.com/foobar, quiero ver la página sobre foobars, no una página de categoría de WP que muestre todas las entradas de blog con esa categoría.
- Cuando voy a la entrada de blog sobre cosas divertidas, la URL es example.com/foobar/cosas-divertidas-que-hacer-con-foobars/
Configuración
Esta es mi configuración (no requiere plugins adicionales ni edición de código) Un par de plugins instalados son WP Rocket y Yoast en los que me enfocaré en este hilo.
Panel de WP->Ajustes->Enlaces permanentes
Selecciona "Estructura personalizada" e ingresa /%category%/%postname%/ en el campo
En la misma página, cambia "Base de categorías" a un solo punto "." (sin comillas, solo un punto/punto final)
Tengo Yoast instalado, que tenía configurado para sobrescribir los ajustes de enlaces permanentes, pero creo que esto estropeó mi tarea actual.
Panel de WP->SEO->Avanzado->Enlaces permanentes(pestaña)
"Cambiar URLs->Eliminar la base de categoría..." = Mantener
Luego necesitas limpiar la caché. Uso WP Rocket para caché, así que vacié la caché y ahora todo funciona como debería.
Edición: asegúrate de guardar los cambios después de los pasos 3 y 5

Depende. Si estás intentando configurar 2 páginas diferentes con la misma URL, no es una buena idea. Pero si no te importan las páginas de categoría, puedes redirigirlas a tus páginas.
RedirectMatch 301 ^/category/(.*)$ /$1
Este código va en el archivo .htaccess
y redirige /category/página a /página/

¡Gracias! Sin embargo, como mencioné antes, no tengo la base de categoría adjunta a la URL. Y no puedo usar el redireccionamiento 301 tradicional ya que ambas URLs son iguales.

La forma "WordPress" de hacer esto sería crear una plantilla PHP personalizada para tu página de categoría y aplicar tus personalizaciones allí, en lugar de crear una "Página" única.
También hay numerosos plugins disponibles que te permiten añadir imágenes y otros campos personalizados a la página de archivo de categoría, lo que puede ser una mejor opción si prefieres no modificar los archivos del tema.
Alternativamente, sugeriría añadir una base de categoría que sea quizás una de tus palabras clave objetivo principales.

El problema es, creo, que WordPress trata las "páginas" de manera diferente. Tienen mejor posicionamiento que las páginas de categoría tradicionales. Muchos SEOs están haciendo lo que he preguntado arriba: eliminar completamente la categoría y reemplazarla con páginas.

Probablemente deberías explicar cómo añadir esta plantilla de página (pista: jerarquía de plantillas), etc.

@Sid - si el contenido es idéntico, ¿por qué una página de archivo de categoría se posicionaría diferente que una página?

@Milo - El contenido no será idéntico, solo la URL será igual. Las páginas tendrán contenido mucho más estructurado y enlaces apuntando a material relacionado.

@Sid mi punto era que podrías obtener los mismos resultados mediante una plantilla de categoría, extrayendo contenido adicional desde otro lugar. Una forma rápida de lograrlo es con el plugin Advanced Custom Fields, que te permite añadir contenido adicional a las páginas de administración de términos de taxonomía - editores wysiwyg, campos de relación, etc.

Lo siento pero no tengo suficiente reputación para comentar en la respuesta de @bencergazda.
Encontré que esta es la mejor solución. Pero tuve un error con la imagen que se muestra en el encabezado del tema, porque no obtenía el ID correcto de la publicación.
Para solucionarlo, agregué la siguiente línea de código: "global $post; $post->ID = $matchingPage->ID;"
El resultado
function loadPageFirst() {
// obtener la categoría actual
$actualCategory = get_category( get_query_var('cat') );
// obtener la página con el mismo slug
$matchingPage = get_page_by_path( $actualCategory->slug );
// Si no hay coincidencia, cargar la plantilla de listado normal y salir (editar si estás usando una plantilla de listado personalizada, ej. category.php)
if (!$matchingPage) {
include( get_template_directory() . '/archive.php');
die();
}
// Hacer una nueva consulta con el ID de la página y cargar la plantilla de página
global $post; $post->ID = $matchingPage->ID;
query_posts( 'page_id=' . $matchingPage->ID );
include( get_template_directory() . '/page.php');
die();
}
add_filter( 'category_template', 'loadPageFirst' );
Saludos cordiales

Lo siento, pero tampoco tengo suficiente reputación para comentar en la respuesta de @bencergazda.
Hice algunas modificaciones en su función. Eliminé la parte que cargaba la página de categoría (no era necesaria) y añadí la jerarquía de páginas:
function loadPageFirst( $file ) {
// obtener la categoría actual
$actualCategory = get_category( get_query_var('cat') );
// obtener la página con el mismo slug
$matchingPage = get_page_by_path( $actualCategory->slug );
if ( ! $matchingPage ) {
return $file;
}
// Hacer una nueva consulta con el ID de la página y cargar la plantilla de página
query_posts( 'page_id=' . $matchingPage->ID );
$page_template = get_page_template_slug( $matchingPage->ID ) ? get_page_template_slug( $matchingPage->ID ) : null;
$pages = array(
$page_template,
'page-' . $actualCategory->slug . '.php',
'page-' . $matchingPage->ID . '.php',
'page.php',
'singular.php',
'index.php',
);
foreach ( $pages as $page ) {
$file = get_theme_file_path( $page );
if ( $page === null || ! file_exists( $file ) ) {
continue;
}
return $file;
}
}
add_filter( 'category_template', 'loadPageFirst' );

Esto es increíble. Exactamente un post de hace 10 años y todavía funciona perfectamente. Me pregunto si la misma solución es posible para las etiquetas. Me gustaría reemplazar las páginas de archivo de etiquetas con páginas reales sobre las que tenga más control.
¿Alguien puede ayudarme a lograr esto? ¡Gracias de antemano!

Por favor no agregues "gracias" como respuesta. Una vez que tengas suficiente reputación, podrás votar a favor de preguntas y respuestas que hayas encontrado útiles. - De la revisión
