Вопрос или проблема
Я полагаю, что контент Гутенберга был встроен в WP 6.2, если все блоки имеют версию 3. Я использовал функцию, подобную приведенной ниже, чтобы добавить очень важные пользовательские классы к тегам <body>
в админке, что, в свою очередь, изменяет способ отображения контента. Это важно для компоновки и последовательности.
add_filter('admin_body_class', function ($classes) {
global $pagenow;
//проверка, является ли текущая страница post.php и установлены ли параметры поста
if ( $pagenow ==='post.php' || $pagenow ==='post-new.php' ) {
global $post;
/* ... */
$classes .= ' super-important-editing-class';
}
return $classes;
});
Я искал, как сумасшедший, чтобы найти фильтр, который позволит мне сделать то же самое с тегом тела iframe ('block-editor-iframe__body editor-styles-wrapper ...'
).
Кто-то знает, как это сделать?
Наконец, через год у меня есть решение. Думаю, его можно написать более разумно, но это то, что я придумал, если кому-то интересно.
В этом ответе я получаю имена классов из значений метаданных, но, как вы можете видеть ниже, их можно устанавливать напрямую или с помощью какой-либо функциональности на выбор.
functions.php
(обратите внимание на изменение от фильтра admin_body_class
к действию enqueue_block_assets
).
function site_editor_styles() {
if ( is_admin() ) {
global $pagenow;
$classes="";
if ( $pagenow ==='post.php' || $pagenow ==='post-new.php' ) {
global $post;
$post_type = get_post_type($post->ID);
$class1 = 'my-default-class-1';
$class2 = 'my-default-class-2';
/* Если вы используете ACF, вы можете использовать get_field() */
if( class_exists('ACF') ) {
/* Проверяем, находимся ли мы на шаблоне */
if ($post_type == 'wp_block') {
$class1 = 'pattern-class-1';
$class2 = 'pattern-class-2';
} else {
$class1 = get_field('my_key', $post->ID);
$class1 = get_field('my_key', $post->ID);
}
}
/* Если вы не используете ACF или другую альтернативу, вы можете использовать get_post_meta($post->ID, 'your_meta_key', true); */
/*
if ($post_type == 'wp_block') {
$class1 = 'pattern-class-1';
$class2 = 'pattern-class-2';
} else {
$class1 = get_post_meta($post->ID, 'my_key', true);
$class1 = get_post_meta($post->ID, 'my_key', true);
}
*/
// Отдельные строки для ясности
$classes .= 'post-type-' . $post_type . ' ';
$classes .= 'my-class-' . $class1 . ' ';
$classes .= 'my-class-' . $class2;
}
// Подключение или Javascript
wp_enqueue_script(
'custom-iframe-classes',
get_template_directory_uri() . '/assets/js/editor.js',
array('wp-blocks', 'wp-dom'),
filemtime( get_stylesheet_directory() . '/assets/js/editor.js' ),
true
);
// Передаем имена классов в скрипт
wp_localize_script('custom-iframe-classes', 'iframeBodyData', [
'classes' => $classes,
]);
}
}
add_action( 'enqueue_block_assets', 'site_editor_styles' );
editor.js
wp.domReady(() => {
// Пытаемся добавить классы немедленно, если iframe уже доступен
function addClassesToIframeBody() {
const editorIframe = document.querySelector('iframe')
if (editorIframe) {
const editorBody= editorIframe.contentDocument.querySelector(".editor-styles-wrapper");
if (editorBody) {
editorBody.classList.add(...iframeBodyData.classes.split(' '));
console.log('Классы добавлены в тело iframe');
return true;
}
}
return false;
}
if (!addClassesToIframeBody()) {
// Наблюдаем за `document.body`, чтобы увидеть добавление iframe
const observer = new MutationObserver(() => {
const editorIframe = document.querySelector('iframe')
if (editorIframe) {
const editorBody= editorIframe.contentDocument.querySelector(".editor-styles-wrapper");
if (editorBody) {
if (addClassesToIframeBody()) {
observer.disconnect();
console.log('Прекратили наблюдение - тело iframe найдено и изменено');
}
} else {
console.log('Тело (.editor-styles-wrapper) не найдено')
}
}
});
console.log('Запуск MutationObserver на document.body');
observer.observe(document.body, { childList: true, subtree: true });
}
});
И чтобы заставить что-то произойти с новыми классами, добавленными к <body>
, я также подключаю таблицу стилей.
functions.scss
function site_enqueue_editor_styles() {
if ( is_admin() ) {
$editor_css_path = get_stylesheet_directory() . '/assets/dist/css/gutenberg.editor.min.css';
if (file_exists($editor_css_path)) {
$css_version = filemtime($editor_css_path);
} else {
$css_version = mt_rand();
}
wp_enqueue_style( 'admin-editor',
get_stylesheet_directory_uri() . '/assets/dist/css/gutenberg.editor.min.css',
false,
$css_version
);
}
}
add_action( 'enqueue_block_assets', 'site_enqueue_editor_styles' );
gutenberg.editor.scss
.block-editor-iframe__html.is-zoomed-out {
/* Стили для уменьшенного масштаба */
background-color: #e0e0e0;
.block-editor-iframe__body.editor-styles-wrapper {
padding: 0 2rem;
.editor-visual-editor__post-title-wrapper {
margin-top: 2rem;
}
}
}
.block-editor-iframe__body.editor-styles-wrapper {
/* Это стилизует все тело */
background-color: darkkhaki;
&.post-type-post {
/* стили для постов */
}
&.post-type-page {
/* стили для страниц */
background-color: lightsalmon;
}
&.post-type-cpt {
/* стили для пользовательского типа поста, измените cpt на имя типа поста */
}
&.content-width-editorial-narrow .editor-visual-editor__post-title-wrapper {
/* это стилизует область заголовка */
background-color: skyblue;
padding: 1rem 5rem;
margin-top: 1rem !important;
}
&.content-width-editorial-narrow .wp-block-post-content {
/* это стилизует область контента */
background-color: papayawhip;
padding: 5rem;
}
}
Ответ или решение
Для добавления классов к iframe тегу
в редакторе Gutenberg, начиная с версии WordPress 6.2, необходимо воспользоваться специальным подходом, который включает использование действий и скриптов. Ниже представлена детальная инструкция с описанием всех деталей процесса.Шаг 1: Использование действия enqueue_block_assets
Для начала, добавьте следующий код в файл functions.php
вашей темы. Этот код будет обрабатывать добавление классов в iframe на страницах редактирования постов и страниц.
function site_editor_styles() {
if ( is_admin() ) {
global $pagenow;
$classes = "";
if ( $pagenow === 'post.php' || $pagenow === 'post-new.php' ) {
global $post;
$post_type = get_post_type($post->ID);
$class1 = 'my-default-class-1';
$class2 = 'my-default-class-2';
// Получение классов из метаданных
if( class_exists('ACF') ) {
if ($post_type == 'wp_block') {
$class1 = 'pattern-class-1';
$class2 = 'pattern-class-2';
} else {
$class1 = get_field('my_key', $post->ID);
$class2 = get_field('my_other_key', $post->ID);
}
}
$classes .= 'post-type-' . $post_type . ' ';
$classes .= 'my-class-' . $class1 . ' ';
$classes .= 'my-class-' . $class2;
}
// Подключение JavaScript
wp_enqueue_script(
'custom-iframe-classes',
get_template_directory_uri() . '/assets/js/editor.js',
array('wp-blocks', 'wp-dom'),
filemtime(get_stylesheet_directory() . '/assets/js/editor.js'),
true
);
// Передача данных классов в JavaScript
wp_localize_script('custom-iframe-classes', 'iframeBodyData', [
'classes' => $classes,
]);
}
}
add_action('enqueue_block_assets', 'site_editor_styles');
Шаг 2: JavaScript для добавления классов в iframe
Теперь создайте файл JavaScript (editor.js
) в папке assets/js
вашей темы и добавьте следующий код. Этот код добавляет классы ко всем нужным элементам внутри iframe.
wp.domReady(() => {
function addClassesToIframeBody() {
const editorIframe = document.querySelector('iframe');
if (editorIframe) {
const editorBody = editorIframe.contentDocument.querySelector(".editor-styles-wrapper");
if (editorBody) {
editorBody.classList.add(...iframeBodyData.classes.split(' '));
console.log('Классы добавлены к body iframe');
return true;
}
}
return false;
}
if (!addClassesToIframeBody()) {
const observer = new MutationObserver(() => {
const editorIframe = document.querySelector('iframe');
if (editorIframe) {
const editorBody = editorIframe.contentDocument.querySelector(".editor-styles-wrapper");
if (editorBody && addClassesToIframeBody()) {
observer.disconnect();
console.log('Остановка наблюдений - тело iframe найдено и изменено');
}
}
});
console.log('Запуск MutationObserver на document.body');
observer.observe(document.body, { childList: true, subtree: true });
}
});
Шаг 3: Стилизация с помощью CSS
Добавьте соответствующие стили в ваш файл CSS, например, в gutenberg.editor.scss
, чтобы применить стили к новым классам, которые вы добавили.
.block-editor-iframe__body.editor-styles-wrapper {
background-color: darkkhaki;
&.post-type-post {
// Стили для постов
}
&.post-type-page {
background-color: lightsalmon;
}
}
Заключение
С помощью этого подхода вы можете легко добавлять классы к тегу
внутри iframe редактирования Gutenberg. Это позволит вам управлять стилями и макетом редактора более эффективно, сохраняя при этом необходимую гибкость при создании пользовательских интерфейсов для админ-панели WordPress.Ключевые моменты, которые стоит выделить:
- Используйте
enqueue_block_assets
, чтобы обеспечить правильное подключение и передачу данных JavaScript. - Применяйте
MutationObserver
для отслеживания изменений, чтобы добавлять классы еще до полной загрузки iframe. - Управляйте стилями в соответствии с вашими требованиями через CSS.
Данный метод дает разработчикам возможность кастомизировать редактор Gutenberg, улучшая опыт работы с ним за счет удобного и последовательного оформления.