Редактор TinyMCE ломает мой красивый HTML

9

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

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

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

Это совершенно законно в HTML5. Однако редактору WP это не нравится, и он преобразуется в:

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

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

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

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;
}
Доминик П
источник
Попробуйте этот плагин, если у вас нет Доминика ... У него иногда возникают проблемы с обновлениями, но по большей части он позволяет вам использовать html полностью так, как вы ожидаете. wordpress.org/plugins/preserved-html-editor-markup-plus
Брайан Уиллис

Ответы:

17

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

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

Хотя этот будет держать ваш р тег от получения раздели, это не исправит проблему в разметке на веб - интерфейсе все еще получает сброшенные вверх. Вы можете DISABLE wpautop. Если вы сделаете это И включите p в число допустимых потомков, это БУДЕТ ИСПРАВИТЬ ВАШУ ВОПРОС .

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

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: отключить автоматическое 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 нет пробелов . Если вы сделаете это, вы можете использовать опцию один выше и избежать необходимости отключать TinyMCE все вместе. Просто помните, что вам также нужно добавить немного CSS в таблицу стилей, чтобы правильно отобразить диапазон.

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

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 в таблице стилей

.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" />
    awesome caption
[/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">Some amazing descriptive text</figcaption>
</figure>

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

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

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

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

Вариант 5: сохраненный HTML-редактор Markup Plus

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

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


Дополнительный кредит: отладка вашей проблемы / редактирование других опций TinyMCE

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

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

Редактор TinyMCE

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

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

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

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

Брайан Уиллис
источник
Спасибо, что поймали эту опечатку в моем примере HTML (я редактировал вопрос). Просто чтобы быть ясно, реальный рассматриваемый HTML не имеет этой проблемы. Я проверю плагин, который вы упомянули.
Доминик П
Надеюсь, это поможет Доминику! И последнее, что я хотел бы упомянуть, это то, что вы можете добавлять подписи в WordPress через загрузчик медиа. Кроме того, я считаю, что семантически правильный способ сделать это так. w3schools.com/tags/tag_figcaption.asp
Брайан Уиллис
Это интересная мысль. Я не рассматривал разметку как рисунок и подпись. Я попробую.
Доминик П
Просто чтобы закрыть это. Я завелся с помощью <span>тегов. Я ненавижу, что моя разметка теперь зависит от пробелов, но сейчас это был путь наименьшего сопротивления. Я пытался, <figcaption>но это элемент блочного уровня, и TinyMCE не позволил бы <a>тегам обернуть его, поэтому я вернулся на круги своя. Еще раз спасибо за все идеи.
Доминик П
Доминик, проверьте вариант 4 выше, если вы хотите использовать <figure>. Я полностью забыл, что шорткод встроенной подписи делает это по умолчанию!
Брайан Уиллис