diff --git a/src/pages/docs/how-to/override-blocks/images/block-console.png b/src/pages/docs/how-to/override-blocks/images/block-console.png new file mode 100644 index 00000000..5b83efeb Binary files /dev/null and b/src/pages/docs/how-to/override-blocks/images/block-console.png differ diff --git a/src/pages/docs/how-to/override-blocks/images/core-code-block-decoupled-preview.png b/src/pages/docs/how-to/override-blocks/images/core-code-block-decoupled-preview.png new file mode 100644 index 00000000..12d5c5b2 Binary files /dev/null and b/src/pages/docs/how-to/override-blocks/images/core-code-block-decoupled-preview.png differ diff --git a/src/pages/docs/how-to/override-blocks/images/core-code-block-ide-attributes.png b/src/pages/docs/how-to/override-blocks/images/core-code-block-ide-attributes.png new file mode 100644 index 00000000..e9272ee8 Binary files /dev/null and b/src/pages/docs/how-to/override-blocks/images/core-code-block-ide-attributes.png differ diff --git a/src/pages/docs/how-to/override-blocks/images/core-code-block.png b/src/pages/docs/how-to/override-blocks/images/core-code-block.png new file mode 100644 index 00000000..e0209069 Binary files /dev/null and b/src/pages/docs/how-to/override-blocks/images/core-code-block.png differ diff --git a/src/pages/docs/how-to/override-blocks/index.mdx b/src/pages/docs/how-to/override-blocks/index.mdx new file mode 100644 index 00000000..8f1ae516 --- /dev/null +++ b/src/pages/docs/how-to/override-blocks/index.mdx @@ -0,0 +1,313 @@ +export const metadata = { + title: "Override blocks", +}; + +This guide covers the steps required to override WordPress blocks (the blocks that are available in the [WordPress block editor](https://wordpress.org/documentation/article/wordpress-block-editor/)). This can be useful when you want to render a block as a component in your frontend app, but take things a step further and customize its markup or functionality in some way. + +## Prerequisites + +Ensure that you have completed the steps in our [Rendering blocks](/docs/how-to/rendering-blocks) guide and have WordPress blocks rendering in your app successfully before proceeding with the steps below. + +## Steps + +### 1. Choose a block to override + +For this guide, we are going to override the native WordPress `Code` block that renders a formatted block of code. + + + +### 2. Review block features and settings + +Try using the block yourself in the WordPress block editor and get familiar with the features it has. Review the settings it has in the Settings Panel and change a few of them to see what they do. + +### 3. Inspect the block data via the GraphiQL IDE + +In the WordPress admin sidebar, go to `GraphQL` > `GraphiQL IDE` to open the GraphiQL IDE. If you're not familiar, this is a tool we can use for composing and testing GraphQL queries. This can help you understand what data your frontend app will receive when it executes a particular query. + +Paste the following query into the GraphiQL IDE and hit the `▶️` button to execute the query. Replace `/posts/testing` with the path to the blog post that contains the block you want to override. + +```graphql +{ + post(id: "/posts/testing", idType: URI) { + editorBlocks { + renderedHtml + ... on CoreCode { + attributes { + borderColor + backgroundColor + content + style + textColor + fontSize + } + } + } + } +} +``` + +The GraphiQL IDE will then display the data that was returned in the response to that query. It should look something like the example response below. + +```json +{ + "data": { + "post": { + "editorBlocks": [ + { + "renderedHtml": "\n
// Computes the nth Fibonacci number\nfunction fib(n) {\n var a = 0, b = 1, c;\n if (n < 3) {\n if (n < 0) return fib(-n);\n if (n === 0) return 0;\n return 1;\n }\n while (--n)\n c = a + b, a = b, b = c;\n return c;\n}\n",
+ "attributes": {
+ "borderColor": null,
+ "backgroundColor": "tertiary",
+ "content": "// Computes the nth Fibonacci number\nfunction fib(n) {\n var a = 0, b = 1, c;\n if (n < 3) {\n if (n < 0) return fib(-n);\n if (n === 0) return 0;\n return 1;\n }\n while (--n)\n c = a + b, a = b, b = c;\n return c;\n}",
+ "style": "{\"color\":{\"text\":\"#333333\"},\"border\":{\"color\":\"#333333\",\"width\":\"2px\"}}",
+ "textColor": null,
+ "fontSize": "small"
+ }
+ }
+ ]
+ }
+ }
+}
+```
+
+You can try modifying the query and running it again to see how the response changes. To learn about the fields that are available for that block, click the `Docs` link in GraphiQL, search for `CoreCode`, and click on `CoreCodeAttributes`. You will see the following:
+
+
+
+Notice that with some of the attributes like `backgroundColor`, the editor used the [`theme.json`](https://developer.wordpress.org/themes/global-settings-and-styles/introduction-to-theme-json/) palette slug name instead of the actual value, i.e., `tertiary`. It also stored the custom hardcoded styles in the `style` fields as a JSON string. We will handle them appropriately when we override the block.
+
+### 4. Define the block in your frontend app
+
+Create a `wp-blocks` folder in the root folder of your project. Create a new `CoreCode.js` file inside of it that contains the following code.
+
+```js title="wp-blocks/CoreCode.js"
+import React from "react";
+
+export default function CoreCode(props) {
+ console.log(props.attributes);
+ return
+ {`${attributes?.content}`}
+
+ );
+}
+
+// Add fragment
+CoreCode.fragments = {
+ key: `CoreCodeBlockFragment`,
+ entry: gql`
+ fragment CoreCodeBlockFragment on CoreCode {
+ attributes {
+ borderColor
+ backgroundColor
+ content
+ style
+ textColor
+ fontSize
+ fontFamily
+ cssClassName
+ }
+ }
+ `,
+};
+
+CoreCode.displayName = "CoreCode";
+```
+
+Now that you have the styles configured correctly, you can navigate to the page that contains this block in your frontend app to confirm that the block matches the styles in the WordPress editor. Make sure to tweak the block in the WordPress block editor and verify that the changes are being reflected when you reload that page in your frontend app.
+
+
+
+## Further considerations
+
+> What if the block is missing some attributes?
+
+If the block does not have any attributes or has only a few of them declared in the `block.json` for that block (you can view the `block.json` file for the block at https://github.com/WordPress/gutenberg/blob/trunk/packages/block-library/), you can still try to extend the block API by declaring additional attributes for that block.
+
+Follow the [filters reference guide](reference/plugin-filters) to create a block that uses the `additional_block_attributes` property. The attributes will then be available to query from that block.
+
+```php
+class CoreCode extends WPGraphQL\ContentBlocks\Blocks\Block
+{
+ protected ?array $additional_block_attributes = array(
+ // Write your attributes here
+ );
+}
+```
+
+Note that if you include those extensions in a custom plugin, your Headless Website application is dependent on the inclusion of this plugin. You need to make sure you bundle them together; otherwise, the queries you perform in the application will fail.
+
+> Can I style the block differently?
+
+Yes, you can style the block in many ways, choosing to ignore some of the attributes altogether. You can also use an external React Library to style the block, such as Material UI or ChakraUI.
+
+Bear in mind that this will almost always result in a degraded user editing experience, as the styles in the WordPress block editor view won't match the styles of the rendered headless page.
+
+> What if the block contains custom JavaScript assets?
+
+Some Core blocks include JavaScript assets that are injected into the WordPress page so they can run in the front view. Many [dynamic blocks](https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/creating-dynamic-blocks/) use this functionality to include user interactivity. Since React is not bundled as a dependency in the browser, the client-side code that WordPress ships to the frontend in traditional WordPress sites typically consists of plain JavaScript or jQuery.
+
+To review and handle bundled JavaScript assets, consider these options:
+
+- **Include them in your code**: This is not recommended, as React does not play well with plain JavaScript and jQuery, which may lead to compatibility issues.
+- **Rewrite them as React components**: You can attempt to rewrite the code in React. If the bundled code can be understood and rewritten with low effort, then this could be a viable approach.
+- **Use an equivalent React Component from a library**: A simpler alternative is to find a compatible React package and use it instead of replicating the block's interactivity. This can often free the developer from implementing the functionality from scratch.
+
+Inevitably, this is a common challenge when using Blocks in a Headless Website setup, so it's up to you to weigh the pros and cons of each approach.
diff --git a/src/pages/docs/reference/wordpress-blocks-provider/index.mdx b/src/pages/docs/reference/wordpress-blocks-provider/index.mdx
index 138a58cb..39a5d7ea 100644
--- a/src/pages/docs/reference/wordpress-blocks-provider/index.mdx
+++ b/src/pages/docs/reference/wordpress-blocks-provider/index.mdx
@@ -25,7 +25,6 @@ export default function MyApp({ Component, pageProps }) {
config={{
// [!code ++]
blocks, // [!code ++]
- theme: null, // [!code ++]
}}
>
{" "}
@@ -72,7 +71,6 @@ import blocks from "../wp-blocks/index.js"; // [!code ++]