El editor de TinyMCE está rompiendo mi hermoso HTML

9

Esto es prácticamente un duplicado exacto de: ¿Cómo hacer que Wordpress y TinyMCE acepten etiquetas <a> envolviendo elementos de nivel de bloque como se permite en HTML5? y HTML5, WordPress y Tiny MCE: el ajuste de la etiqueta de anclaje alrededor de los resultados div en un resultado funky

Mi problema es que la solución sugerida ( tiny_mce_before_initfiltro) no parece resolver mi problema. Tengo HTML que se ve así:

<a href="#">
    <img src="path/to/file.jpg" />
    <p>Some amazing descriptive text</p>
</a>

El es perfectamente legal en HTML5. Sin embargo, al editor de WP no le gusta y lo transforma en:

<a href="#">
    <img src="path/to/file.jpg" />
</a>
<p>Some amazing descriptive text</p>

Esto, por supuesto, rompe mi diseño. ¿Alguien sabe de alguna manera puedo prevenir este comportamiento? No puedo renunciar al componente Visual del editor y apegarme al texto plano. Cualquier sugerencia es bienvenida.

Para que quede claro, cuando se utiliza el código de abajo ( se sugiere aquí ), las <p>etiquetas se les permite permanecer en el interior de los anclajes, pero se añade una gran cantidad de espacio adicional junto con una &nbsp;entidad que se multiplica cada vez que se cambia de modo visual y texto.

add_filter('tiny_mce_before_init', 'modify_valid_children');

function modify_valid_children($settings){
    $settings['valid_children']="+a[div|p|ul|ol|li|h1|h2|h3|h4|h5|h5|h6]";
    return $settings;
}
Dominic P
fuente
Pruebe este complemento si no tiene Dominic ... Ocasionalmente tiene un problema aquí o allá en las actualizaciones, pero en su mayor parte le permite usar html completamente como lo esperaría. wordpress.org/plugins/preserved-html-editor-markup-plus
Bryan Willis

Respuestas:

17

Independientemente de lo que haya configurado como hijos válidos, WordPress maneja las etiquetas p y los saltos de línea de una manera muy única. Probablemente notará eventualmente, si aún no lo ha hecho, que al cambiar del editor de texto al editor visual y viceversa, sus <p>etiquetas se eliminan, similar a lo que ocurre en la interfaz. Una forma de evitar que esto suceda es dando a las <p>etiquetas una clase personalizada.

<p class="text">This p tag won't get removed"</p>.

Si bien this evitará que su etiqueta p se elimine, no solucionará su problema, ya que su marcado en la interfaz aún se arruina. Podrías DESACTIVAR wpautop. Si hace eso Y tiene p incluido en niños válidos, esto FIJARÁ SU PROBLEMA .

OPCIÓN 1: Desactivar Autop y establecer hijos válidos

remove_filter( 'the_content', 'wpautop' );
add_filter('tiny_mce_before_init', 'modify_valid_children', 99);
function modify_valid_children($settings){     
    $settings['valid_children']="+a[div|p|ul|ol|li|h1|span|h2|h3|h4|h5|h5|h6]";
    return $settings;
}

Sin embargo, debo advertirte que en el momento en que cambies del editor HTML a TinyMCE, tu HTML se destruirá. Una solución alternativa es deshabilitar TinyMCE por completo para ciertos tipos de publicaciones como en la opción 2 a continuación.


OPCIÓN 2: Desactivar Auto P, TinyMCE y Establecer hijos válidos

remove_filter( 'the_content', 'wpautop' );
add_filter('tiny_mce_before_init', 'modify_valid_children', 99);
function modify_valid_children($settings){     
    $settings['valid_children']="+a[div|p|ul|ol|li|h1|span|h2|h3|h4|h5|h5|h6]";
    return $settings;
}
add_filter('user_can_richedit', 'disable_wyswyg_to_preserve_my_markup');
function disable_wyswyg_to_preserve_my_markup( $default ){
  if( get_post_type() === 'post') return false;
  return $default;
}

Para la mayoría de las personas, aunque esto no es una opción.


Entonces, ¿qué otras opciones hay? Una solución alternativa que noté que funciona es usar una etiqueta span con una clase y asegurarse de que no haya espacios en blanco entre sus etiquetas HTML . Si hace esto, puede usar la opción uno anterior y evitar tener que desactivar TinyMCE por completo. Solo recuerda que también tendrás que agregar un poco de CSS a tu hoja de estilo para mostrar el lapso correctamente.

OPCIÓN 3: Opción 1 + Etiquetas de extensión con estilo

HTML

<a href="#"><img src="https://placehold.it/300x200?text=Don%27t+P+On+Me" alt="" /><span class="noautop">Some amazing descriptive text</span></a>

CSS en la hoja de estilo

.noautop {
    display: block;
}

Opción 4: utilizar el shortcode del cargador de medios incorporado

cargador de medios shortcode

Inicialmente olvidé este, pero el shortcode [caption] se verá así:

[caption id="attachment_167" align="alignnone" width="169"]
    <img class="size-medium wp-image-167" src="http://example.com/example.png" alt="" width="169" height="300" />
    awesome caption
[/caption]

La salida se verá así:

<figure id="attachment_167" style="width: 169px" class="wp-caption alignnone">
    <img class="size-medium wp-image-167" src="http://example.com/example.png" alt="" width="169" height="300" />
    <figcaption class="wp-caption-text">Some amazing descriptive text</figcaption>
</figure>

Si no desea etiquetas de figura, puede usar un complemento como código abreviado de contenido personalizado que le permite hacer esto:

[raw] <p>this content will not get filtered by wordpress</p> [/raw]

¿Pero por qué el editor no puede trabajar como yo quiero?

He pasado innumerables horas tratando de hacer que esto funcione bien en los últimos dos años. Ocasionalmente, encontraré una solución que funcione perfectamente, pero luego WordPress empujará una actualización que volverá a estropear todo. La única solución que he encontrado para funcionar completamente como debería, me lleva a la mejor respuesta que tengo.

Opción 5: Editor HTML conservado Markup Plus

Así que ahórrate el dolor de cabeza y ve con esto. De forma predeterminada, el Editor de HTML conservado Markup Plus solo afecta a las páginas nuevas. Si desea cambiar las páginas ya creadas, debe ir a www.example.com/wp-admin/options-writing.php y editar la configuración del complemento. También podrá cambiar el comportamiento predeterminado de la nueva línea.

Nota: Si decide usar esto, asegúrese de verificar el hilo de soporte cuando se inicie una nueva actualización de WordPress. Ocasionalmente, un cambio arruinará las cosas, por lo que es mejor asegurarse de que el complemento funcione en las versiones más nuevas.


Crédito adicional: depuración de su problema / edición de otras opciones de TinyMCE

Si desea inspeccionar y editar fácilmente sus configuraciones de TinyMCE manualmente, como lo hace con los filtros, puede instalar la configuración avanzada de TinyMCE . Le permite ver TODAS las opciones configuradas de TinyMCE y editarlas desde una interfaz simple. También puede agregar nuevas opciones como lo haría con los filtros. Hace las cosas mucho más fáciles de entender.

Por ejemplo, tengo tanto eso como el editor HTML conservado Markup Plus. La siguiente captura de pantalla es de la página de administración de configuración avanzada de TinyMCE. Si bien la captura de pantalla está cortando el 90% de lo que realmente está allí, puede ver que muestra los elementos secundarios válidos disponibles para editar y cuáles agregó el Editor HTML conservado Markup Plus .

Editor de TinyMCE

Esta es una forma extremadamente útil de no solo personalizar completamente su editor, sino también de ver lo que está sucediendo. Es posible que incluso puedas descubrir qué estaba causando tu problema en ese momento. Después de revisar los parámetros yo mismo mientras estaba habilitado el Marcado del editor HTML preservado, vi algunas opciones adicionales que se podrían agregar a un filtro personalizado.

function fix_tiny_mce_before_init( $in ) {

    // You can actually debug this without actually needing Advanced Tinymce Config enabled:
    // print_r( $in );
    // exit();

  $in['valid_children']="+a[div|p|ul|ol|li|h1|span|h2|h3|h4|h5|h5|h6]";
    $in[ 'force_p_newlines' ] = FALSE;
    $in[ 'remove_linebreaks' ] = FALSE;
    $in[ 'force_br_newlines' ] = FALSE;
    $in[ 'remove_trailing_nbsp' ] = FALSE;
    $in[ 'apply_source_formatting' ] = FALSE;
    $in[ 'convert_newlines_to_brs' ] = FALSE;
    $in[ 'verify_html' ] = FALSE;
    $in[ 'remove_redundant_brs' ] = FALSE;
    $in[ 'validate_children' ] = FALSE;
    $in[ 'forced_root_block' ]= FALSE;

    return $in;
}
add_filter( 'tiny_mce_before_init', 'fix_tiny_mce_before_init' );

Lamentablemente este método no funcionó. Probablemente haya alguna expresión regular o JavaScript que esté sucediendo al actualizar la publicación y / o cambiar entre editores. Si echa un vistazo al código fuente del Editor HTML preservado, puede ver que funciona un poco de JavaScript en el lado del administrador, por lo que mi último consejo sería verificar cómo funciona el complemento si desea agregar esta funcionalidad en su tema.

De todos modos, lo siento por cualquiera que haya llegado tan lejos en mi respuesta. Solo pensé en compartir mis propias experiencias al tratar con el editor de WordPress, ¡así que otros espero que no tengan que pasar horas tratando de resolver esto como lo hice yo!

Bryan Willis
fuente
Gracias por detectar ese error tipográfico en mi HTML de ejemplo (edité la pregunta). Para ser claros, el HTML real en cuestión no tiene ese problema. Comprobaré el complemento que mencionaste.
Dominic P
Espero que esto ayude a Dominic! Una última cosa que me gustaría mencionar es que puede agregar subtítulos en WordPress a través del cargador de medios. Además, creo que semánticamente la forma correcta de hacerlo es así. w3schools.com/tags/tag_figcaption.asp
Bryan Willis
Ese es un pensamiento interesante. No había considerado marcarlo como figura y leyenda. Lo intentaré.
Dominic P
Solo para cerrar esto. Terminé usando <span>etiquetas. Odio que mi marcado ahora dependa del espacio en blanco, pero por ahora era el camino de menor resistencia. Lo intenté <figcaption>pero es un elemento de nivel de bloque, y TinyMCE no permitió que las <a>etiquetas lo envolvieran, así que volví al punto de partida. Gracias de nuevo por todas las ideas.
Dominic P
Dominic, mira la opción 4 anterior si quieres usar el <figure>. ¡Olvidé por completo que el código abreviado del subtítulo lo hace por defecto!
Bryan Willis