У wordpress в записях работает фильтр wpautop, а также интерпритатор тэгов. Если вставить стили и скрипты напрямую и пару раз переключить визуальный и тестовый режимы, то мы увидим, что скрипты и стили пострадают. При выводе во фронтенд ситуация еще хуже.
Создадим специальную дополнительную область в админке для включения подобных файлов. Область применения самая разная: от калькуляторов до примеров работы того или иного скрипта. Можно прописывать стили, которые относятся только к этой записи.
Создаем текстовую область
Создаем дополнительное поле в виде текстовой области
// Добавляем новый метабокс function myplugin_add_custom_box() { add_meta_box( 'wp_editor_test_1_box', 'Поле для кода', 'wp_editor_meta_box' ); } // Вывод метабокса в админке function wp_editor_meta_box( $post ) { wp_nonce_field( plugin_basename( __FILE__ ), 'myplugin_noncename' ); $field_value = get_post_meta( $post->ID, 'connecter', false ); wp_editor( $field_value[0], 'connecter', array( 'textarea_rows'=>6, 'wpautop'=>0, 'tinymce'=>0, 'quicktags'=>0, 'media_buttons'=>0, ) ); } // Сохранение значения поля function myplugin_save_postdata( $post_id ) { if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return; if ( ( isset ( $_POST['myplugin_noncename'] ) ) && ( ! wp_verify_nonce( $_POST['myplugin_noncename'], plugin_basename( __FILE__ ) ) ) ) return; if ( ( isset ( $_POST['post_type'] ) ) && ( 'page' == $_POST['post_type'] ) ) { if ( ! current_user_can( 'edit_page', $post_id ) ) { return; } } else { if ( ! current_user_can( 'edit_post', $post_id ) ) { return; } } if ( isset ( $_POST['connecter'] ) ) { update_post_meta( $post_id, 'connecter', $_POST['connecter'] ); } }
Вот в этом месте, мы отключаем от тестовой области все лишнее для данного функционала (визуальный редактор, загрузчик медиа, кнопки тегов):
wp_editor( $field_value[0], 'connecter', array( 'textarea_rows'=>6, 'wpautop'=>0, 'tinymce'=>0, 'quicktags'=>0, 'media_buttons'=>0, )
Также здесь задается первоначальный размер текстовой области ‘textarea_rows’=>6 (по умолчанию 10).
Данное дополнительное поле добавиться ко всем типам записей в том числе и страницам. Если нам необходимо локализовать поле для конкретного типа записей, изменим первый блок:
function myplugin_add_custom_box() { $screens = array( 'post', 'page' ); //через запятую прописываем необходимые типы add_meta_box( 'wp_editor_test_1_box', 'Поле для кода', 'wp_editor_meta_box', $screens ); }
После добавления поля в админке (перед полем) мы увидим ошибку — Undefined offset: 0. Это не страшно. Она исчезает, когда поле заполнено.
Выводим данные поля
Очень важно чтобы данные из этого специфического поля выводились как можно «ниже». Во-первых из-за того чтобы не тормозить загрузку страницы, во-вторых чтобы к моменту вывода скриптов уже была подгружена библиотека jquery. Чтобы выводить это поле там где нужно, пропишем в подвале перед закрывающим тегом /body следующий хук:
<?php do_action( 'body-before' ); ?>
Теперь мы можем к нему привязать функцию вывода
//Вывод содержимого поля function sitedirectlyfield() { global $post; echo get_post_meta($post->ID, 'connecter', true); } add_action( 'body-before', 'sitedirectlyfield' );
global $post; — в данном случае обязателен, т.к. без него не будет связи с глобальной переменной.
Скрипты и стили в категориях
Сделаем тот же функционал только для категорий. Создаем функцию по созданию метаполей для таксономий (подробнее про эту функцию), если она где-то подключена в другом плагине, то второй раз подключать не нужно.
class trueTaxonomyMetaBox { private $opt; private $prefix; function __construct( $option ) { $this->opt = (object) $option; $this->prefix = $this->opt->id .'_'; // префикс настроек foreach( $this->opt->taxonomy as $taxonomy ){ add_action( $taxonomy . '_edit_form_fields', array( &$this, 'fill'), 10, 2 ); // хук добавления полей } // установим таблицу в $wpdb, если её нет global $wpdb; if( ! isset( $wpdb->termmeta ) ) $wpdb->termmeta = $wpdb->prefix .'termmeta'; add_action('edit_term', array( &$this, 'save'), 10, 1 ); // хук сохранения значений полей } function fill( $term, $taxonomy ){ foreach( $this->opt->args as $param ){ $def = array('id'=>'', 'title'=>'', 'type'=>'', 'desc'=>'', 'std'=>'', 'args'=>array() ); $param = (object) array_merge( $def, $param ); $meta_key = $this->prefix . $param->id; $meta_value = get_metadata('term', $term->term_id, $meta_key, true ) ?: $param->std; echo '<tr class ="form-field">'; echo '<th scope="row"><label for="'. $meta_key .'">'. $param->title .'</label></th>'; echo '<td>'; // textarea if( $param->type == 'textarea' ){ echo '<textarea name="'. $meta_key .'" type="'. $param->type .'" id="'. $meta_key .'" value="'. htmlspecialchars( $meta_value ) .'" class="large-text">'. htmlspecialchars( $meta_value ) .'</textarea>'; if( $param->desc ) echo '<p class="description">' . $param->desc . '</p>'; } //$meta_value = htmlspecialchars_decode($meta_value); echo ''; echo ''; } } function save( $term_id ){ foreach( $this->opt->args as $field ){ $meta_key = $this->prefix . $field['id']; if( ! isset($_POST[ $meta_key ]) ) continue; if( $meta_value = trim($_POST[ $meta_key ]) ){ update_metadata('term', $term_id, $meta_key, $meta_value, ''); } else { delete_metadata('term', $term_id, $meta_key, '', false ); } } } }
Создаем поле
// Создаем метабокс add_action('init', 'register_additional_term_fields'); function register_additional_term_fields(){ new trueTaxonomyMetaBox( array( 'id' => 'impadeg', // id играет роль префикса названий полей 'taxonomy' => array('category'), // названия таксономий, для которых нужно добавить ниже перечисленные поля 'args' => array( array( 'id' => 'impadeg', // атрибуты name и id без префикса, получится "impadeg_impadeg" 'title' => 'Scripts & Styles', 'type' => 'textarea', 'desc' => 'Подключение скриптов и стилей', 'std' => '', // по умолчанию ) ) ) ); }
Выводим поле на сайте. Я использую специально созданный перед /body хук body-before.
// Выводим поле function siteconnecter() { $category_id = get_query_var( 'cat' ); echo htmlspecialchars_decode(get_metadata('term', $category_id, 'impadeg_impadeg', true )); } add_action( 'body-before', 'siteconnecter' );
В данном решении, при сохранении поля, я применил обработчик содержимого htmlspecialchars, чтобы он экранировал поступающую в него информацию (преобразовывал теги html в символы) и не нарушал форму поля в админке. А перед выводом поля, я наоборот декодирую его в html сущности с помощью функции htmlspecialchars_decode
Оба (для записи / для категории) этих решения конфликтуют с плагином сжатия кода Autoptimize. Также в данные поля нельзя вставить шорткоды, но думаю эту проблему можно решить..
Выводим поле в произвольной таксономии
Для произвольной таксономии необходимо немного поменять определение id термина. Ну и для примера, вывод поля я прицепил к хуку woocommerce, после вывода товаров.
function siteconnecter() { $q_obj = get_queried_object(); echo htmlspecialchars_decode(get_metadata('term', $q_obj->term_id, 'impadeg_impadeg', true )); } add_action( 'woocommerce_after_shop_loop', 'siteconnecter', 90 );
get_queried_object() — определяет текущий объект таксономии