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

Docs: Clarify the purpose of the @wordpress/editor package #30136

Merged
merged 1 commit into from
Mar 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
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
38 changes: 17 additions & 21 deletions docs/explanations/architecture/modularity.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ These packages are used to power the Block Editor, but they can be used to power

Using a modular architecture has several benefits for all the actors involved:

* Each package is an independent unit and has a well defined public API that is used to interact with other packages and third-party code. This makes it easier for **Core Contributors** to reason about the codebase. They can focus on a single package at a time, understand it and make updates while knowing exactly how these changes could impact all the other parts relying on the given package.
* A module approach is also beneficial to the **end-user**. It allows to selectively load scripts on different WordPress Admin pages while keeping the bundle size contained. For instance, if we use the components package to power our plugin's settings page, there's no need to load the block-editor package on that page.
* This architecture also allows **third-party developers** to reuse these packages inside and outside the WordPress context by using these packages as npm or WordPress script dependencies.
- Each package is an independent unit and has a well defined public API that is used to interact with other packages and third-party code. This makes it easier for **Core Contributors** to reason about the codebase. They can focus on a single package at a time, understand it and make updates while knowing exactly how these changes could impact all the other parts relying on the given package.
- A module approach is also beneficial to the **end-user**. It allows to selectively load scripts on different WordPress Admin pages while keeping the bundle size contained. For instance, if we use the components package to power our plugin's settings page, there's no need to load the block-editor package on that page.
- This architecture also allows **third-party developers** to reuse these packages inside and outside the WordPress context by using these packages as npm or WordPress script dependencies.

## Types of packages

Expand All @@ -24,23 +24,21 @@ These are the packages that ship in WordPress itself as JavaScript scripts. Thes

Third-party developers can use these production packages in two different ways:

* If you're building a JavaScript application, website, page that runs outside of the context of WordPress, you can consume these packages like any other JavaScript package in the npm registry.
- If you're building a JavaScript application, website, page that runs outside of the context of WordPress, you can consume these packages like any other JavaScript package in the npm registry.

```
npm install @wordpress/components
```

```js
import { Button } from '@wordpress/components';
import { Button } from '@wordpress/components';

function MyApp() {
return (
<Button>Nice looking button</Button>
);
return <Button>Nice looking button</Button>;
}
```

* If you're building a plugin that runs on WordPress, you'd probably prefer consuming the package that ships with WordPress itself. This allows multiple plugins to reuse the same packages and avoid code duplication. In WordPress, these packages are available as WordPress scripts with a handle following this format `wp-package-name` (e.g. `wp-components`). Once you add the script to your own WordPress plugin scripts dependencies, the package will be available on the `wp` global variable.
- If you're building a plugin that runs on WordPress, you'd probably prefer consuming the package that ships with WordPress itself. This allows multiple plugins to reuse the same packages and avoid code duplication. In WordPress, these packages are available as WordPress scripts with a handle following this format `wp-package-name` (e.g. `wp-components`). Once you add the script to your own WordPress plugin scripts dependencies, the package will be available on the `wp` global variable.

```php
// myplugin.php
Expand All @@ -53,9 +51,7 @@ wp_register_script( 'myscript', 'pathtomyscript.js', array ('wp-components', "wp
const { Button } = wp.components;

function MyApp() {
return (
<Button>Nice looking button</Button>
);
return <Button>Nice looking button</Button>;
}
```

Expand All @@ -65,8 +61,8 @@ Script dependencies definition can be a tedious task for developers. Mistakes an

Some production packages provide stylesheets to function properly.

* If you're using the package as an npm dependency, the stylesheets will be available on the `build-style` folder of the package. Make sure to load this style file on your application.
* If you're working in the context of WordPress, you'll have to enqueue these stylesheets or add them to your stylesheets dependencies. The stylesheet handles are the same as the script handles.
- If you're using the package as an npm dependency, the stylesheets will be available on the `build-style` folder of the package. Make sure to load this style file on your application.
- If you're working in the context of WordPress, you'll have to enqueue these stylesheets or add them to your stylesheets dependencies. The stylesheet handles are the same as the script handles.

In the context of existing WordPress pages, if you omit to define the scripts or styles dependencies properly, your plugin might still work properly if these scripts and styles are already loaded there by WordPress or by other plugins, but it's highly recommended to define all your dependencies exhaustively if you want to avoid potential breakage in future versions.

Expand All @@ -88,16 +84,16 @@ It's often surprising to new contributors to discover that the post editor is co

The above [Why?](#why) section should provide some context for how individual packages aim to satisfy specific requirements. That applies to these packages as well:

- `@wordpress/block-editor` provides components for implementing a block editor, operating on a primitive value of an array of block objects. It makes no assumptions for how this value is saved, and has no awareness (or requirement) of a WordPress site.
- `@wordpress/editor` utilizes components from `@wordpress/block-editor`, and associates the loading and saving mechanism of the blocks value to a post and post content. With the awareness of the concept of a WordPress post, it also provides various components relevant for working with a post object in the context of an editor (e.g. a post title input component). This package can support editing posts of any post type, and does not assume that it is rendered in any particular WordPress screen, or in any particular layout arrangement.
- `@wordpress/edit-post` is the implementation of the "New Post" ("Edit Post") screen in the WordPress admin. It is responsible for the layout of the various components provided by `@wordpress/editor` and `@wordpress/block-editor`, with full awareness of how it is presented in the specific screen in the WordPress administrative dashboard.
- `@wordpress/block-editor` provides components for implementing a block editor, operating on a primitive value of an array of block objects. It makes no assumptions for how this value is saved, and has no awareness (or requirement) of a WordPress site.
- `@wordpress/editor` is the enhanced version of the block editor for WordPress posts. It utilizes components from the `@wordpress/block-editor` package. Having an awareness of the concept of a WordPress post, it associates the loading and saving mechanism of the value representing blocks to a post and its content. It also provides various components relevant for working with a post object in the context of an editor (e.g., a post title input component). This package can support editing posts of any post type and does not assume that rendering happens in any particular WordPress screen or layout arrangement.
- `@wordpress/edit-post` is the implementation of the "New Post" ("Edit Post") screen in the WordPress admin. It is responsible for the layout of the various components provided by `@wordpress/editor` and `@wordpress/block-editor`, with full awareness of how it is presented in the specific screen in the WordPress administrative dashboard.

Structured this way, these packages can be used in a variety of combinations outside the use-case of the "New Post" screen:

- A `@wordpress/edit-site` or `@wordpress/edit-widgets` package can serve as similar implementations of a "Site Editor" or "Widgets Editor", in much the same way as `@wordpress/edit-post`.
- `@wordpress/editor` could be used in the implementation of the "Reusable Block" block, since it is essentially a nested block editor associated with the post type `wp_block`.
- `@wordpress/block-editor` could be used independently from WordPress, or with a completely different save mechanism. For example, it could be used for a comments editor for posts of a site.
- A `@wordpress/edit-site` or `@wordpress/edit-widgets` package can serve as similar implementations of a "Site Editor" or "Widgets Editor", in much the same way as `@wordpress/edit-post`.
- `@wordpress/editor` could be used in the implementation of the "Reusable Block" block, since it is essentially a nested block editor associated with the post type `wp_block`.
- `@wordpress/block-editor` could be used independently from WordPress, or with a completely different save mechanism. For example, it could be used for a comments editor for posts of a site.

## Going further

- [Package Reference](/docs/reference-guides/packages.md)
- [Package Reference](/docs/reference-guides/packages.md)
66 changes: 32 additions & 34 deletions packages/editor/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Editor

Building blocks for WordPress editors.
This module utilizes components from the `@wordpress/block-editor` package. Having an awareness of the concept of a WordPress post, it associates the loading and saving mechanism of the value representing blocks to a post and its content. It also provides various components relevant for working with a post object in the context of an editor (e.g., a post title input component). This package can support editing posts of any post type and does not assume that rendering happens in any particular WordPress screen or layout arrangement.

## Installation

Expand All @@ -22,7 +22,7 @@ The goal of the editor element is to let the user manipulate the content of thei

Such a crucial step is handled by the grammar parsing which takes the serialized content of the post and infers an ordered block list using, preferably, syntax hints present in HTML comments. The editor is initialized with a state representation of the block nodes generated by the parsing of the raw content of a post element: `wp.blocks.parse( post.content.raw )`.

The *visual editor* is thus a component that contains and renders the list of block nodes from the internal state into the page. This removes any trace of imperative handling when it comes to finding a block and manipulating a block. As a matter of fact, the visual editor or the text editor are just two different—equally valid—views of the same representation of state. The internal representation of the post content is updated as blocks are updated and it is serialized back to be saved in `post_content`.
The _visual editor_ is thus a component that contains and renders the list of block nodes from the internal state into the page. This removes any trace of imperative handling when it comes to finding a block and manipulating a block. As a matter of fact, the visual editor or the text editor are just two different—equally valid—views of the same representation of state. The internal representation of the post content is updated as blocks are updated and it is serialized back to be saved in `post_content`.

Individual blocks are handled by the `VisualBlock` component, which attaches event handlers and renders the `edit` function of a block definition to the document with the corresponding attributes and local state. The `edit` function is the markup shape of a component while in editing mode.

Expand All @@ -37,43 +37,44 @@ When returned by your block's `edit` implementation, renders a toolbar of icon b
Example:

```js
( function( editor, element ) {
( function ( editor, element ) {
var el = element.createElement,
BlockControls = editor.BlockControls,
AlignmentToolbar = editor.AlignmentToolbar;

function edit( props ) {
return [
// Controls: (only visible when block is selected)
el( BlockControls, { key: 'controls' },
el(
BlockControls,
{ key: 'controls' },
el( AlignmentToolbar, {
value: props.align,
onChange: function( nextAlign ) {
props.setAttributes( { align: nextAlign } )
}
onChange: function ( nextAlign ) {
props.setAttributes( { align: nextAlign } );
},
} )
),

// Block content: (with alignment as attribute)
el( 'p', { key: 'text', style: { textAlign: props.align } },
el(
'p',
{ key: 'text', style: { textAlign: props.align } },
'Hello World!'
),
];
}
} )(
window.wp.editor,
window.wp.element
);
} )( window.wp.editor, window.wp.element );
```

Note in this example that we render `AlignmentToolbar` as a child of the `BlockControls` element. This is another pre-configured component you can use to simplify block text alignment.

Alternatively, you can create your own toolbar controls by passing an array of `controls` as a prop to the `BlockControls` component. Each control should be an object with the following properties:

- `icon: string` - Slug of the Dashicon to be shown in the control's toolbar button
- `title: string` - A human-readable localized text to be shown as the tooltip label of the control's button
- `subscript: ?string` - Optional text to be shown adjacent the button icon as subscript (for example, heading levels)
- `isActive: ?boolean` - Whether the control should be considered active / selected. Defaults to `false`.
- `icon: string` - Slug of the Dashicon to be shown in the control's toolbar button
- `title: string` - A human-readable localized text to be shown as the tooltip label of the control's button
- `subscript: ?string` - Optional text to be shown adjacent the button icon as subscript (for example, heading levels)
- `isActive: ?boolean` - Whether the control should be considered active / selected. Defaults to `false`.

To create divisions between sets of controls within the same `BlockControls` element, passing `controls` instead as a nested array (array of arrays of objects). A divider will be shown between each set of controls.

Expand All @@ -83,23 +84,23 @@ Render a rich [`contenteditable` input](https://developer.mozilla.org/en-US/docs

The following properties (non-exhaustive list) are made available:

- `value: string` - Markup value of the field. Only valid markup is
allowed, as determined by `inline` value and available controls.
- `onChange: Function` - Callback handler when the value of the field changes,
passing the new value as its only argument.
- `placeholder: string` - A text hint to be shown to the user when the field
value is empty, similar to the
[`input` and `textarea` attribute of the same name](https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/HTML5_updates#The_placeholder_attribute).
- `multiline: String` - A tag name to use for the tag that should be inserted
when Enter is pressed. For example: `li` in a list block, and `p` for a
block that can contain multiple paragraphs. The default is that only inline
elements are allowed to be used in inserted into the text, effectively
disabling the behavior of the "Enter" key.
- `value: string` - Markup value of the field. Only valid markup is
allowed, as determined by `inline` value and available controls.
- `onChange: Function` - Callback handler when the value of the field changes,
passing the new value as its only argument.
- `placeholder: string` - A text hint to be shown to the user when the field
value is empty, similar to the
[`input` and `textarea` attribute of the same name](https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/HTML5_updates#The_placeholder_attribute).
- `multiline: String` - A tag name to use for the tag that should be inserted
when Enter is pressed. For example: `li` in a list block, and `p` for a
block that can contain multiple paragraphs. The default is that only inline
elements are allowed to be used in inserted into the text, effectively
disabling the behavior of the "Enter" key.

Example:

```js
( function( editor, element ) {
( function ( editor, element ) {
var el = element.createElement,
RichText = editor.RichText;

Expand All @@ -110,15 +111,12 @@ Example:

return el( RichText, {
value: props.attributes.text,
onChange: onChange
onChange: onChange,
} );
}

// blocks.registerBlockType( ..., { edit: edit, ... } );
} )(
window.wp.editor,
window.wp.element
);
} )( window.wp.editor, window.wp.element );
```

<br/><br/><p align="center"><img src="https://s.w.org/style/images/codeispoetry.png?1" alt="Code is Poetry." /></p>
2 changes: 1 addition & 1 deletion packages/editor/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@wordpress/editor",
"version": "9.26.0",
"description": "Building blocks for WordPress editors.",
"description": "Enhanced block editor for WordPress posts.",
"author": "The WordPress Contributors",
"license": "GPL-2.0-or-later",
"keywords": [
Expand Down