【问题标题】:Dynamic Block - How to create dynamic stylesheet on post save / load动态块 - 如何在保存/加载后创建动态样式表
【发布时间】:2019-11-02 08:38:57
【问题描述】:

我已经使用 Create Guten Block (https://github.com/ahmadawais/create-guten-block) 创建了一个有效的 Gutenberg 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>
        );
    },

最好的解决方案是为整个页面/帖子生成某种样式表,其中包含来自所有块的所有设置。

如果样式表生成发生在页面保存时,最好的方法是,但如果它发生在页面加载时也可以。由于这些帖子不会很大,因此性能应该不是那么大的问题。

【问题讨论】:

  • 你真的需要创建一个样式表,比如“创建一个filename.css”文件吗?或者如果组件具有某种样式就足够了,这取决于块的属性?
  • @niklas 是的,我想要一个 filename.css ;如果每次有人访问页面时都生成它,那将是可以的。 (我知道,对性能不好)
  • “避免内联样式”的要求从何而来。它可能仍然比加载新样式表更高效。

标签: javascript css wordpress reactjs create-guten-block


【解决方案1】:

所以在四处挖掘之后,我自己弄清楚了。 以防万一其他人遇到此问题,这是解决方案:

首先,属性必须在registerBlockTypefunction中定义

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 就不会将该值保存到块对象的属性中。 为了解决这个问题,我们将使用来自registerBlockTypesave 函数。 (对此快速说明:这不会触发编辑器小部件的默认值,因此您必须在第一次将小部件插入古腾堡编辑器时更改背景颜色的值才能看到它。要解决此问题,请使用 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 保存我们的默认值。很确定有一个更好的解决方案,但是因为我刚开始使用 react / Gutenberg,所以这是唯一让它为我工作的东西。

好的,现在我们可以将属性保存到块对象中。 现在我们要创建我们的动态样式表。 为此,我们正在以下目录/plugin-dir/src/中创建一个新的 .php 文件,因为我们使用的是 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-blocks。 之后,我们需要我们自己的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 已加载并应用于您的块。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-26
    • 1970-01-01
    • 2022-08-10
    • 2023-03-08
    • 2022-11-16
    • 2015-04-07
    • 2011-05-26
    相关资源
    最近更新 更多