Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update platform docs intro #61341

Merged
merged 4 commits into from
Dec 11, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 62 additions & 33 deletions platform-docs/docs/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,76 +10,105 @@ Let's discover how to use the **Gutenberg Block Editor** to build your own block
## What you'll need

- [Node.js](https://nodejs.org/en/download/) version 20.10 or above.
- We're going to be using "vite" to setup our single page application (SPA) that contains a block editor. You can use your own setup, and your own application for this.
- We're going to be using "Vite" to setup our single page application (SPA) that contains a block editor. You can use your own setup, and your own application for this.

## Preparing the SPA powered by Vite.

First bootstrap a vite project using `npm create vite@latest` and pick `Vanilla` variant and `JavaScript` as a language.
First bootstrap a Vite project using `npm create vite@latest` and pick `React` variant and `JavaScript` as a language.

Once done, you can navigate to your application folder and run it locally using `npm run dev`. Open the displayed local URL in a browser.

## Installing dependencies

To build a block editor, you need to install the following dependencies:

- `@wordpress/blocks`
- `@wordpress/block-editor`
- `@wordpress/block-library`
- `@wordpress/components`

## Appease package expectations

The package `@wordpress/block-library` expects an env variable `IS_GUTENBERG_PLUGIN` to be defined. The quickest way to meet this requirement is to add it with `define` to the Vite config in `vite.config.js`. If using another bundler/build tool refer to its documentation for how to do this.

```js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
// highlight-next-line
define: { 'process.env.IS_GUTENBERG_PLUGIN': false },
plugins: [react()],
})
```

## JSX

We're going to be using JSX to write our UI and components. So one of the first steps we need to do is to configure our build tooling, By default vite supports JSX and and outputs the result as a React pragma. The Block editor uses React so there's no need to configure anything here but if you're using a different bundler/build tool, make sure the JSX transpilation is setup properly.
We're going to be using JSX to write our UI and components as the block editor is built with React. Using the Vite bootstrap described above there’s no need to configure anything as it outputs the result as a React pragma. If you're using a different bundler/build tool, you may need to configure the JSX transpilation to do the same.

## Bootstrap your block editor

It's time to render our first block editor.
It's time to render our first block editor. Update your `src/App.jsx` file with the following code:

- Update your `index.jsx` file with the following code:
```jsx
import { createElement, useState } from "react";
import { createRoot } from 'react-dom/client';
import { useState } from "react";
import {
BlockEditorProvider,
BlockCanvas,
} from "@wordpress/block-editor";
import { registerCoreBlocks } from "@wordpress/block-library";
import { getBlockTypes } from "@wordpress/blocks";

// Default styles that are needed for the editor.
import "@wordpress/components/build-style/style.css";
import "@wordpress/block-editor/build-style/style.css";
import componentsStyles from "@wordpress/components/build-style/style.css?raw";
import blockEditorStyles from "@wordpress/block-editor/build-style/style.css?raw";
import blockEditorContentStyles from "@wordpress/block-editor/build-style/content.css?raw";

// Default styles that are needed for the core blocks.
import "@wordpress/block-library/build-style/common.css";
import "@wordpress/block-library/build-style/style.css";
import "@wordpress/block-library/build-style/editor.css";

// Register the default core block types.
registerCoreBlocks();

function Editor() {
import blocksCommonStyles from "@wordpress/block-library/build-style/common.css?raw";
import blocksStyles from "@wordpress/block-library/build-style/style.css?raw";
import blocksEditorStyles from "@wordpress/block-library/build-style/editor.css?raw";

const styles = `
${ componentsStyles }
${ blockEditorStyles }
${ blockEditorContentStyles }
${ blocksCommonStyles }
${ blocksStyles }
${ blocksEditorStyles }
`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While we should do this for "content styles", some of these styles shouldn't be injected into the iframe and others should be injected inside and outside the iframe:

  • components (in both places because of placeholders and buttons)
  • block-editor/style style shouldn't be loaded in the iframe IMO (if something is not working we should fix it in gutenberg), instead it should be loaded in the app directly (so direct import here)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I’d meant to revisit this and get it right.

  • (if something is not working we should fix it in gutenberg)

Agreed. I can’t quite recall what style issues I’d noted. Perhaps the default block appender was not getting styled but since #66630 that doesn’t appear to be an issue.


const registeredBlockTypes = getBlockTypes();
// Registers the default core block types, avoiding doing so again during HMR.
if (
! registeredBlockTypes.length ||
! registeredBlockTypes.some((blockType) => blockType.name.startsWith('core/'))
) registerCoreBlocks();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a simpler way to do this. We're trying to teach people how to build a block editor, we should try to keep things as simple as possible. For instance is there something like ! isHMR && registerCoreBlocks() instead of using the block package.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn’t see a simple way to branch for HMR but could have missed something. Reregistering the blocks was not any fatal issue but it polluted the console quite a bit. Now that I’ve tested with the latest @wordpress packages I’m not seeing console messages output for blocks and I don’t know why. Still, there is one that gets output for the core/footnote format. The simplest way I thought of to avoid this is instructing that the registerCoreBlocks call be made in src/main.jsx.


export default function Editor() {
const [blocks, setBlocks] = useState([]);
return (
/*
The BlockEditorProvider is the wrapper of the block editor's state.
All the UI elements of the block editor need to be rendered within this provider.
*/
<BlockEditorProvider
value={blocks}
onChange={setBlocks}
onInput={setBlocks}
>
<>
<style>{ styles }</style>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's avoid this and just do importfor the two stylesheets that need to load here. We should clarify what things are "content" styles and what things are "UI styles". I think we should add a paragraph to explain this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay. This style tag is gone. This reason it was this way was because I’d added the ?raw param to the their import path to tell Vite not to process them and due to that Vite won’t automatically inject them. I can’t remember if there was any issue with Vite processing them or if I just thought it was better dev performance. Now instead of doing an import for those files I’ve instructed that they be added to index.html (the vite-ignore attribute will also keep them from being processed).

I know it’s not quite as simple that way but I think it may help express the difference with these UI styles versus the content styles. I also added a note hoping to help explain it, not sure if it suffices.

{/*
The BlockEditorProvider is the wrapper of the block editor's state.
All the UI elements of the block editor need to be rendered within this provider.
*/}
<BlockEditorProvider
value={blocks}
onChange={setBlocks}
onInput={setBlocks}
>
{/*
The BlockCanvas component renders the block list within an iframe
and wire up all the necessary events to make the block editor work.
and wires up all the necessary events to make the block editor work.
*/}
<BlockCanvas height="500px" />
</BlockEditorProvider>
<BlockCanvas height="500px" styles={ [ { css: styles } ] }/>
</BlockEditorProvider>
</>
);
}

// Render your React component instead
const root = createRoot(document.getElementById("app"));
root.render(<Editor />);
```

That's it! You now have a very basic block editor with several block types included by default: paragraphs, headings, lists, quotes, images...
Loading