From 325f33721b172668817c4fd2eb72da268178affc Mon Sep 17 00:00:00 2001 From: Kellen Mace Date: Thu, 13 Feb 2025 14:14:54 -0500 Subject: [PATCH 1/6] Add React Components to Blocks how-to --- next.config.mjs | 5 + ...orpicker-controls-for-color-attributes.png | Bin 0 -> 42813 bytes .../images/react-component-in-edit-mode.png | Bin 0 -> 20997 bytes .../react-component-in-preview-mode.png | Bin 0 -> 2062 bytes .../react-components-to-blocks/index.mdx | 211 ++++++++++++++++++ 5 files changed, 216 insertions(+) create mode 100644 src/pages/docs/how-to/react-components-to-blocks/images/colorpicker-controls-for-color-attributes.png create mode 100644 src/pages/docs/how-to/react-components-to-blocks/images/react-component-in-edit-mode.png create mode 100644 src/pages/docs/how-to/react-components-to-blocks/images/react-component-in-preview-mode.png create mode 100644 src/pages/docs/how-to/react-components-to-blocks/index.mdx diff --git a/next.config.mjs b/next.config.mjs index 995a7805..c820c46d 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -35,6 +35,11 @@ const nextConfig = { destination: "/docs/how-to/rendering-blocks/", permanent: true, }, + { + source: "/tutorial/react-components-to-gutenberg-blocks", + destination: "/docs/how-to/react-components-to-blocks/", + permanent: true, + }, { source: "/guide/how-to-use-sitemaps", destination: "/docs/how-to/sitemaps/", diff --git a/src/pages/docs/how-to/react-components-to-blocks/images/colorpicker-controls-for-color-attributes.png b/src/pages/docs/how-to/react-components-to-blocks/images/colorpicker-controls-for-color-attributes.png new file mode 100644 index 0000000000000000000000000000000000000000..ec6729b60467570c2c9fea35e6ba07041ae9e6e1 GIT binary patch literal 42813 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

6AOBeQ|+s( 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

Jd8Eq#YF7vLDI#fFc^qIQAvaXiJI0@}2yB}x{c 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 Q1cl1b-PO~Dy*niFci?ebu>b%7 literal 0 HcmV?d00001 diff --git a/src/pages/docs/how-to/react-components-to-blocks/images/react-component-in-preview-mode.png b/src/pages/docs/how-to/react-components-to-blocks/images/react-component-in-preview-mode.png new file mode 100644 index 0000000000000000000000000000000000000000..721a3ddc851cd1927b6fb449daad60cd598256a9 GIT binary patch literal 2062 zcmb_ddpH~B8vk;S5Hgo`>5SN#gQu8=l)6L^leEf;>OrkR2ve%=3#&9mQFX~W?WSl) zMqSFbgO(tAS(RSqQgVV+wM1QFXiMC3((UYddb+>PbI$k2_q@-0`MtmQ{l4dYb3XHQ z$6|J1003A9o#qVyTqOc2`pun%HP-5Y+3fiF%iRXv!f_EE=LLV8NKN7iS zn}2k&fgNJ;lQeXsIeO%^q`5tH8$-(coARXn-z&@7xqA<7ntJ?v>3C)MS{>b+l(wgG zcllc4 zZ~wkx?ujOM=RF{f!^F)gv0VPQ<>gmHx{?k!Aw_|1v`^}}oO9vBz%p!7#;(Tcwz&Ve ziV-eDm}No-8><+wlYyj;EnQ;^WdnQ2j-b2kkP}Ig;AFU*oAn|GVX{%HxH^Km-t%QC z%B157iR7Jbr6sB<7X%t4<#*B%B2H^uMC06QFdp2iW`XnZI<$k|FZRy#gT_Sj9htW( zlaIOQDo{`rnIzL0=d=v@fw>bB^e%DDhff4Xo z8lt_m#NY>X2T)=h`BJJteQezn83{;H^!1dP!FABIUKnRX@`tAtkl8D43$Rq#RK8K$ zS?F=kQib-FeJyBkM`CzHT7(AnRXz*#I>V?O7T9^K5c2-4$4o&k5I-5X?~It~!gHd7 zw7EWA(`=h@PJPr}Jiplk@#tpXJ}(cV@0D@?1j~}3?1+YX?rhtX6JCod+lQdTMH1TA zsd|ktol#3j;Z8ho{I0SHO_ig+I^kdM$5wllQVbt=KW1y_(uY&Npz>>7mD%%F62Bxq z65|o(8y>$k?ux+q9q9X@IoYobRtaqkcDc0eenI!|Xxtj(0v!s11~BZ%arWr@=U5g< z?ji3sJzhOe;z0jNDA*xWh?$h3HCGg7ZJIwZJ5IDf`v+~bL@ykRkhuU)_)Qru`BSTK z)x&O~uRna$6x+{~h5)lfVGr+m!=TKq$N8%`nbsPMS5+*ZS4XrEj%PcOonsIGW>ljxGDV7x}gIofDeyMdMM)U(D=643b{&`i|t|*&y zjp;{b`=N!y`%c~6b$F~?a1Cl^YkBuY7Dlx6?ed}?z;Gg_rfSGu(7}t}7=WY$6;rS~ z>m!MLNMRlW38rN4<-&QKx*NFtP*Ku3A8TB8zgR5`(P3mD#hm&uXE9tWZ9Yp8KwtZuyQTASY4S2;c1(UjbCR~w;K7Yv zlR8oQl&NQP-SUUWh?Lv)5px|OSxm`R6f;Dq>_sBPgTJ=!;H~?tkU_^8$I#F*8!ek8 zJ!e&mk)S5Wh)8A?Z(uWrZhyAh6j)u&_7Tnwv8(A77Y8$Ydp1nsHv<}=r>_3+j{|p_ z!kbQ;*KKvSx52A-VSwdmYFXR5WVFSgrA#K*yO33Rp|FhMtN)Q)zGVIE;f*K5%jpXz z#8FVyq$a!>+iwZ_s~}+rHgfq(IROchkZ)Pu@%_)RcZ_c%-cIeMq#wE0B93(!1t8Sv zq2cF!MQ0HMPmv&^?PLnstMwKZ{F<`#+ZQp(Xpm9s3<#`0(uyz;+qKTu6@W^E#nz=+ z1Ofu>PeNRvPf-%)PrOP~oX#77f<84-NpoJ&Dl_nxT@daxd_2)7U^!OUY5Gh6s0q+m zd5q+AjiSE|Uj+xe5N#YzwXjs{3W5VTZbfI5R1IWwWfJ~f)OaxN^87DPA3Mye*#OaM zx%!#I3D4se6RtzR1nkG7PKTFT;;b#eEc~x!|H<#|4*b>Yzta5QAsJ_k%;Z;QTBCsK NFx)(8*Ibyqe*vi55u*SA literal 0 HcmV?d00001 diff --git a/src/pages/docs/how-to/react-components-to-blocks/index.mdx b/src/pages/docs/how-to/react-components-to-blocks/index.mdx new file mode 100644 index 00000000..605b5c04 --- /dev/null +++ b/src/pages/docs/how-to/react-components-to-blocks/index.mdx @@ -0,0 +1,211 @@ +export const metadata = { + title: "React Components to Blocks", + description: + "Create blocks in your Next.js app that also work in the WordPress Block Editor.", +}; + +The `@faustwp/block-editor-utils` package provides helper functions for converting React components into blocks. This means you can use the same components in both places—your Next.js app and the WordPress Block Editor. + +In this how-to guide, we will walk through the steps required to create a new block named `my-first-block` using this workflow. + +## Prerequisites + +Make sure you have followed the [Basic Setup](/docs/how-to/basic-setup/) steps to get Faust.js set up. + +## 1. Install the Dev Dependencies + +First, from your root folder, install the required dev dependencies: + +```bash +npm install @wordpress/scripts @faustwp/block-editor-utils --save-dev +``` + +Now we're ready to explore the process of using this package's helpers to convert a React component to blocks. + +## 2. Create and Register a Block Component + +For the purposes of this guide we are using the a simple React component. Add a folder called `my-first-block` to the `wp-blocks` folder, then add the following into a jsx file called `MyFirstBlock.jsx`: + +```js title="MyFirstBlock.jsx" +function MyFirstBlock({ style, className, attributes, children, ...props }) { + const styles = { + ...style, + }; + const cssClassName = "create-block-my-first-block"; + return ( +

+ ); +} + +export default MyFirstBlock; +``` + +This React component consists of a `div` element with three attributes that controls the content and the style of the box. Let's describe them briefly: + +- **message**: is a text message that gets displayed. +- **bg_color**: controls the background color. +- **text_color**: controls the text color. + +We would like to use this React component in WordPress using the Block Editor. Traditionally, this step would require us (the developers) to register a block within WordPress, provide a `block.json` and write code for the [Edit and Save](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-edit-save/) functions for the editor. Once those steps are done, then the block would be usable in the Block Editor list. + +That is a lot of know-how and development effort for simply trying to use the React component in the editor side. What if we just provided the React component and let the framework handle all the block registration and creating the editor form fields for changing the content? + +This is what `@faustwp/block-editor-utils` package tries to do. It provides a `registerFaustBlock` helper function, that handles all the necessary configuration, registration and generation of Editor Form fields and [Inspector controls](https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/block-controls-toolbar-and-sidebar/) for you. A developer can provide the React component and are able to review this within the WordPress Block Editor and use it in both places. + +```js title="index.js" +import "./style.scss"; + +// Import block.json +import metadata from "./block.json"; + +// Import our React component +import MyFirstBlock from "./MyFirstBlock"; + +import { registerFaustBlock } from "@faustwp/block-editor-utils"; + +// Register the React component as a Block Editor block +registerFaustBlock(MyFirstBlock, { blockJson: metadata }); +``` + +The `registerFaustBlock` helper takes the following arguments: + +- **component**: the actual React component to convert into a Block Editor block. (**Required**). +- **metadata**: a metadata object that contains several fields: + - **blockJson**: the `block.json` object that describes the component attributes. (**Required**). + - **edit**: provides a custom Edit function that describes the structure of your block in the context of the editor. (**Optional**). + - **save**: provides a custom Save function that defines the way in which the different attributes should be combined into the final markup. (**Optional**). + +Now let's take a look at the `block.json`. Since we declared three configurable attributes for our component, we need to declare them as attributes here. + +Here is the final `block.json` with the assigned attributes object: + +```json +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 2, + "name": "create-block/my-first-block", + "version": "0.1.0", + "title": "My First Block", + "category": "widgets", + "icon": "smiley", + "description": "Example block scaffolded with Create Block tool.", + "supports": { + "html": false + }, + "attributes": { + "message": { + "type": "string", + "default": "My First Block" + }, + "bg_color": { "type": "string", "default": "#000000" }, + "text_color": { "type": "string", "default": "#ffffff" } + }, + "textdomain": "my-first-block", + "editorScript": "file:./index.js", + "editorStyle": "file:./index.css", + "style": "file:./style-index.css" +} +``` + +### 3. Sync the block with WordPress + +Add the following `blockset` script to your `package.json` file, then run it on the command line: + +```json title="package.json" +"scripts": { + ... + "blockset": "faust blockset" +}, +``` + +```sh +npm run blockset +``` + +The cli tool will compile the blocks within the `wp-blocks` folder and upload them to your WordPress site in a special location that Faust uses to detect and register the blocks. + +## 4. Try out the Component in the Block Editor + +Open the WordPress Block Editor and try out the new block. This is what it will look like at first glance in Edit mode: + +![React Component in Edit Mode](./images/react-component-in-edit-mode.png) + +You can interact with the form fields, and then click outside the block contents where you will see the component rendered in Preview mode. + +![React Component in Preview Mode.](./images/react-component-in-preview-mode.png) + +## 5. Configure the Form Controls + +So far we've been able to render the React component in the Block Editor, change some of the attributes, and reflect the changes in the page. + +However, a few of the attributes that control the color are using [text field](https://developer.wordpress.org/block-editor/reference-guides/components/text-control/) controls, which may prove problematic since they allow invalid values. What if we wanted to use a proper color picker component? + +Since the `block.json` [attribute types](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-attributes/#type-validation) do not allow `color` as a value, we will have to provide a different configuration to allow that option. + +When registering the React component using `registerFaustBlock` , it allows extra configuration to be used in case you want to declare which kinds of controls to use on each attribute. + +Add the following config object as a property to the `MyFirstBlock` function: + +```js title="MyFirstBlock.jsx" +... +MyFirstBlock.config = { + name: "MyFirstBlock", + editorFields: { + bg_color: { + location: "inspector", + control: "color", + }, + text_color: { + location: "inspector", + control: "color", + }, + }, +}; +``` + +Here we included an object with the following properties: + +- **name**: the name of the block. +- **editorFields**: the list of Editor metadata configuration. This consists of two attributes that we want to specify: the type of control to use and the location within the editor. For example, by using `location: "inspector",` we are telling this control to appear in the [Block Sidebar](https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/block-controls-toolbar-and-sidebar/) section. By using `control: "color"`, we are indicating that we want to use a [ColorPicker](https://developer.wordpress.org/block-editor/reference-guides/components/color-picker/) component instead of the regular `TextControl`. + +Once you update the component, you can refresh the page and create a new block. Now instead of having two text fields inside the block, we have two `ColorPicker` fields in the sidebar section: + +![Using ColorPicker controls for the color attributes.](./images/colorpicker-controls-for-color-attributes.png) + +## 6. Form Control Reference List + +So far we've seen examples of two controls: The `ColorPicker` handled by the `control: "color"` and the `TextControl`, which is set as default for every `type: "string"` in the `block.json` attributes list. You can experiment with adding more, however. + +The corresponding table represents the mapping logic between the `block.json` attributes and their associated fields: + +| type | field | comment | +| ------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------- | +| string | TextControl | Renders a [TextControl field](https://developer.wordpress.org/block-editor/reference-guides/components/text-control/) of type `text` | +| boolean | RadioControl | Renders a [RadioControl field](https://developer.wordpress.org/block-editor/reference-guides/components/radio-control/) | +| integer | TextControl | Renders a [TextControl field](https://developer.wordpress.org/block-editor/reference-guides/components/text-control/) of type `number` | +| number | TextControl | Renders a [TextControl field](https://developer.wordpress.org/block-editor/reference-guides/components/text-control/) of type `number` | +| object | TextAreaControl | Renders a [TextAreaControl field](https://developer.wordpress.org/block-editor/reference-guides/components/textarea-control/) | + +The following control types will also be available when using the `editorFields` metadata when specifying a `control` property: + +| control | field | comment | +| -------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------- | +| color | ColorPicker | Renders a [ColorPicker field](https://developer.wordpress.org/block-editor/reference-guides/components/color-picker/) | +| text | TextControl | Renders a [TextControl field](https://developer.wordpress.org/block-editor/reference-guides/components/text-control/) of type `text` | +| textarea | TextAreaControl | Renders a [TextAreaControl field](https://developer.wordpress.org/block-editor/reference-guides/components/textarea-control/) | +| radio | RadioControl | Renders a [RadioControl field](https://developer.wordpress.org/block-editor/reference-guides/components/radio-control/) | +| select | SelectControl | Renders a [SelectControl field](https://developer.wordpress.org/block-editor/reference-guides/components/select-control/) | +| range | RangeControl | Renders a [RangeControl field](https://developer.wordpress.org/block-editor/reference-guides/components/range-control/) | +| number | TextControl | Renders a [TextControl field](https://developer.wordpress.org/block-editor/reference-guides/components/text-control/) of type `number` | +| checkbox | CheckBoxControl | Renders a [CheckBoxControl field](https://developer.wordpress.org/block-editor/reference-guides/components/checkbox-control/) | + +> [!NOTE] +> The `editorFields` configuration provides necessary hints for the helper to render the specified controls. It always overrides any configuration that is declared in the `block.json` attributes section. If you are not seeing the appropriate control used, check that your `editorFields` contain the correct attribute name and the correct `control` property. + +## Learn More + +This concludes this how-to guide for using the `@faustwp/block-editor-utils` package to convert React components into Block Editor blocks. To learn more, see [this RFC document](https://github.com/wpengine/faustjs/issues/1522) that explains in detail the different options and configurations regarding the usage of the `@faustwp/block-editor-utils`. From 10df36d38e7ccfcfbefa46f0dfc776bb15afae31 Mon Sep 17 00:00:00 2001 From: Kellen Mace Date: Thu, 13 Feb 2025 14:27:36 -0500 Subject: [PATCH 2/6] Update React Components to Blocks doc to address Discord user feedback --- .../react-components-to-blocks/index.mdx | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/pages/docs/how-to/react-components-to-blocks/index.mdx b/src/pages/docs/how-to/react-components-to-blocks/index.mdx index 605b5c04..e1a703a7 100644 --- a/src/pages/docs/how-to/react-components-to-blocks/index.mdx +++ b/src/pages/docs/how-to/react-components-to-blocks/index.mdx @@ -41,6 +41,10 @@ function MyFirstBlock({ style, className, attributes, children, ...props }) { ); } +MyFirstBlock.config = { + name: "MyFirstBlock", +}; + export default MyFirstBlock; ``` @@ -50,6 +54,8 @@ This React component consists of a `div` element with three attributes that cont - **bg_color**: controls the background color. - **text_color**: controls the text color. +The `MyFirstBlock.config` object here with a `name` value inside is used to specify the name of the block. + We would like to use this React component in WordPress using the Block Editor. Traditionally, this step would require us (the developers) to register a block within WordPress, provide a `block.json` and write code for the [Edit and Save](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-edit-save/) functions for the editor. Once those steps are done, then the block would be usable in the Block Editor list. That is a lot of know-how and development effort for simply trying to use the React component in the editor side. What if we just provided the React component and let the framework handle all the block registration and creating the editor form fields for changing the content? @@ -146,31 +152,28 @@ However, a few of the attributes that control the color are using [text field](h Since the `block.json` [attribute types](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-attributes/#type-validation) do not allow `color` as a value, we will have to provide a different configuration to allow that option. -When registering the React component using `registerFaustBlock` , it allows extra configuration to be used in case you want to declare which kinds of controls to use on each attribute. +When registering the React component using `registerFaustBlock`, it allows extra configuration to be used in case you want to declare which kinds of controls to use on each attribute. -Add the following config object as a property to the `MyFirstBlock` function: +In your `MyFirstBlock.jsx` file, add the following `editorFields` to your `MyFirstBlock.config` object: ```js title="MyFirstBlock.jsx" ... MyFirstBlock.config = { name: "MyFirstBlock", - editorFields: { - bg_color: { - location: "inspector", - control: "color", - }, - text_color: { - location: "inspector", - control: "color", - }, - }, + editorFields: {// [!code ++] + bg_color: {// [!code ++] + location: "inspector",// [!code ++] + control: "color",// [!code ++] + },// [!code ++] + text_color: {// [!code ++] + location: "inspector",// [!code ++] + control: "color",// [!code ++] + },// [!code ++] + },// [!code ++] }; ``` -Here we included an object with the following properties: - -- **name**: the name of the block. -- **editorFields**: the list of Editor metadata configuration. This consists of two attributes that we want to specify: the type of control to use and the location within the editor. For example, by using `location: "inspector",` we are telling this control to appear in the [Block Sidebar](https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/block-controls-toolbar-and-sidebar/) section. By using `control: "color"`, we are indicating that we want to use a [ColorPicker](https://developer.wordpress.org/block-editor/reference-guides/components/color-picker/) component instead of the regular `TextControl`. +`editorFields` represents Block Editor metadata configuration data. This consists of two attributes that we want to specify: the type of control to use and the location within the editor. For example, by using `location: "inspector",` we are telling this control to appear in the [Block Sidebar](https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/block-controls-toolbar-and-sidebar/) section. By using `control: "color"`, we are indicating that we want to use a [ColorPicker](https://developer.wordpress.org/block-editor/reference-guides/components/color-picker/) component instead of the regular `TextControl`. Once you update the component, you can refresh the page and create a new block. Now instead of having two text fields inside the block, we have two `ColorPicker` fields in the sidebar section: From 18af81821675bb969b72c33f6fa71084cf48de56 Mon Sep 17 00:00:00 2001 From: Kellen Mace Date: Thu, 13 Feb 2025 15:45:59 -0500 Subject: [PATCH 3/6] Add blockset reference doc --- src/pages/docs/nav.json | 4 + src/pages/docs/reference/blockset/index.mdx | 83 +++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 src/pages/docs/reference/blockset/index.mdx diff --git a/src/pages/docs/nav.json b/src/pages/docs/nav.json index dc072dfb..e8a1720b 100644 --- a/src/pages/docs/nav.json +++ b/src/pages/docs/nav.json @@ -116,6 +116,10 @@ { "title": "WordPressBlocksViewer", "route": "/docs/reference/wordpress-blocks-viewer" + }, + { + "title": "blockset", + "route": "/docs/reference/blockset" } ] }, diff --git a/src/pages/docs/reference/blockset/index.mdx b/src/pages/docs/reference/blockset/index.mdx new file mode 100644 index 00000000..9d6f70d9 --- /dev/null +++ b/src/pages/docs/reference/blockset/index.mdx @@ -0,0 +1,83 @@ +export const metadata = { + title: "blockset", + description: + "Deploy Faust.js blocks to your backend WordPress site using the `blockset` command.", +}; + +Faust's `blockset` command deploys Faust.js blocks to your backend WordPress site so they may be used in the Block Editor. This reference page lists the prerequisites and usage instructions for the `blockset` command. + +## Prerequisites + +In order to use the `blockset` command, you will need the following. + +### Packages and Plugins + +These NPM packages installed: + +- `@faustwp/cli` +- `@wordpress/scripts` + +These WordPress plugins installed and activated: + +- [Faust.js WordPress Plugin](https://wordpress.org/plugins/faustwp/) +- [WPGraphQL](https://wordpress.org/plugins/wp-graphql/) +- [WPGraphQL Content Blocks](https://github.com/wpengine/wp-graphql-content-blocks) + +### A Created Block + +Before syncing a block to your WordPress backend site, you must of course have a block created. + +If you don't have a block already created, you can use the official [@wordpress/create-block](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-create-block/) package to scaffold out a new block inside a directory named `wp-blocks` within your Next.js app. + +``` +wp-blocks +├── block-a +│ ├── block.json +│ ├── edit.js +│ ├── editor.scss +│ ├── index.js +│ ├── save.js +│ └── style.scss +└── index.js +``` + +> [!NOTE] +> See our [React Components to Blocks](/docs/how-to/react-components-to-blocks/) how-to guide for more information on how to create React components that can be used as blocks in the Block Editor. + +## `blockset` Command Usage + +The `blockset` command can be run by adding `faust blockset` to one or more of your `package.json` scripts, then running those scripts from the command line. + +This example is utilizing npm pre-hooks to automatically execute the blockset process whenever `npm run dev` or `npm run build` are run: + +```json title="package.json" +{ + "scripts": { + "predev": "faust blockset", // [!code ++] + "dev": "faust dev", + "prebuild": "faust blockset", // [!code ++] + "build": "faust build" + }, + "devDependencies": { + "@faustwp/cli": "^1.2.1", + "@wordpress/scripts": "26.18.0" + } +} +``` + +With that code in place, each time a developer runs `npm run dev` or `npm run build`, the `blockset` command will be executed, syncing the blocks within the `wp-blocks` folder to your WordPress backend. + +## Example App + +To see a working example of an app that has been configured to use the `blockset` command, see our block-support example app, here: + +https://github.com/wpengine/faustjs/tree/canary/examples/next/block-support + +If you'd like, you can clone this example app and run it locally with this command: + +```bash +npx create-next-app \ +-e https://github.com/wpengine/faustjs/tree/canary \ +--example-path examples/next/block-support \ +--use-npm +``` From f0695651ad7e5340691991963e7bff91fd9eb44b Mon Sep 17 00:00:00 2001 From: Kellen Mace Date: Thu, 13 Feb 2025 15:46:34 -0500 Subject: [PATCH 4/6] Minor wording tweak --- src/pages/docs/how-to/react-components-to-blocks/index.mdx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pages/docs/how-to/react-components-to-blocks/index.mdx b/src/pages/docs/how-to/react-components-to-blocks/index.mdx index e1a703a7..699074c9 100644 --- a/src/pages/docs/how-to/react-components-to-blocks/index.mdx +++ b/src/pages/docs/how-to/react-components-to-blocks/index.mdx @@ -60,7 +60,9 @@ We would like to use this React component in WordPress using the Block Editor. T That is a lot of know-how and development effort for simply trying to use the React component in the editor side. What if we just provided the React component and let the framework handle all the block registration and creating the editor form fields for changing the content? -This is what `@faustwp/block-editor-utils` package tries to do. It provides a `registerFaustBlock` helper function, that handles all the necessary configuration, registration and generation of Editor Form fields and [Inspector controls](https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/block-controls-toolbar-and-sidebar/) for you. A developer can provide the React component and are able to review this within the WordPress Block Editor and use it in both places. +This is what the `@faustwp/block-editor-utils` package tries to do. It provides a `registerFaustBlock` helper function, that handles all the necessary configuration, registration and generation of Editor Form fields and [Inspector controls](https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/block-controls-toolbar-and-sidebar/) for you. A developer can provide the React component and are able to review this within the WordPress Block Editor and use it in both places. + +Within your `wp-blocks/my-first-block` folder replace the `index.js` contents with the following code: ```js title="index.js" import "./style.scss"; From 2099c6579a503e7f76e25c13f05e32522e06b12a Mon Sep 17 00:00:00 2001 From: Kellen Mace Date: Thu, 13 Feb 2025 16:00:49 -0500 Subject: [PATCH 5/6] Add redirect to the blockset doc --- next.config.mjs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/next.config.mjs b/next.config.mjs index c820c46d..4e3646a4 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -85,6 +85,11 @@ const nextConfig = { destination: "/docs/how-to/generate-types-with-graphql-codegen/", permanent: true, }, + { + source: "/guide/how-to-register-decoupled-blocks", + destination: "/docs/reference/blockset/", + permanent: true, + }, { source: "/tutorial/get-started-with-wp-graphql-content-blocks", destination: "/docs/how-to/rendering-blocks/", From 0c205ec97cdc47dfd82887e1542fdb6e1675c804 Mon Sep 17 00:00:00 2001 From: Alex Moon Date: Thu, 13 Feb 2025 15:10:23 -0800 Subject: [PATCH 6/6] Update src/pages/docs/how-to/react-components-to-blocks/index.mdx --- src/pages/docs/how-to/react-components-to-blocks/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/docs/how-to/react-components-to-blocks/index.mdx b/src/pages/docs/how-to/react-components-to-blocks/index.mdx index 699074c9..a1630bf8 100644 --- a/src/pages/docs/how-to/react-components-to-blocks/index.mdx +++ b/src/pages/docs/how-to/react-components-to-blocks/index.mdx @@ -8,7 +8,7 @@ The `@faustwp/block-editor-utils` package provides helper functions for converti In this how-to guide, we will walk through the steps required to create a new block named `my-first-block` using this workflow. -## Prerequisites +## 0. Prerequisites Make sure you have followed the [Basic Setup](/docs/how-to/basic-setup/) steps to get Faust.js set up.