Edytor TinyMCE łamie mój piękny HTML

9

Jest to właściwie dokładna kopia: Jak sprawić, by Wordpress i TinyMCE akceptowały tagi <a> zawijające elementy na poziomie bloku, jak dozwolone w HTML5? oraz HTML5, WordPress i Tiny MCE - owinięcie tagu kotwicy wokół div daje efektowne wyjście

Mój problem polega na tym, że sugerowane rozwiązanie ( tiny_mce_before_initfiltr) nie wydaje się rozwiązać mojego problemu. Mam HTML, który wygląda następująco:

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

Jest to całkowicie legalne w HTML5. Jednak edytor WP nie lubi tego i przekształca go w:

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

To oczywiście psuje mój układ. Czy ktoś wie, jak mogę temu zapobiec? Nie mogę zrezygnować z komponentu Visual edytora i trzymać się zwykłego tekstu. Wszelkie sugestie są mile widziane.

Żeby było jasne, kiedy używam poniższego kodu ( sugerowanego tutaj ), <p>tagi mogą pozostać wewnątrz kotwic, ale dodaje się dużo dodatkowej przestrzeni wraz z &nbsp;bytem, ​​który mnoży się za każdym razem, gdy przełączasz się między trybem wizualnym a tekstowym.

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.
źródło
Wypróbuj tę wtyczkę, jeśli nie masz Dominika ... Czasami pojawia się problem z aktualizacjami, ale w większości pozwala całkowicie wykorzystać HTML tak, jak tego oczekujesz. wordpress.org/plugins/preserved-html-editor-markup-plus
Bryan Willis

Odpowiedzi:

17

Bez względu na to, co skonfigurowałeś jako prawidłowe dzieci, WordPress obsługuje tagi p, a także podział linii w bardzo unikalny sposób. Prawdopodobnie w końcu zauważysz, jeśli jeszcze tego nie zrobiłeś, że podczas przełączania z edytora tekstu do edytora wizualnego i odwrotnie, <p>tagi są usuwane, podobnie jak w interfejsie użytkownika. Aby temu zapobiec, należy nadać <p>tagom niestandardową klasę.

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

Chociaż ten uchroni twój tag p przed usunięciem, nie rozwiąże twojego problemu, ponieważ twoje znaczniki na interfejsie wciąż są zepsute. Możesz WYŁĄCZYĆ wpautop. Jeśli to zrobisz ORAZ włączysz p do ważnych dzieci, USUNIĘTO TWOJE PROBLEM .

OPCJA 1: Wyłącz automatyczne uruchamianie i ustaw prawidłowe dzieci

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

Powinienem cię jednak ostrzec, że po drugim przejściu z edytora HTML z powrotem do TinyMCE twój HTML zostanie zniszczony. Obejściem tego problemu jest całkowite wyłączenie TinyMCE dla niektórych typów postów, jak w opcji 2 poniżej.


OPCJA 2: Wyłącz Auto P, TinyMCE i Ustaw prawidłowe dzieci

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

Jednak dla większości osób ten nie jest opcją.


Jakie są inne opcje? Jednym z obejść, które zauważyłem, jest użycie znacznika zakresu z klasą i upewnienie się, że między znacznikami HTML nie ma białych znaków . Jeśli to zrobisz, możesz użyć opcji 1 powyżej i uniknąć konieczności całkowitego wyłączania TinyMCE. Pamiętaj tylko, że będziesz musiał dodać trochę CSS do arkusza stylów, aby poprawnie wyświetlić zakres.

OPCJA 3: Opcja 1 + stylizowane tagi rozpiętości

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 w arkuszu stylów

.noautop {
    display: block;
}

Opcja 4: użyj wbudowanego kodu do przesyłania multimediów

program do przesyłania multimediów shortcode

Początkowo zapomniałem tego, ale skrót [podpis] będzie wyglądał następująco:

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

Dane wyjściowe będą wyglądać następująco:

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

Jeśli nie chcesz tagów rysunkowych, możesz użyć wtyczki, takiej jak niestandardowy kod skrótu treści, który pozwala to zrobić:

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

Dlaczego jednak edytor nie może działać tak, jak chcę?

W ciągu ostatnich kilku lat spędziłem niezliczone godziny, starając się, aby to zadziałało. Czasami wpadam na rozwiązanie, które działa idealnie, ale wtedy WordPress wypchnie aktualizację, która wszystko popsunie. Jedyne rozwiązanie, jakie kiedykolwiek znalazłem, by działało tak, jak powinno, prowadzi do najlepszej odpowiedzi, jaką mam.

Opcja 5: Zachowany edytor HTML Markup Plus

Więc oszczędzaj sobie bólu głowy i po prostu idź z tym. Domyślnie Preserved HTML Editor Markup Plus wpływa tylko na nowe strony. Jeśli chcesz zmienić już utworzone strony, musisz przejść do www.example.com/wp-admin/options-writing.php i edytować ustawienia wtyczki. Będziesz także mógł zmienić domyślne zachowanie nowej linii.

Uwaga: jeśli zdecydujesz się użyć tego, upewnij się, że sprawdziłeś wątek wsparcia, gdy zostanie uruchomiona nowa aktualizacja WordPress. Czasami zmiana może zepsuć wszystko, więc najlepiej upewnić się, że wtyczka działa w nowszych wersjach.


Dodatkowy kredyt: debugowanie problemu / edycja innych opcji TinyMCE

Jeśli chcesz ręcznie sprawdzić i łatwo edytować konfiguracje TinyMCE, podobnie jak w przypadku filtrów, możesz zainstalować zaawansowaną konfigurację TinyMCE . Pozwala wyświetlić WSZYSTKIE skonfigurowane opcje TinyMCE i edytować je za pomocą prostego interfejsu. Możesz także dodać nowe opcje, tak jak w przypadku filtrów. Ułatwia to zrozumienie.

Na przykład mam zarówno to, jak i Zachowany edytor HTML Markup Plus. Poniższy zrzut ekranu przedstawia stronę administratora Advanced TinyMCE Config. Podczas gdy zrzut ekranu obcina 90% tego, co naprawdę tam jest, możesz zobaczyć, że pokazuje poprawne elementy potomne dostępne do edycji oraz te, które dodano Zachowany edytor HTML Markup Plus .

Edytor TinyMCE

Jest to niezwykle pomocny sposób nie tylko całkowitego dostosowania edytora, ale także zobaczenia, co się dzieje. Być może będziesz nawet w stanie dowiedzieć się, co było przyczyną Twojego problemu. Po samodzielnym przejrzeniu parametrów, gdy włączony był Zachowany znacznik edytora HTML, zobaczyłem dodatkowe opcje, które można dodać do niestandardowego filtra.

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' );

Niestety ta metoda nie zadziałała. Prawdopodobnie występuje aktualizacja wyrażeń regularnych lub JavaScript, które występują podczas aktualizacji posta i / lub przełączania się między edytorami. Jeśli spojrzysz na kod źródłowy Zachowanego edytora HTML, zobaczysz, że JavaScript działa po stronie administratora, więc moją ostatnią radą byłoby sprawdzenie, jak działa wtyczka, jeśli chcesz dodać tę funkcjonalność do swojego motywu.

W każdym razie przepraszam za każdego, kto zaszedł tak daleko w mojej odpowiedzi. Pomyślałem, że podzielę się własnymi doświadczeniami związanymi z edytorem WordPress, więc inni, miejmy nadzieję, nie będą musieli spędzać godzin próbując rozgryźć to tak, jak ja!

Bryan Willis
źródło
Dzięki za złapanie tej literówki w moim przykładowym kodzie HTML (zredagowałem pytanie). Żeby było jasne, prawdziwy HTML nie ma tego problemu. Sprawdzę wtyczkę, o której wspomniałeś.
Dominic P
Mam nadzieję, że to pomoże Dominicowi! Ostatnią rzeczą, o której chciałbym wspomnieć, jest to, że możesz dodawać podpisy w wordpressie za pośrednictwem programu do przesyłania multimediów. Ponadto uważam, że semantycznie poprawny sposób na zrobienie tego jest taki. w3schools.com/tags/tag_figcaption.asp
Bryan Willis
To interesująca myśl. Nie zastanawiałem się nad oznaczeniem go jako postaci i podpisu. Spróbuję.
Dominic P
Żeby to zamknąć. Skończyłem za pomocą <span>tagów. Nienawidzę tego, że moje znaczniki zależą teraz od białych pól, ale na razie była to ścieżka najmniejszego oporu. Próbowałem, <figcaption>ale jest to element na poziomie bloku, a TinyMCE nie pozwolił <a>tagom go owinąć, więc wróciłem do punktu wyjścia. Jeszcze raz dziękuję za wszystkie pomysły.
Dominic P
Dominic, sprawdź opcję 4 powyżej, jeśli chcesz użyć <figure>. Zupełnie zapomniałem, że wbudowany skrót napisów robi to domyślnie!
Bryan Willis,