Динамический блок - Как создать динамическую таблицу стилей после сохранения / загрузки

Я создал рабочий блок Гутенберга с помощью создания блока Гутена ( https://github.com/ahmadawais/create-guten-block). В настоящее время он работает только со встроенными стилями, но в качестве требования я должен избегать их.

Поэтому я хочу создать таблицу стилей пост / страница при сохранении поста, включая настройки стиля для моих блоков (например, цвет фона, цвет, размер шрифта...)

Текущая функция сохранения моего блока (block.js)

save: function( props ) {
        const { attributes: { typetext, infotext, linktext, background_color, background_button_color, text_color, text_color_button }} = props;
        return (
            <div id="cgb-infoblock" className="cgb-infoblock">
                <div className="cgb-infoblock-body" style={{
                    backgroundColor: background_color,
                    color: text_color,
                }}>
                    <div className="cgb-infoblock-type">
                        <p>
                            <span className="cgb-infoblock-icon"><i>i</i></span>
                            { typetext && !! typetext.length && (
                                <RichText.Content
                                    tagName="span"
                                    className={ classnames(
                                        'cgb-infoblock-type-text'
                                    ) }
                                    style={ {
                                        color: text_color
                                    } }
                                    value={ typetext }
                                />
                            )}
                        </p>
                    </div>
                    <div className="cgb-infoblock-text">
                        { infotext && !! infotext.length && (
                            <RichText.Content
                                tagName="p"
                                style={ {
                                    color: text_color
                                } }
                                value={ infotext }
                            />
                        )}
                    </div>
                </div>
                <div className="cgb-infoblock-button" style={{
                    backgroundColor: background_button_color,
                    color: text_color_button,
                }}>
                    { linktext && !! linktext.length && (
                        <RichText.Content
                            tagName="p"
                            style={ {
                                color: text_color_button
                            } }
                            value={ linktext }
                        />
                    )}
                </div>
            </div>
        );
    },

Лучшим решением будет генерация таблицы стилей для всей страницы / поста со всеми настройками из всех блоков.

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

1 ответ

Решение

Поэтому, покопавшись, я сам все понял. На случай, если кто-то еще получил эту проблему, вот решение:

Прежде всего, атрибуты должны быть определены в registerBlockTypeфункция

registerBlockType( 'cgb/your-block-type', {
title: __( 'Your Block Name' ),
icon: 'shield',
category: 'maybe-a-category',
keywords: [
    __( 'some keywords' ),
],

attributes: {
    background_color: {
        type: 'string',
        default: 'default' //we will use the "default"-value later
    },
},

Так что теперь Wordpress знает, какие атрибуты вы хотите сохранить. Проблема теперь, пока значение "по умолчанию" не перезаписывается, Wordpress не будет сохранять значение в атрибутах объекта блока. Чтобы решить эту проблему, мы будем использовать save функция от registerBlockType, (Краткое примечание: это не вызовет значение по умолчанию для виджета редактора, поэтому вам всегда нужно изменить значение background_color, чтобы увидеть его при первой вставке виджета в редактор Гутенберга. Чтобы это исправить, используйте saveDefaultValue(this.props) в самом начале вашего render() функция).

    save: function( props ) {

    saveDefaultValues(props);

    const { attributes: {background_color}} = props;
    return (
        //... here's your html that's beeing saved
    );
},

function saveDefaultValues(props) {
    if(props.attributes.background_color === 'default'){
        props.attributes.background_color = '#f1f6fb';
    }
}

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

Хорошо, теперь мы можем сохранить наши атрибуты в блок-объект. Теперь мы хотим создать нашу динамическую таблицу стилей. Для этого мы создаем новый файл.php в следующем каталоге /plugin-dir/src/так как мы используем create-guten-block. Имя не имеет значения, но я назвал его так же, как моя таблица стилей. `Gutenberg-styles.css.php``

gutenberg-styles.css.php позже создам gutenberg-styles.cssфайл, каждый раз, когда кто-то посещает пост. Но сначала мы смотрим в plugin.phpфайл. Добавьте следующий код:

function create_dynamic_gutenberg_stylesheet() {
    global $post;
    require_once plugin_dir_path( __FILE__ ) . 'src/gutenberg-styles.css.php';

    wp_enqueue_style('cgb/gutenberg-styles', plugins_url( 'src/gutenberg-styles.css',  __FILE__ ));
}
add_action('wp_head', 'create_dynamic_gutenberg_stylesheet', 5, 0);

Этот код обращается к global $post переменная, она нужна нам, чтобы получить все блоки Гутенберга из текущего посещенного поста. После этого нам нужны наши собственные gutenberg-styles.css.php которая автоматически создаст нашу таблицу стилей, которая будет помещена в следующую строку. Теперь подключите его к wp_head(возможно, вы также можете подключить его к сохранению WordPress, но вам придется проделать большую работу для постановки таблицы стилей в очередь)

Наконец, загляните в наш gutenberg-styles.css.php:

$styleSheetPath = plugin_dir_path( __FILE__ ) . 'gutenberg-styles.css';
$styleSheet = '';
$blocks = parse_blocks($post->post_content);

//loop over all blocks and create styles
foreach($blocks as $block) {
    $blockType = $block['blockName'];
    $blockAttributes = $block['attrs']; //these are the attributes we've forced to saved in our block's save function

    //switch case so you can target different blocks
    switch ($blockType) {
    case 'cgb/your-block-type':
        $styleSheet .= '.your-block-class {'.PHP_EOL
        $styleSheet .= 'background-color: '.$blockAttributes['background_color'].';'.PHP_EOL
        $styleSheet .= '}'.PHP_EOL
        break;
    }
}

file_put_contents($styleSheetPath, $styleSheet); //write css styles to stylesheet (creates file if it not exists)

я добавил PHP_EOL на каждой строке, чтобы генерировать разрывы строк, вам не нужно это делать. Но теперь вы можете посетить страницу со своим пользовательским блоком и увидеть gutenberg-styles.css загружается и применяется к вашим блокам.

Другие вопросы по тегам