O editor TinyMCE está quebrando meu lindo HTML

9

Esta é praticamente uma duplicata exata de: Como fazer o Wordpress e o TinyMCE aceitarem tags <a> que envolvem elementos no nível do bloco, conforme permitido no HTML5? e HTML5, WordPress e Tiny MCE issue - empacotar a tag anchor em torno de div resulta em uma saída descolada

Meu problema é que a solução sugerida ( tiny_mce_before_initfiltro) parece não resolver o meu problema. Eu tenho HTML que se parece com isso:

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

O é perfeitamente legal no HTML5. No entanto, o editor WP não gosta e o transforma em:

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

Isso, é claro, quebra meu layout. Alguém sabe de uma maneira que eu possa impedir esse comportamento? Não consigo desistir do componente Visual do editor e manter o texto sem formatação. Todas as sugestões são bem-vindas.

Só para esclarecer, quando eu uso o código abaixo ( sugerido aqui ), as <p>tags podem permanecer dentro das âncoras, mas muito espaço extra é adicionado junto com uma &nbsp;entidade que se multiplica sempre que você alterna entre os modos Visual e 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
fonte
Experimente este plugin se você não tiver Dominic ... Ocasionalmente, há um problema aqui ou ali nas atualizações, mas na maioria das vezes permite usar o html completamente da maneira que você espera. wordpress.org/plugins/preserved-html-editor-markup-plus #
Bryan Willis

Respostas:

17

Independentemente do que você configurou como filhos válidos, o WordPress lida com tags p e com quebras de linha de uma maneira muito única. Você provavelmente notará eventualmente, se ainda não o fez, que ao alternar do editor de texto para o editor visual e vice-versa, suas <p>tags são removidas, semelhante ao que ocorre no frontend. Uma maneira de impedir que isso aconteça é dando às <p>tags uma classe personalizada.

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

Embora isto ↑ evite que sua tag p seja removida, ele não solucionará o problema, pois sua marcação no front-end ainda é reduzida. Você poderia DISABLE wpautop. Se você fizer isso E tiver incluído crianças válidas, isso CONSERTARÁ SUA EDIÇÃO .

OPÇÃO 1: Desativar Autop e definir filhos 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;
}

Eu devo avisá-lo, porém, que, no segundo em que você alternar do editor de HTML para o TinyMCE, seu HTML será destruído. Uma solução alternativa é desativar completamente o TinyMCE para determinados tipos de postagem, como na opção 2 abaixo.


OPÇÃO 2: Desativar P automático, TinyMCE e definir filhos 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 a maioria das pessoas, porém este não é uma opção.


Então, que outras opções existem? Uma solução alternativa que notei que funciona é usar uma tag span com uma classe e garantir que não haja espaço em branco entre suas tags HTML . Se você fizer isso, poderá usar a opção um acima e evitar ter que desativar o TinyMCE todos juntos. Lembre-se de que você também precisará adicionar um pouco de CSS à sua folha de estilo para exibir a extensão corretamente.

OPÇÃO 3: Opção 1 + Tags de extensão com 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 na folha de estilo

.noautop {
    display: block;
}

Opção 4: use o código de acesso do carregador de mídia incorporado

shortcode media uploader

Inicialmente esqueci este, mas o código de acesso [legenda] ficará assim:

[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]

A saída terá a seguinte aparência:

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

Se você não deseja tags de figura, pode usar um plug-in como código de acesso personalizado, que permite fazer isso:

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

Por que o editor não pode funcionar como eu quero?

Passei inúmeras horas tentando fazer com que isso funcionasse bem nos últimos dois anos. Ocasionalmente, vou encontrar uma solução que funcione perfeitamente, mas o WordPress fará uma atualização que estraga tudo de novo. A única solução que eu já encontrei para funcionar completamente como deveria, me leva à melhor resposta que tenho.

Opção 5: Preserved HTML Editor Markup Plus

Portanto, salve-se da dor de cabeça e continue com isso. Por padrão, o Preserved HTML Editor Markup Plus afeta apenas novas páginas. Se você deseja alterar as páginas já criadas, acesse www.example.com/wp-admin/options-writing.php e edite as configurações do plug-in. Você também poderá alterar o comportamento padrão da nova linha.

Nota: Se você decidir usar isso, verifique o segmento de suporte quando uma nova atualização do WordPress for iniciada. Ocasionalmente, uma alteração atrapalha as coisas, por isso é melhor garantir que o plug-in funcione nas versões mais recentes.


Crédito extra: depurando seu problema / editando outras opções do TinyMCE

Se você deseja inspecionar e editar facilmente suas configurações do TinyMCE manualmente, como faz com os filtros, pode instalar a configuração avançada do TinyMCE . Permite visualizar TODAS as opções configuradas do TinyMCE e editá-las a partir de uma interface simples. Você também pode adicionar novas opções, como faria com os filtros. Isso torna as coisas muito mais fáceis de entender.

Por exemplo, eu tenho isso e o Preserved HTML Editor Markup Plus. A captura de tela abaixo é da página de administração do Advanced TinyMCE Config. Enquanto a captura de tela está cortando 90% do que realmente existe, é possível ver que ela mostra os filhos válidos disponíveis para edição e quais foram adicionados ao Preserved HTML Editor Markup Plus .

Editor TinyMCE

Essa é uma maneira extremamente útil de não apenas personalizar completamente o seu editor, mas também de ver o que está acontecendo. Você pode até descobrir o que estava causando o problema. Depois de examinar os parâmetros enquanto a marcação Preserved HTML Editor estava ativada, vi algumas opções adicionais que poderiam ser adicionadas a um 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' );

Infelizmente esse método não funcionou. Provavelmente existe algum regex ou JavaScript que está acontecendo ao atualizar a postagem e / ou alternar entre editores. Se você der uma olhada no código-fonte do Preserved HTML Editor, poderá ver que ele funciona com JavaScript no lado do administrador. Por isso, meu último conselho é verificar como o plug-in funciona, se você deseja adicionar essa funcionalidade ao seu tema.

Enfim, desculpe-me por quem chegou tão longe na minha resposta. Apenas pensei em compartilhar minhas próprias experiências ao lidar com o editor do WordPress, para que outras pessoas não precisem gastar horas tentando descobrir isso como eu fiz!

Bryan Willis
fonte
Obrigado por capturar esse erro de digitação no meu exemplo HTML (eu editei a pergunta). Só para esclarecer, o HTML real em questão não tem esse problema. Vou fazer o checkout do plugin que você mencionou.
Dominic P
Espero que isso ajude Dominic! Uma última coisa que gostaria de mencionar é que você pode adicionar legendas no wordpress através do uploader de mídia. Além disso, acredito que semanticamente a maneira correta de fazer isso é assim. w3schools.com/tags/tag_figcaption.asp
Bryan Willis
Esse é um pensamento interessante. Eu não tinha considerado marcá-lo como uma figura e legenda. Vou tentar.
Dominic P
Apenas para fechar isso. Acabei usando <span>etiquetas. Eu odeio que minha marcação agora seja dependente do espaço em branco, mas foi o caminho de menor resistência no momento. Eu tentei, <figcaption>mas é um elemento de nível de bloco e o TinyMCE não permitiria que as <a>tags o envolvessem, então eu estava de volta à estaca zero. Mais uma vez obrigado por todas as idéias.
Dominic P
Dominic, Confira a opção 4 acima se você quiser usar o <figure>. Eu esqueci totalmente que o código de legenda embutido faz isso por padrão!
Bryan Willis