Редактор TinyMCE портит мой HTML-код

15 янв. 2016 г., 03:24:22
Просмотры: 15.2K
Голосов: 9

Это практически точная копия вопросов: Как заставить WordPress и TinyMCE принимать теги <a> вокруг блочных элементов, разрешенных в HTML5? и Проблема с HTML5, WordPress и Tiny MCE - оборачивание div в тег ссылки дает странный результат

Моя проблема в том, что предлагаемое решение (фильтр tiny_mce_before_init) не решает мою задачу. У меня есть HTML-код, который выглядит так:

<a href="#">
    <img src="path/to/file.jpg" />
    <p>Какой-то замечательный описательный текст</p>
</a>

Это полностью валидно в HTML5. Однако редактор WP не принимает это и преобразует в:

<a href="#">
    <img src="path/to/file.jpg" />
</a>
<p>Какой-то замечательный описательный текст</p>

Это, конечно, ломает мою верстку. Кто-нибудь знает способ предотвратить такое поведение? Я не могу отказаться от визуального редактора и перейти на чистый текст. Любые предложения приветствуются.

Для ясности: когда я использую код ниже (предложенный здесь), теги <p> остаются внутри ссылок, но добавляется много лишнего пробела вместе с сущностью &nbsp;, которая множится при каждом переключении между визуальным и текстовым режимами.

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;
}
1
Комментарии

Попробуй этот плагин, если еще не пробовал, Dominic... Иногда могут быть небольшие проблемы при обновлениях, но в целом он позволяет использовать HTML так, как ты ожидаешь. https://wordpress.org/plugins/preserved-html-editor-markup-plus/

Bryan Willis Bryan Willis
15 янв. 2016 г. 04:25:30
Все ответы на вопрос 2
7
17

Независимо от того, что вы настроили как допустимые дочерние элементы, WordPress обрабатывает теги <p> и переносы строк очень своеобразно. Вы, вероятно, со временем заметите (если еще не заметили), что при переключении с текстового редактора на визуальный и обратно ваши теги <p> удаляются, подобно тому, что происходит на фронтенде. Способ предотвратить это — добавить тегу <p> пользовательский класс.

<p class="text">Этот тег p не будет удален</p>.

Хотя этот метод предотвратит удаление вашего тега <p>, он не решит проблему, так как разметка на фронтенде все равно будет испорчена. Вы можете ОТКЛЮЧИТЬ функцию wpautop. Если вы сделаете это И включите p в допустимые дочерние элементы, это РЕШИТ ВАШУ ПРОБЛЕМУ.

ВАРИАНТ 1: Отключить Autop и задать допустимые дочерние элементы

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

Однако предупреждаю: как только вы переключитесь с HTML-редактора обратно в TinyMCE, ваш HTML будет разрушен. Обходной путь — полностью отключить TinyMCE для определенных типов записей, как в варианте 2 ниже.


ВАРИАНТ 2: Отключить Auto P, TinyMCE и задать допустимые дочерние элементы

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

Однако для большинства людей этот вариант не подходит.


Какие еще есть варианты? Один из обходных путей, который я обнаружил, — использовать тег span с классом и убедиться, что между HTML-тегами нет пробелов. Если сделать так, можно использовать вариант 1 выше и избежать необходимости полностью отключать TinyMCE. Только не забудьте добавить CSS в таблицу стилей, чтобы span отображался корректно.

ВАРИАНТ 3: Вариант 1 + Стилизованные теги Span

HTML

<a href="#"><img src="https://placehold.it/300x200?text=Don%27t+P+On+Me" alt="Не добавляйте теги P" /><span class="noautop">Какой-то замечательный описательный текст</span></a>

CSS в таблице стилей

.noautop {
    display: block;
}

Вариант 4: Использовать встроенный шорткод медиазагрузчика

шорткод медиазагрузчика

Изначально я забыл об этом, но шорткод [caption] будет выглядеть так:

[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" />
    замечательная подпись
[/caption]

Результат будет выглядеть так:

<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">Какой-то замечательный описательный текст</figcaption>
</figure>

Если вам не нужны теги figure, можно использовать плагин, например custom content shortcode, который позволяет делать так:

[raw] <p>этот контент не будет отфильтрован WordPress</p> [/raw]

Почему редактор просто не может работать так, как я хочу?

Я потратил бесчисленные часы, пытаясь заставить это работать правильно за последние пару лет. Иногда мне удавалось найти идеальное решение, но затем WordPress выпускал обновление, которое снова все ломало. Единственное решение, которое полностью работало как надо, привело меня к лучшему ответу.

Вариант 5: Preserved HTML Editor Markup Plus

Так что избавьтесь от головной боли и просто используйте этот плагин. По умолчанию Preserved HTML Editor Markup Plus влияет только на новые страницы. Если нужно изменить уже созданные страницы, перейдите по адресу www.example.com/wp-admin/options-writing.php и отредактируйте настройки плагина. Там же можно изменить поведение переносов строк по умолчанию.

Примечание: Если решите использовать этот плагин, обязательно проверяйте ветку поддержки после выхода новых обновлений WordPress. Иногда изменения могут сломать функциональность, поэтому лучше убедиться, что плагин работает в новых версиях.


Дополнительно: Отладка проблемы / Редактирование других настроек TinyMCE

Если хотите проверить и легко отредактировать настройки TinyMCE вручную, как с фильтрами, установите плагин advanced TinyMCE config. Он позволяет просматривать ВСЕ настройки TinyMCE и редактировать их через простой интерфейс. Также можно добавлять новые параметры, как с фильтрами. Это значительно упрощает понимание.

Например, у меня установлены и этот плагин, и Preserved HTML Editor Markup Plus. На скриншоте ниже показана страница настроек Advanced TinyMCE Config. Хотя скриншот обрезает 90% реального содержимого, видно, какие допустимые дочерние элементы доступны для редактирования и какие добавил Preserved HTML Editor Markup Plus.

Редактор TinyMCE

Это крайне полезный способ не только полностью настроить редактор, но и понять, что происходит. Возможно, вы даже сможете определить причину проблемы. Изучив параметры при включенном Preserved HTML Editor Markup, я заметил дополнительные опции, которые можно добавить в пользовательский фильтр.

function fix_tiny_mce_before_init( $in ) {

    // Можно отладить это без необходимости включать Advanced Tinymce Config:
    // 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' );

К сожалению, этот метод не сработал. Вероятно, есть какое-то регулярное выражение или JavaScript, которое выполняется при обновлении записи или переключении между редакторами. Если посмотреть исходный код Preserved HTML Editor, видно, что он выполняет JavaScript-работу на стороне админки, поэтому последний совет — изучить, как работает плагин, если хотите добавить эту функциональность в свою тему.

В любом случае, извините, если вы дочитали до этого места. Просто хотел поделиться своим опытом работы с редактором WordPress, чтобы другие, возможно, не тратили столько времени на решение этой проблемы, как я!

15 янв. 2016 г. 04:34:58
Комментарии

Спасибо, что заметили опечатку в моем примере HTML (я исправил вопрос). Чтобы было понятно, в реальном HTML этой проблемы нет. Я проверю плагин, который вы упомянули.

Dominic P Dominic P
15 янв. 2016 г. 08:05:47

Надеюсь, это поможет, Доминик! Еще хочу упомянуть, что вы можете добавлять подписи в WordPress через загрузчик медиафайлов. Также я считаю, что семантически правильный способ сделать это выглядит так. http://www.w3schools.com/tags/tag_figcaption.asp

Bryan Willis Bryan Willis
15 янв. 2016 г. 21:45:51

Интересная мысль. Я не рассматривал вариант разметки как figure и caption. Попробую сделать так.

Dominic P Dominic P
16 янв. 2016 г. 21:23:38

Просто чтобы закрыть этот вопрос. В итоге я использовал теги <span>. Мне не нравится, что моя разметка теперь зависит от пробелов, но пока это был путь наименьшего сопротивления. Я пробовал <figcaption>, но это блочный элемент, и TinyMCE не позволял обернуть его в теги <a>, так что я вернулся к исходной точке. Еще раз спасибо за все идеи.

Dominic P Dominic P
17 янв. 2016 г. 00:28:39

Доминик, посмотри вариант 4 выше, если хочешь использовать <figure>. Я совсем забыл, что встроенный шорткод для подписи делает это по умолчанию!

Bryan Willis Bryan Willis
19 янв. 2016 г. 05:43:57

Брайан, это хорошая идея, но мне все еще нужно, чтобы весь <figure> был кликабельным, так что я снова возвращаюсь к оборачиванию его в тег <a> (или использованию нескольких тегов <a>, чего я бы предпочел избежать).

Dominic P Dominic P
19 янв. 2016 г. 20:30:56

Да, хорошая мысль. Кстати, если ты еще не пробовал Custom Content Shortcode, я бы рекомендовал его попробовать. Это, без сомнения, самый полезный плагин, особенно при работе с подобными задачами.

Bryan Willis Bryan Willis
19 янв. 2016 г. 20:46:45
Показать остальные 2 комментариев
0

Прежде всего: Большое спасибо за отличный ответ Брайана, который также документирует трудности, с которыми он столкнулся.

В результате собственных экспериментов (включая некоторые предложения Брайана), я считаю, что следующий плагин может значительно помочь в обеспечении согласованности при переключении между HTML- и визуальным редактором: Advanced Editor Tools (ранее TinyMCE Advanced) - https://wordpress.org/plugins/tinymce-advanced/.

На первый взгляд, плагин не делал то, что я ожидал. Но затем я нашел параметр настроек "preserve paragraph tags". Визуальный редактор больше не удаляет теги <p> и <br> из HTML-редактора. Более того: после переключения между редакторами я обнаружил, что почти все пустые строки исчезли, а вместо них появилось множество тегов <p> и </p>. Недостаток в том, что визуальное отображение в редакторе имеет небольшие странности, но это считается незначительной проблемой. Для меня важно следующее: вы точно знаете, где находится курсор, благодаря почти полному соответствию WYSIWYG. В конце концов: даже без этой конкретной настройки визуальный редактор имеет недостатки в отображении по сравнению с предпросмотром/финальным результатом.

Теперь я чувствую, что у меня есть полный контроль над пробелами в тексте. Даже когда я нажимаю Enter в визуальном редакторе (или Shift+Enter), генерируются дополнительные теги. Опять же недостаток: это видно только в HTML-режиме (и в финальном виде) - визуальный редактор не показывает дополнительное пространство. Но что с того? Главное, что он больше не ломает мой красивый HTML!

29 нояб. 2021 г. 01:24:26