动态块 - 如何在 post 保存/加载时创建动态样式表
Dynamic Block - How to create dynamic stylesheet on post save / load
我使用 Create Guten Block (https://github.com/ahmadawais/create-guten-block) 创建了一个可用的 Gutenberg Block。
目前它只适用于内联样式,但作为一项要求,我必须避免使用它们。
因此我想在保存 post 时创建一个 post/page 样式表,包括我的块的样式设置(例如背景颜色、颜色、字体大小...)
我方块的当前保存功能(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>
);
},
最好的解决方案是为整个 page/post 生成某种样式表,其中包含所有块的所有设置。
最好的方法是样式表生成发生在页面保存时,但如果它发生在页面加载时也可以。由于那些 post 不会很大,因此性能应该不是什么大问题。
所以在四处挖掘之后我自己弄明白了。
以防万一其他人遇到此问题,这里是解决方案:
首先,必须在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 知道您要保存哪些属性。现在的问题是,只要 "default" 值没有被覆盖,Wordpress 就不会将该值保存到块对象的属性中。
为了解决这个问题,我们将使用 registerBlockType
中的 save
函数。
(关于这一点的快速说明:这不会触发编辑器小部件的默认值,因此您总是必须更改 background_color 的值才能在第一次将小部件插入古腾堡编辑器时看到它。要解决此问题,请在 render()
函数的开头使用 saveDefaultValue(this.props)
。)
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,这是唯一让它为我工作的东西。
好的,现在我们可以将属性保存到Block-object中了。
现在我们要创建我们的动态样式表。
为此,我们在以下目录 /plugin-dir/src/
中创建一个新的 .php 文件,因为我们使用的是 create-guten-block。名称并不重要,但我将其命名为与我的样式表相同的方式。 `gutenberg-styles.css.php``
gutenberg-styles.css.php
稍后将在每次有人访问 post 时创建一个 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
变量,我们需要它从当前访问的 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
已加载并应用于您的块。
我使用 Create Guten Block (https://github.com/ahmadawais/create-guten-block) 创建了一个可用的 Gutenberg Block。 目前它只适用于内联样式,但作为一项要求,我必须避免使用它们。
因此我想在保存 post 时创建一个 post/page 样式表,包括我的块的样式设置(例如背景颜色、颜色、字体大小...)
我方块的当前保存功能(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>
);
},
最好的解决方案是为整个 page/post 生成某种样式表,其中包含所有块的所有设置。
最好的方法是样式表生成发生在页面保存时,但如果它发生在页面加载时也可以。由于那些 post 不会很大,因此性能应该不是什么大问题。
所以在四处挖掘之后我自己弄明白了。 以防万一其他人遇到此问题,这里是解决方案:
首先,必须在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 知道您要保存哪些属性。现在的问题是,只要 "default" 值没有被覆盖,Wordpress 就不会将该值保存到块对象的属性中。
为了解决这个问题,我们将使用 registerBlockType
中的 save
函数。
(关于这一点的快速说明:这不会触发编辑器小部件的默认值,因此您总是必须更改 background_color 的值才能在第一次将小部件插入古腾堡编辑器时看到它。要解决此问题,请在 render()
函数的开头使用 saveDefaultValue(this.props)
。)
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,这是唯一让它为我工作的东西。
好的,现在我们可以将属性保存到Block-object中了。
现在我们要创建我们的动态样式表。
为此,我们在以下目录 /plugin-dir/src/
中创建一个新的 .php 文件,因为我们使用的是 create-guten-block。名称并不重要,但我将其命名为与我的样式表相同的方式。 `gutenberg-styles.css.php``
gutenberg-styles.css.php
稍后将在每次有人访问 post 时创建一个 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
变量,我们需要它从当前访问的 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
已加载并应用于您的块。