From 55fdcdc985e1498ffba217565014cc3637e29007 Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Thu, 29 Apr 2021 15:21:40 +0200 Subject: [PATCH] Merge changes published in the Gutenberg plugin "release/10.5" branch --- .editorconfig | 7 - .eslintrc.js | 2 +- .github/PULL_REQUEST_TEMPLATE.md | 2 + .github/workflows/build-plugin-zip.yml | 3 +- .github/workflows/bundle-size.yml | 2 +- .github/workflows/create-block.yml | 2 +- .github/workflows/end2end-test.yml | 3 +- .github/workflows/performance.yml | 4 +- .github/workflows/pull-request-automation.yml | 2 +- .github/workflows/rnmobile-android-runner.yml | 2 +- .github/workflows/rnmobile-ios-runner.yml | 2 +- .github/workflows/static-checks.yml | 2 +- .github/workflows/storybook-pages.yml | 2 +- .github/workflows/unit-test.yml | 7 +- .wp-env.json | 2 +- CODE_OF_CONDUCT.md | 10 +- CONTRIBUTING.md | 12 +- LICENSE.md | 426 +- README.md | 6 +- bin/packages/watch.js | 186 +- bin/plugin/commands/packages.js | 7 +- bin/test-create-block.sh | 4 +- changelog.txt | 254 + composer.json | 7 +- docs/README.md | 15 +- docs/contributors/README.md | 16 +- docs/contributors/accessibility-testing.md | 8 +- docs/contributors/code/README.md | 16 +- .../getting-started-with-code-contribution.md | 86 +- docs/contributors/code/git-workflow.md | 34 +- docs/contributors/code/grammar.md | 1 - docs/contributors/code/release.md | 16 +- docs/contributors/code/scripts.md | 94 +- docs/contributors/design/README.md | 6 +- docs/contributors/design/the-block.md | 9 +- docs/contributors/documentation/copy-guide.md | 110 +- docs/contributors/folder-structure.md | 23 +- docs/contributors/localizing.md | 2 +- docs/contributors/repository-management.md | 113 +- docs/contributors/roadmap.md | 32 +- docs/explanations/architecture/README.md | 18 +- docs/explanations/architecture/data-flow.md | 80 +- .../full-site-editing-templates.md | 16 +- .../explanations/architecture/key-concepts.md | 8 +- docs/explanations/architecture/performance.md | 7 +- docs/getting-started/README.md | 4 +- docs/getting-started/faq.md | 38 +- docs/getting-started/history.md | 18 +- docs/getting-started/outreach.md | 108 +- .../tutorials/create-block/attributes.md | 14 +- .../create-block/author-experience.md | 47 +- .../tutorials/create-block/block-anatomy.md | 3 +- .../tutorials/create-block/block-code.md | 2 +- .../tutorials/devenv/README.md | 30 +- .../tutorials/devenv/docker-ubuntu.md | 6 +- docs/how-to-guides/accessibility.md | 6 +- .../backward-compatibility/README.md | 59 +- .../backward-compatibility/meta-box.md | 16 +- .../how-to-guides/block-based-theme/README.md | 35 +- .../block-based-themes-2-adding-blocks.md | 6 +- .../applying-styles-with-stylesheets.md | 30 +- .../block-controls-toolbar-and-sidebar.md | 76 +- .../block-tutorial/creating-dynamic-blocks.md | 79 +- ...roducing-attributes-and-editable-fields.md | 43 +- .../nested-blocks-inner-blocks.md | 44 +- .../writing-your-first-block-type.md | 37 +- docs/how-to-guides/designers/animation.md | 26 +- docs/how-to-guides/designers/block-design.md | 54 +- .../designers/design-resources.md | 6 +- .../how-to-guides/designers/user-interface.md | 20 +- docs/how-to-guides/feature-flags.md | 26 +- .../format-api/1-register-format.md | 32 +- .../format-api/2-toolbar-button.md | 161 +- .../format-api/3-apply-format.md | 86 +- docs/how-to-guides/internationalization.md | 85 +- .../javascript/extending-the-block-editor.md | 6 +- .../javascript/loading-javascript.md | 2 +- .../javascript/plugins-background.md | 6 +- .../javascript/scope-your-code.md | 20 +- .../javascript/troubleshooting.md | 2 +- docs/how-to-guides/metabox/README.md | 3 +- .../metabox/meta-block-1-intro.md | 1 - .../how-to-guides/metabox/meta-block-3-add.md | 47 +- .../metabox/meta-block-4-use-data.md | 3 +- .../metabox/meta-block-5-finishing.md | 1 - docs/how-to-guides/notices/README.md | 10 +- docs/how-to-guides/platform/README.md | 8 +- .../platform/custom-block-editor/README.md | 7 +- .../platform/custom-block-editor/tutorial.md | 230 +- .../sidebar-tutorial/plugin-sidebar-0.md | 2 +- .../plugin-sidebar-1-up-and-running.md | 7 +- .../plugin-sidebar-2-styles-and-controls.md | 18 +- .../plugin-sidebar-4-initialize-input.md | 76 +- .../plugin-sidebar-5-update-meta.md | 62 +- .../plugin-sidebar-6-finishing-touches.md | 149 +- .../themes/block-based-themes.md | 10 + docs/how-to-guides/themes/theme-json.md | 16 +- docs/how-to-guides/themes/theme-support.md | 29 +- docs/manifest.json | 66 +- docs/reference-guides/README.md | 14 +- docs/reference-guides/block-api/README.md | 12 +- .../block-api/block-annotations.md | 12 +- .../block-api/block-api-versions.md | 12 + .../block-api/block-attributes.md | 23 +- .../block-api/block-context.md | 55 +- .../block-api/block-deprecation.md | 99 +- .../block-api/block-edit-save.md | 136 +- .../block-api/block-metadata.md | 8 +- .../block-api/block-patterns.md | 18 +- .../block-api/block-registration.md | 12 +- .../block-api/block-supports.md | 137 +- .../block-api/block-templates.md | 23 +- .../block-api/block-transforms.md | 284 +- .../block-api/block-variations.md | 10 +- docs/reference-guides/block-api/versions.md | 12 - docs/reference-guides/data/README.md | 18 +- .../data/data-core-annotations.md | 1 - .../data/data-core-block-editor.md | 21 +- .../reference-guides/data/data-core-blocks.md | 1 - .../data/data-core-edit-post.md | 1 - .../reference-guides/data/data-core-editor.md | 13 +- .../data/data-core-keyboard-shortcuts.md | 1 - .../data/data-core-notices.md | 1 - docs/reference-guides/data/data-core-nux.md | 1 - .../data/data-core-viewport.md | 1 - docs/reference-guides/data/data-core.md | 1 - .../filters/autocomplete-filters.md | 16 +- .../reference-guides/filters/block-filters.md | 178 +- .../filters/editor-filters.md | 22 +- docs/reference-guides/filters/i18n-filters.md | 50 +- docs/reference-guides/packages.md | 5 +- docs/reference-guides/richtext.md | 21 +- docs/reference-guides/slotfills/README.md | 22 +- .../slotfills/main-dashboard-button.md | 41 +- .../plugin-block-settings-menu-item.md | 2 +- .../plugin-document-setting-panel.md | 15 +- .../slotfills/plugin-post-publish-panel.md | 1 - .../slotfills/plugin-post-status-info.md | 1 - .../slotfills/plugin-pre-publish-panel.md | 1 - docs/toc.json | 514 +- docs/tool/index.js | 4 +- gutenberg.php | 9 +- jsconfig.json | 2 +- lerna.json | 4 +- lib/block-editor.php | 293 + lib/block-patterns.php | 174 +- lib/block-patterns/heading.php | 16 + lib/block-patterns/large-header-left.php | 33 + .../large-header-text-button.php | 35 + .../media-text-arquitecture.php | 21 + lib/block-patterns/media-text-art.php | 21 + lib/block-patterns/media-text-nature.php | 28 + lib/block-patterns/quote.php | 30 + .../text-two-columns-title-offset.php | 53 + lib/block-patterns/text-two-columns-title.php | 31 + lib/block-patterns/text-two-columns.php | 44 + .../three-columns-media-text.php | 69 + lib/block-patterns/three-columns-text.php | 43 + lib/block-patterns/three-images-gallery.php | 43 + lib/block-patterns/two-buttons.php | 22 + lib/block-patterns/two-images-gallery.php | 15 + lib/block-supports/border.php | 95 +- lib/block-supports/colors.php | 4 +- lib/blocks.php | 5 +- lib/class-wp-rest-menu-items-controller.php | 4 +- lib/class-wp-rest-widget-types-controller.php | 124 +- lib/class-wp-rest-widgets-controller.php | 75 +- lib/class-wp-sidebar-block-editor-control.php | 8 - lib/class-wp-theme-json-resolver.php | 133 +- lib/class-wp-theme-json-schema-v0.php | 340 + lib/class-wp-theme-json.php | 753 +- lib/client-assets.php | 53 +- lib/compat.php | 2 +- lib/editor-settings.php | 70 +- lib/experimental-default-theme.json | 10 +- .../default-template-types.php | 6 +- lib/full-site-editing/edit-site-page.php | 4 +- lib/full-site-editing/full-site-editing.php | 9 + lib/full-site-editing/page-templates.php | 18 +- lib/full-site-editing/template-loader.php | 18 +- lib/full-site-editing/template-parts.php | 81 +- lib/full-site-editing/templates.php | 97 +- lib/global-styles.php | 112 +- lib/init.php | 1 + lib/interface-wp-theme-json-schema.php | 23 + lib/load.php | 3 + lib/navigation-page.php | 2 +- lib/navigation.php | 2 +- lib/query-utils.php | 6 +- lib/widgets-customize.php | 29 + lib/widgets-page.php | 4 +- package-lock.json | 60599 ++++++++-------- package.json | 34 +- packages/README.md | 23 +- packages/a11y/CHANGELOG.md | 8 +- packages/a11y/tsconfig.json | 5 +- packages/api-fetch/CHANGELOG.md | 26 +- packages/api-fetch/README.md | 8 +- .../api-fetch/src/middlewares/preloading.js | 6 +- .../src/middlewares/test/preloading.js | 70 +- packages/api-fetch/tsconfig.json | 13 +- packages/autop/CHANGELOG.md | 14 +- packages/babel-preset-default/CHANGELOG.md | 2 +- packages/base-styles/README.md | 16 +- packages/base-styles/_colors.scss | 1 - packages/base-styles/_mixins.scss | 1 + packages/blob/CHANGELOG.md | 8 +- packages/block-editor/CHANGELOG.md | 2 +- packages/block-editor/README.md | 10 + .../components/alignment-control/README.md | 12 +- .../src/components/autocomplete/README.md | 3 +- .../block-alignment-control/README.md | 5 +- .../src/components/block-breadcrumb/README.md | 3 +- .../src/components/block-compare/README.md | 20 +- .../src/components/block-context/README.md | 11 +- .../src/components/block-controls/fill.js | 35 +- .../src/components/block-draggable/index.js | 1 + .../block-draggable/stories/index.js | 2 +- .../README.md | 2 +- .../src/components/block-icon/README.md | 3 +- .../src/components/block-inspector/README.md | 6 +- .../block-list/block-selection-button.js | 52 +- .../src/components/block-list/index.js | 13 +- .../components/block-list/insertion-point.js | 17 +- .../src/components/block-list/style.scss | 13 + .../block-list/use-block-props/index.js | 3 + .../use-block-props/use-nav-mode-exit.js | 30 +- .../use-block-props/use-scroll-into-view.js | 64 + .../block-media-update-progress/README.md | 48 +- .../block-actions-menu.native.js | 17 +- .../src/components/block-mover/README.md | 6 +- .../src/components/block-navigation/README.md | 4 +- .../src/components/block-navigation/tree.js | 8 +- .../use-block-navigation-drop-zone.js | 185 +- .../block-parent-selector/README.md | 1 - .../components/block-parent-selector/index.js | 105 +- .../components/block-patterns-list/README.md | 4 +- .../src/components/block-preview/README.md | 42 +- .../block-selection-clearer/index.js | 7 +- .../block-settings-menu-controls/README.md | 6 +- .../block-settings-menu-controls/index.js | 25 +- .../components/block-settings-menu/README.md | 5 +- .../block-transformations-menu.native.js | 3 +- .../src/components/block-switcher/index.js | 54 +- .../pattern-transformations-menu.js | 137 + .../src/components/block-switcher/style.scss | 41 +- .../test/use-transformed.patterns.js | 336 + .../components/block-switcher/test/utils.js | 167 + .../use-transformed-patterns.js | 116 + .../src/components/block-switcher/utils.js | 57 + .../src/components/block-title/README.md | 3 +- .../src/components/block-toolbar/README.md | 5 +- .../src/components/block-types-list/README.md | 2 +- .../block-variation-picker/README.md | 4 +- .../block-variation-transforms/README.md | 30 +- .../README.md | 32 +- .../components/border-style-control/index.js | 64 + .../border-style-control/style.scss | 14 + .../button-block-appender/README.md | 22 +- .../src/components/colors/use-colors.js | 8 +- .../src/components/copy-handler/README.md | 3 +- .../src/components/copy-handler/index.js | 12 +- .../src/components/editable-text/README.md | 24 +- .../src/components/iframe/index.js | 9 +- .../components/image-size-control/README.md | 38 +- packages/block-editor/src/components/index.js | 1 + .../src/components/inner-blocks/README.md | 54 +- .../src/components/inner-blocks/index.js | 19 +- .../use-inner-block-template-sync.js | 6 +- .../inserter-draggable-blocks/index.js | 1 + .../inserter/hooks/use-insertion-point.js | 9 +- .../src/components/inserter/menu.native.js | 26 +- .../src/components/inserter/pattern-panel.js | 11 + .../inspector-advanced-controls/README.md | 6 +- .../inspector-advanced-controls/index.js | 11 +- .../components/inspector-controls/README.md | 252 +- .../components/inspector-controls/index.js | 11 +- .../justify-content-control/README.md | 34 +- .../components/line-height-control/README.md | 1 - .../src/components/link-control/README.md | 278 +- .../components/media-placeholder/README.md | 131 +- .../media-placeholder/index.native.js | 2 + .../components/media-replace-flow/README.md | 44 +- .../media-upload-progress/README.md | 49 +- .../src/components/media-upload/README.md | 84 +- .../components/media-upload/index.native.js | 32 +- .../multi-selection-inspector/README.md | 4 +- .../src/components/observe-typing/README.md | 3 +- .../src/components/plain-text/README.md | 10 +- .../src/components/provider/README.md | 21 +- .../responsive-block-control/README.md | 129 +- .../src/components/rich-text/README.md | 38 +- .../selection-scroll-into-view/index.js | 56 +- .../src/components/ungroup-button/README.md | 4 +- .../src/components/url-input/README.md | 72 +- .../use-block-display-information/README.md | 5 +- .../components/use-block-drop-zone/README.md | 3 +- .../components/use-block-drop-zone/index.js | 64 +- .../src/components/use-on-block-drop/index.js | 82 +- .../components/use-resize-canvas/README.md | 6 +- .../src/components/use-resize-canvas/index.js | 6 +- .../src/components/warning/README.md | 16 +- .../components/writing-flow/focus-capture.js | 99 - .../src/components/writing-flow/index.js | 61 +- .../writing-flow/use-multi-selection.js | 4 +- .../block-editor/src/hooks/border-color.js | 234 + .../block-editor/src/hooks/border-radius.js | 29 - .../block-editor/src/hooks/border-style.js | 37 + .../block-editor/src/hooks/border-width.js | 50 + packages/block-editor/src/hooks/border.js | 88 +- .../block-editor/src/hooks/color-panel.js | 2 +- packages/block-editor/src/hooks/color.js | 4 +- packages/block-editor/src/hooks/index.js | 3 + .../block-editor/src/hooks/index.native.js | 2 + packages/block-editor/src/hooks/test/style.js | 10 +- .../block-editor/src/hooks/use-color-props.js | 118 + packages/block-editor/src/index.js | 4 + packages/block-editor/src/store/actions.js | 13 +- packages/block-editor/src/store/reducer.js | 26 + packages/block-editor/src/store/selectors.js | 78 + .../block-editor/src/store/test/reducer.js | 73 + .../block-editor/src/store/test/selectors.js | 51 + packages/block-editor/src/style.scss | 1 + packages/block-library/CHANGELOG.md | 82 +- packages/block-library/README.md | 56 + .../test/__snapshots__/edit.native.js.snap | 3 - packages/block-library/src/button/block.json | 16 +- .../block-library/src/button/color-edit.js | 8 +- .../block-library/src/button/color-props.js | 82 - .../block-library/src/button/deprecated.js | 137 +- packages/block-library/src/button/edit.js | 51 +- .../block-library/src/button/edit.native.js | 56 +- packages/block-library/src/button/save.js | 18 +- packages/block-library/src/button/style.scss | 6 + .../block-library/src/buttons/edit.native.js | 13 +- packages/block-library/src/buttons/style.scss | 5 + packages/block-library/src/column/block.json | 4 +- packages/block-library/src/column/edit.js | 36 +- packages/block-library/src/columns/block.json | 5 +- .../src/cover/controls.native.js | 11 +- packages/block-library/src/cover/edit.js | 20 +- .../block-library/src/cover/edit.native.js | 44 +- packages/block-library/src/cover/shared.js | 3 +- .../src/cover/test/edit.native.js | 283 + packages/block-library/src/editor.scss | 1 - packages/block-library/src/embed/edit.js | 13 +- .../src/embed/embed-loading.native.js | 8 + .../src/embed/embed-placeholder.native.js | 20 + .../src/embed/variations.native.js | 3 + packages/block-library/src/file/block.json | 7 + packages/block-library/src/file/edit.js | 79 +- packages/block-library/src/file/editor.scss | 25 + packages/block-library/src/file/frontend.js | 6 + packages/block-library/src/file/index.php | 38 + packages/block-library/src/file/inspector.js | 42 +- packages/block-library/src/file/save.js | 29 +- packages/block-library/src/file/style.scss | 4 + .../test/__snapshots__/edit.native.js.snap | 11 +- packages/block-library/src/file/utils.js | 71 + packages/block-library/src/gallery/edit.js | 121 +- packages/block-library/src/heading/block.json | 3 +- packages/block-library/src/image/edit.js | 2 +- .../block-library/src/image/edit.native.js | 25 +- packages/block-library/src/index.js | 2 + packages/block-library/src/index.native.js | 1 + .../block-library/src/latest-posts/block.json | 6 +- .../src/legacy-widget/edit/form.js | 184 +- .../edit/widget-type-selector.js | 3 +- packages/block-library/src/list/block.json | 9 +- packages/block-library/src/list/edit.js | 5 +- .../test/__snapshots__/edit.native.js.snap | 1 - .../block-library/src/navigation-link/edit.js | 35 +- .../navigation-link/fallback-variations.js | 8 +- .../src/navigation-link/index.php | 2 +- .../test/__snapshots__/hooks.js.snap | 4 + .../block-library/src/navigation/block.json | 5 +- packages/block-library/src/navigation/edit.js | 8 +- .../block-library/src/navigation/editor.scss | 1 + .../block-library/src/navigation/style.scss | 17 + .../src/page-list/convert-to-links-modal.js | 124 + packages/block-library/src/page-list/edit.js | 80 +- .../block-library/src/page-list/editor.scss | 14 + .../block-library/src/page-list/index.php | 12 +- .../page-list/test/convert-to-links-modal.js | 399 + .../block-library/src/paragraph/block.json | 8 +- .../block-library/src/post-author/block.json | 5 +- .../src/post-comments-count/block.json | 4 +- .../src/post-comments-form/block.json | 5 +- .../src/post-comments-link/block.json | 23 + .../src/post-comments-link/edit.js | 112 + .../src/post-comments-link/index.js | 21 + .../src/post-comments-link/index.php | 65 + .../src/post-comments/block.json | 10 +- .../block-library/src/post-content/block.json | 5 +- .../block-library/src/post-content/index.php | 8 +- .../block-library/src/post-date/block.json | 5 +- .../block-library/src/post-excerpt/block.json | 5 +- .../src/post-featured-image/block.json | 5 +- .../src/post-hierarchical-terms/block.json | 5 +- .../block-library/src/post-title/block.json | 8 +- .../block-library/src/post-title/style.scss | 3 + .../block-library/src/preformatted/block.json | 3 +- .../block-library/src/pullquote/block.json | 13 +- packages/block-library/src/pullquote/edit.js | 2 +- .../src/query-pagination-next/block.json | 5 +- .../src/query-pagination-numbers/block.json | 5 +- .../src/query-pagination-previous/block.json | 5 +- .../src/query-pagination/block.json | 5 +- packages/block-library/src/query/editor.scss | 2 + packages/block-library/src/quote/block.json | 6 +- packages/block-library/src/quote/edit.js | 5 +- packages/block-library/src/search/block.json | 9 +- .../block-library/src/search/edit.native.js | 43 +- .../src/search/style.native.scss | 17 +- .../test/__snapshots__/edit.native.js.snap | 65 +- .../block-library/src/separator/block.json | 2 +- .../src/separator/separator-settings.js | 2 +- packages/block-library/src/site-logo/edit.js | 10 +- .../block-library/src/site-logo/editor.scss | 4 +- packages/block-library/src/site-logo/index.js | 4 +- .../block-library/src/site-logo/index.php | 8 +- .../block-library/src/site-logo/style.scss | 3 +- .../src/site-title/edit/index.js | 33 +- .../src/site-title/edit/level-toolbar.js | 42 +- .../block-library/src/social-link/block.json | 4 +- .../block-library/src/social-link/index.php | 6 +- .../block-library/src/social-links/block.json | 6 +- .../block-library/src/social-links/edit.js | 15 +- .../src/social-links/editor.scss | 42 +- packages/block-library/src/spacer/block.json | 4 +- packages/block-library/src/style.scss | 1 + packages/block-library/src/table/edit.js | 2 +- .../block-library/src/template-part/index.php | 12 +- .../src/term-description/index.php | 11 +- .../block-library/src/text-columns/block.json | 5 +- packages/block-library/src/verse/block.json | 7 +- packages/block-library/src/verse/editor.scss | 3 - packages/block-library/src/video/edit.js | 17 +- .../block-library/src/video/edit.native.js | 24 +- packages/block-library/src/video/editor.scss | 17 + .../CHANGELOG.md | 8 +- .../CHANGELOG.md | 10 +- .../block-serialization-spec-parser/README.md | 4 +- packages/blocks/README.md | 34 +- packages/blocks/src/api/factory.js | 4 + packages/blocks/src/api/index.js | 1 + .../blocks/src/api/raw-handling/readme.md | 5 +- packages/blocks/src/api/test/utils.js | 89 + packages/blocks/src/api/utils.js | 19 + .../src/block-content-provider/README.md | 3 +- packages/components/CHANGELOG.md | 188 +- packages/components/CONTRIBUTING.md | 6 +- packages/components/package.json | 2 + packages/components/src/CONTRIBUTING.md | 36 +- packages/components/src/README.md | 5 +- .../src/angle-picker-control/README.md | 15 +- packages/components/src/animate/README.md | 30 +- .../components/src/autocomplete/README.md | 76 +- .../components/src/base-control/README.md | 59 +- .../src/box-control/all-input-control.js | 9 +- packages/components/src/box-control/icon.js | 24 +- packages/components/src/box-control/index.js | 28 +- .../src/box-control/input-controls.js | 67 +- .../box-control/styles/box-control-styles.js | 1 + .../components/src/button-group/README.md | 10 +- packages/components/src/button/README.md | 7 + packages/components/src/button/style.scss | 14 +- .../components/src/checkbox-control/README.md | 33 +- .../components/src/clipboard-button/README.md | 3 +- .../components/src/color-indicator/README.md | 4 +- .../components/src/color-palette/README.md | 35 +- .../components/src/color-picker/README.md | 1 + .../components/src/combobox-control/README.md | 78 +- packages/components/src/date-time/README.md | 27 +- packages/components/src/date-time/date.js | 93 +- packages/components/src/date-time/index.js | 5 +- packages/components/src/date-time/style.scss | 34 +- .../src/dimension-control/README.md | 67 +- packages/components/src/disabled/README.md | 12 +- packages/components/src/draggable/index.js | 7 +- packages/components/src/drop-zone/README.md | 48 +- packages/components/src/drop-zone/index.js | 115 +- packages/components/src/drop-zone/provider.js | 262 +- packages/components/src/drop-zone/style.scss | 4 - packages/components/src/dropdown/README.md | 93 +- .../src/focal-point-picker/index.native.js | 4 +- .../tooltip/index.native.js | 2 +- .../components/src/focusable-iframe/README.md | 8 +- .../components/src/font-size-picker/README.md | 29 +- .../components/src/form-file-upload/README.md | 32 +- packages/components/src/form-toggle/README.md | 29 +- .../components/src/form-token-field/README.md | 94 +- packages/components/src/guide/README.md | 29 +- .../components/src/higher-order/README.md | 3 +- .../higher-order/navigate-regions/README.md | 20 +- .../with-constrained-tabbing/README.md | 23 +- .../with-fallback-styles/README.md | 31 +- .../src/higher-order/with-filters/README.md | 13 +- .../higher-order/with-focus-outside/README.md | 6 +- .../higher-order/with-focus-return/README.md | 31 +- .../src/higher-order/with-notices/README.md | 20 +- .../with-spoken-messages/README.md | 21 +- packages/components/src/index.js | 12 +- packages/components/src/index.native.js | 3 + .../src/input-control/input-field.js | 5 +- .../src/isolated-event-container/README.md | 3 +- .../src/keyboard-shortcuts/README.md | 40 +- packages/components/src/menu-group/README.md | 8 +- packages/components/src/menu-item/README.md | 30 +- .../src/menu-items-choice/README.md | 13 +- .../components/src/mobile/badge/README.md | 31 + .../src/mobile/badge/index.native.js | 27 + .../components/src/mobile/badge/style.scss | 15 + .../bottom-sheet-select-control/README.md | 2 +- .../bottom-sheet-navigation/README.md | 71 +- .../src/mobile/bottom-sheet/cell.native.js | 13 +- .../mobile/bottom-sheet/range-cell.native.js | 7 +- .../bottom-sheet/range-text-input.native.js | 5 +- .../bottom-sheet/stepper-cell/index.native.js | 1 - .../mobile/bottom-sheet/sub-sheet/README.md | 11 +- .../bottom-sheet/test/range-cell.native.js | 71 + .../src/mobile/cycle-select-control/README.md | 5 +- .../src/mobile/image/index.native.js | 11 +- .../src/mobile/inserter-button/README.md | 49 +- packages/components/src/modal/README.md | 97 +- .../src/navigable-container/README.md | 42 +- packages/components/src/notice/README.md | 38 +- packages/components/src/panel/README.md | 6 + packages/components/src/panel/row.js | 16 +- packages/components/src/popover/README.md | 71 +- .../components/src/query-controls/README.md | 14 +- .../components/src/radio-control/README.md | 39 +- packages/components/src/radio-group/README.md | 19 +- .../components/src/resizable-box/README.md | 15 +- .../components/src/resizable-box/style.scss | 21 +- .../src/responsive-wrapper/README.md | 10 +- packages/components/src/sandbox/README.md | 6 +- packages/components/src/scroll-lock/README.md | 5 +- .../components/src/select-control/README.md | 115 +- packages/components/src/slot-fill/README.md | 43 +- .../src/slot-fill/bubbles-virtually/fill.js | 14 +- packages/components/src/snackbar/README.md | 24 +- packages/components/src/spinner/README.md | 6 +- .../components/src/style-provider/index.js | 20 + .../src/style-provider/index.native.js | 3 + packages/components/src/tab-panel/README.md | 63 +- .../components/src/text-control/README.md | 76 +- .../components/src/text-highlight/README.md | 9 +- .../components/src/textarea-control/README.md | 37 +- .../components/src/toggle-control/README.md | 35 +- .../components/src/toolbar-button/README.md | 4 +- .../components/src/toolbar-group/README.md | 2 +- .../components/src/toolbar-item/README.md | 4 +- packages/components/src/toolbar/README.md | 12 +- packages/components/src/tooltip/README.md | 20 +- packages/components/src/tree-grid/README.md | 81 +- packages/components/src/tree-select/README.md | 22 +- packages/components/src/ui/card/README.md | 2 +- packages/components/src/ui/heading/README.md | 1 - packages/components/src/ui/styles/test/css.js | 115 - .../components/src/ui/styles/test/styled.js | 100 - packages/components/src/ui/text/README.md | 2 +- packages/components/tsconfig.json | 1 + packages/compose/CHANGELOG.md | 10 +- packages/compose/README.md | 12 +- .../src/higher-order/if-condition/README.md | 9 +- .../higher-order/with-global-events/README.md | 7 +- .../higher-order/with-instance-id/README.md | 9 +- .../higher-order/with-safe-timeout/README.md | 3 +- .../src/higher-order/with-state/README.md | 9 +- .../hooks/use-constrained-tabbing/README.md | 9 +- .../compose/src/hooks/use-dialog/README.md | 25 +- .../compose/src/hooks/use-dragging/README.md | 25 +- .../compose/src/hooks/use-drop-zone/index.js | 181 + .../src/hooks/use-focus-on-mount/README.md | 9 +- .../src/hooks/use-focus-return/README.md | 9 +- .../src/hooks/use-instance-id/README.md | 9 +- packages/compose/src/index.js | 1 + packages/core-data/README.md | 2 +- .../__experimental-fetch-link-suggestions.js | 30 +- .../__experimental-fetch-link-suggestions.js | 8 + packages/core-data/src/locks/README.md | 17 +- packages/core-data/src/resolvers.js | 26 +- packages/core-data/src/selectors.js | 2 +- packages/create-block/CHANGELOG.md | 5 + packages/create-block/README.md | 4 +- .../create-block/lib/init-package-json.js | 2 +- packages/create-block/lib/init-wp-scripts.js | 2 +- packages/create-block/lib/scaffold.js | 4 +- .../lib/templates/es5/.editorconfig.mustache | 7 - .../templates/esnext/.editorconfig.mustache | 7 - packages/customize-widgets/package.json | 8 +- .../block-inspector-button/index.js | 38 + .../block-inspector-button/style.scss | 21 + .../src/components/inserter/style.scss | 2 +- .../inspector/block-inspector-button.js | 15 - .../src/components/inspector/index.js | 122 - .../src/components/inspector/style.scss | 25 - .../src/components/move-to-sidebar/index.js | 49 + .../components/sidebar-block-editor/index.js | 173 +- .../sidebar-block-editor/sidebar-adapter.js | 208 +- .../sidebar-editor-provider.js | 29 + .../use-sidebar-block-editor.js | 239 +- .../src/controls/inserter-outer-section.js | 193 +- .../src/controls/inspector-section.js | 58 + .../src/controls/sidebar-control.js | 85 +- .../src/controls/sidebar-section.js | 90 +- .../customize-widgets/src/filters/index.js | 5 + .../src/filters/move-to-sidebar.js | 108 + .../src/filters/replace-media-upload.js} | 0 packages/customize-widgets/src/index.js | 18 +- packages/customize-widgets/src/style.scss | 2 +- packages/data-controls/CHANGELOG.md | 8 +- packages/data-controls/README.md | 2 +- packages/data/CHANGELOG.md | 2 +- packages/data/README.md | 21 +- .../data/src/components/use-select/index.js | 106 +- packages/data/src/plugins/README.md | 3 +- .../data/src/plugins/persistence/README.md | 3 +- packages/date/CHANGELOG.md | 14 +- packages/deprecated/CHANGELOG.md | 8 +- packages/deprecated/README.md | 8 +- packages/docgen/CHANGELOG.md | 20 +- packages/docgen/README.md | 60 +- packages/docgen/lib/get-jsdoc-from-token.js | 22 +- packages/docgen/lib/get-type-annotation.js | 112 +- packages/docgen/lib/index.js | 2 +- .../default-class-anonymous/exports.json | 22 +- .../fixtures/default-class-named/exports.json | 27 +- .../default-function-anonymous/exports.json | 22 +- .../fixtures/default-function-named/ast.json | 37 +- .../default-function-named/exports.json | 27 +- .../fixtures/default-function-named/ir.json | 2 +- .../test/fixtures/default-identifier/ast.json | 42 +- .../fixtures/default-identifier/exports.json | 12 +- .../fixtures/default-import-default/ast.json | 37 +- .../default-import-default/exports.json | 12 +- .../default-import-default/module-ir.json | 2 +- .../fixtures/default-import-named/ast.json | 42 +- .../default-import-named/exports.json | 12 +- .../default-import-named/module-ir.json | 8 +- .../fixtures/default-named-export/ast.json | 47 +- .../default-named-export/exports.json | 37 +- .../fixtures/default-parse-error/exports.json | 235 +- .../exports.json | 12 +- .../exports.json | 22 +- .../fixtures/default-variable/exports.json | 17 +- .../test/fixtures/named-class/exports.json | 27 +- .../named-default-exported/exports.json | 27 +- .../named-default-exported/module-ir.json | 12 +- .../test/fixtures/named-default/exports.json | 27 +- .../fixtures/named-default/module-ir.json | 12 +- .../test/fixtures/named-function/exports.json | 27 +- .../test/fixtures/named-function/ir.json | 2 +- .../named-identifier-destructuring/ast.json | 92 +- .../exports.json | 22 +- .../test/fixtures/named-identifier/ast.json | 52 +- .../fixtures/named-identifier/exports.json | 22 +- .../named-identifiers-and-inline/ast.json | 137 +- .../named-identifiers-and-inline/exports.json | 72 +- .../test/fixtures/named-identifiers/ast.json | 147 +- .../fixtures/named-identifiers/exports.json | 52 +- .../test/fixtures/named-identifiers/ir.json | 18 +- .../fixtures/named-import-named/exports.json | 57 +- .../fixtures/named-import-namespace/ast.json | 47 +- .../named-import-namespace/exports.json | 22 +- .../module-exports.json | 27 +- .../named-import-namespace/module-ir.json | 8 +- .../test/fixtures/named-variable/exports.json | 32 +- .../fixtures/named-variables/exports.json | 47 +- .../fixtures/namespace-commented/exports.json | 17 +- .../namespace-commented/module-ir.json | 2 +- .../test/fixtures/namespace/exports.json | 12 +- .../test/fixtures/namespace/module-ir.json | 2 +- .../test/fixtures/tags-function/exports.json | 67 +- .../test/fixtures/tags-variable/exports.json | 32 +- .../example.ts | 3 + .../get-node.js | 363 + .../array-destructuring-array-type/example.ts | 3 + .../get-node.js | 281 + .../array-destructuring-tuple-type/example.ts | 3 + .../get-node.js | 380 + .../assignment-pattern/example.ts | 3 + .../assignment-pattern/get-node.js | 233 + .../example.ts | 4 + .../get-node.js | 194 + .../example.ts | 3 + .../get-node.js | 315 + .../test/get-intermediate-representation.js | 29 +- packages/docgen/test/get-type-annotation.js | 156 +- packages/dom-ready/CHANGELOG.md | 8 +- packages/dom/CHANGELOG.md | 14 +- packages/dom/README.md | 26 +- packages/dom/package.json | 1 + .../dom/src/dom/document-has-selection.js | 7 +- .../src/dom/document-has-text-selection.js | 9 +- .../dom/document-has-uncollapsed-selection.js | 3 +- packages/dom/src/dom/get-computed-style.js | 19 +- packages/dom/src/dom/get-offset-parent.js | 13 +- packages/dom/src/dom/get-range-height.js | 1 + packages/dom/src/dom/get-scroll-container.js | 8 +- .../src/dom/hidden-caret-range-from-point.js | 2 +- .../input-field-has-uncollapsed-selection.js | 7 +- packages/dom/src/dom/is-edge.js | 28 +- packages/dom/src/dom/is-entirely-selected.js | 14 +- packages/dom/src/dom/is-html-input-element.js | 9 + packages/dom/src/dom/is-input-or-text-area.js | 9 + packages/dom/src/dom/is-number-input.js | 21 +- packages/dom/src/dom/is-selection-forward.js | 7 + packages/dom/src/dom/is-text-field.js | 23 +- .../src/dom/place-caret-at-horizontal-edge.js | 15 +- .../src/dom/place-caret-at-vertical-edge.js | 5 +- packages/dom/src/dom/remove-invalid-html.js | 4 +- packages/dom/src/dom/replace-tag.js | 6 + packages/dom/src/dom/replace.js | 2 + packages/dom/src/dom/wrap.js | 6 + packages/dom/src/utils/assert-is-defined.ts | 5 +- packages/dom/tsconfig.json | 18 +- packages/e2e-test-utils/src/preview.js | 3 + .../assets/greeting-reusable-block.json | 8 +- .../e2e-tests/config/setup-debug-artifacts.js | 54 - packages/e2e-tests/fixtures/blocks/README.md | 16 +- .../core__4-invalid-starting-letter.json | 20 +- ...ore__4-invalid-starting-letter.parsed.json | 18 +- .../fixtures/blocks/core__archives.json | 22 +- .../blocks/core__archives.parsed.json | 20 +- .../core__archives__showPostCounts.json | 22 +- ...core__archives__showPostCounts.parsed.json | 20 +- .../fixtures/blocks/core__audio.json | 28 +- .../fixtures/blocks/core__audio.parsed.json | 31 +- .../blocks/core__audio__deprecated-1.json | 24 +- .../core__audio__deprecated-1.parsed.json | 27 +- .../fixtures/blocks/core__block.json | 20 +- .../fixtures/blocks/core__block.parsed.json | 27 +- ...re__button__border_radius__deprecated.html | 3 + ...re__button__border_radius__deprecated.json | 27 + ...ton__border_radius__deprecated.parsed.json | 22 + ..._border_radius__deprecated.serialized.html | 5 + .../core__button__center__deprecated.json | 24 +- ...re__button__center__deprecated.parsed.json | 31 +- .../blocks/core__button__squared.html | 2 +- .../blocks/core__button__squared.json | 36 +- .../blocks/core__button__squared.parsed.json | 45 +- .../core__button__squared.serialized.html | 2 +- .../fixtures/blocks/core__buttons.json | 66 +- .../fixtures/blocks/core__buttons.parsed.json | 79 +- .../blocks/core__buttons__deprecated-1.json | 62 +- .../core__buttons__deprecated-1.parsed.json | 77 +- .../fixtures/blocks/core__calendar.json | 16 +- .../blocks/core__calendar.parsed.json | 23 +- .../fixtures/blocks/core__categories.json | 24 +- .../blocks/core__categories.parsed.json | 31 +- .../e2e-tests/fixtures/blocks/core__code.json | 20 +- .../fixtures/blocks/core__code.parsed.json | 27 +- .../fixtures/blocks/core__column.json | 62 +- .../fixtures/blocks/core__column.parsed.json | 73 +- .../blocks/core__column__deprecated-1.json | 66 +- .../core__column__deprecated-1.parsed.json | 77 +- .../fixtures/blocks/core__columns.json | 146 +- .../fixtures/blocks/core__columns.parsed.json | 169 +- .../blocks/core__columns__deprecated.json | 162 +- .../core__columns__deprecated.parsed.json | 137 +- .../fixtures/blocks/core__cover.json | 58 +- .../fixtures/blocks/core__cover.parsed.json | 65 +- .../blocks/core__cover__deprecated-1.json | 56 +- .../core__cover__deprecated-1.parsed.json | 33 +- .../blocks/core__cover__deprecated-2.json | 56 +- .../core__cover__deprecated-2.parsed.json | 33 +- .../blocks/core__cover__deprecated-3.json | 56 +- .../core__cover__deprecated-3.parsed.json | 33 +- .../blocks/core__cover__deprecated-4.json | 70 +- .../core__cover__deprecated-4.parsed.json | 73 +- .../blocks/core__cover__deprecated-5.json | 62 +- .../core__cover__deprecated-5.parsed.json | 65 +- .../blocks/core__cover__deprecated-6.json | 196 +- .../core__cover__deprecated-6.parsed.json | 223 +- .../blocks/core__cover__gradient-image.json | 60 +- .../core__cover__gradient-image.parsed.json | 67 +- .../blocks/core__cover__gradient-video.json | 60 +- .../core__cover__gradient-video.parsed.json | 69 +- .../blocks/core__cover__gradient.json | 58 +- .../blocks/core__cover__gradient.parsed.json | 63 +- .../blocks/core__cover__solid-color.json | 58 +- .../core__cover__solid-color.parsed.json | 63 +- .../blocks/core__cover__video-overlay.json | 60 +- .../core__cover__video-overlay.parsed.json | 69 +- .../fixtures/blocks/core__cover__video.json | 58 +- .../blocks/core__cover__video.parsed.json | 67 +- .../fixtures/blocks/core__embed.json | 28 +- .../fixtures/blocks/core__embed.parsed.json | 31 +- .../blocks/core__file__new-window.json | 31 +- .../blocks/core__file__new-window.parsed.json | 33 +- .../core__file__no-download-button.json | 29 +- ...core__file__no-download-button.parsed.json | 33 +- .../blocks/core__file__no-text-link.json | 27 +- .../core__file__no-text-link.parsed.json | 33 +- .../blocks/core__file__pdf-preview.html | 3 + .../blocks/core__file__pdf-preview.json | 18 + .../core__file__pdf-preview.parsed.json | 15 + .../core__file__pdf-preview.serialized.html | 3 + .../fixtures/blocks/core__freeform.json | 20 +- .../blocks/core__freeform.parsed.json | 27 +- .../blocks/core__freeform__undelimited.json | 20 +- .../core__freeform__undelimited.parsed.json | 18 +- .../blocks/core__gallery-with-caption.json | 58 +- .../core__gallery-with-caption.parsed.json | 37 +- .../fixtures/blocks/core__gallery.json | 58 +- .../fixtures/blocks/core__gallery.parsed.json | 37 +- .../blocks/core__gallery__columns.json | 60 +- .../blocks/core__gallery__columns.parsed.json | 39 +- .../blocks/core__gallery__deprecated-1.json | 46 +- .../core__gallery__deprecated-1.parsed.json | 33 +- .../blocks/core__gallery__deprecated-2.json | 56 +- .../core__gallery__deprecated-2.parsed.json | 33 +- .../blocks/core__gallery__deprecated-3.json | 56 +- .../core__gallery__deprecated-3.parsed.json | 39 +- .../blocks/core__gallery__deprecated-4.json | 76 +- .../core__gallery__deprecated-4.parsed.json | 41 +- .../blocks/core__gallery__deprecated-5.json | 88 +- .../core__gallery__deprecated-5.parsed.json | 41 +- .../fixtures/blocks/core__group.json | 70 +- .../fixtures/blocks/core__group.parsed.json | 79 +- .../blocks/core__group__deprecated-2.json | 46 +- .../core__group__deprecated-2.parsed.json | 55 +- ...re__group__deprecated-inner-container.json | 70 +- ...up__deprecated-inner-container.parsed.json | 79 +- .../blocks/core__group__deprecated.json | 50 +- .../core__group__deprecated.parsed.json | 57 +- .../blocks/core__heading__deprecated-1.json | 24 +- .../core__heading__deprecated-1.parsed.json | 33 +- .../blocks/core__heading__deprecated-2.json | 24 +- .../core__heading__deprecated-2.parsed.json | 31 +- .../blocks/core__heading__deprecated-3.json | 32 +- .../core__heading__deprecated-3.parsed.json | 31 +- .../blocks/core__heading__deprecated-4.json | 26 +- .../core__heading__deprecated-4.parsed.json | 33 +- .../blocks/core__heading__h2-color.json | 24 +- .../core__heading__h2-color.parsed.json | 31 +- .../fixtures/blocks/core__heading__h2.json | 22 +- .../blocks/core__heading__h2.parsed.json | 27 +- .../fixtures/blocks/core__heading__h4-em.json | 22 +- .../blocks/core__heading__h4-em.parsed.json | 31 +- .../blocks/core__heading_align-textalign.json | 26 +- .../core__heading_align-textalign.parsed.json | 33 +- .../e2e-tests/fixtures/blocks/core__html.json | 20 +- .../fixtures/blocks/core__html.parsed.json | 27 +- .../fixtures/blocks/core__image.json | 24 +- .../fixtures/blocks/core__image.parsed.json | 27 +- .../blocks/core__image__attachment-link.json | 28 +- .../core__image__attachment-link.parsed.json | 31 +- .../blocks/core__image__center-caption.json | 26 +- .../core__image__center-caption.parsed.json | 31 +- .../core__image__custom-link-class.json | 30 +- ...core__image__custom-link-class.parsed.json | 31 +- .../blocks/core__image__custom-link-rel.json | 30 +- .../core__image__custom-link-rel.parsed.json | 31 +- .../blocks/core__image__custom-link.json | 28 +- .../core__image__custom-link.parsed.json | 31 +- .../blocks/core__image__deprecated-1.json | 26 +- .../core__image__deprecated-1.parsed.json | 31 +- .../blocks/core__image__deprecated-2.json | 30 +- .../core__image__deprecated-2.parsed.json | 35 +- .../blocks/core__image__deprecated-3.json | 30 +- .../core__image__deprecated-3.parsed.json | 35 +- .../blocks/core__image__media-link.json | 28 +- .../core__image__media-link.parsed.json | 31 +- .../blocks/core__invalid-Capitals.json | 20 +- .../blocks/core__invalid-Capitals.parsed.json | 18 +- .../blocks/core__invalid-special.json | 20 +- .../blocks/core__invalid-special.parsed.json | 18 +- .../blocks/core__latest-comments.json | 26 +- .../blocks/core__latest-comments.parsed.json | 31 +- .../fixtures/blocks/core__latest-posts.json | 48 +- .../blocks/core__latest-posts.parsed.json | 31 +- .../core__latest-posts__displayPostDate.json | 48 +- ..._latest-posts__displayPostDate.parsed.json | 29 +- .../fixtures/blocks/core__list__ul.json | 22 +- .../blocks/core__list__ul.parsed.json | 27 +- .../fixtures/blocks/core__loginout.json | 22 +- .../blocks/core__loginout.parsed.json | 23 +- .../fixtures/blocks/core__media-text.json | 60 +- .../blocks/core__media-text.parsed.json | 61 +- .../core__media-text__image-alt-no-align.json | 60 +- ...media-text__image-alt-no-align.parsed.json | 63 +- ...t__image-fill-no-focal-point-selected.json | 62 +- ...e-fill-no-focal-point-selected.parsed.json | 63 +- ..._image-fill-with-focal-point-selected.json | 70 +- ...fill-with-focal-point-selected.parsed.json | 71 +- ...ore__media-text__is-stacked-on-mobile.json | 60 +- ...dia-text__is-stacked-on-mobile.parsed.json | 63 +- ..._media-text__media-right-custom-width.json | 62 +- ...text__media-right-custom-width.parsed.json | 69 +- ...re__media-text__vertical-align-bottom.json | 62 +- ...ia-text__vertical-align-bottom.parsed.json | 63 +- .../blocks/core__media-text__video.json | 60 +- .../core__media-text__video.parsed.json | 61 +- .../fixtures/blocks/core__missing.json | 24 +- .../fixtures/blocks/core__missing.parsed.json | 33 +- .../e2e-tests/fixtures/blocks/core__more.json | 20 +- .../fixtures/blocks/core__more.parsed.json | 27 +- .../core__more__custom-text-teaser.json | 22 +- ...core__more__custom-text-teaser.parsed.json | 33 +- .../blocks/core__navigation-link.json | 24 +- .../blocks/core__navigation-link.parsed.json | 33 +- .../fixtures/blocks/core__navigation.json | 20 +- .../blocks/core__navigation.parsed.json | 27 +- .../blocks/core__navigation__deprecated.json | 64 +- .../core__navigation__deprecated.parsed.json | 73 +- .../fixtures/blocks/core__nextpage.json | 16 +- .../blocks/core__nextpage.parsed.json | 27 +- .../fixtures/blocks/core__page-list.json | 16 +- .../blocks/core__page-list.parsed.json | 14 +- .../blocks/core__paragraph__align-right.json | 24 +- .../core__paragraph__align-right.parsed.json | 31 +- .../blocks/core__paragraph__deprecated-4.json | 24 +- .../core__paragraph__deprecated-4.parsed.json | 31 +- .../blocks/core__paragraph__deprecated.json | 22 +- .../core__paragraph__deprecated.parsed.json | 27 +- .../fixtures/blocks/core__post-author.json | 22 +- .../blocks/core__post-author.parsed.json | 23 +- .../blocks/core__post-comment-author.json | 16 +- .../core__post-comment-author.parsed.json | 23 +- .../blocks/core__post-comment-content.json | 16 +- .../core__post-comment-content.parsed.json | 23 +- .../blocks/core__post-comment-date.json | 16 +- .../core__post-comment-date.parsed.json | 23 +- .../fixtures/blocks/core__post-comment.json | 16 +- .../blocks/core__post-comment.parsed.json | 27 +- .../blocks/core__post-comments-count.json | 16 +- .../core__post-comments-count.parsed.json | 23 +- .../blocks/core__post-comments-form.json | 16 +- .../core__post-comments-form.parsed.json | 23 +- .../blocks/core__post-comments-link.html | 1 + .../blocks/core__post-comments-link.json | 10 + .../core__post-comments-link.parsed.json | 9 + .../core__post-comments-link.serialized.html | 1 + .../fixtures/blocks/core__post-comments.json | 16 +- .../blocks/core__post-comments.parsed.json | 23 +- .../fixtures/blocks/core__post-content.json | 16 +- .../blocks/core__post-content.parsed.json | 23 +- .../fixtures/blocks/core__post-date.json | 20 +- .../blocks/core__post-date.parsed.json | 23 +- .../fixtures/blocks/core__post-excerpt.json | 22 +- .../blocks/core__post-excerpt.parsed.json | 23 +- .../blocks/core__post-featured-image.json | 20 +- .../core__post-featured-image.parsed.json | 23 +- .../blocks/core__post-hierarchical-terms.json | 16 +- .../core__post-hierarchical-terms.parsed.json | 23 +- .../blocks/core__post-navigation-link.json | 22 +- .../core__post-navigation-link.parsed.json | 27 +- .../fixtures/blocks/core__post-tags.json | 16 +- .../blocks/core__post-tags.parsed.json | 23 +- .../fixtures/blocks/core__post-title.json | 26 +- .../blocks/core__post-title.parsed.json | 23 +- .../fixtures/blocks/core__preformatted.json | 20 +- .../blocks/core__preformatted.parsed.json | 27 +- .../fixtures/blocks/core__pullquote.json | 22 +- .../blocks/core__pullquote.parsed.json | 27 +- .../blocks/core__pullquote__deprecated-1.json | 24 +- .../core__pullquote__deprecated-1.parsed.json | 27 +- .../blocks/core__pullquote__deprecated-2.json | 22 +- .../core__pullquote__deprecated-2.parsed.json | 27 +- .../blocks/core__pullquote__deprecated-3.json | 26 +- .../core__pullquote__deprecated-3.parsed.json | 33 +- .../blocks/core__pullquote__main-color.json | 28 +- .../core__pullquote__main-color.parsed.json | 35 +- .../core__pullquote__multi-paragraph.json | 22 +- ...re__pullquote__multi-paragraph.parsed.json | 27 +- .../fixtures/blocks/core__query-loop.json | 16 +- .../blocks/core__query-loop.parsed.json | 23 +- .../blocks/core__query-pagination-next.json | 16 +- .../core__query-pagination-next.parsed.json | 23 +- .../core__query-pagination-numbers.json | 16 +- ...core__query-pagination-numbers.parsed.json | 23 +- .../core__query-pagination-previous.json | 16 +- ...ore__query-pagination-previous.parsed.json | 23 +- .../blocks/core__query-pagination.json | 16 +- .../blocks/core__query-pagination.parsed.json | 27 +- .../fixtures/blocks/core__query-title.json | 20 +- .../blocks/core__query-title.parsed.json | 23 +- .../fixtures/blocks/core__query.json | 54 +- .../fixtures/blocks/core__query.parsed.json | 23 +- .../blocks/core__quote__deprecated-1.json | 24 +- .../core__quote__deprecated-1.parsed.json | 27 +- .../blocks/core__quote__deprecated-2.json | 24 +- .../core__quote__deprecated-2.parsed.json | 31 +- .../fixtures/blocks/core__quote__style-1.json | 22 +- .../blocks/core__quote__style-1.parsed.json | 27 +- .../fixtures/blocks/core__quote__style-2.json | 24 +- .../blocks/core__quote__style-2.parsed.json | 31 +- .../e2e-tests/fixtures/blocks/core__rss.json | 34 +- .../fixtures/blocks/core__rss.parsed.json | 39 +- .../fixtures/blocks/core__search.json | 26 +- .../fixtures/blocks/core__search.parsed.json | 23 +- .../blocks/core__search__custom-text.json | 30 +- .../core__search__custom-text.parsed.json | 31 +- .../fixtures/blocks/core__separator.json | 16 +- .../blocks/core__separator.parsed.json | 27 +- .../fixtures/blocks/core__shortcode.json | 20 +- .../blocks/core__shortcode.parsed.json | 27 +- .../fixtures/blocks/core__site-logo.json | 16 +- .../blocks/core__site-logo.parsed.json | 23 +- .../fixtures/blocks/core__site-tagline.json | 16 +- .../blocks/core__site-tagline.parsed.json | 23 +- .../fixtures/blocks/core__site-title.json | 20 +- .../blocks/core__site-title.parsed.json | 23 +- .../blocks/core__social-link-amazon.json | 22 +- .../core__social-link-amazon.parsed.json | 27 +- .../blocks/core__social-link-bandcamp.json | 22 +- .../core__social-link-bandcamp.parsed.json | 27 +- .../blocks/core__social-link-behance.json | 22 +- .../core__social-link-behance.parsed.json | 27 +- .../blocks/core__social-link-chain.json | 22 +- .../core__social-link-chain.parsed.json | 27 +- .../blocks/core__social-link-codepen.json | 22 +- .../core__social-link-codepen.parsed.json | 27 +- .../blocks/core__social-link-deviantart.json | 22 +- .../core__social-link-deviantart.parsed.json | 27 +- .../blocks/core__social-link-dribbble.json | 22 +- .../core__social-link-dribbble.parsed.json | 27 +- .../blocks/core__social-link-dropbox.json | 22 +- .../core__social-link-dropbox.parsed.json | 27 +- .../blocks/core__social-link-etsy.json | 22 +- .../blocks/core__social-link-etsy.parsed.json | 27 +- .../blocks/core__social-link-facebook.json | 22 +- .../core__social-link-facebook.parsed.json | 27 +- .../blocks/core__social-link-feed.json | 22 +- .../blocks/core__social-link-feed.parsed.json | 27 +- .../core__social-link-fivehundredpx.json | 22 +- ...ore__social-link-fivehundredpx.parsed.json | 27 +- .../blocks/core__social-link-flickr.json | 22 +- .../core__social-link-flickr.parsed.json | 27 +- .../blocks/core__social-link-foursquare.json | 22 +- .../core__social-link-foursquare.parsed.json | 27 +- .../blocks/core__social-link-github.json | 22 +- .../core__social-link-github.parsed.json | 27 +- .../blocks/core__social-link-goodreads.json | 22 +- .../core__social-link-goodreads.parsed.json | 27 +- .../blocks/core__social-link-google.json | 22 +- .../core__social-link-google.parsed.json | 27 +- .../blocks/core__social-link-instagram.json | 22 +- .../core__social-link-instagram.parsed.json | 27 +- .../blocks/core__social-link-lastfm.json | 22 +- .../core__social-link-lastfm.parsed.json | 27 +- .../blocks/core__social-link-linkedin.json | 22 +- .../core__social-link-linkedin.parsed.json | 27 +- .../blocks/core__social-link-mail.json | 22 +- .../blocks/core__social-link-mail.parsed.json | 27 +- .../blocks/core__social-link-mastodon.json | 22 +- .../core__social-link-mastodon.parsed.json | 27 +- .../blocks/core__social-link-medium.json | 22 +- .../core__social-link-medium.parsed.json | 27 +- .../blocks/core__social-link-meetup.json | 22 +- .../core__social-link-meetup.parsed.json | 27 +- .../blocks/core__social-link-pinterest.json | 22 +- .../core__social-link-pinterest.parsed.json | 27 +- .../blocks/core__social-link-pocket.json | 22 +- .../core__social-link-pocket.parsed.json | 27 +- .../blocks/core__social-link-reddit.json | 22 +- .../core__social-link-reddit.parsed.json | 27 +- .../blocks/core__social-link-skype.json | 22 +- .../core__social-link-skype.parsed.json | 27 +- .../blocks/core__social-link-snapchat.json | 22 +- .../core__social-link-snapchat.parsed.json | 27 +- .../blocks/core__social-link-soundcloud.json | 22 +- .../core__social-link-soundcloud.parsed.json | 27 +- .../blocks/core__social-link-spotify.json | 22 +- .../core__social-link-spotify.parsed.json | 27 +- .../blocks/core__social-link-tumblr.json | 22 +- .../core__social-link-tumblr.parsed.json | 27 +- .../blocks/core__social-link-twitch.json | 22 +- .../core__social-link-twitch.parsed.json | 27 +- .../blocks/core__social-link-twitter.json | 22 +- .../core__social-link-twitter.parsed.json | 27 +- .../blocks/core__social-link-vimeo.json | 22 +- .../core__social-link-vimeo.parsed.json | 27 +- .../fixtures/blocks/core__social-link-vk.json | 22 +- .../blocks/core__social-link-vk.parsed.json | 27 +- .../blocks/core__social-link-wordpress.json | 22 +- .../core__social-link-wordpress.parsed.json | 27 +- .../blocks/core__social-link-yelp.json | 22 +- .../blocks/core__social-link-yelp.parsed.json | 27 +- .../blocks/core__social-link-youtube.json | 22 +- .../core__social-link-youtube.parsed.json | 27 +- .../fixtures/blocks/core__social-link.json | 22 +- .../blocks/core__social-link.parsed.json | 29 +- .../fixtures/blocks/core__social-links.json | 44 +- .../blocks/core__social-links.parsed.json | 53 +- .../fixtures/blocks/core__spacer.json | 20 +- .../fixtures/blocks/core__spacer.parsed.json | 27 +- .../blocks/core__spacer__horizontal.json | 22 +- .../core__spacer__horizontal.parsed.json | 24 +- .../fixtures/blocks/core__table.json | 288 +- .../fixtures/blocks/core__table.parsed.json | 27 +- .../fixtures/blocks/core__table__caption.json | 288 +- .../blocks/core__table__caption.parsed.json | 27 +- .../blocks/core__table__deprecated-1.json | 286 +- .../core__table__deprecated-1.parsed.json | 27 +- .../blocks/core__table__scope-attribute.json | 294 +- .../core__table__scope-attribute.parsed.json | 27 +- .../fixtures/blocks/core__tag-cloud.json | 22 +- .../blocks/core__tag-cloud.parsed.json | 18 +- .../core__tag-cloud__showTagCounts.json | 22 +- ...core__tag-cloud__showTagCounts.parsed.json | 20 +- .../fixtures/blocks/core__template-part.json | 22 +- .../blocks/core__template-part.parsed.json | 20 +- .../blocks/core__term-description.json | 20 +- .../blocks/core__term-description.parsed.json | 27 +- .../fixtures/blocks/core__text-columns.json | 38 +- .../blocks/core__text-columns.parsed.json | 31 +- .../core__text__converts-to-paragraph.json | 22 +- ...e__text__converts-to-paragraph.parsed.json | 27 +- .../fixtures/blocks/core__verse.json | 20 +- .../fixtures/blocks/core__verse.parsed.json | 27 +- .../blocks/core__verse__deprecated.json | 22 +- .../core__verse__deprecated.parsed.json | 31 +- .../fixtures/blocks/core__video.json | 36 +- .../fixtures/blocks/core__video.parsed.json | 27 +- .../core_buttons__simple__deprecated.json | 62 +- ...re_buttons__simple__deprecated.parsed.json | 73 +- packages/e2e-tests/fixtures/utils.js | 9 +- packages/e2e-tests/jest.config.js | 1 - .../specs/editor/blocks/heading.test.js | 2 +- .../adding-patterns.test.js.snap | 8 +- .../editor/various/draggable-block.test.js | 4 +- .../editor/various/post-visibility.test.js | 2 +- .../post-editor-template-mode.test.js.snap | 21 + .../__snapshots__/navigation.test.js.snap | 4 +- .../experiments/document-settings.test.js | 5 +- .../fixtures/menu-items-response-fixture.json | 2616 +- .../experiments/multi-entity-editing.test.js | 3 +- .../post-editor-template-mode.test.js | 97 +- .../specs/experiments/template-part.test.js | 3 +- .../specs/widgets/adding-widgets.test.js | 72 +- packages/edit-navigation/README.md | 49 +- .../inspector-additions/manage-locations.js | 58 +- .../components/inspector-additions/style.scss | 2 + .../src/components/layout/index.js | 227 +- packages/edit-post/package.json | 4 +- .../src/components/browser-url/README.md | 3 +- .../edit-post/src/components/header/index.js | 54 +- .../header/template-save-button/index.js | 49 - .../components/header/template-title/index.js | 22 +- .../components/keyboard-shortcuts/index.js | 28 +- .../edit-post/src/components/layout/index.js | 9 +- .../src/components/layout/style.scss | 2 +- .../src/components/preferences-modal/index.js | 6 + .../test/__snapshots__/index.js.snap | 4 +- .../sidebar/page-attributes/index.js | 55 +- .../components/sidebar/post-schedule/index.js | 6 +- .../sidebar/post-schedule/style.scss | 6 + .../components/sidebar/post-status/index.js | 2 - .../components/sidebar/post-template/index.js | 95 - .../sidebar/post-template/style.scss | 13 - .../sidebar/settings-header/index.js | 59 +- .../sidebar/settings-sidebar/index.js | 65 +- .../sidebar/template-summary/index.js | 41 + .../sidebar/template-summary/style.scss | 4 + .../components/sidebar/template/actions.js | 132 + .../src/components/sidebar/template/index.js | 114 + .../components/sidebar/template/style.scss | 9 + .../src/components/visual-editor/index.js | 107 +- .../src/components/visual-editor/style.scss | 12 + packages/edit-post/src/editor.js | 67 +- packages/edit-post/src/editor.native.js | 24 +- packages/edit-post/src/store/actions.js | 42 + packages/edit-post/src/store/selectors.js | 31 +- packages/edit-post/src/style.scss | 3 +- packages/edit-site/CHANGELOG.md | 2 +- packages/edit-site/README.md | 1 - .../src/components/block-editor/index.js | 24 +- .../edit-site/src/components/editor/index.js | 194 +- .../edit-site/src/components/editor/utils.js | 12 +- .../header/document-actions/index.js | 12 +- .../edit-site/src/components/header/index.js | 6 +- .../src/components/save-button/index.js | 9 +- .../src/components/sidebar/border-panel.js | 147 + .../sidebar/global-styles-sidebar.js | 9 + .../components/sidebar/typography-panel.js | 10 +- .../convert-to-template-part.js | 75 +- .../template-part-converter/style.scss | 71 + packages/edit-widgets/CHANGELOG.md | 2 +- packages/edit-widgets/README.md | 6 +- .../src/components/header/index.js | 4 +- .../src/components/header/undo-redo/redo.js | 11 +- .../src/components/header/undo-redo/undo.js | 11 +- .../components/move-to-widget-area/index.js | 51 + .../index.js | 28 +- packages/edit-widgets/src/filters/index.js | 5 + .../src/filters/move-to-widget-area.js | 63 + .../src/filters/replace-media-upload.js | 13 + packages/edit-widgets/src/hooks/index.js | 4 - packages/edit-widgets/src/index.js | 2 +- .../src/register-legacy-widget-variations.js | 3 +- packages/edit-widgets/src/store/actions.js | 57 + .../edit-widgets/src/store/transformers.js | 3 +- packages/edit-widgets/src/store/utils.js | 1 + packages/editor/src/components/README.md | 6 +- .../src/components/autocompleters/README.md | 3 +- .../components/entities-saved-states/index.js | 15 +- packages/editor/src/components/index.js | 2 +- .../local-autosave-monitor/README.md | 6 +- .../local-autosave-monitor/index.js | 8 +- .../src/components/page-attributes/check.js | 36 +- .../src/components/page-attributes/style.scss | 8 - .../components/page-attributes/template.js | 57 - .../components/page-attributes/test/check.js | 79 - .../components/post-featured-image/README.md | 62 +- .../post-publish-panel/prepublish.js | 6 +- .../src/components/post-schedule/index.js | 81 +- .../src/components/post-taxonomies/README.md | 22 +- .../src/components/post-template/index.js | 65 + .../post-type-support-check/README.md | 11 +- packages/editor/src/store/selectors.js | 25 +- .../editor/src/store/test/actions.native.js | 2 +- .../editor/src/store/test/reducer.native.js | 2 +- packages/editor/src/store/test/selectors.js | 40 + .../src/store/utils/get-template-part-icon.js | 19 + packages/element/CHANGELOG.md | 4 +- packages/element/README.md | 29 +- packages/env/CHANGELOG.md | 7 + packages/env/README.md | 4 +- .../env/lib/build-docker-compose-config.js | 4 +- packages/env/lib/cli.js | 12 +- packages/env/lib/commands/destroy.js | 43 +- packages/env/lib/commands/logs.js | 2 - packages/env/lib/commands/start.js | 23 +- packages/env/lib/config/config.js | 3 +- .../config/test/__snapshots__/config.js.snap | 4 + packages/env/lib/config/test/config.js | 2 + packages/env/lib/init-config.js | 55 +- packages/env/lib/wordpress.js | 52 - .../env/test/build-docker-compose-config.js | 31 + packages/env/test/cli.js | 4 - packages/escape-html/CHANGELOG.md | 6 +- packages/eslint-plugin/CHANGELOG.md | 4 +- packages/eslint-plugin/README.md | 2 +- .../docs/rules/dependency-group.md | 2 +- .../docs/rules/gutenberg-phase.md | 7 +- .../eslint-plugin/docs/rules/i18n-ellipsis.md | 1 - .../rules/i18n-no-collapsible-whitespace.md | 6 +- .../docs/rules/i18n-no-variables.md | 2 +- .../docs/rules/i18n-text-domain.md | 2 +- .../docs/rules/i18n-translator-comments.md | 7 +- .../no-base-control-with-label-without-id.md | 31 +- .../rules/no-unused-vars-before-return.md | 2 +- .../docs/rules/react-no-unsafe-timeout.md | 2 +- packages/format-library/CHANGELOG.md | 10 +- packages/hooks/CHANGELOG.md | 20 +- packages/hooks/README.md | 46 +- packages/html-entities/CHANGELOG.md | 4 +- packages/i18n/CHANGELOG.md | 38 +- packages/i18n/README.md | 14 + packages/i18n/src/create-i18n.js | 46 +- packages/i18n/src/default-i18n.js | 11 + packages/i18n/src/index.js | 1 + packages/i18n/src/test/create-i18n.js | 80 + packages/i18n/tsconfig.json | 6 +- packages/icons/README.md | 9 +- packages/icons/src/index.js | 1 + packages/icons/src/library/crop.js | 2 +- packages/icons/src/library/move-to.js | 12 + packages/icons/src/library/overlay-text.js | 2 +- packages/interface/README.md | 22 +- .../README.md | 26 +- .../complementary-area-toggle/README.md | 27 +- .../src/components/pinned-items/README.md | 20 +- packages/is-shallow-equal/CHANGELOG.md | 26 +- packages/is-shallow-equal/README.md | 61 +- packages/keycodes/README.md | 2 +- packages/list-reusable-blocks/CHANGELOG.md | 2 +- packages/media-utils/CHANGELOG.md | 2 +- packages/media-utils/README.md | 15 +- packages/notices/README.md | 4 +- packages/nux/README.md | 6 +- packages/nux/src/components/dot-tip/README.md | 13 +- packages/postcss-plugins-preset/CHANGELOG.md | 5 + packages/postcss-plugins-preset/package.json | 4 +- packages/postcss-themes/CHANGELOG.md | 4 + packages/postcss-themes/package.json | 4 +- packages/primitives/CHANGELOG.md | 2 +- packages/primitives/README.md | 9 +- .../primitives/src/block-quotation/README.md | 4 +- .../primitives/src/horizontal-rule/README.md | 4 +- packages/primitives/src/svg/README.md | 5 +- packages/priority-queue/CHANGELOG.md | 4 +- .../CHANGELOG.md | 8 +- .../project-management-automation/README.md | 21 +- .../lib/tasks/add-milestone/README.md | 3 +- .../lib/tasks/assign-fixed-issues/README.md | 3 +- .../README.md | 3 +- .../first-time-contributor-label/README.md | 3 +- packages/react-native-aztec/CHANGELOG.md | 5 +- packages/react-native-aztec/README.md | 151 +- .../ios/RNTAztecView/RCTAztecView.swift | 1 + packages/react-native-aztec/package.json | 2 +- packages/react-native-bridge/CHANGELOG.md | 3 +- packages/react-native-bridge/README.md | 22 +- .../android/react-native-bridge/build.gradle | 2 +- .../main/assets/gutenberg-web-single-block | 2 +- .../GutenbergBridgeJS2Parent.java | 4 + .../RNReactNativeGutenbergBridgeModule.java | 2 + .../WPAndroidGlue/DeferredEventEmitter.java | 12 +- .../mobile/WPAndroidGlue/GutenbergProps.kt | 3 + .../WPAndroidGlue/WPAndroidGlueCode.java | 4 + .../local-storage-overrides.json | 50 +- packages/react-native-bridge/index.js | 9 + .../react-native-bridge/ios/Gutenberg.swift | 2 +- packages/react-native-bridge/package.json | 2 +- packages/react-native-editor/CHANGELOG.md | 19 +- .../__device-tests__/CONTRIBUTING.md | 32 +- .../__device-tests__/README.md | 46 +- .../gutenberg-editor-cover.test.js | 57 + .../gutenberg-editor-gallery.test.js | 3 + .../gutenberg-editor-image-@canary.test.js | 3 + .../__device-tests__/pages/editor-page.js | 11 + packages/react-native-editor/app.json | 4 +- .../AppIcon.appiconset/Contents.json | 104 +- .../Images.xcassets/Contents.json | 10 +- .../aztec.imageset/Contents.json | 40 +- packages/react-native-editor/ios/Podfile.lock | 8 +- packages/react-native-editor/package.json | 2 +- packages/react-native-editor/src/index.js | 2 + packages/redux-routine/CHANGELOG.md | 20 +- packages/reusable-blocks/README.md | 110 +- .../rich-text/src/component/index.native.js | 2 +- packages/scripts/CHANGELOG.md | 19 + packages/scripts/README.md | 18 +- packages/scripts/config/jest-e2e.config.js | 1 + .../jest-environment-puppeteer/index.js | 42 +- packages/scripts/config/webpack.config.js | 13 +- packages/scripts/package.json | 16 +- packages/scripts/scripts/format-js.js | 136 +- packages/scripts/scripts/format.js | 116 + packages/server-side-render/CHANGELOG.md | 11 +- packages/server-side-render/README.md | 45 +- packages/shortcode/CHANGELOG.md | 4 +- packages/token-list/CHANGELOG.md | 8 +- packages/token-list/README.md | 10 +- packages/url/CHANGELOG.md | 2 +- packages/url/src/test/fixtures/wpt-data.json | 293 +- packages/warning/CHANGELOG.md | 2 +- packages/wordcount/CHANGELOG.md | 16 +- phpunit/block-editor-test.php | 318 + phpunit/class-block-templates-test.php | 24 +- ...lass-rest-widget-types-controller-test.php | 22 +- .../class-rest-widgets-controller-test.php | 273 +- ...class-wp-rest-template-controller-test.php | 6 +- ...ass-wp-theme-json-legacy-settings-test.php | 202 - phpunit/class-wp-theme-json-resolver-test.php | 14 + .../class-wp-theme-json-schema-v0-test.php | 156 + phpunit/class-wp-theme-json-test.php | 288 +- phpunit/fixtures/block.json | 13 +- .../pattern-directory/browse-all.json | 51 +- .../pattern-directory/browse-category-2.json | 35 +- .../pattern-directory/browse-keyword-11.json | 51 +- .../pattern-directory/search-button.json | 67 +- readme.txt | 2 +- storybook/README.md | 4 +- storybook/stories/playground/index.js | 48 +- storybook/webpack.config.js | 6 +- .../full-content/full-content.test.js | 13 +- test/native/setup.js | 40 +- webpack.config.js | 115 +- 1364 files changed, 62008 insertions(+), 49442 deletions(-) create mode 100644 docs/reference-guides/block-api/block-api-versions.md delete mode 100644 docs/reference-guides/block-api/versions.md create mode 100644 lib/block-editor.php create mode 100644 lib/block-patterns/heading.php create mode 100644 lib/block-patterns/large-header-left.php create mode 100644 lib/block-patterns/large-header-text-button.php create mode 100644 lib/block-patterns/media-text-arquitecture.php create mode 100644 lib/block-patterns/media-text-art.php create mode 100644 lib/block-patterns/media-text-nature.php create mode 100644 lib/block-patterns/quote.php create mode 100644 lib/block-patterns/text-two-columns-title-offset.php create mode 100644 lib/block-patterns/text-two-columns-title.php create mode 100644 lib/block-patterns/text-two-columns.php create mode 100644 lib/block-patterns/three-columns-media-text.php create mode 100644 lib/block-patterns/three-columns-text.php create mode 100644 lib/block-patterns/three-images-gallery.php create mode 100644 lib/block-patterns/two-buttons.php create mode 100644 lib/block-patterns/two-images-gallery.php create mode 100644 lib/class-wp-theme-json-schema-v0.php create mode 100644 lib/interface-wp-theme-json-schema.php create mode 100644 packages/block-editor/src/components/block-list/use-block-props/use-scroll-into-view.js create mode 100644 packages/block-editor/src/components/block-switcher/pattern-transformations-menu.js create mode 100644 packages/block-editor/src/components/block-switcher/test/use-transformed.patterns.js create mode 100644 packages/block-editor/src/components/block-switcher/test/utils.js create mode 100644 packages/block-editor/src/components/block-switcher/use-transformed-patterns.js create mode 100644 packages/block-editor/src/components/block-switcher/utils.js create mode 100644 packages/block-editor/src/components/border-style-control/index.js create mode 100644 packages/block-editor/src/components/border-style-control/style.scss delete mode 100644 packages/block-editor/src/components/writing-flow/focus-capture.js create mode 100644 packages/block-editor/src/hooks/border-color.js create mode 100644 packages/block-editor/src/hooks/border-style.js create mode 100644 packages/block-editor/src/hooks/border-width.js create mode 100644 packages/block-editor/src/hooks/use-color-props.js delete mode 100644 packages/block-library/src/button/color-props.js create mode 100644 packages/block-library/src/cover/test/edit.native.js create mode 100644 packages/block-library/src/embed/embed-loading.native.js create mode 100644 packages/block-library/src/embed/embed-placeholder.native.js create mode 100644 packages/block-library/src/embed/variations.native.js create mode 100644 packages/block-library/src/file/frontend.js create mode 100644 packages/block-library/src/file/index.php create mode 100644 packages/block-library/src/file/utils.js create mode 100644 packages/block-library/src/page-list/convert-to-links-modal.js create mode 100644 packages/block-library/src/page-list/test/convert-to-links-modal.js create mode 100644 packages/block-library/src/post-comments-link/block.json create mode 100644 packages/block-library/src/post-comments-link/edit.js create mode 100644 packages/block-library/src/post-comments-link/index.js create mode 100644 packages/block-library/src/post-comments-link/index.php create mode 100644 packages/block-library/src/post-title/style.scss delete mode 100644 packages/block-library/src/verse/editor.scss create mode 100644 packages/components/src/mobile/badge/README.md create mode 100644 packages/components/src/mobile/badge/index.native.js create mode 100644 packages/components/src/mobile/badge/style.scss create mode 100644 packages/components/src/mobile/bottom-sheet/test/range-cell.native.js create mode 100644 packages/components/src/style-provider/index.js create mode 100644 packages/components/src/style-provider/index.native.js delete mode 100644 packages/components/src/ui/styles/test/css.js delete mode 100644 packages/components/src/ui/styles/test/styled.js create mode 100644 packages/compose/src/hooks/use-drop-zone/index.js create mode 100644 packages/customize-widgets/src/components/block-inspector-button/index.js create mode 100644 packages/customize-widgets/src/components/block-inspector-button/style.scss delete mode 100644 packages/customize-widgets/src/components/inspector/block-inspector-button.js delete mode 100644 packages/customize-widgets/src/components/inspector/index.js delete mode 100644 packages/customize-widgets/src/components/inspector/style.scss create mode 100644 packages/customize-widgets/src/components/move-to-sidebar/index.js create mode 100644 packages/customize-widgets/src/components/sidebar-block-editor/sidebar-editor-provider.js create mode 100644 packages/customize-widgets/src/controls/inspector-section.js create mode 100644 packages/customize-widgets/src/filters/index.js create mode 100644 packages/customize-widgets/src/filters/move-to-sidebar.js rename packages/{edit-widgets/src/hooks/components/index.js => customize-widgets/src/filters/replace-media-upload.js} (100%) create mode 100644 packages/docgen/test/fixtures/type-annotations/array-destructuring-any-other-type/example.ts create mode 100644 packages/docgen/test/fixtures/type-annotations/array-destructuring-any-other-type/get-node.js create mode 100644 packages/docgen/test/fixtures/type-annotations/array-destructuring-array-type/example.ts create mode 100644 packages/docgen/test/fixtures/type-annotations/array-destructuring-array-type/get-node.js create mode 100644 packages/docgen/test/fixtures/type-annotations/array-destructuring-tuple-type/example.ts create mode 100644 packages/docgen/test/fixtures/type-annotations/array-destructuring-tuple-type/get-node.js create mode 100644 packages/docgen/test/fixtures/type-annotations/assignment-pattern/example.ts create mode 100644 packages/docgen/test/fixtures/type-annotations/assignment-pattern/get-node.js create mode 100644 packages/docgen/test/fixtures/type-annotations/exported-variable-declaration-statics/example.ts create mode 100644 packages/docgen/test/fixtures/type-annotations/exported-variable-declaration-statics/get-node.js create mode 100644 packages/docgen/test/fixtures/type-annotations/object-destructuring-object-literal-type/example.ts create mode 100644 packages/docgen/test/fixtures/type-annotations/object-destructuring-object-literal-type/get-node.js create mode 100644 packages/dom/src/dom/is-html-input-element.js create mode 100644 packages/dom/src/dom/is-input-or-text-area.js delete mode 100644 packages/e2e-tests/config/setup-debug-artifacts.js create mode 100644 packages/e2e-tests/fixtures/blocks/core__button__border_radius__deprecated.html create mode 100644 packages/e2e-tests/fixtures/blocks/core__button__border_radius__deprecated.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__button__border_radius__deprecated.parsed.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__button__border_radius__deprecated.serialized.html create mode 100644 packages/e2e-tests/fixtures/blocks/core__file__pdf-preview.html create mode 100644 packages/e2e-tests/fixtures/blocks/core__file__pdf-preview.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__file__pdf-preview.parsed.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__file__pdf-preview.serialized.html create mode 100644 packages/e2e-tests/fixtures/blocks/core__post-comments-link.html create mode 100644 packages/e2e-tests/fixtures/blocks/core__post-comments-link.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__post-comments-link.parsed.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__post-comments-link.serialized.html create mode 100644 packages/e2e-tests/specs/experiments/__snapshots__/post-editor-template-mode.test.js.snap delete mode 100644 packages/edit-post/src/components/header/template-save-button/index.js delete mode 100644 packages/edit-post/src/components/sidebar/post-template/index.js delete mode 100644 packages/edit-post/src/components/sidebar/post-template/style.scss create mode 100644 packages/edit-post/src/components/sidebar/template-summary/index.js create mode 100644 packages/edit-post/src/components/sidebar/template-summary/style.scss create mode 100644 packages/edit-post/src/components/sidebar/template/actions.js create mode 100644 packages/edit-post/src/components/sidebar/template/index.js create mode 100644 packages/edit-post/src/components/sidebar/template/style.scss create mode 100644 packages/edit-site/src/components/sidebar/border-panel.js create mode 100644 packages/edit-widgets/src/components/move-to-widget-area/index.js create mode 100644 packages/edit-widgets/src/filters/index.js create mode 100644 packages/edit-widgets/src/filters/move-to-widget-area.js create mode 100644 packages/edit-widgets/src/filters/replace-media-upload.js delete mode 100644 packages/edit-widgets/src/hooks/index.js delete mode 100644 packages/editor/src/components/page-attributes/template.js delete mode 100644 packages/editor/src/components/page-attributes/test/check.js create mode 100644 packages/editor/src/components/post-template/index.js create mode 100644 packages/editor/src/store/utils/get-template-part-icon.js create mode 100644 packages/icons/src/library/move-to.js create mode 100644 packages/scripts/scripts/format.js create mode 100644 phpunit/block-editor-test.php delete mode 100644 phpunit/class-wp-theme-json-legacy-settings-test.php create mode 100644 phpunit/class-wp-theme-json-schema-v0-test.php diff --git a/.editorconfig b/.editorconfig index 2f3fbe64be9f7d..0cdfc80277e889 100644 --- a/.editorconfig +++ b/.editorconfig @@ -13,13 +13,6 @@ insert_final_newline = true trim_trailing_whitespace = true indent_style = tab -[*.yml] -indent_style = space -indent_size = 2 - -[*.md] -trim_trailing_whitespace = false - [*.{gradle,java,kt}] indent_style = space diff --git a/.eslintrc.js b/.eslintrc.js index 1b6aab088e87ac..bac9e84341434e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -204,7 +204,7 @@ module.exports = { }, }, { - files: [ 'bin/**/*.js' ], + files: [ 'bin/**/*.js', 'packages/env/**' ], rules: { 'no-console': 'off', }, diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 75b32fa346231d..45bad9c0612a1a 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,5 +1,7 @@ + + ## Description diff --git a/.github/workflows/build-plugin-zip.yml b/.github/workflows/build-plugin-zip.yml index 19cf5ca106a040..e2707e81f5d7cb 100644 --- a/.github/workflows/build-plugin-zip.yml +++ b/.github/workflows/build-plugin-zip.yml @@ -92,6 +92,7 @@ jobs: - name: Cherry-pick to trunk run: | git checkout trunk + git pull TRUNK_VERSION=$(jq --raw-output '.version' package.json) if [[ ${{ steps.get_version.outputs.old_version }} == "$TRUNK_VERSION" ]]; then git cherry-pick "${{ steps.get_version.outputs.release_branch }}" @@ -112,7 +113,7 @@ jobs: - name: Use Node.js 14.x uses: actions/setup-node@46071b5c7a2e0c34e49c3cb8a0e792e86e18d5ea # v2.1.5 with: - node-version: 14.x + node-version: 14.x - name: Cache node modules uses: actions/cache@26968a09c0ea4f3e233fdddbafd1166051a095f6 # v2.1.4 diff --git a/.github/workflows/bundle-size.yml b/.github/workflows/bundle-size.yml index 16a32deba10e3d..f6111b9fb49324 100644 --- a/.github/workflows/bundle-size.yml +++ b/.github/workflows/bundle-size.yml @@ -15,7 +15,7 @@ jobs: - name: Use Node.js 14.x uses: actions/setup-node@46071b5c7a2e0c34e49c3cb8a0e792e86e18d5ea # v2.1.5 with: - node-version: 14.x + node-version: 14.x - uses: preactjs/compressed-size-action@7d87f60a6b0c7d193b8183ce859ed00b356ea92f # v2.1.0 with: diff --git a/.github/workflows/create-block.yml b/.github/workflows/create-block.yml index 167dcd061c0a84..435c418a86139a 100644 --- a/.github/workflows/create-block.yml +++ b/.github/workflows/create-block.yml @@ -20,7 +20,7 @@ jobs: - name: Use Node.js ${{ matrix.node }}.x uses: actions/setup-node@46071b5c7a2e0c34e49c3cb8a0e792e86e18d5ea # v2.1.5 with: - node-version: ${{ matrix.node }} + node-version: ${{ matrix.node }} - name: Cache node modules uses: actions/cache@26968a09c0ea4f3e233fdddbafd1166051a095f6 # v2.1.4 diff --git a/.github/workflows/end2end-test.yml b/.github/workflows/end2end-test.yml index 2d7cc32f96ddef..9552175c283ff6 100644 --- a/.github/workflows/end2end-test.yml +++ b/.github/workflows/end2end-test.yml @@ -24,7 +24,7 @@ jobs: - name: Use Node.js 14.x uses: actions/setup-node@46071b5c7a2e0c34e49c3cb8a0e792e86e18d5ea # v2.1.5 with: - node-version: 14.x + node-version: 14.x - name: Cache node modules uses: actions/cache@26968a09c0ea4f3e233fdddbafd1166051a095f6 # v2.1.4 @@ -42,7 +42,6 @@ jobs: - name: Install WordPress run: | - chmod -R 767 ./ # TODO: Possibly integrate in wp-env npm run wp-env start - name: Running the tests diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml index c9d068b53f3765..f438981e6125fa 100644 --- a/.github/workflows/performance.yml +++ b/.github/workflows/performance.yml @@ -3,7 +3,7 @@ name: Performances Tests on: pull_request: release: - types: [created] + types: [published] jobs: performance: @@ -17,7 +17,7 @@ jobs: - name: Use Node.js 14.x uses: actions/setup-node@46071b5c7a2e0c34e49c3cb8a0e792e86e18d5ea # v2.1.5 with: - node-version: 14.x + node-version: 14.x - name: Cache node modules uses: actions/cache@26968a09c0ea4f3e233fdddbafd1166051a095f6 # v2.1.4 diff --git a/.github/workflows/pull-request-automation.yml b/.github/workflows/pull-request-automation.yml index 46274e7b414484..6c84669f3e3905 100644 --- a/.github/workflows/pull-request-automation.yml +++ b/.github/workflows/pull-request-automation.yml @@ -17,7 +17,7 @@ jobs: - name: Use Node.js 14.x uses: actions/setup-node@46071b5c7a2e0c34e49c3cb8a0e792e86e18d5ea # v2.1.5 with: - node-version: 14.x + node-version: 14.x # Changing into the action's directory and running `npm install` is much # faster than a full project-wide `npm ci`. diff --git a/.github/workflows/rnmobile-android-runner.yml b/.github/workflows/rnmobile-android-runner.yml index a247dc6aa35d7d..6fa1009201bc6b 100644 --- a/.github/workflows/rnmobile-android-runner.yml +++ b/.github/workflows/rnmobile-android-runner.yml @@ -19,7 +19,7 @@ jobs: - name: Use Node.js 14.x uses: actions/setup-node@46071b5c7a2e0c34e49c3cb8a0e792e86e18d5ea # v2.1.5 with: - node-version: 14.x + node-version: 14.x - name: Restore npm cache uses: actions/cache@26968a09c0ea4f3e233fdddbafd1166051a095f6 # v2.1.4 diff --git a/.github/workflows/rnmobile-ios-runner.yml b/.github/workflows/rnmobile-ios-runner.yml index 56503aa72edf71..36584173a0ccad 100644 --- a/.github/workflows/rnmobile-ios-runner.yml +++ b/.github/workflows/rnmobile-ios-runner.yml @@ -19,7 +19,7 @@ jobs: - name: Use Node.js 14.x uses: actions/setup-node@46071b5c7a2e0c34e49c3cb8a0e792e86e18d5ea # v2.1.5 with: - node-version: 14.x + node-version: 14.x - name: Restore npm cache uses: actions/cache@26968a09c0ea4f3e233fdddbafd1166051a095f6 # v2.1.4 diff --git a/.github/workflows/static-checks.yml b/.github/workflows/static-checks.yml index 26c56de20ac881..ba66847963df72 100644 --- a/.github/workflows/static-checks.yml +++ b/.github/workflows/static-checks.yml @@ -19,7 +19,7 @@ jobs: - name: Use Node.js 14.x uses: actions/setup-node@46071b5c7a2e0c34e49c3cb8a0e792e86e18d5ea # v2.1.5 with: - node-version: 14.x + node-version: 14.x - name: Cache node modules uses: actions/cache@26968a09c0ea4f3e233fdddbafd1166051a095f6 # v2.1.4 diff --git a/.github/workflows/storybook-pages.yml b/.github/workflows/storybook-pages.yml index 5d9de94c4267b5..50eb5351225bf8 100644 --- a/.github/workflows/storybook-pages.yml +++ b/.github/workflows/storybook-pages.yml @@ -17,7 +17,7 @@ jobs: - name: Use Node.js 14.x uses: actions/setup-node@46071b5c7a2e0c34e49c3cb8a0e792e86e18d5ea # v2.1.5 with: - node-version: 14.x + node-version: 14.x - name: Cache node modules uses: actions/cache@26968a09c0ea4f3e233fdddbafd1166051a095f6 # v2.1.4 diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 01d11cb8090485..b1d0bb6278bb42 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -24,7 +24,7 @@ jobs: - name: Use Node.js ${{ matrix.node }}.x uses: actions/setup-node@46071b5c7a2e0c34e49c3cb8a0e792e86e18d5ea # v2.1.5 with: - node-version: ${{ matrix.node }} + node-version: ${{ matrix.node }} - name: Cache node modules uses: actions/cache@26968a09c0ea4f3e233fdddbafd1166051a095f6 # v2.1.4 @@ -60,7 +60,7 @@ jobs: - name: Use Node.js 14.x uses: actions/setup-node@46071b5c7a2e0c34e49c3cb8a0e792e86e18d5ea # v2.1.5 with: - node-version: 14.x + node-version: 14.x - name: Cache node modules uses: actions/cache@26968a09c0ea4f3e233fdddbafd1166051a095f6 # v2.1.4 @@ -78,7 +78,6 @@ jobs: - name: Install WordPress run: | - chmod -R 767 ./ # TODO: Possibly integrate in wp-env npm run wp-env start - name: Running lint check @@ -103,7 +102,7 @@ jobs: - name: Use Node.js 14.x uses: actions/setup-node@46071b5c7a2e0c34e49c3cb8a0e792e86e18d5ea # v2.1.5 with: - node-version: 14.x + node-version: 14.x - name: Cache node modules uses: actions/cache@26968a09c0ea4f3e233fdddbafd1166051a095f6 # v2.1.4 diff --git a/.wp-env.json b/.wp-env.json index 4d67d71c82fb55..260787b97fe05a 100644 --- a/.wp-env.json +++ b/.wp-env.json @@ -3,7 +3,7 @@ "plugins": [ "." ], - "themes": [ "WordPress/theme-experiments/tt1-blocks#tt1-blocks@0.4.3" ], + "themes": [ "WordPress/theme-experiments/tt1-blocks#tt1-blocks@0.4.5" ], "env": { "tests": { "mappings": { diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 5a77323cc3c694..f9afa872a60842 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -2,10 +2,10 @@ This project comes under the WordPress [Etiquette](https://wordpress.org/about/e In the WordPress open source project, we realize that our biggest asset is the community that we foster. The project, as a whole, follows these basic philosophical principles from The Cathedral and The Bazaar. -- Contributions to the WordPress open source project are for the benefit of the WordPress community as a whole, not specific businesses or individuals. All actions taken as a contributor should be made with the best interests of the community in mind. -- Participation in the WordPress open source project is open to all who wish to join, regardless of ability, skill, financial status, or any other criteria. -- The WordPress open source project is a volunteer-run community. Even in cases where contributors are sponsored by companies, that time is donated for the benefit of the entire open source community. -- Any member of the community can donate their time and contribute to the project in any form including design, code, documentation, community building, etc. For more information, go to make.wordpress.org. -- The WordPress open source community cares about diversity. We strive to maintain a welcoming environment where everyone can feel included, by keeping communication free of discrimination, incitement to violence, promotion of hate, and unwelcoming behavior. +- Contributions to the WordPress open source project are for the benefit of the WordPress community as a whole, not specific businesses or individuals. All actions taken as a contributor should be made with the best interests of the community in mind. +- Participation in the WordPress open source project is open to all who wish to join, regardless of ability, skill, financial status, or any other criteria. +- The WordPress open source project is a volunteer-run community. Even in cases where contributors are sponsored by companies, that time is donated for the benefit of the entire open source community. +- Any member of the community can donate their time and contribute to the project in any form including design, code, documentation, community building, etc. For more information, go to make.wordpress.org. +- The WordPress open source community cares about diversity. We strive to maintain a welcoming environment where everyone can feel included, by keeping communication free of discrimination, incitement to violence, promotion of hate, and unwelcoming behavior. The team involved will block any user who causes any breach in this. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 942cc50b1d0a3a..116622a9c0a86b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,19 +6,19 @@ Welcome to WordPress' Gutenberg project! We hope you join us in creating the fut To learn all about contributing to the Gutenberg project, see the [Contributor Guide](/docs/contributors/README.md). The handbook includes all the details you need to get setup and start shaping the future of web publishing. -- Code? See the [developer section](/docs/contributors/code/README.md). +- Code? See the [developer section](/docs/contributors/code/README.md). -- Design? See the [design section](/docs/contributors/design/README.md). +- Design? See the [design section](/docs/contributors/design/README.md). -- Documentation? See the [documentation section](/docs/contributors/documentation/README.md). +- Documentation? See the [documentation section](/docs/contributors/documentation/README.md). -- Triage? We need help reviewing existing issues to make sure they’re relevant and actionable. Triage is an important contribution because it allows us to work on the highest priority issues. To learn more, please see the [triaging issues section](docs/contributors/triage.md). +- Triage? We need help reviewing existing issues to make sure they’re relevant and actionable. Triage is an important contribution because it allows us to work on the highest priority issues. To learn more, please see the [triaging issues section](docs/contributors/triage.md). ## Guidelines -- As with all WordPress projects, we want to ensure a welcoming environment for everyone. With that in mind, all contributors are expected to follow our [Code of Conduct](/CODE_OF_CONDUCT.md). +- As with all WordPress projects, we want to ensure a welcoming environment for everyone. With that in mind, all contributors are expected to follow our [Code of Conduct](/CODE_OF_CONDUCT.md). -- All WordPress projects are [licensed under the GPLv2+](/LICENSE.md), and all contributions to Gutenberg will be released under the GPLv2+ license. You maintain copyright over any contribution you make, and by submitting a pull request, you are agreeing to release that contribution under the GPLv2+ license. +- All WordPress projects are [licensed under the GPLv2+](/LICENSE.md), and all contributions to Gutenberg will be released under the GPLv2+ license. You maintain copyright over any contribution you make, and by submitting a pull request, you are agreeing to release that contribution under the GPLv2+ license. ## Reporting Security Issues diff --git a/LICENSE.md b/LICENSE.md index a6523290d51581..6e7143b3c561e3 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,20 +1,24 @@ -### WordPress - Web publishing software +## Gutenberg - Copyright 2011-2021 by the contributors + Copyright 2016-2021 by the contributors -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. +**License for Contributions (on and after April 15, 2021)** -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. +All code contributed to the Gutenberg project is dual-licensed, +and released under both of the following licenses: -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License or (at your option) any later version (the “GPL”) +and the Mozilla Public License, Version 2.0 (the “MPL”). + +**Project License** + +The Gutenberg project license is not affected by the License for Contributions (as +discussed in the [Dual License section](#dual-license) below). The Gutenberg project +continues to be free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2 of the License or (at your option) any +later version (the “GPL”). This program incorporates work covered by the following copyright and permission notices: @@ -35,8 +39,49 @@ and WordPress is released under the GPL +### Dual License + +**We are currently in the process of changing Gutenberg’s software license from +GPL to a dual license: GPL and MPL.** + +**This process involves two independent steps (1) obtaining permission for dual +licensing from contributors of already contributed Gutenberg code and (2) +dual licensing of all contributions to Gutenberg that are made on or after +April 15, 2021.** + +**For part (1): We’re reaching out to everyone who has contributed code, prior +to April 15, 2021, and asking that they agree to dual license their +contribution to the project. We expect this process to be completed by +mid-year, 2021.** + +**For part (2): We have changed the license for contributed code to this +repository to make clear that all contributions on or after April 15, 2021 +will be made under the dual-license.** + +**When we have received all necessary rights and permissions to dual license +the pre-April 15, 2021 code of the Gutenberg project (Part 1 above), you will +have the option to use and distribute all of the Gutenberg project under +either the GPL or MPL license. At this time we will change the “Project +License” to the following:** + + The Gutenberg project is free software; you can redistribute it and/or modify + it under the terms of either of the following licenses: + + 1. the GNU General Public License as published by the Free Software Foundation; + either version 2 of the License or (at your option) any later version (the + “GPL”) OR + + 2. the Mozilla Public License Version 2.0 (the “MPL”). + --- +## Full Text of Referenced Licenses + +1. [GNU General Public License, Version 2](#gnu-general-public-license-version-2) +2. [Mozilla Public License, Version 2.0](#mozilla-public-license-version-20) + +## GNU General Public License, Version 2 + ### GNU GENERAL PUBLIC LICENSE Version 2, June 1991 @@ -135,17 +180,14 @@ portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: - **a)** You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. - **b)** You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. - **c)** If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement @@ -182,12 +224,10 @@ the scope of this License. under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: - **a)** Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, - **b)** Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable @@ -195,7 +235,6 @@ copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, - **c)** Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the @@ -398,3 +437,352 @@ applications with the library. If this is what you want to do, use the [GNU Lesser General Public License](http://www.gnu.org/licenses/lgpl.html) instead of this License. + +--- + +## Mozilla Public License, Version 2.0 + +### 1. Definitions + +**1.1. “Contributor”** +means each individual or legal entity that creates, contributes to +the creation of, or owns Covered Software. + +**1.2. “Contributor Version”** +means the combination of the Contributions of others (if any) used +by a Contributor and that particular Contributor's Contribution. + +**1.3. “Contribution”** +means Covered Software of a particular Contributor. + +**1.4. “Covered Software”** +means Source Code Form to which the initial Contributor has attached +the notice in Exhibit A, the Executable Form of such Source Code +Form, and Modifications of such Source Code Form, in each case +including portions thereof. + +**1.5. “Incompatible With Secondary Licenses”** +means + +- **(a)** that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or +- **(b)** that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +**1.6. “Executable Form”** +means any form of the work other than Source Code Form. + +**1.7. “Larger Work”** +means a work that combines Covered Software with other material, in +a separate file or files, that is not Covered Software. + +**1.8. “License”** +means this document. + +**1.9. “Licensable”** +means having the right to grant, to the maximum extent possible, +whether at the time of the initial grant or subsequently, any and +all of the rights conveyed by this License. + +**1.10. “Modifications”** +means any of the following: + +- **(a)** any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or +- **(b)** any new file in Source Code Form that contains any Covered + Software. + +**1.11. “Patent Claims” of a Contributor** +means any patent claim(s), including without limitation, method, +process, and apparatus claims, in any patent Licensable by such +Contributor that would be infringed, but for the grant of the +License, by the making, using, selling, offering for sale, having +made, import, or transfer of either its Contributions or its +Contributor Version. + +**1.12. “Secondary License”** +means either the GNU General Public License, Version 2.0, the GNU +Lesser General Public License, Version 2.1, the GNU Affero General +Public License, Version 3.0, or any later versions of those +licenses. + +**1.13. “Source Code Form”** +means the form of the work preferred for making modifications. + +**1.14. “You” (or “Your”)** +means an individual or a legal entity exercising rights under this +License. For legal entities, “You” includes any entity that +controls, is controlled by, or is under common control with You. For +purposes of this definition, “control” means **(a)** the power, direct +or indirect, to cause the direction or management of such entity, +whether by contract or otherwise, or **(b)** ownership of more than +fifty percent (50%) of the outstanding shares or beneficial +ownership of such entity. + +### 2. License Grants and Conditions + +#### 2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +- **(a)** under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and +- **(b)** under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +#### 2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +#### 2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +- **(a)** for any code that a Contributor has removed from Covered Software; + or +- **(b)** for infringements caused by: **(i)** Your and any other third party's + modifications of Covered Software, or **(ii)** the combination of its + Contributions with other software (except as part of its Contributor + Version); or +- **(c)** under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +#### 2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +#### 2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +#### 2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +#### 2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +### 3. Responsibilities + +#### 3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +#### 3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +- **(a)** such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +- **(b)** You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +#### 3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +#### 3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +#### 3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +### 4. Inability to Comply Due to Statute or Regulation + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: **(a)** comply with +the terms of this License to the maximum extent possible; and **(b)** +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +### 5. Termination + +**5.1.** The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated **(a)** provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and **(b)** on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +**5.2.** If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +**5.3.** In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +### 6. Disclaimer of Warranty + +> Covered Software is provided under this License on an “as is” +> basis, without warranty of any kind, either expressed, implied, or +> statutory, including, without limitation, warranties that the +> Covered Software is free of defects, merchantable, fit for a +> particular purpose or non-infringing. The entire risk as to the +> quality and performance of the Covered Software is with You. +> Should any Covered Software prove defective in any respect, You +> (not any Contributor) assume the cost of any necessary servicing, +> repair, or correction. This disclaimer of warranty constitutes an +> essential part of this License. No use of any Covered Software is +> authorized under this License except under this disclaimer. + +### 7. Limitation of Liability + +> Under no circumstances and under no legal theory, whether tort +> (including negligence), contract, or otherwise, shall any +> Contributor, or anyone who distributes Covered Software as +> permitted above, be liable to You for any direct, indirect, +> special, incidental, or consequential damages of any character +> including, without limitation, damages for lost profits, loss of +> goodwill, work stoppage, computer failure or malfunction, or any +> and all other commercial damages or losses, even if such party +> shall have been informed of the possibility of such damages. This +> limitation of liability shall not apply to liability for death or +> personal injury resulting from such party's negligence to the +> extent applicable law prohibits such limitation. Some +> jurisdictions do not allow the exclusion or limitation of +> incidental or consequential damages, so this exclusion and +> limitation may not apply to You. + +### 8. Litigation + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +### 9. Miscellaneous + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +### 10. Versions of the License + +#### 10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +#### 10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +#### 10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +#### 10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +## Exhibit A - Source Code Form License Notice + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +## Exhibit B - “Incompatible With Secondary Licenses” Notice + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/README.md b/README.md index dd556dbd03eb23..aec379107a6fff 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # Gutenberg [![End-to-End Tests](https://github.com/WordPress/gutenberg/workflows/End-to-End%20Tests/badge.svg)](https://github.com/WordPress/gutenberg/actions?query=workflow%3A%22End-to-End+Tests%22+branch%3Atrunk) -[![Static Analysis (Linting, License, Type checks...)](https://github.com/WordPress/gutenberg/workflows/Static%20Analysis%20(Linting,%20License,%20Type%20checks...)/badge.svg)](https://github.com/WordPress/gutenberg/actions?query=workflow%3A%22Static+Analysis+%28Linting%2C+License%2C+Type+checks...%29%22+branch%3Atrunk) +[![Static Analysis (Linting, License, Type checks...)]()](https://github.com/WordPress/gutenberg/actions?query=workflow%3A%22Static+Analysis+%28Linting%2C+License%2C+Type+checks...%29%22+branch%3Atrunk) [![Unit Tests](https://github.com/WordPress/gutenberg/workflows/Unit%20Tests/badge.svg)](https://github.com/WordPress/gutenberg/actions?query=workflow%3A%22Unit+Tests%22+branch%3Atrunk) [![Create Block](https://github.com/WordPress/gutenberg/workflows/Create%20Block/badge.svg)](https://github.com/WordPress/gutenberg/actions?query=workflow%3A%22Create+Block%22+branch%3Atrunk) -[![React Native E2E Tests (iOS)](https://github.com/WordPress/gutenberg/workflows/React%20Native%20E2E%20Tests%20(iOS)/badge.svg)](https://github.com/WordPress/gutenberg/actions?query=workflow%3A%22React+Native+E2E+Tests+%28iOS%29%22+branch%3Atrunk) -[![React Native E2E Tests (Android)](https://github.com/WordPress/gutenberg/workflows/React%20Native%20E2E%20Tests%20(Android)/badge.svg)](https://github.com/WordPress/gutenberg/actions?query=workflow%3A%22React+Native+E2E+Tests+%28Android%29%22+branch%3Atrunk) +[![React Native E2E Tests (iOS)]()](https://github.com/WordPress/gutenberg/actions?query=workflow%3A%22React+Native+E2E+Tests+%28iOS%29%22+branch%3Atrunk) +[![React Native E2E Tests (Android)]()](https://github.com/WordPress/gutenberg/actions?query=workflow%3A%22React+Native+E2E+Tests+%28Android%29%22+branch%3Atrunk) [![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org) diff --git a/bin/packages/watch.js b/bin/packages/watch.js index 69256b7937c5b4..404d45dd0309ef 100644 --- a/bin/packages/watch.js +++ b/bin/packages/watch.js @@ -11,79 +11,155 @@ const chalk = require( 'chalk' ); * Internal dependencies */ const getPackages = require( './get-packages' ); - const BUILD_SCRIPT = path.resolve( __dirname, './build.js' ); +const PACKAGES_DIR = path.resolve( __dirname, '../../packages' ); +const modulePackages = getPackages(); let filesToBuild = new Map(); -const exists = ( filename ) => { +/** + * Determines whether a file exists. + * + * @param {string} filename + * + * @return {boolean} True if a file exists. + */ +function exists( filename ) { try { return fs.statSync( filename ).isFile(); } catch ( e ) {} return false; -}; +} -// Exclude test files including .js files inside of __tests__ or test folders -// and files with a suffix of .test or .spec (e.g. blocks.test.js), -// and deceitful source-like files, such as editor swap files. -const isSourceFile = ( filename ) => { +/** + * Determine if a file is source code. + * + * Exclude test files including .js files inside of __tests__ or test folders + * and files with a suffix of .test or .spec (e.g. blocks.test.js), + * and deceitful source-like files, such as editor swap files. + * + * @param {string} filename + * + * @return {boolean} True if the file a source file. + */ +function isSourceFile( filename ) { return ( + /\/src\/.+\.(js|json|scss)$/.test( filename ) && ! [ - /\/(benchmark|__mocks__|__tests__|test|storybook|stories)\/.+.js$/, + /\/(benchmark|__mocks__|__tests__|test|storybook|stories)\/.+/, /.\.(spec|test)\.js$/, - ].some( ( regex ) => regex.test( filename ) ) && - /.\.(js|json|scss)$/.test( filename ) + ].some( ( regex ) => regex.test( filename ) ) ); -}; +} + +/** + * Determine if a file is in a module package. + * + * getPackages only returns packages that have a package.json with the module + * field. Only build these packages. + * + * @param {string} filename + * + * @return {boolean} True if the file is in a module package. + */ +function isModulePackage( filename ) { + return modulePackages.some( ( packagePath ) => { + return filename.indexOf( packagePath ) > -1; + } ); +} -const rebuild = ( filename ) => filesToBuild.set( filename, true ); +/** + * Is the file something the watch task should monitor or skip? + * + * @param {string} filename + * @param {symbol} skip + * + * @return {boolean | symbol} True if the file should be watched. + */ +function isWatchableFile( filename, skip ) { + return isSourceFile( filename ) && isModulePackage( filename ) + ? true + : skip; +} -getPackages().forEach( ( p ) => { - const srcDir = path.resolve( p, 'src' ); - try { - fs.accessSync( srcDir, fs.F_OK ); - watch( - path.resolve( p, 'src' ), - { recursive: true, delay: 500 }, - ( event, filename ) => { - if ( ! isSourceFile( filename ) ) { - return; - } +/** + * Returns the associated file in the build folder for a given source file. + * + * @param {string} srcFile + * + * @return {string} Path to the build file. + */ +function getBuildFile( srcFile ) { + // Could just use string.replace, but the user might have the project + // checked out and nested under another src folder. + const packageDir = srcFile.substr( 0, srcFile.lastIndexOf( '/src/' ) ); + const filePath = srcFile.substr( srcFile.lastIndexOf( '/src/' ) + 5 ); + return path.resolve( packageDir, 'build', filePath ); +} + +/** + * Adds a build file to the set of files that should be rebuilt. + * + * @param {'update'} event The event name + * @param {string} filename + */ +function updateBuildFile( event, filename ) { + if ( exists( filename ) ) { + try { + console.log( chalk.green( '->' ), `${ event }: ${ filename }` ); + filesToBuild.set( filename, true ); + } catch ( e ) { + console.log( + chalk.red( 'Error:' ), + `Unable to update file: ${ filename } - `, + e + ); + } + } +} + +/** + * Removes a build file from the build folder + * (usually triggered the associated source file was deleted) + * + * @param {'remove'} event The event name + * @param {string} filename + */ +function removeBuildFile( event, filename ) { + const buildFile = getBuildFile( filename ); + if ( exists( buildFile ) ) { + try { + fs.unlink( buildFile, () => { + console.log( chalk.red( '<-' ), `${ event }: ${ filename }` ); + } ); + } catch ( e ) { + console.log( + chalk.red( 'Error:' ), + `Unable to remove build file: ${ filename } - `, + e + ); + } + } +} - const filePath = path.resolve( srcDir, filename ); - if ( event === 'update' && exists( filePath ) ) { - console.log( - chalk.green( '->' ), - `${ event }: ${ filename }` - ); - rebuild( filePath ); - } else { - const buildFile = path.resolve( - srcDir, - '..', - 'build', - filename - ); - try { - fs.unlinkSync( buildFile ); - process.stdout.write( - chalk.red( ' \u2022 ' ) + - path.relative( - path.resolve( srcDir, '..', '..' ), - buildFile - ) + - ' (deleted)' + - '\n' - ); - } catch ( e ) {} - } - } - ); - } catch ( e ) { - // doesn't exist +// Start watching packages. +watch( + PACKAGES_DIR, + { recursive: true, delay: 500, filter: isWatchableFile }, + ( event, filename ) => { + switch ( event ) { + case 'update': + updateBuildFile( event, filename ); + break; + case 'remove': + removeBuildFile( event, filename ); + break; + } } -} ); +); +// Run a separate interval that calls the build script. +// This effectively acts as a throttle for building files. setInterval( () => { const files = Array.from( filesToBuild.keys() ); if ( files.length ) { diff --git a/bin/plugin/commands/packages.js b/bin/plugin/commands/packages.js index 2b9a46ab3f758d..d60e7c383e840f 100644 --- a/bin/plugin/commands/packages.js +++ b/bin/plugin/commands/packages.js @@ -398,8 +398,11 @@ async function publishNpmLatestDistTag() { await prepareForPackageRelease(); log( - '\n>> 🎉 WordPress packages are now published!\n', - 'Let also people know on WordPress Slack.\n' + '\n>> 🎉 WordPress packages are now published!\n\n', + 'Please remember to run `git cherry-pick` in the `trunk` branch for the newly created commits during the release with labels:\n', + ' - Update changelog files (if exists)\n', + ' - chore(release): publish\n\n', + 'Finally, let also people know on WordPress Slack and celebrate together.' ); } diff --git a/bin/test-create-block.sh b/bin/test-create-block.sh index 6b1ea6842f9094..b6e22fdb42031b 100755 --- a/bin/test-create-block.sh +++ b/bin/test-create-block.sh @@ -25,8 +25,8 @@ status "Scaffolding block..." npx wp-create-block esnext-test --no-wp-scripts cd esnext-test -status "Formatting JavaScript files..." -../node_modules/.bin/wp-scripts format-js +status "Formatting files..." +../node_modules/.bin/wp-scripts format status "Building block..." ../node_modules/.bin/wp-scripts build diff --git a/changelog.txt b/changelog.txt index 32eb746fff6f1c..8bc481c3278ccf 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,259 @@ == Changelog == += 10.5.2 = + +## Bug Fixes + + - Include new API for useSelect to prevent the global editor white screen. + + += 10.5.1 = + + + +### Bug Fixes + +- Plugin: Fix "Undefined variable: $image_default_size". ([31324](https://github.com/WordPress/gutenberg/pull/31324)) +- Select mode: Fix navigate by pointer. ([31321](https://github.com/WordPress/gutenberg/pull/31321)) +- Fix Inserter Drag and Drop. ([31319](https://github.com/WordPress/gutenberg/pull/31319)) + +### Code Quality + +- Plugin: Unregister only registered block patterns. ([31325](https://github.com/WordPress/gutenberg/pull/31325)) + + + + += 10.5.0 = + +### Enhancements + +- Block Library: + - Buttons: + - Add Typography support. ([30394](https://github.com/WordPress/gutenberg/pull/30394)) + - Explicitly add text-align-center to legacy buttons. ([30525](https://github.com/WordPress/gutenberg/pull/30525)) + - Update to use color support utils to retrieve classes and styles. ([30870](https://github.com/WordPress/gutenberg/pull/30870)) + - Columns: Add column count to the column block label. ([30248](https://github.com/WordPress/gutenberg/pull/30248)) + - File: Add support for embedding PDFs. ([30857](https://github.com/WordPress/gutenberg/pull/30857)) + - List: Add placeholder attribute. ([30958](https://github.com/WordPress/gutenberg/pull/30958)) + - Post Comments Link: New block added. ([29564](https://github.com/WordPress/gutenberg/pull/29564)) + - Site Logo: + - Update the site logo description to be more illustrative. ([30909](https://github.com/WordPress/gutenberg/pull/30909)) + - Add an initial value to the Site Logo block. ([30907](https://github.com/WordPress/gutenberg/pull/30907)) + - Site Title: + - Normalize the toolbar. ([30999](https://github.com/WordPress/gutenberg/pull/30999)) + - Normalize the toolbar (II). ([31032](https://github.com/WordPress/gutenberg/pull/31032)) + - Social Links: + - Add text placeholder next to appender. ([29851](https://github.com/WordPress/gutenberg/pull/29851)) + - Remove obsolete hardcoded focus style from Social Links. ([30721](https://github.com/WordPress/gutenberg/pull/30721)) + - Template Part: Add active block variation information in Block Parent Selector. ([30731](https://github.com/WordPress/gutenberg/pull/30731)) + - Term Description: Don't output if there's no description. ([30564](https://github.com/WordPress/gutenberg/pull/30564)) + - Verse: Add support for custom colors. ([27736](https://github.com/WordPress/gutenberg/pull/27736)) + - Video: Add uploading state. ([30837](https://github.com/WordPress/gutenberg/pull/30837)) +- Block Patterns: + - Revisit the bundled block patterns. ([29973](https://github.com/WordPress/gutenberg/pull/29973)) + - Small adjustments to bundled block patterns. ([31105](https://github.com/WordPress/gutenberg/pull/31105)) + - Suggest block pattern transformations that are contextual to the currently selected 'simple' blocks (no InnerBlocks). ([30469](https://github.com/WordPress/gutenberg/pull/30469)) + - Query Patterns: + - Try more opinionated query block patterns. ([30763](https://github.com/WordPress/gutenberg/pull/30763)) + - Add the small image and title pattern back in, fix excerpt length.. ([30817](https://github.com/WordPress/gutenberg/pull/30817)) +- Components: Add create-styles. ([30509](https://github.com/WordPress/gutenberg/pull/30509)) +- Design Tools: + - Add border color, style and width support. ([30124](https://github.com/WordPress/gutenberg/pull/30124)) + - BoxControl: Allow configurable sides. ([30606](https://github.com/WordPress/gutenberg/pull/30606)) + - Color Block Support: Add utilities to retrieve color classes and styles. ([30869](https://github.com/WordPress/gutenberg/pull/30869)) +- General Interface: + - Animate the canvas transitions. ([30802](https://github.com/WordPress/gutenberg/pull/30802)) + - Include block title into block switcher label. ([30808](https://github.com/WordPress/gutenberg/pull/30808)) + - Inspector Controls: Rephrase, polish, and make consistent color labels. ([30075](https://github.com/WordPress/gutenberg/pull/30075)) + - Move the template mode edit and new links to a dedicated template panel. ([30900](https://github.com/WordPress/gutenberg/pull/30900)) + - Update design of the resize handles. ([30339](https://github.com/WordPress/gutenberg/pull/30339)) +- Icons: Update icons for text overlay and crop. ([30673](https://github.com/WordPress/gutenberg/pull/30673)) +- i18n: Add `resetLocaleData` method. ([30419](https://github.com/WordPress/gutenberg/pull/30419)) +- Publishing Flow: Show post events in the post schedule calendar. ([29716](https://github.com/WordPress/gutenberg/pull/29716)) +- Template Editing Mode: + - Allow creating custom block templates in classic themes. ([30438](https://github.com/WordPress/gutenberg/pull/30438)) + - Replace the document tab with a template tab in template mode. ([30860](https://github.com/WordPress/gutenberg/pull/30860)) + - Unify saving flow between template mode and default mode. ([30793](https://github.com/WordPress/gutenberg/pull/30793)) + - Updates the template mode canvas padding and adds a backlink. ([30658](https://github.com/WordPress/gutenberg/pull/30658)) +- Site Editor: + - Add 'area' selection to convert to template part flow. ([30395](https://github.com/WordPress/gutenberg/pull/30395)) + - Add do_block_template_part function. ([30345](https://github.com/WordPress/gutenberg/pull/30345)) + - Add skip link to block templates. ([30336](https://github.com/WordPress/gutenberg/pull/30336)) + - Remove single-post from the default templates set. ([29668](https://github.com/WordPress/gutenberg/pull/29668)) + - Themes: Fix template-hierarchy fallbacks. ([30599](https://github.com/WordPress/gutenberg/pull/30599)) +- Writing Flow: Scroll selected block only if it has no focus. ([30924](https://github.com/WordPress/gutenberg/pull/30924)) + + +### Bug Fixes + +- API Fetch: Make preloaded OPTIONS requests use `parse` setting. ([28862](https://github.com/WordPress/gutenberg/pull/28862)) +- Block Library: + - Duplicate media types to avoid bad imports. ([30973](https://github.com/WordPress/gutenberg/pull/30973)) + - Image Block: Disable media buttons in the uploading state. ([30863](https://github.com/WordPress/gutenberg/pull/30863)) + - Query: Fix max-height to query pattern preview. ([30757](https://github.com/WordPress/gutenberg/pull/30757)) + - Post Title: Fix warnings for RichText in inline containers. ([30666](https://github.com/WordPress/gutenberg/pull/30666)) + - Site Title Add default block after pressing enter at the end of Site Title. ([30996](https://github.com/WordPress/gutenberg/pull/30996)) +- Block Editor: + - Bring back imageDefaultSize shim for WP 5.7. ([30955](https://github.com/WordPress/gutenberg/pull/30955)) + - Fix the position of vertical add a new block in RTL mode. ([31035](https://github.com/WordPress/gutenberg/pull/31035)) + - Template part: Fix PHP notice for placeholder block. ([30928](https://github.com/WordPress/gutenberg/pull/30928)) +- Components: + - Add a StyleProvider to support CSS-in-JS components inside iframes. ([31010](https://github.com/WordPress/gutenberg/pull/31010)) + - Apply a StyleProvider around fills that can be used inside the iframe. ([31073](https://github.com/WordPress/gutenberg/pull/31073)) + - Fix "RadioControl: checked" style outside of Gutenberg. ([30670](https://github.com/WordPress/gutenberg/pull/30670)) + - Fix Post Date component. ([30790](https://github.com/WordPress/gutenberg/pull/30790)) + - Fix Post Publishing Popover moving when certain dates are clicked. ([30298](https://github.com/WordPress/gutenberg/pull/30298)) + - Fix useForceUpdate Memory Leak: Only setState if the component is still mounted. ([30667](https://github.com/WordPress/gutenberg/pull/30667)) +- General Interface: Fix is-link style to take colors from wp-admin theme. ([30823](https://github.com/WordPress/gutenberg/pull/30823)) +- Inserter: Stop event propagation for the select element's onBlur to fix the behavior in iOS when selecting a pattern category. ([30717](https://github.com/WordPress/gutenberg/pull/30717)) +- Site Editor: + - Focus save button when entities save states panel is opened. ([30873](https://github.com/WordPress/gutenberg/pull/30873)) + - Remove call to wpautop that unintentionally alters block markup in template parts. ([30552](https://github.com/WordPress/gutenberg/pull/30552)) +- Template Editing Mode: Hide the template selector and template mode from non-viewable post types. ([30861](https://github.com/WordPress/gutenberg/pull/30861)) + +### Experiments + +- Block-based Widgets: + - API: + - Don't use deprecated widget_class property. ([30429](https://github.com/WordPress/gutenberg/pull/30429)) + - Fix null instance property when instance settings are empty. ([30713](https://github.com/WordPress/gutenberg/pull/30713)) + - Remove deprecated properties. ([30853](https://github.com/WordPress/gutenberg/pull/30853)) + - Customizer Integration: + - Add media uploader capabilities to block-based widget customize screen. ([30954](https://github.com/WordPress/gutenberg/pull/30954)) + - Add move to widget area dropdown in customizer. ([30896](https://github.com/WordPress/gutenberg/pull/30896)) + - Add rich text formats. ([30952](https://github.com/WordPress/gutenberg/pull/30952)) + - Fix editing performance in Widgets Customizer. ([30654](https://github.com/WordPress/gutenberg/pull/30654)) + - Fix block-based widget customizer initializing too soon. ([30864](https://github.com/WordPress/gutenberg/pull/30864)) + - Refactor the inspector in Widgets Customizer to use core's controls. ([30431](https://github.com/WordPress/gutenberg/pull/30431)) + - Legacy Widget: Improve backwards compatibility. ([30709](https://github.com/WordPress/gutenberg/pull/30709)) + - Widget editor: + - Add a toolbar button to move between widget areas. ([30826](https://github.com/WordPress/gutenberg/pull/30826)) + - Fix the undo/redo buttons in the standalone block-based widgets editor. ([30989](https://github.com/WordPress/gutenberg/pull/30989)) +- Navigation Editor and Block: + - Fix navigation placeholder height issue. ([30824](https://github.com/WordPress/gutenberg/pull/30824)) + - Fix alignment issue on the nav screen manage locations buttons. ([30441](https://github.com/WordPress/gutenberg/pull/30441)) + - Limit navigation nesting depth to 5. ([30199](https://github.com/WordPress/gutenberg/pull/30199)) + - Nav-created drafts should not render on the front end. ([29692](https://github.com/WordPress/gutenberg/pull/29692)) + - Page List: Add ability to convert to navigation links. ([30390](https://github.com/WordPress/gutenberg/pull/30390)) + - Show justification controls for vertical variant. ([30351](https://github.com/WordPress/gutenberg/pull/30351)) + - Use theme locations description instead of the slug for navigation screen location labels. ([30797](https://github.com/WordPress/gutenberg/pull/30797)) +- Global Styles: + - Absorb editor settings transformation in WP_Theme_JSON. ([30610](https://github.com/WordPress/gutenberg/pull/30610)) + - Clean cached data when switching themes. ([30830](https://github.com/WordPress/gutenberg/pull/30830)) + - Extract sanitize method. ([30809](https://github.com/WordPress/gutenberg/pull/30809)) + - Fix: CSS variable reference mechanism regression. ([31015](https://github.com/WordPress/gutenberg/pull/31015)) + - Make the dependency of the star matcher explicit when translating `theme.json`. ([30604](https://github.com/WordPress/gutenberg/pull/30604)) + - Only remove the default font family in the editor from themes with theme.json file. ([30895](https://github.com/WordPress/gutenberg/pull/30895)) + - Refactor how we iterate over the tree. ([30801](https://github.com/WordPress/gutenberg/pull/30801)) + - Remove no longer needed translations handled in PHP for settings. ([30605](https://github.com/WordPress/gutenberg/pull/30605)) + - theme.json: Add util to transform from a v0 schema to the latest. ([30600](https://github.com/WordPress/gutenberg/pull/30600)) + +### Documentation + +- docgen: + - Add support for TS exported static non-function variables. ([30971](https://github.com/WordPress/gutenberg/pull/30971)) + - Add support for assignment patterns. ([30681](https://github.com/WordPress/gutenberg/pull/30681)) + - Add support for object-destructuring. ([30675](https://github.com/WordPress/gutenberg/pull/30675)) + - Find parameters by index rather than name and handle array destructuring. ([29945](https://github.com/WordPress/gutenberg/pull/29945)) +- Handbook: + - Add documentation for border block supports. ([31039](https://github.com/WordPress/gutenberg/pull/31039)) + - Add documentation for border styles. ([31040](https://github.com/WordPress/gutenberg/pull/31040)) + - Add fix to suggested prefixes of the branch. ([30953](https://github.com/WordPress/gutenberg/pull/30953)) + - Change references from Block Style Variations to Block Styles. ([30911](https://github.com/WordPress/gutenberg/pull/30911)) + - Fix Block Editor Accessibility link. ([30569](https://github.com/WordPress/gutenberg/pull/30569)) + - Fix more example for register_block_type - apiVersion to api_version. ([30819](https://github.com/WordPress/gutenberg/pull/30819)) + - Fix PHP example for register_block_type - apiVersion to api_version. ([30818](https://github.com/WordPress/gutenberg/pull/30818)) + - Fixed a type and made the whole explanation more clear. ([30487](https://github.com/WordPress/gutenberg/pull/30487)) + - Fixes broken GitHub links to commonly used labels. ([30875](https://github.com/WordPress/gutenberg/pull/30875)) + - Improve semantics in the block-based theme guide. ([30946](https://github.com/WordPress/gutenberg/pull/30946)) + - Include a note about `is_default` property for `register_block_style`. ([30792](https://github.com/WordPress/gutenberg/pull/30792)) + - Organize Block API Reference. ([30980](https://github.com/WordPress/gutenberg/pull/30980)) + - Packages: Further clarify the npm publishing process. ([30733](https://github.com/WordPress/gutenberg/pull/30733)) + - Update getting started with code. ([30447](https://github.com/WordPress/gutenberg/pull/30447)) +- Libs: + - Blocks: Fix PHPDocs of `gutenberg_block_has_support`. ([31050](https://github.com/WordPress/gutenberg/pull/31050)) + - Query Utils: Fix return type of `construct_wp_query_args()`. ([30611](https://github.com/WordPress/gutenberg/pull/30611)) +- License: Interim dual license license of future contributions. ([30383](https://github.com/WordPress/gutenberg/pull/30383)) +- Packages: + - Block Library - Social Links: Update param type. ([30652](https://github.com/WordPress/gutenberg/pull/30652)) + - Components: Add documentation for the text prop on the Button component. ([30796](https://github.com/WordPress/gutenberg/pull/30796)) + - Core Data: Fixes return type for getEntitiesByKind. ([30639](https://github.com/WordPress/gutenberg/pull/30639)) + - Block Editor: Update import statement of ImageSizeControl component. ([30704](https://github.com/WordPress/gutenberg/pull/30704)) + - Hooks: Add namespace param clarification. ([30501](https://github.com/WordPress/gutenberg/pull/30501)) + +### Code Quality + +- Block Editor: + - Simplify focus capture. ([31036](https://github.com/WordPress/gutenberg/pull/31036)) + - Standardize loading default block editor settings. ([30245](https://github.com/WordPress/gutenberg/pull/30245)) +- Block Library: + - Button Block: Use hook-based border support. ([30194](https://github.com/WordPress/gutenberg/pull/30194)) + - Cover: Rename isBlogUrl to isUploadingMedia. ([30435](https://github.com/WordPress/gutenberg/pull/30435)) + - Cover: Use ALLOWED_MEDIA_TYPES shared constant. ([30977](https://github.com/WordPress/gutenberg/pull/30977)) +- Block Patterns: Clean up bundled pattern titles & categories. ([30998](https://github.com/WordPress/gutenberg/pull/30998)) +- Components: Remove `create-styles` in favor of vanilla emotion. ([31048](https://github.com/WordPress/gutenberg/pull/31048)) +- dom: + - Add types to caret placement functions. ([30750](https://github.com/WordPress/gutenberg/pull/30750)) + - Add types to document-has-selection. ([30386](https://github.com/WordPress/gutenberg/pull/30386)) + - Add types to is-edge and dependencies. ([30546](https://github.com/WordPress/gutenberg/pull/30546)) + - Add types to miscellaneous files. ([30774](https://github.com/WordPress/gutenberg/pull/30774)) + - Add types to removeInvalidHTML and stripHTML. ([30752](https://github.com/WordPress/gutenberg/pull/30752)) + - Only assert defined in development. ([30807](https://github.com/WordPress/gutenberg/pull/30807)) + - Type the remaining files. ([30841](https://github.com/WordPress/gutenberg/pull/30841)) +- Drop zone: Rewrite without provider. ([30310](https://github.com/WordPress/gutenberg/pull/30310)) +- Gutenberg Plugin: + - Account for editor styles file removal on WP trunk. ([30894](https://github.com/WordPress/gutenberg/pull/30894)) + - Format all markdown files using Prettier formatter. ([30715](https://github.com/WordPress/gutenberg/pull/30715)) + - Format all JSON files using Prettier formatter. ([30714](https://github.com/WordPress/gutenberg/pull/30714)) + - Updated `.editorconfig` files to work with automatic file formatting. ([30794](https://github.com/WordPress/gutenberg/pull/30794)) + - Update WP compatibility check in `gutenberg_pre_init()`. ([29938](https://github.com/WordPress/gutenberg/pull/29938)) +- Improve get_merged_data() code. ([30612](https://github.com/WordPress/gutenberg/pull/30612)) +- Remove unnecessary semicolons in PHP. ([30780](https://github.com/WordPress/gutenberg/pull/30780)) +- Replace older-style PHP type conversion functions with typecasts. ([30531](https://github.com/WordPress/gutenberg/pull/30531)) + +### Tools + +- Testing: + - Block Library - Cover Block: + - Add edit media integration tests. ([30270](https://github.com/WordPress/gutenberg/pull/30270)) + - Replace media end-to-end test. ([30306](https://github.com/WordPress/gutenberg/pull/30306)) + - Fix end-to-end test failure screenshots not capturing at the right time. ([28449](https://github.com/WordPress/gutenberg/pull/28449)) + - Fixture regeneration: Infer tabs use from prettier configuration. ([30813](https://github.com/WordPress/gutenberg/pull/30813)) + - Skip unstable template part end-to-end test. ([30748](https://github.com/WordPress/gutenberg/pull/30748)) + - Trim block fixture HTML when generating other test fixture files. ([30981](https://github.com/WordPress/gutenberg/pull/30981)) + - Wire PHP tests for block editor settings. ([30984](https://github.com/WordPress/gutenberg/pull/30984)) +- wp-env: + - Better errors when Docker is not started. ([30882](https://github.com/WordPress/gutenberg/pull/30882)) + - Bump tt1-blocks dependency to v0.4.5. ([30045](https://github.com/WordPress/gutenberg/pull/30045)) + - Disable Xdebug for php < 7.2. ([30651](https://github.com/WordPress/gutenberg/pull/30651)) + - Fix chown cannot access 'wp-config.php'. ([30053](https://github.com/WordPress/gutenberg/pull/30053)) + - Fix issue with unquoted paths in docker-compose call. ([30692](https://github.com/WordPress/gutenberg/pull/30692)) + - Remove platform-specific destroy commands. ([30638](https://github.com/WordPress/gutenberg/pull/30638)) + - Set default environment type to local. ([28808](https://github.com/WordPress/gutenberg/pull/28808)) + - Update changelog and CI. ([30646](https://github.com/WordPress/gutenberg/pull/30646)) +- Build Tooling: + - Add comments to webpack entrypoint function. ([30629](https://github.com/WordPress/gutenberg/pull/30629)) + - Create frontend entry points for block-library, outputting code loadable from the browser.. ([30341](https://github.com/WordPress/gutenberg/pull/30341)) + - Perf Workflow: Trigger upon release publishing. ([30628](https://github.com/WordPress/gutenberg/pull/30628)) + - Pull trunk before pushing. ([30615](https://github.com/WordPress/gutenberg/pull/30615)) + - Remind about required cherry-picks after npm publishing. ([30868](https://github.com/WordPress/gutenberg/pull/30868)) + - Update development tools to work with PostCSS (try 2). ([30347](https://github.com/WordPress/gutenberg/pull/30347)) + - Use consistently latest keyword for npm publishing. ([30866](https://github.com/WordPress/gutenberg/pull/30866)) +- Scripts: + - Allow CSS modules in the build commands. ([29182](https://github.com/WordPress/gutenberg/pull/29182)) + - Include YAML files in prettification. ([30240](https://github.com/WordPress/gutenberg/pull/30240)) + + += 10.4.1 = + +### Bug Fixes + +- Editor: Handle case where unavailable siteData is causing WSOD. ([30812](https://github.com/WordPress/gutenberg/pull/30812)) +- Site Logo: Fix default size. ([30846](https://github.com/WordPress/gutenberg/pull/30846)) +- Latest posts block: Show error for password protected posts. + + = 10.4.0 = ### Enhancements diff --git a/composer.json b/composer.json index 3e6346fa821f98..dc614eb33307be 100644 --- a/composer.json +++ b/composer.json @@ -5,7 +5,12 @@ "description": "Prototyping since 1440. Development hub for the editor focus in core.", "homepage": "https://wordpress.github.io/gutenberg/", "keywords": [ - "gutenberg", "wordpress", "editor", "wp", "react", "javascript" + "gutenberg", + "wordpress", + "editor", + "wp", + "react", + "javascript" ], "support": { "issues": "https://github.com/WordPress/gutenberg/issues" diff --git a/docs/README.md b/docs/README.md index 26cdbe393ad49e..8da0f469ae3122 100644 --- a/docs/README.md +++ b/docs/README.md @@ -28,15 +28,14 @@ The Editor offers rich new value to users with visual, drag-and-drop creation to Whether you want to extend the functionality of the block editor, or create a plugin based on it, [see the developer documentation](/docs/how-to-guides/README.md) to find all the information about the basic concepts you need to get started, the block editor APIs and its architecture. -- [Gutenberg Architecture](/docs/explanations/architecture/README.md) -- [Block Style Variations](/docs/reference-guides/filters/block-filters.md#block-style-variations) -- [Creating Block Patterns](/docs/reference-guides/block-api/block-patterns.md) -- [Theming for the Block Editor](/docs/how-to-guides/themes/README.md) -- [Block API Reference](/docs/reference-guides/block-api/README.md) -- [Block Editor Accessibility](/docs/reference-guides/accessibility.md) -- [Internationalization](/docs/how-to-guides/internationalization.md) +- [Gutenberg Architecture](/docs/explanations/architecture/README.md) +- [Block Styles](/docs/reference-guides/filters/block-filters.md#block-styles) +- [Creating Block Patterns](/docs/reference-guides/block-api/block-patterns.md) +- [Theming for the Block Editor](/docs/how-to-guides/themes/README.md) +- [Block API Reference](/docs/reference-guides/block-api/README.md) +- [Block Editor Accessibility](/docs/how-to-guides/accessibility.md) +- [Internationalization](/docs/how-to-guides/internationalization.md) ### Contribute to the block editor Everything you need to know to [start contributing to the block editor](/docs/contributors/README.md) . Whether you are interested in the design, code, triage, documentation, support or internationalization of the block editor, you will find here guides to help you. - diff --git a/docs/contributors/README.md b/docs/contributors/README.md index 08b0d3ca0dc421..f8dcaed57e29a5 100644 --- a/docs/contributors/README.md +++ b/docs/contributors/README.md @@ -8,25 +8,25 @@ Gutenberg is a sub-project of Core WordPress. Please see the [Core Contributor H Find the section below based on what you are looking to contribute: -- **Code?** See the [developer section](/docs/contributors/code/README.md). +- **Code?** See the [developer section](/docs/contributors/code/README.md). -- **Design?** See the [design section](/docs/contributors/design/README.md). +- **Design?** See the [design section](/docs/contributors/design/README.md). -- **Documentation?** See the [documentation section](/docs/contributors/documentation/README.md) +- **Documentation?** See the [documentation section](/docs/contributors/documentation/README.md) -- **Triage Support?** See the [triaging issues section](/docs/contributors/triage.md) +- **Triage Support?** See the [triaging issues section](/docs/contributors/triage.md) -- **Internationalization?** See the [localizing and translating section](/docs/contributors/localizing.md) +- **Internationalization?** See the [localizing and translating section](/docs/contributors/localizing.md) ### Repository Management The Gutenberg project uses Github for managing code and tracking issues. Please see the following sections for the project methodologies using Github. -- [Issue Management](/docs/contributors/repository-management.md#issues) +- [Issue Management](/docs/contributors/repository-management.md#issues) -- [Pull Requests](/docs/contributors/repository-management.md#pull-requests) +- [Pull Requests](/docs/contributors/repository-management.md#pull-requests) -- [Teams and Projects](/docs/contributors/repository-management.md#teams) +- [Teams and Projects](/docs/contributors/repository-management.md#teams) ## Guidelines diff --git a/docs/contributors/accessibility-testing.md b/docs/contributors/accessibility-testing.md index 4e6e915222e80d..46085df4afb817 100644 --- a/docs/contributors/accessibility-testing.md +++ b/docs/contributors/accessibility-testing.md @@ -10,9 +10,9 @@ Make sure you have set up your local environment following the instructions on [ In addition to mouse, make sure the interface is fully accessible for keyboard-only users. Try to interact with your changes using only the keyboard: -- Make sure interactive elements can receive focus using Tab, Shift+Tab or arrow keys. -- Buttons should be activable by pressing Enter and Space. -- Radio buttons and checkboxes should be checked by pressing Space, but not Enter. +- Make sure interactive elements can receive focus using Tab, Shift+Tab or arrow keys. +- Buttons should be activable by pressing Enter and Space. +- Radio buttons and checkboxes should be checked by pressing Space, but not Enter. If the elements can be focused using arrow keys, but not Tab or Shift+Tab, consider grouping them using one of the [WAI-ARIA composite subclass roles](https://www.w3.org/TR/wai-aria-1.1/#composite), such as [`toolbar`](https://www.w3.org/TR/wai-aria-1.1/#toolbar), [`menu`](https://www.w3.org/TR/wai-aria-1.1/#menu) and [`listbox`](https://www.w3.org/TR/wai-aria-1.1/#listbox). @@ -23,7 +23,7 @@ If the interaction is complex or confusing to you, consider that it's also going According to the [WebAIM: Screen Reader User Survey #8 Results](https://webaim.org/projects/screenreadersurvey8/#usage), these are the most common screen reader and browser combinations: | Screen Reader & Browser | # of Respondents | % of Respondents | -|-----------------------------|------------------|------------------| +| --------------------------- | ---------------- | ---------------- | | JAWS with Chrome | 259 | 21.4% | | NVDA with Firefox | 237 | 19.6% | | NVDA with Chrome | 218 | 18.0% | diff --git a/docs/contributors/code/README.md b/docs/contributors/code/README.md index 53637b380ca65d..4bc3b0070c47c2 100644 --- a/docs/contributors/code/README.md +++ b/docs/contributors/code/README.md @@ -16,11 +16,11 @@ Browse [the issues list](https://github.com/wordpress/gutenberg/issues) to find ## Contributor Resources -* [Getting Started](/docs/contributors/code/getting-started-with-code-contribution.md) documents getting your development environment setup, this includes your test site and developer tools suggestions. -* [Git Workflow](/docs/contributors/code/git-workflow.md) documents the git process for deploying changes using pull requests. -* [Coding Guidelines](/docs/contributors/code/coding-guidelines.md) outline additional patterns and conventions used in the Gutenberg project. -* [Testing Overview](/docs/contributors/code/testing-overview.md) for PHP and JavaScript development in Gutenberg. -* [Accessibility Testing](/docs/contributors/accessibility-testing.md) documents the process of testing accessibility in Gutenberg. -* [Managing Packages](/docs/contributors/code/managing-packages.md) documents the process for managing the npm packages. -* [Gutenberg Release Process](/docs/contributors/code/release.md) - a checklist for the different types of releases for the Gutenberg project. -* [React Native mobile Gutenberg](/docs/contributors/code/native-mobile.md) - a guide on the React Native based mobile Gutenberg editor. +- [Getting Started](/docs/contributors/code/getting-started-with-code-contribution.md) documents getting your development environment setup, this includes your test site and developer tools suggestions. +- [Git Workflow](/docs/contributors/code/git-workflow.md) documents the git process for deploying changes using pull requests. +- [Coding Guidelines](/docs/contributors/code/coding-guidelines.md) outline additional patterns and conventions used in the Gutenberg project. +- [Testing Overview](/docs/contributors/code/testing-overview.md) for PHP and JavaScript development in Gutenberg. +- [Accessibility Testing](/docs/contributors/accessibility-testing.md) documents the process of testing accessibility in Gutenberg. +- [Managing Packages](/docs/contributors/code/managing-packages.md) documents the process for managing the npm packages. +- [Gutenberg Release Process](/docs/contributors/code/release.md) - a checklist for the different types of releases for the Gutenberg project. +- [React Native mobile Gutenberg](/docs/contributors/code/native-mobile.md) - a guide on the React Native based mobile Gutenberg editor. diff --git a/docs/contributors/code/getting-started-with-code-contribution.md b/docs/contributors/code/getting-started-with-code-contribution.md index f5384b1bd05874..ba25adcb62c8f0 100644 --- a/docs/contributors/code/getting-started-with-code-contribution.md +++ b/docs/contributors/code/getting-started-with-code-contribution.md @@ -2,47 +2,68 @@ The following guide is for setting up your local environment to contribute to the Gutenberg project. There is significant overlap between an environment to contribute and an environment used to extend the WordPress block editor. You can review the [Development Environment tutorial](/docs/getting-started/tutorials/devenv/README.md) for additional setup information. -## Development Tools (Node) +## Prerequisites -Gutenberg is a JavaScript project and requires [Node.js](https://nodejs.org/). The project is built using the latest active LTS release of node, and the latest version of NPM. See the [LTS release schedule](https://github.com/nodejs/Release#release-schedule) for details. +- Node.js + Gutenberg is a JavaScript project and requires [Node.js](https://nodejs.org/). The project is built using the latest active LTS release of node, and the latest version of NPM. See the [LTS release schedule](https://github.com/nodejs/Release#release-schedule) for details. We recommend using the [Node Version Manager](https://github.com/nvm-sh/nvm) (nvm) since it is the easiest way to install and manage node for macOS, Linux, and Windows 10 using WSL2. See [our Development Tools guide](/docs/getting-started/tutorials/devenv/README.md#development-tools) or the Nodejs site for additional installation instructions. -After installing Node, you can build Gutenberg by running the following from within the cloned repository: +- Git + Gutenberg is using git for source control. Make sure you have an updated version of git installed on your computer, as well as a GitHub account. You can read the [Git Workflow](/docs/contributors/code/git-workflow.md) to learn more about using git and GitHub with Gutenberg +- [Recommended] Docker Desktop + We recommend using the [wp-env package](/packages/env/README.md) for setting WordPress environment locally. You'll need to install Docker to use `wp-env`. See the [Development Environment tutorial for additional details](/docs/getting-started/tutorials/devenv/README.md). + > Note: To install Docker on Windows 10 Home Edition, follow the [install instructions from Docker for Windows with WSL2](https://docs.docker.com/docker-for-windows/wsl/). + +As an alternative to Docker setup, you can use [Local by Flywheel](https://localbyflywheel.com/), [WampServer](http://www.wampserver.com/en/), or [MAMP](https://www.mamp.info/), or even use a remote server. + +## Getting the Gutenberg code + +Fork the Gutenberg repository, clone it to your computer and add the WordPress repository as upstream. + +```bash +$ git clone https://github.com/YOUR_GITHUB_USERNAME/gutenberg.git +$ cd gutenberg +$ git remote add upstream https://github.com/WordPress/gutenberg.git +``` + +## Building Gutenberg as a plugin + +Install the Gutenberg dependencies and build your code in development mode: ```bash npm ci -npm run build +npm run dev ``` > Note: The install scripts require [Python](https://www.python.org/) to be installed and in the path of the local system. This might be installed by default for your operating system, or require downloading and installing. -Once built, Gutenberg is ready to be used as a WordPress plugin! +There are two ways to build your code. While developing, you probably will want to use `npm run dev` to run continuous builds automatically as source files change. The dev build also includes additional warnings and errors to help troubleshoot while developing. Once you are happy with your changes, you can run `npm build` to create optimized production build. -`npm run build` creates a single build of the project once. While developing, you probably will want to use `npm run dev` to run continuous builds automatically as source files change. The dev build also includes additional warnings and errors to help troubleshoot while developing. +Once built, Gutenberg is ready to be used as a WordPress plugin! -## Local Environment +## Local WordPress Environment -If you are familiar with WordPress and already have an environment setup, use the above build as a standard WordPress plugin by putting the gutenberg directory in your wp-content/plugins/ directory. +To test a WordPress plugin, you need to have WordPress itself installed. If you already have a WordPress environment setup, use the above Gutenberg build as a standard WordPress plugin by putting the gutenberg directory in your wp-content/plugins/ directory. If you do not have a local WordPress environment setup, follow the steps in the rest of this section to create one. -### Using wp-env to Install a Local Environment +### Using Docker and wp-env The [wp-env package](/packages/env/README.md) was developed with the Gutenberg project as a quick way to create a standard WordPress environment using Docker. It is also published as the `@wordpress/env` npm package. By default, `wp-env` can run in a plugin directory to create and run a WordPress environment, mounting and activating the plugin automatically. You can also configure `wp-env` to use existing installs, multiple plugins, or themes. See the [wp-env package](/packages/env/README.md#wp-envjson) for complete documentation. -If you don't already have it, you'll need to install Docker and Docker Compose in order to use `wp-env`. See the [Development Environment tutorial for additional details](/docs/getting-started/tutorials/devenv/README.md). - -Once Docker is installed and running: To install WordPress, run the following from within the cloned gutenberg directory: +Make sure Docker is running, and start `wp-env` from within the gutenberg directory: ```bash npm run wp-env start ``` -> Note: `npm run` will use the version specified within the Gutenberg project, making sure you are running the latest wp-env version. +This script will create a Docker instance behind the scenes with the latest WordPress Docker image, and then will map the Gutenberg plugin code from your local copy to the environment as a Docker volume. This way, any changes you make to the code locally are reflected immediately in the WordPress instance. + +> Note: `npm run` will use the `wp-env` / `WordPress`?? version specified within the Gutenberg project, making sure you are running the latest wp-env version. To stop the running environment: @@ -50,6 +71,20 @@ To stop the running environment: npm run wp-env stop ``` +If everyting went well, you should see the following message in your terminal: + +```bash +WordPress development site started at http://localhost:8888/ +WordPress test site started at http://localhost:8889/ +MySQL is listening on port 51220 + + ✔ Done! (in 261s 898ms) +``` + +And if you open Docker dashboard by rightclicking the icon in the menu bar(on Mac) or system tray (on Linux and Windows) and selecting 'Dashboard', you will see that the script has downloaded some Docker Images, and is running a Docker Container with fully functional WordPress installation: +![Screenshot of the WordPress Docker Container Running](https://cldup.com/mt9cKES-YZ.png) +![Screenshot of the Downloaded Docker Images for WordPress Development Environment](https://cldup.com/bNpgaRSkcG.png) + To destroy the install completely: ```bash @@ -58,12 +93,11 @@ npm run wp-env destroy Explore the [package documentation](/packages/env/README.md) for additional commands. - #### Accessing the Local WordPress Install The WordPress installation should now be available at `http://localhost:8888` -You can access the Dashboard at: `http://localhost:8888/wp-admin/` using **Username**: `admin`, **Password**: `password`. You'll notice the Gutenberg plugin installed and activated, this is your local build. +You can access the Dashboard at: `http://localhost:8888/wp-admin/` using **Username**: `admin`, **Password**: `password`. You'll notice the Gutenberg plugin installed and activated, this is your local build. #### Troubleshooting @@ -71,7 +105,7 @@ If you run into an issue, check the [troubleshooting section in `wp-env` documen ### Using Local or MAMP -You can also use [Local by Flywheel](https://localbyflywheel.com/), [WampServer](http://www.wampserver.com/en/), or [MAMP](https://www.mamp.info/) as alternative environments to run a local WordPress environment. To do so clone and install Gutenberg as a regular plugin in your installation by creating a symlink or copying the directory to the proper `wp-content/plugins` directory. +As an alternative to Docker and `wp-env`, you can also use [Local by Flywheel](https://localbyflywheel.com/), [WampServer](http://www.wampserver.com/en/), or [MAMP](https://www.mamp.info/) to run a local WordPress environment. To do so clone and install Gutenberg as a regular plugin in your installation by creating a symlink or copying the directory to the proper `wp-content/plugins` directory. You will also need some extra configuration to be able to run the e2e tests. @@ -91,9 +125,9 @@ WP_BASE_URL=http://localhost:8888/gutenberg npm run test-e2e You'll need to disable OPCache in order to correctly work on PHP files. To fix: -- Go to **MAMP > Preferences > PHP** -- Under **Cache**, select **off** -- Confirm with **OK** +- Go to **MAMP > Preferences > PHP** +- Under **Cache**, select **off** +- Confirm with **OK** #### Incoming connections @@ -101,20 +135,20 @@ By default, the web server (Apache) launched by MAMP will listen to all incoming While it is possible to fix this, you should fix it at your own risk, since it breaks MAMP's ability to parse web server configurations and, as a result, makes MAMP think that Apache is listening to the wrong port. Consider switching away from MAMP. Otherwise, you can use the following: -- Edit `/Applications/MAMP/conf/apache/httpd.conf` -- Change `Listen 8888` to `Listen 127.0.0.1:8888` +- Edit `/Applications/MAMP/conf/apache/httpd.conf` +- Change `Listen 8888` to `Listen 127.0.0.1:8888` #### Linking to other directories You may like to create links in your `plugins` and `themes` directories to other folders, e.g. -- wp-content/plugins/gutenberg -> ~/projects/gutenberg -- wp-content/themes/twentytwenty -> ~/projects/twentytwenty +- wp-content/plugins/gutenberg -> ~/projects/gutenberg +- wp-content/themes/twentytwenty -> ~/projects/twentytwenty If so, you need to instruct Apache to allow following such links: -- Open or start a new file at `/Applications/MAMP/htdocs/.htaccess` -- Add the following line: `Options +SymLinksIfOwnerMatch` +- Open or start a new file at `/Applications/MAMP/htdocs/.htaccess` +- Add the following line: `Options +SymLinksIfOwnerMatch` #### Using WP-CLI @@ -164,7 +198,7 @@ With the extension installed, ESLint will use the [.eslintrc.js](https://github. [Prettier](https://prettier.io/) is a tool that allows you to define an opinionated format, and automate fixing the code to match that format. Prettier and ESlint are similar, Prettier is more about formatting and style, while ESlint is for detecting coding errors. -To use Prettier with Visual Studio Code, you should install the [Prettier - Code formatter extension](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode). You can then configure it to be the default formatter and to automatically fix issues on save, by adding the following to your settings. __**Note**: depending on where you are viewing this document, the brackets may show as double, the proper format is just a single bracket.__ +To use Prettier with Visual Studio Code, you should install the [Prettier - Code formatter extension](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode). You can then configure it to be the default formatter and to automatically fix issues on save, by adding the following to your settings. **_Note_: depending on where you are viewing this document, the brackets may show as double, the proper format is just a single bracket.** ```json "[[javascript]]": { diff --git a/docs/contributors/code/git-workflow.md b/docs/contributors/code/git-workflow.md index 38741e3c1ba21d..16db71ffc7127b 100644 --- a/docs/contributors/code/git-workflow.md +++ b/docs/contributors/code/git-workflow.md @@ -1,23 +1,23 @@ # Git Workflow -The Gutenberg project follows a standard pull request process for contributions. See GitHub's documentation for [additional details about pull requests](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests). - This documentation is intended to help you get started using git with Gutenberg. Git is a powerful source code management tool; to learn git deeply, check out the [Pro Git book](https://git-scm.com/book/en/v2) available free online under CC BY-NC-SA 3.0 license. If you are unfamiliar with using git, it is worthwhile to explore and play with it. Try out the [git tutorial](https://git-scm.com/docs/gittutorial) as well as the [git user manual](https://git-scm.com/docs/user-manual) for help getting started. +The Gutenberg project follows a standard pull request process for contributions. See GitHub's documentation for [additional details about pull requests](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests). + ## Overview An overview of the process for contributors is: -- Fork the Gutenberg repository. -- Clone the forked repository. -- Create a new branch. -- Make code changes. -- Confirm tests pass. -- Commit the code changes within the newly created branch. -- Push the branch to the forked repository. -- Submit a pull request to the Gutenberg repository. +- Fork the Gutenberg repository. +- Clone the forked repository. +- Create a new branch. +- Make code changes. +- Confirm tests pass. +- Commit the code changes within the newly created branch. +- Push the branch to the forked repository. +- Submit a pull request to the Gutenberg repository. See the [repository management document](/docs/contributors/repository-management.md) for additional information on how the Gutenberg project uses GitHub. @@ -25,12 +25,10 @@ See the [repository management document](/docs/contributors/repository-managemen The workflow for code and documentation is the same, since both are managed in GitHub. You can watch a [video walk-through of contributing documentation](https://wordpress.tv/2020/09/02/marcus-kazmierczak-contribute-developer-documentation-to-gutenberg/) and the accompanying [slides for contributing to Gutenberg](https://mkaz.blog/wordpress/contribute-documentation-to-gutenberg/). - Here is a visual overview of the Git workflow: ![Visual Overview of Git Workflow](https://developer.wordpress.org/files/2020/09/git-workflow.png) - **Step 1**: Go to the Gutenberg repository on GitHub and click Fork. This creates a copy of the main Gutenberg repository to your account. ![Screenshot showing fork button on GitHub](https://developer.wordpress.org/files/2020/09/gutenberg-fork.png) @@ -75,17 +73,17 @@ Do not make a new pull request for updates; by pushing your change to your repos That’s it! Once approved and merged, your change will be incorporated into the main repository. 🎉 - ## Branch Naming You should name your branches using a prefixes and short description, like this: `[type]/[change]`. Suggested prefixes: -- `add/` = add a new feature -- `try/` = experimental feature, "tentatively add" -- `update/` = update an existing feature -- `remove/` = remove an existing feature +- `add/` = add a new feature +- `try/` = experimental feature, "tentatively add" +- `update/` = update an existing feature +- `remove/` = remove an existing feature +- `fix/` = fix an existing issue For example, `add/gallery-block` means you're working on adding a new gallery block. @@ -124,7 +122,7 @@ upstream https://github.com/WordPress/gutenberg.git (push) To sync your fork, you first need to fetch the upstream changes and merge them into your local copy: -``` sh +```sh git fetch upstream git checkout trunk git merge upstream/trunk diff --git a/docs/contributors/code/grammar.md b/docs/contributors/code/grammar.md index 1bbe77dc5ecf09..ae59259932f91e 100644 --- a/docs/contributors/code/grammar.md +++ b/docs/contributors/code/grammar.md @@ -1,4 +1,3 @@ - # Block Grammar
Block_List
= $(!Block .)* (Block $(!Block .)*)* $(.*)
Block
= Block_Void diff --git a/docs/contributors/code/release.md b/docs/contributors/code/release.md index aba102136232c8..bc6c0e4272cf96 100644 --- a/docs/contributors/code/release.md +++ b/docs/contributors/code/release.md @@ -47,6 +47,7 @@ This will cause the new version to be available to users of WordPress all over t You should check that folks are able to install the new version from their Dashboard. Once released, all that's left to do is writing a release post on [make.wordpress.org/core](https://make.wordpress.org/core/). You can find some tips on that below. + ### Writing the Release Notes and Post The release notes draft is auto-generated by a script that looks for pull requests for the current milestone, and groups them by pull request label. @@ -77,6 +78,7 @@ If a bug is found in a release candidate and a fix is committed to `trunk`, we s 3. When done, push the changes to GitHub: `git push`. If you decide that the fixes deserve another release candidate before the stable version is published, create one by following the instructions above. Let other contributors know that a new release candidate has been released in the [`#core-editor` channel](https://wordpress.slack.com/messages/C02QB2JS7). + ## Packages Releases to npm and WordPress Core Updates The Gutenberg repository mirrors the [WordPress SVN repository](https://make.wordpress.org/core/handbook/about/release-cycle/) in terms of branching for each SVN branch, a corresponding Gutenberg `wp/*` branch is created: @@ -110,7 +112,7 @@ The first step is automated via `./bin/plugin/cli.js npm-latest` command. You on 7. Update the `CHANGELOG.md` files of the packages with the new publish version calculated and commit to the `wp/trunk` branch. Assuming the package versions are written using this format `major.minor.patch`, make sure to bump at least the `minor` version number after every major WordPress release. For example, if the CHANGELOG of the package to be released indicates that the next unreleased version is `5.6.1`, choose `5.7.0` as a version in case of `minor` version. This is important as the patch version numbers should be reserved in case bug fixes are needed for a minor WordPress release (see below). 8. Log-in to npm via the console: `npm login`. Note that you should have 2FA enabled. 9. From the `wp/trunk` branch, install npm dependencies with `npm ci`. -10. Run the script `npm run publish:prod`. +10. Run the script `npm run publish:latest`. - When asked for the version numbers to choose for each package pick the values of the updated CHANGELOG files. - You'll be asked for your One-Time Password (OTP) a couple of times. This is the code from the 2FA authenticator app you use. Depending on how many packages are to be released you may be asked for more than one OTP, as they tend to expire before all packages are released. - If the publishing process ends up incomplete (perhaps because it timed-out or an bad OTP was introduce) you can resume it via [`lerna publish from-package`](https://github.com/lerna/lerna/tree/HEAD/commands/publish#bump-from-package). @@ -121,7 +123,7 @@ Finally, now that the npm packages are ready, a patch can be created and committ The following workflow is needed when bug fixes or security releases need to be backported into WordPress Core. This can happen in a few use-cases: -- During the `beta` and the `RC` period of the WordPress release cycle. +- During the `RC` period of the WordPress release cycle when `wp/X.Y` (example `wp/5.7`) branch for the release is already present. - For WordPress minor releases and WordPress security releases (example `5.1.1`). 1. Check out the relevant WordPress major branch (If the minor release is 5.2.1, check out `wp/5.2`). @@ -133,12 +135,12 @@ Now, the branch is ready to be used to publish the npm packages. 1. Check out the WordPress branch used before (Example `wp/5.2`). 2. `git pull`. -3. Run the [package release process] but when asked for the version numbers to choose for each package, (assuming the package versions are written using this format `major.minor.patch`) make sure to bump only the `patch` version number. For example, if the last published package version for this WordPress branch was `5.6.0`, choose `5.6.1` as a version. +3. Run the `npm run publish:patch` command (see more in [package release process]) but when asked for the version numbers to choose for each package, (assuming the package versions are written using this format `major.minor.patch`) make sure to bump only the `patch` version number. For example, if the last published package version for this WordPress branch was `5.6.0`, choose `5.6.1` as a version. **Note:** For WordPress `5.0` and WordPress `5.1`, a different release process was used. This means that when choosing npm package versions targeting these two releases, you won't be able to use the next `patch` version number as it may have been already used. You should use the "metadata" modifier for these. For example, if the last published package version for this WordPress branch was `5.6.1`, choose `5.6.1+patch.1` as a version. -3. Update the `CHANGELOG.md` files of the published packages with the new released versions and commit to the corresponding branch (Example `wp/5.2`). -4. Cherry-pick the CHANGELOG update commits into the `trunk` branch of Gutenberg. +3. Optionally update the `CHANGELOG.md` files of the published packages with the new released versions and commit to the corresponding branch (Example `wp/5.2`). +4. Cherry-pick the CHANGELOG update commits, if any, into the `trunk` branch of Gutenberg. Now, the npm packages should be ready and a patch can be created and committed into the corresponding WordPress SVN branch. @@ -213,11 +215,11 @@ Now that the changes have been committed to the `wp/trunk` branch and the Travis > @wordpress/scripts > lerna success found 3 packages ready to publish > ``` -2. Run the [package release process] but when asked for the version numbers to choose for each package use the versions you made note of above when updating each packages `CHANGELOG.md` file. +2. Run the `npm run publish:latest` command (see more in [package release process]) but when asked for the version numbers to choose for each package use the versions you made note of above when updating each packages `CHANGELOG.md` file. > Truncated example of publishing process output > > ``` - > npm run publish:prod + > npm run publish:latest > > Build Progress: [==============================] 100% > lerna notice cli v3.18.2 diff --git a/docs/contributors/code/scripts.md b/docs/contributors/code/scripts.md index 7efaa2a42cbdbb..3b36c8f4be4956 100644 --- a/docs/contributors/code/scripts.md +++ b/docs/contributors/code/scripts.md @@ -6,65 +6,65 @@ The editor provides several vendor and internal scripts to plugin developers. Sc The editor includes a number of packages to enable various pieces of functionality. Plugin developers can utilize them to create blocks, editor plugins, or generic plugins. -| Script Name | Handle | Description | -|-------------|--------|-------------| -| [Blob](/packages/blob/README.md) | wp-blob | Blob utilities | -| [Block Library](/packages/block-library/README.md) | wp-block-library | Block library for the editor | -| [Blocks](/packages/blocks/README.md) | wp-blocks | Block creations | -| [Block Serialization Default Parser](/packages/block-serialization-default-parser/README.md) | wp-block-serialization-default-parser | Default block serialization parser implementations for WordPress documents | -| [Block Serialization Spec Parser](/packages/block-serialization-spec-parser/README.md) | wp-block-serialization-spec-parser | Grammar file (grammar.pegjs) for WordPress posts | -| [Components](/packages/components/README.md) | wp-components | Generic components to be used for creating common UI elements | -| [Compose](/packages/compose/README.md) | wp-compose | Collection of handy Higher Order Components (HOCs) | -| [Core Data](/packages/core-data/README.md) | wp-core-data | Simplify access to and manipulation of core WordPress entities | -| [Data](/packages/data/README.md) | wp-data | Data module serves as a hub to manage application state for both plugins and WordPress itself | -| [Date](/packages/date/README.md) | wp-date | Date module for WordPress | -| [Deprecated](/packages/deprecated/README.md) | wp-deprecated | Utility to log a message to notify developers about a deprecated feature | -| [Dom](/packages/dom/README.md) | wp-dom | DOM utilities module for WordPress | -| [Dom Ready](/packages/dom-ready/README.md) | wp-dom-ready | Execute callback after the DOM is loaded | -| [Editor](/packages/editor/README.md) | wp-editor | Building blocks for WordPress editors | -| [Edit Post](/packages/edit-post/README.md) | wp-edit-post | Edit Post Module for WordPress | -| [Element](/packages/element/README.md) | wp-element |Element is, quite simply, an abstraction layer atop [React](https://reactjs.org/) | -| [Escape Html](/packages/escape-html/README.md) | wp-escape-html | Escape HTML utils | -| [Hooks](/packages/hooks/README.md) | wp-hooks | A lightweight and efficient EventManager for JavaScript | -| [Html Entities](/packages/html-entities/README.md) | wp-html-entities | HTML entity utilities for WordPress | -| [I18N](/packages/i18n/README.md) | wp-i18n | Internationalization utilities for client-side localization | -| [Is Shallow Equal](/packages/is-shallow-equal/README.md) | wp-is-shallow-equal | A function for performing a shallow comparison between two objects or arrays | -| [Keycodes](/packages/keycodes/README.md) | wp-keycodes | Keycodes utilities for WordPress, used to check the key pressed in events like `onKeyDown` | -| [List Reusable blocks](/packages/list-reusable-blocks/README.md) | wp-list-reusable-blocks | Package used to add import/export links to the listing page of the reusable blocks | -| [NUX](/packages/nux/README.md) | wp-nux | Components, and wp.data methods useful for onboarding a new user to the WordPress admin interface | -| [Plugins](/packages/plugins/README.md) | wp-plugins | Plugins module for WordPress | -| [Redux Routine](/packages/redux-routine/README.md) | wp-redux-routine | Redux middleware for generator coroutines | -| [Rich Text](/packages/rich-text/README.md) | wp-rich-text | Helper functions to convert HTML or a DOM tree into a rich text value and back | -| [Shortcode](/packages/shortcode/README.md) | wp-shortcode | Shortcode module for WordPress | -| [Token List](/packages/token-list/README.md) | wp-token-list | Constructable, plain JavaScript [DOMTokenList](https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList) implementation, supporting non-browser runtimes | -| [URL](/packages/url/README.md) | wp-url | A collection of utilities to manipulate URLs | -| [Viewport](/packages/viewport/README.md) | wp-viewport | Module for responding to changes in the browser viewport size | -| [Wordcount](/packages/wordcount/README.md) | wp-wordcount | WordPress word count utility | +| Script Name | Handle | Description | +| -------------------------------------------------------------------------------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [Blob](/packages/blob/README.md) | wp-blob | Blob utilities | +| [Block Library](/packages/block-library/README.md) | wp-block-library | Block library for the editor | +| [Blocks](/packages/blocks/README.md) | wp-blocks | Block creations | +| [Block Serialization Default Parser](/packages/block-serialization-default-parser/README.md) | wp-block-serialization-default-parser | Default block serialization parser implementations for WordPress documents | +| [Block Serialization Spec Parser](/packages/block-serialization-spec-parser/README.md) | wp-block-serialization-spec-parser | Grammar file (grammar.pegjs) for WordPress posts | +| [Components](/packages/components/README.md) | wp-components | Generic components to be used for creating common UI elements | +| [Compose](/packages/compose/README.md) | wp-compose | Collection of handy Higher Order Components (HOCs) | +| [Core Data](/packages/core-data/README.md) | wp-core-data | Simplify access to and manipulation of core WordPress entities | +| [Data](/packages/data/README.md) | wp-data | Data module serves as a hub to manage application state for both plugins and WordPress itself | +| [Date](/packages/date/README.md) | wp-date | Date module for WordPress | +| [Deprecated](/packages/deprecated/README.md) | wp-deprecated | Utility to log a message to notify developers about a deprecated feature | +| [Dom](/packages/dom/README.md) | wp-dom | DOM utilities module for WordPress | +| [Dom Ready](/packages/dom-ready/README.md) | wp-dom-ready | Execute callback after the DOM is loaded | +| [Editor](/packages/editor/README.md) | wp-editor | Building blocks for WordPress editors | +| [Edit Post](/packages/edit-post/README.md) | wp-edit-post | Edit Post Module for WordPress | +| [Element](/packages/element/README.md) | wp-element | Element is, quite simply, an abstraction layer atop [React](https://reactjs.org/) | +| [Escape Html](/packages/escape-html/README.md) | wp-escape-html | Escape HTML utils | +| [Hooks](/packages/hooks/README.md) | wp-hooks | A lightweight and efficient EventManager for JavaScript | +| [Html Entities](/packages/html-entities/README.md) | wp-html-entities | HTML entity utilities for WordPress | +| [I18N](/packages/i18n/README.md) | wp-i18n | Internationalization utilities for client-side localization | +| [Is Shallow Equal](/packages/is-shallow-equal/README.md) | wp-is-shallow-equal | A function for performing a shallow comparison between two objects or arrays | +| [Keycodes](/packages/keycodes/README.md) | wp-keycodes | Keycodes utilities for WordPress, used to check the key pressed in events like `onKeyDown` | +| [List Reusable blocks](/packages/list-reusable-blocks/README.md) | wp-list-reusable-blocks | Package used to add import/export links to the listing page of the reusable blocks | +| [NUX](/packages/nux/README.md) | wp-nux | Components, and wp.data methods useful for onboarding a new user to the WordPress admin interface | +| [Plugins](/packages/plugins/README.md) | wp-plugins | Plugins module for WordPress | +| [Redux Routine](/packages/redux-routine/README.md) | wp-redux-routine | Redux middleware for generator coroutines | +| [Rich Text](/packages/rich-text/README.md) | wp-rich-text | Helper functions to convert HTML or a DOM tree into a rich text value and back | +| [Shortcode](/packages/shortcode/README.md) | wp-shortcode | Shortcode module for WordPress | +| [Token List](/packages/token-list/README.md) | wp-token-list | Constructable, plain JavaScript [DOMTokenList](https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList) implementation, supporting non-browser runtimes | +| [URL](/packages/url/README.md) | wp-url | A collection of utilities to manipulate URLs | +| [Viewport](/packages/viewport/README.md) | wp-viewport | Module for responding to changes in the browser viewport size | +| [Wordcount](/packages/wordcount/README.md) | wp-wordcount | WordPress word count utility | ## Vendor Scripts The editor also uses some popular third-party packages and scripts. Plugin developers can use these scripts as well without bundling them in their code (and increasing file sizes). -| Script Name | Handle | Description | -|-------------|--------|-------------| -| [React](https://reactjs.org) | react | React is a JavaScript library for building user interfaces | +| Script Name | Handle | Description | +| ---------------------------------------------------- | --------- | ----------------------------------------------------------------------------------------------------- | +| [React](https://reactjs.org) | react | React is a JavaScript library for building user interfaces | | [React Dom](https://reactjs.org/docs/react-dom.html) | react-dom | Serves as the entry point to the DOM and server renderers for React, intended to be paired with React | -| [Moment](https://momentjs.com/) | moment| Parse, validate, manipulate, and display dates and times in JavaScript | -| [Lodash](https://lodash.com) | lodash| Lodash is a JavaScript library which provides utility functions for common programming tasks | +| [Moment](https://momentjs.com/) | moment | Parse, validate, manipulate, and display dates and times in JavaScript | +| [Lodash](https://lodash.com) | lodash | Lodash is a JavaScript library which provides utility functions for common programming tasks | ## Polyfill Scripts The editor also provides polyfills for certain features that may not be available in all modern browsers. It is recommended to use the main `wp-polyfill` script handle which takes care of loading all the below mentioned polyfills. -| Script Name | Handle | Description | -|-------------|--------|-------------| -| [Babel Polyfill](https://babeljs.io/docs/en/babel-polyfill) | wp-polyfill | Emulate a full ES2015+ environment. Main script to load all the below mentioned additional polyfills | -| [Fetch Polyfill](https://www.npmjs.com/package/whatwg-fetch) | wp-polyfill-fetch | Polyfill that implements a subset of the standard Fetch specification | -| [Promise Polyfill](https://www.npmjs.com/package/promise-polyfill) | wp-polyfill-promise| Lightweight ES6 Promise polyfill for the browser and node | -| [Formdata Polyfill](https://www.npmjs.com/package/formdata-polyfill) | wp-polyfill-formdata| Polyfill conditionally replaces the native implementation | -| [Node Contains Polyfill](https://polyfill.io) | wp-polyfill-node-contains |Polyfill for Node.contains | -| [Element Closest Polyfill](https://www.npmjs.com/package/element-closest) | wp-polyfill-element-closest| Return the closest element matching a selector up the DOM tree | +| Script Name | Handle | Description | +| ------------------------------------------------------------------------- | --------------------------- | ---------------------------------------------------------------------------------------------------- | +| [Babel Polyfill](https://babeljs.io/docs/en/babel-polyfill) | wp-polyfill | Emulate a full ES2015+ environment. Main script to load all the below mentioned additional polyfills | +| [Fetch Polyfill](https://www.npmjs.com/package/whatwg-fetch) | wp-polyfill-fetch | Polyfill that implements a subset of the standard Fetch specification | +| [Promise Polyfill](https://www.npmjs.com/package/promise-polyfill) | wp-polyfill-promise | Lightweight ES6 Promise polyfill for the browser and node | +| [Formdata Polyfill](https://www.npmjs.com/package/formdata-polyfill) | wp-polyfill-formdata | Polyfill conditionally replaces the native implementation | +| [Node Contains Polyfill](https://polyfill.io) | wp-polyfill-node-contains | Polyfill for Node.contains | +| [Element Closest Polyfill](https://www.npmjs.com/package/element-closest) | wp-polyfill-element-closest | Return the closest element matching a selector up the DOM tree | ## Bundling and code sharing diff --git a/docs/contributors/design/README.md b/docs/contributors/design/README.md index 22628b8c38d357..acf1b6cc9b2342 100644 --- a/docs/contributors/design/README.md +++ b/docs/contributors/design/README.md @@ -32,9 +32,9 @@ From the [kickoff post](https://make.wordpress.org/core/2017/01/04/focus-tech-an We can extract a few key principles from this: -- **Authoring rich posts is a key strength of WordPress.** -- **Blocks will unify features and types of interaction under a single interface.** Users shouldn’t have to write shortcodes, custom HTML, or paste URLs to embed. Users only need to learn how the block works in order to use all of its features. -- **Make core features more discoverable**, reducing hard-to-find “Mystery meat.” WordPress supports a large number of blocks and 30+ embeds. Let’s increase their visibility. +- **Authoring rich posts is a key strength of WordPress.** +- **Blocks will unify features and types of interaction under a single interface.** Users shouldn’t have to write shortcodes, custom HTML, or paste URLs to embed. Users only need to learn how the block works in order to use all of its features. +- **Make core features more discoverable**, reducing hard-to-find “Mystery meat.” WordPress supports a large number of blocks and 30+ embeds. Let’s increase their visibility. ### Why diff --git a/docs/contributors/design/the-block.md b/docs/contributors/design/the-block.md index bdb0c920c77c11..f35e17d0195928 100644 --- a/docs/contributors/design/the-block.md +++ b/docs/contributors/design/the-block.md @@ -4,12 +4,12 @@ At the core of Gutenberg lies the concept of the block. From a technical point o From a user perspective, blocks allow any kind of content, media, or functionality to be directly added to their site in a more consistent and usable way. The “add block” button gives the user access to an entire library of options all in one place, rather than having to hunt through menus or know shortcodes. -But most importantly, Gutenberg is built on the principle of *direct manipulation*, which means that the primary options for how an element is displayed are controlled *in the context of the block itself*. This is a big shift from the traditional WordPress model, where options that were often buried deep in layers of navigation menus controlled the elements on a page through indirect mechanisms. +But most importantly, Gutenberg is built on the principle of _direct manipulation_, which means that the primary options for how an element is displayed are controlled _in the context of the block itself_. This is a big shift from the traditional WordPress model, where options that were often buried deep in layers of navigation menus controlled the elements on a page through indirect mechanisms. So, for example, a user can add an image, write its caption, change its width and layout, add a link around it, all from within the block interface in the canvas. The same principle should apply to more complex blocks, like a "navigation menu", with the user being able to add, edit, move, and finalize the full presentation of their navigation. -* Users only need to learn one interface — the block — to add and edit everything on their site. Users shouldn’t have to write shortcodes, custom HTML, or understand hidden mechanisms to embed content. -* Gutenberg makes core features more discoverable, reducing hard-to-find “Mystery meat.” WordPress supports a large number of blocks and 30+ embeds. Let’s increase their visibility. +- Users only need to learn one interface — the block — to add and edit everything on their site. Users shouldn’t have to write shortcodes, custom HTML, or understand hidden mechanisms to embed content. +- Gutenberg makes core features more discoverable, reducing hard-to-find “Mystery meat.” WordPress supports a large number of blocks and 30+ embeds. Let’s increase their visibility. ## Building Blocks @@ -18,10 +18,13 @@ What does this mean for designers and developers? The block structure plus the p ![Gutenberg Blueprint](https://cldup.com/LQrPNubkJY.png) ### The primary interface for a block is the content area of the block. + The placeholder content in the content area of the block can be thought of as a guide or interface for users to follow a set of instructions or “fill in the blanks” (more on placeholders later). Since the content area represents what will actually appear on the site, interaction here hews closest to the principle of direct manipulation and will be most intuitive to the user. This should be thought of as the primary interface for adding and manipulating content and adjusting how it is displayed. ### The block toolbar is the place for critical options that can’t be incorporated into placeholder UI. + Basic block settings won’t always make sense in the context of the placeholder / content UI. As a secondary option, options that are critical to the functionality of a block can live in the block toolbar. The block toolbar is one step removed from direct manipulation, but is still highly contextual and visible on all screen sizes, so it is a great secondary option. ### The Settings Sidebar should only be used for advanced, tertiary controls. + The Settings Sidebar is not visible by default on a small / mobile screen, and may also be collapsed even in a desktop view. Therefore, it should not be relied on for anything that is necessary for the basic operation of the block. Pick good defaults, make important actions available in the block toolbar, and think of the sidebar as something that only power users may discover. diff --git a/docs/contributors/documentation/copy-guide.md b/docs/contributors/documentation/copy-guide.md index 24b3635fe328c2..36de90c9de9600 100644 --- a/docs/contributors/documentation/copy-guide.md +++ b/docs/contributors/documentation/copy-guide.md @@ -1,14 +1,17 @@ # Copy Guidelines ## Longer Text + Guidelines for writing multi-line/step instructions or narrative introductions/orientation to pages or features. This will obviously vary quite a lot depending on the context, but here are some general tips: #### ONE: Contractions are your friends! + They’re more conversational, and a simple way to make text sound friendlier and less formal. (And they save a bit of space as well: a win-win.) #### TWO: Cut phrases that inflate your word count without actually adding meaning. + This happens frequently in two specific instances. First, when writing in the passive voice: > This block can be used to display single images. @@ -36,6 +39,7 @@ Features don’t allow anyone to do anything; they’re just tools that do speci The more direct sentences are almost always clearer. Scan your copy for the words “can,” “be,” “might,” “allows you to,” and “helps”—they’re the most common culprits, and looking for those words specifically is a way to locate phrasing you can tighten up. #### THREE: Beware of “simple,” “easy,” and “just.” + It is not for us to decide what is simple: it’s for the user to decide. If we say something is easy and the user doesn’t have an easy experience, it undermines their trust in us and what we’re building. The same goes for “just”—many of us know to avoid “simple,” but still use “just” all the time. “Just click here.” “Just enter your username.” It’s the same thing: it implies that something will be no big deal, but we can’t know what the user will find to be a big deal. It’s also safer and more helpful to be specific. “Easy” and “simple” are shorthand for explanations that we haven’t written; whenever you see them, take a minute to think about what they’re standing in for. Maybe “It’s easy to add a block by hitting ‘enter’” really means “You can add more content to the page without taking your hands off the keyboard.” Great! Say the specific thing instead of relying on “easy.” @@ -43,33 +47,40 @@ It’s also safer and more helpful to be specific. “Easy” and “simple” a This isn’t to say that you should banish these words from your vocabulary. You might want to write a tooltip describing how the cover image block now requires less configuration, or an email about how we’re building a tool for quick creation of custom blocks, and you could legitimately say that the cover image block has been simplified or that we’re working to make custom block creation easier—there, the terms are descriptive and relative. But be on the lookout for ways you might be using (or overusing) them to make absolute claims that something is easy or simple, and use those as opportunities to be more specific and clear. #### FOUR: Look out for “we.” + Any time text or instructions uses “we” a lot, it means the focus of the text is on the people behind the software and not the people using the software. Sometimes that’s what you actually want—but it’s usually not. The focus should typically be on the user, what they need, and how they benefit rather than “what we did” or “what we want.” We’re the only ones that care about what we did or want; the user just wants software that works. If you see a lot of “we”s, think about whether you should reframe what you’re writing to focus on the benefits to and successes of the user. ## Bulleted Lists + Guidelines for (duh) writing bulleted lists. #### ONE: Keep sentence structures parallel across all bullets. + Parallel structure makes lists easier to read quickly—their predictability takes some cognitive load off the reader. GOOD: + > What can you do with this block? Lots of things! -> * Add a quote. -> * Highlight a link. -> * Display multiple images. -> * Create a bulleted list. +> +> - Add a quote. +> - Highlight a link. +> - Display multiple images. +> - Create a bulleted list. Every bullet is a full sentence, and ends with a period. (If your list is a bunch of one- or two-word items, those can often just turn into a single regular sentence—easier to read, and space-saving.) Every line begins with a verb that tells the user what the block can do. The subject of the sentence is always the user. A user can absorb this list quickly because once they read the first item, they understand how to read the rest and know what information they’ll find. LESS GOOD: + > What can you do with this block? Lots of things! -> * You can add a quote. -> * Highlighting a link you love. -> * It displays multiple images. Nice for galleries! -> * Bulleted lists +> +> - You can add a quote. +> - Highlighting a link you love. +> - It displays multiple images. Nice for galleries! +> - Bulleted lists Here, every line has different phrasing (some start with a verb, some with a noun) and the subject of the sentence changes (sometimes it’s you, sometimes it’s the block). Some lines have added description, some don't. There’s an incomplete sentence, and punctuation is inconsistent. @@ -78,80 +89,95 @@ Reading this list takes more work because the reader has to parse each bullet an Note: this doesn't mean every bullet has to be super short and start with an action verb! “Predictable” doesn’t have to mean “simple.” It just means that each bullet should have the same sentence structure. This list would also be fine: > What can you do with this block? Lots of things! -> * Try adding a quote. Sometimes someone else said things best! -> * Use it to highlight a link you love—sharing links is the currency of the internet. -> * Create a gallery that displays multiple images, and show off your best photos. +> +> - Try adding a quote. Sometimes someone else said things best! +> - Use it to highlight a link you love—sharing links is the currency of the internet. +> - Create a gallery that displays multiple images, and show off your best photos. Here, each bullet starts with a more user-focused verb and includes a piece of supplemental information for more interest. The punctuation varies a bit, which keeps the lines from feeling too formulaic, but since the basic structure of each is the same, they remain easy to read. #### TWO: When in doubt, start with a verb. (But not always the same verb.) + Do you have to start with a verb? No. But if you’re at a loss, you usually can’t go wrong with a verb (especially since bulleted lists are often describing a series of actions or possible actions). In a simple list that’s meant to be purely instructional (e.g., in UI copy where you just need the user to make a decision), it might be fine to start every bullet with the same verb: > To continue, choose an action: -> * Add a simple text block. -> * Add a pullquote block. -> * Add an image block. +> +> - Add a simple text block. +> - Add a pullquote block. +> - Add an image block. If your list is more persuasive (e.g., trying to convince someone to use a feature by listing its benefits) or includes multi-step instructions, you’ll want to vary your verbs to keep the reader engaged with more interesting language, as in the example above: ->What can you do with this block? Lots of things! ->* Try adding a quote. Sometimes someone else said things best! ->* Use it to highlight a link you love—sharing links is the currency of the internet. ->* Create a gallery that displays multiple images, and show off your best photos. +> What can you do with this block? Lots of things! +> +> - Try adding a quote. Sometimes someone else said things best! +> - Use it to highlight a link you love—sharing links is the currency of the internet. +> - Create a gallery that displays multiple images, and show off your best photos. These aren’t hard-and-fast rules—you might choose the use the same verb in a persuasive list to be more focused and powerful, for example. But they’re good starting places for solid lists. #### THREE: When something's clearly a list, you don't have to tell us it's a list. GOOD: + > What can you do with this block? Lots of things! -> * Add a quote. -> * Highlight a link you love. -> * Display multiple images. +> +> - Add a quote. +> - Highlight a link you love. +> - Display multiple images. LESS GOOD: + > What can you do with this block? Lots of things! Here are some examples of ways you can use it. -> * You can add a quote. -> * Highlighting a link you love. -> * It displays multiple images. Nice for galleries! +> +> - You can add a quote. +> - Highlighting a link you love. +> - It displays multiple images. Nice for galleries! Find the balance between being as clear as possible and trusting a user. On one hand, we know that people don’t always read instructions; on the other, redundancy can make the user feel like we think they’re stupid. #### FOUR: Bold is sometimes your friend. + Use it to focus readers on the key information in a bulleted list. This is especially useful when your bullets include some supplemental but ultimately secondary information. “Key information” is, well, key: bold draws the eye, so stick to the most vital piece of information in a given bullet: ->What can you do with this block? Lots of things! -> * Try adding a **quote**. Sometimes someone else said things best! -> * Use it to highlight a **link** you love—sharing links is the currency of the internet. -> * Create a **gallery** that displays multiple images, and show off your best photos. +> What can you do with this block? Lots of things! +> +> - Try adding a **quote**. Sometimes someone else said things best! +> - Use it to highlight a **link** you love—sharing links is the currency of the internet. +> - Create a **gallery** that displays multiple images, and show off your best photos. On the flipside, bolding too many things creates visual confusion: > **What can you do with this block?** Lots of things! -> * Try adding a **quote**. Sometimes someone else said things best! -> * Use it to highlight a **link** you love—sharing **links** is the currency of the internet. -> * Create a **gallery** that displays **multiple images**, and show off your best **photos**. +> +> - Try adding a **quote**. Sometimes someone else said things best! +> - Use it to highlight a **link** you love—sharing **links** is the currency of the internet. +> - Create a **gallery** that displays **multiple images**, and show off your best **photos**. When lists are short and basic, don't bother—bolding just adds busy-ness. > What can you do with this block? Lots of things! -> * Add a **quote**. -> * Highlight a **link**. -> * Display multiple **images**. +> +> - Add a **quote**. +> - Highlight a **link**. +> - Display multiple **images**. The lack of words creates its own focus; you don't have to add any more. ## UI Descriptions + Guidelines for writing one-line feature descriptions, or short descriptions to clarify options. #### ONE: Clarity above all! + If the user doesn't understand what using a particular option will result in, it doesn't matter how clever your pun is. Wordplay and idioms are frequently unclear, and easily misunderstood. If you use them at all, they should be as supplemental information— never to explain the main idea—and they should be something you’re fairly certain will be understandable to a pretty wide range of people. #### TWO: Refer back to section one, and look out for those bulk-adding phrases. + Active voice is typically the better way to go, and cutting out the bulky phrasing is particularly important when you’ve got limited space and you need people to be able to make decisions and act. Often you can shorten a UI instruction phrase to be both shorter and clearer: > When you click X, Y happens. @@ -171,20 +197,22 @@ vs. Similar phrases are “Once you do X…” or “If you want to do X…” Sometimes there are decision points where “If you want to do X…” is entirely appropriate because there are different paths the user can take based on their goal. But, we often use it to mean “Here is a thing you can do,” which you can express more simply as: “To do X…” #### THREE: Be specific. + When an action depends on the user having completed some prior action, be specific about what’s required and what happens next. We often default to “when you’re ready.” Ready for what? Be specific about whatever the prerequisites are. “When you’re ready” can mean: -* When you want to add another block” -* When you’re satisfied with your post” -* After you’ve finished proofreading your post” -* When you’d like to add a featured image” -* After you’ve configured all the settings” +- When you want to add another block” +- When you’re satisfied with your post” +- After you’ve finished proofreading your post” +- When you’d like to add a featured image” +- After you’ve configured all the settings” And when something means everything, it actually means nothing. The more specific instructions are, the more useful they are, and the more trust the person following them will have in the product. #### FOUR: This is still writing. It should have personality and interest. + Clarity above all, yes, and space is often limited here—but UI text can still be interesting to read. Single lines of description can still be complete sentences. @@ -222,6 +250,7 @@ vs. (And because it bears repeating: no wordplay, please! “Personality” can—and in UI instructions, should—be subtle. We’re talking about text that sounds like it was said by a human being, not forced attempts at whimsy.) #### FIVE: Pay attention to capitalization. + When it comes to headlines and subheads, there are two ways to capitalize: In Title Case, the First Letter of Almost Every Word Is Capitalized @@ -233,9 +262,11 @@ Feature names and dashboard sections typically use title case (think “Site Sta When you’re looking at a full page of UI copy, make sure you’re being consistent across all of it, and that all similar kinds of copy—headlines, tooltips, buttons, etc.—are using the same case. ## Error Messaging + Guidelines for writing error messages that are understandable and useful. #### ONE: Don’t ignore voice/tone in error messaging—they communicate a lot. + Voice and tone can say as much as the individual words themselves. Error messages have to convey a significant amount of information and usually need to be fairly short, but try not to sacrifice tone, or to go too far in either a negative or positive direction. Let’s say someone’s trying to publish a post, but their user role doesn’t allow them to do that. Here are some ways we could—but should not—communicate that: @@ -255,6 +286,7 @@ Here, we sound too cute. We can stay direct, positive, and friendly, even in error messages. How? With tips two through four! #### TWO: Whenever possible, offer a path to resolution. + A good error message doesn’t just alert someone to the fact that something is wrong. > Your user role is incorrect. diff --git a/docs/contributors/folder-structure.md b/docs/contributors/folder-structure.md index 6d9b9c6163764a..af136e4a6be5ff 100644 --- a/docs/contributors/folder-structure.md +++ b/docs/contributors/folder-structure.md @@ -10,16 +10,16 @@ The following snippet explains how the Gutenberg repository is structured omitti ├── CODE_OF_CONDUCT.md │ ├── .editorconfig - ├── .eslintignore - ├── .eslintrc - ├── .jshintignore - ├── .eslintignore + ├── .eslintignore + ├── .eslintrc + ├── .jshintignore + ├── .eslintignore ├── .prettierrc.js ├── .stylelintrc.json ├── .markdownlintignore ├── .npmpackagejsonlintrc.json ├── phpcs.xml.dist - │ Dot files and config files used to configure the various linting tools + │ Dot files and config files used to configure the various linting tools │ used in the repository (PHP, JS, styles...). │ ├── .browserslistrc @@ -31,7 +31,7 @@ The following snippet explains how the Gutenberg repository is structured omitti │ Transpilation and bundling Config files. │ ├── .wp-env.json - │ Config file for the development and testing environment. + │ Config file for the development and testing environment. │ Includes WordPress and the Gutenberg plugin. │ ├── composer.lock @@ -41,9 +41,9 @@ The following snippet explains how the Gutenberg repository is structured omitti │ ├── package-lock.json ├── package.json - │ Handling of JavaScript dependencies. Both for development tools and + │ Handling of JavaScript dependencies. Both for development tools and │ production dependencies. - │ The package.json also serves to define common tasks and scripts + │ The package.json also serves to define common tasks and scripts | used for day to day development. │ ├── changelog.txt @@ -79,9 +79,9 @@ The following snippet explains how the Gutenberg repository is structured omitti │ PHP Source code of the Gutenberg plugin. │ ├── packages - │ Source code of the WordPress packages. + │ Source code of the WordPress packages. │ Packages can be: - │ - Production JavaScript scripts and styles loaded on WordPress + │ - Production JavaScript scripts and styles loaded on WordPress │ and the Gutenberg plugin or distributed as npm packages. │ - Development tools available on npm. │ @@ -108,7 +108,7 @@ The following snippet explains how the Gutenberg repository is structured omitti │ Component Stories to load on the Gutenberg storybook. │ ├── packages/e2e-tests - │ End-2-end tests of the Gutenberg plugin. + │ End-2-end tests of the Gutenberg plugin. │ Distributed as a package for potential reuse in Core and other plugins. │ ├── phpunit @@ -125,4 +125,3 @@ The following snippet explains how the Gutenberg repository is structured omitti │ └── test/unit Configuration for the Packages unit tests. - diff --git a/docs/contributors/localizing.md b/docs/contributors/localizing.md index 66d8df9568296c..954f00f1117176 100644 --- a/docs/contributors/localizing.md +++ b/docs/contributors/localizing.md @@ -1,6 +1,6 @@ # Localizing Gutenberg Plugin -To translate Gutenberg in your locale or language, [select your locale here](https://translate.wordpress.org/projects/wp-plugins/gutenberg) and translate *Development* (which contains the plugin's string) and/or *Development Readme* (please translate what you see in the Details tab of the [plugin page](https://wordpress.org/plugins/gutenberg/)). +To translate Gutenberg in your locale or language, [select your locale here](https://translate.wordpress.org/projects/wp-plugins/gutenberg) and translate _Development_ (which contains the plugin's string) and/or _Development Readme_ (please translate what you see in the Details tab of the [plugin page](https://wordpress.org/plugins/gutenberg/)). A Global Translation Editor (GTE) or Project Translation Editor (PTE) with suitable rights will process your translations in due time. diff --git a/docs/contributors/repository-management.md b/docs/contributors/repository-management.md index 6ece48707c74fe..5239ce3124b96f 100644 --- a/docs/contributors/repository-management.md +++ b/docs/contributors/repository-management.md @@ -4,20 +4,20 @@ This is a living document explaining how we collaboratively manage the Gutenberg This document covers: -- [Issues](#issues) - - [Labels](#labels) - - [Milestones](#milestones) - - [Triaging Issues](#triaging-issues) -- [Pull Requests](#pull-requests) - - [Code Review](#code-review) - - [Design Review](#design-review) - - [Merging Pull Requests](#merging-pull-requests) - - [Closing Pull Requests](#closing-pull-requests) -- [Projects](#projects) +- [Issues](#issues) + - [Labels](#labels) + - [Milestones](#milestones) + - [Triaging Issues](#triaging-issues) +- [Pull Requests](#pull-requests) + - [Code Review](#code-review) + - [Design Review](#design-review) + - [Merging Pull Requests](#merging-pull-requests) + - [Closing Pull Requests](#closing-pull-requests) +- [Projects](#projects) ## Issues -A healthy issue list is one where issues are relevant and actionable. *Relevant* in the sense that they relate to the project’s current priorities. *Actionable* in the sense that it’s clear what action(s) need to be taken to resolve the issue. +A healthy issue list is one where issues are relevant and actionable. _Relevant_ in the sense that they relate to the project’s current priorities. _Actionable_ in the sense that it’s clear what action(s) need to be taken to resolve the issue. Any issues that are irrelevant or not actionable should be closed, because they get in the way of making progress on the project. Imagine the issue list as a desk: the more clutter you have on it, the more difficult it is to use the space to get work done. @@ -27,20 +27,20 @@ All issues should have [one or more labels](https://github.com/WordPress/gutenbe Workflow labels start with “Needs” and may be applied as needed. Ideally, each workflow label will have a group that follows it, such as the Accessibility Team for `Needs Accessibility Feedback`, the Testing Team for `Needs Testing`, etc. -[Priority High](https://github.com/WordPress/gutenberg/labels/Priority%20High) and [Priority OMGWTFBBQ](https://github.com/WordPress/gutenberg/labels/Priority%20OMGWTFBBQ) issues should have an assignee and/or be in an active milestone. +[Priority High](https://github.com/WordPress/gutenberg/labels/%5BPriority%5D%20High) and [Priority OMGWTFBBQ](https://github.com/WordPress/gutenberg/labels/%5BPriority%5D%20OMGWTFBBQ) issues should have an assignee and/or be in an active milestone. Help requests or 'how to' questions should be posted in a relevant support forum as a first step. If something might be a bug but it's not clear, the Support Team or a forum volunteer can help troubleshoot the case to help get all the right information needed for an effective bug report. Here are some labels you might commonly see: -- [Good First Issue](https://github.com/WordPress/gutenberg/labels/Good%20First%20Issue) - Issues identified as good for new contributors to work on. Comment to note that you intend to work on the issue and reference the issue number in the pull request you submit. -- [Good First Review](https://github.com/WordPress/gutenberg/labels/Good%20First%20Review) - Pull requests identified as good for new contributors who are interested in doing code reviews. -- [Needs Accessibility Feedback](https://github.com/WordPress/gutenberg/labels/Accessibility) - Changes that impact accessibility and need corresponding review (e.g. markup changes). -- [Needs Design Feedback](https://github.com/WordPress/gutenberg/labels/Needs%20Design%20Feedback) - Changes that modify the design or user experience in some way and need sign-off. -- [[Type] Bug](https://github.com/WordPress/gutenberg/labels/%5BType%5D%20Bug) - An existing feature is broken in some way. -- [[Type] Enhancement](https://github.com/WordPress/gutenberg/labels/%5BType%5D%20Enhancement) - Gutenberg would be better with this improvement added. -- [[Type] Plugin / Extension Conflict](https://github.com/WordPress/gutenberg/labels/%5BType%5D%20Plugin%20%2F%20Extension%20Conflict) - Documentation of a conflict between Gutenberg and a plugin or extension. The plugin author should be informed and provided documentation on how to address. -- [[Status] Needs More Info](https://github.com/WordPress/gutenberg/labels/%5BStatus%5D%20Needs%20More%20Info) - The issue needs more information in order to be actionable and relevant. Typically this requires follow-up from the original reporter. +- [Good First Issue](https://github.com/WordPress/gutenberg/labels/Good%20First%20Issue) - Issues identified as good for new contributors to work on. Comment to note that you intend to work on the issue and reference the issue number in the pull request you submit. +- [Good First Review](https://github.com/WordPress/gutenberg/labels/Good%20First%20Review) - Pull requests identified as good for new contributors who are interested in doing code reviews. +- [Needs Accessibility Feedback](https://github.com/WordPress/gutenberg/labels/Needs%20Accessibility%20Feedback) - Changes that impact accessibility and need corresponding review (e.g. markup changes). +- [Needs Design Feedback](https://github.com/WordPress/gutenberg/labels/Needs%20Design%20Feedback) - Changes that modify the design or user experience in some way and need sign-off. +- [[Type] Bug](https://github.com/WordPress/gutenberg/labels/%5BType%5D%20Bug) - An existing feature is broken in some way. +- [[Type] Enhancement](https://github.com/WordPress/gutenberg/labels/%5BType%5D%20Enhancement) - Gutenberg would be better with this improvement added. +- [[Type] Plugin Interoperability](https://github.com/WordPress/gutenberg/labels/%5BType%5D%20Plugin%20Interoperability) - Documentation of a conflict between Gutenberg and a plugin or extension. The plugin author should be informed and provided documentation on how to address. +- [[Status] Needs More Info](https://github.com/WordPress/gutenberg/labels/%5BStatus%5D%20Needs%20More%20Info) - The issue needs more information in order to be actionable and relevant. Typically this requires follow-up from the original reporter. [Check out the label directory](https://github.com/WordPress/gutenberg/labels) for a listing of all labels. @@ -50,13 +50,13 @@ We put issues into [milestones](https://github.com/wordpress/gutenberg/milestone Here are some milestones you might see: -- [WordPress X.Y](https://github.com/WordPress/gutenberg/milestone/70): Tasks that should be done for future WordPress releases. -- [X.Y (Gutenberg)](https://github.com/WordPress/gutenberg/milestone/85): PRs targeted for the Gutenberg Plugin X.Y release. -- [Future](https://github.com/WordPress/gutenberg/milestone/35): this is something that is confirmed by everyone as a good thing but doesn’t fall into other criteria. +- [WordPress X.Y](https://github.com/WordPress/gutenberg/milestone/70): Tasks that should be done for future WordPress releases. +- [X.Y (Gutenberg)](https://github.com/WordPress/gutenberg/milestone/85): PRs targeted for the Gutenberg Plugin X.Y release. +- [Future](https://github.com/WordPress/gutenberg/milestone/35): this is something that is confirmed by everyone as a good thing but doesn’t fall into other criteria. ### Triaging Issues -To keep the issue list healthy, it needs to be triaged regularly. *Triage* is the practice of reviewing existing issues to make sure they’re relevant, actionable, and have all the information they need. +To keep the issue list healthy, it needs to be triaged regularly. _Triage_ is the practice of reviewing existing issues to make sure they’re relevant, actionable, and have all the information they need. Anyone can help triage, although you’ll need contributor permission on the Gutenberg repository to modify an issue’s labels or edit its title. @@ -74,30 +74,30 @@ Gutenberg follows a feature branch pull request workflow for all code and docume For labeling and naming pull requests, here are guidelines to consider that make compiling the changelog more efficient and organized. These guidelines are particularly relevant for regular contributors. Don't let getting the following right be a blocker for sharing your work - mistakes are expected and easy to fix! -- When working on experimental screens and features, apply the `[Type] Experimental` label instead of `Feature`, `Enhancement`, etc. -- When working on new features to technical packages (scripts, create-block, adding react hooks, etc), apply the `[Type] New API` label instead of `Feature`, `Enhancement`, etc. -- When fixing a bug or making an enhancement to an internal tool used in the project, apply the `[Type] Build Tooling` instead of `Bugs`, `Enhancement`, etc -- In pull request titles, instead of describing the code change done to fix an issue, consider referring to the actual bug being fixed instead. For example: instead of saying "Check for nullable object in component", it would be preferable to say "Fix editor breakage when clicking the copy block button". +- When working on experimental screens and features, apply the `[Type] Experimental` label instead of `Feature`, `Enhancement`, etc. +- When working on new features to technical packages (scripts, create-block, adding react hooks, etc), apply the `[Type] New API` label instead of `Feature`, `Enhancement`, etc. +- When fixing a bug or making an enhancement to an internal tool used in the project, apply the `[Type] Build Tooling` instead of `Bugs`, `Enhancement`, etc +- In pull request titles, instead of describing the code change done to fix an issue, consider referring to the actual bug being fixed instead. For example: instead of saying "Check for nullable object in component", it would be preferable to say "Fix editor breakage when clicking the copy block button". Along with this process, there are a few important points to mention: -- Non-trivial pull requests should be preceded by a related issue that defines the problem to solve and allows for discussion of the most appropriate solution before actually writing code. -- To make it far easier to merge your code, each pull request should only contain one conceptual change. Keeping contributions atomic keeps the pull request discussion focused on one topic and makes it possible to approve changes on a case-by-case basis. -- Separate pull requests can address different items or todos from their linked issue, there’s no need for a single pull request to cover a single issue if the issue is non-trivial. +- Non-trivial pull requests should be preceded by a related issue that defines the problem to solve and allows for discussion of the most appropriate solution before actually writing code. +- To make it far easier to merge your code, each pull request should only contain one conceptual change. Keeping contributions atomic keeps the pull request discussion focused on one topic and makes it possible to approve changes on a case-by-case basis. +- Separate pull requests can address different items or todos from their linked issue, there’s no need for a single pull request to cover a single issue if the issue is non-trivial. ### Code Review Every pull request goes through a manual code review, in addition to automated tests. The objectives for the code review are best thought of as: -- Correct — Does the change do what it’s supposed to? -- Secure — Would a nefarious party find some way to exploit this change? -- Readable — Will your future self be able to understand this change months down the road? -- Elegant — Does the change fit aesthetically within the overall style and architecture? -- Altruistic — How does this change contribute to the greater whole? +- Correct — Does the change do what it’s supposed to? +- Secure — Would a nefarious party find some way to exploit this change? +- Readable — Will your future self be able to understand this change months down the road? +- Elegant — Does the change fit aesthetically within the overall style and architecture? +- Altruistic — How does this change contribute to the greater whole? -*As a reviewer*, your feedback should be focused on the idea, not the person. Seek to understand, be respectful, and focus on constructive dialog. +_As a reviewer_, your feedback should be focused on the idea, not the person. Seek to understand, be respectful, and focus on constructive dialog. -*As a contributor*, your responsibility is to learn from suggestions and iterate your pull request should it be needed based on feedback. Seek to collaborate and produce the best possible contribution to the greater whole. +_As a contributor_, your responsibility is to learn from suggestions and iterate your pull request should it be needed based on feedback. Seek to collaborate and produce the best possible contribution to the greater whole. Code reviews are encouraged by everyone who is willing to attempt one. If you review a pull request and are confident in the changes, approve it. If you don't feel totally confident it is ready for merging, add your review with a comment that says it should have another set of eyes on it before final approval. This can help filter out obvious bugs and simplify reviews for core members. Following the later reviews will also help improve your reviewing confidence in the future. @@ -109,21 +109,21 @@ If your pull request impacts the design/UI, you need to label appropriately to a As a guide, changes that should be reviewed: -- A change based on a previous design, to confirm the design is still valid with the change. -- Anything that changes something visually. -- If you just want design feedback on an idea or exploration. +- A change based on a previous design, to confirm the design is still valid with the change. +- Anything that changes something visually. +- If you just want design feedback on an idea or exploration. ### Merging Pull Requests A pull request can generally be merged once it is: -- Deemed a worthwhile change to the codebase. -- In compliance with all relevant code review criteria. -- Covered by sufficient tests, as necessary. -- Vetted against all potential edge cases. -- Changelog entries were properly added. -- Reviewed by someone other than the original author. -- [Rebased](/docs/contributors/code/git-workflow.md#keeping-your-branch-up-to-date) onto the latest version of the master branch. +- Deemed a worthwhile change to the codebase. +- In compliance with all relevant code review criteria. +- Covered by sufficient tests, as necessary. +- Vetted against all potential edge cases. +- Changelog entries were properly added. +- Reviewed by someone other than the original author. +- [Rebased](/docs/contributors/code/git-workflow.md#keeping-your-branch-up-to-date) onto the latest version of the master branch. The final pull request merge decision is made by the **@wordpress/gutenberg-core** team. @@ -131,7 +131,6 @@ All members of the WordPress organization on GitHub have the ability to review a Most pull requests will be automatically assigned a release milestone, but please make sure your merged pull request was assigned one. Doing so creates the historical legacy of what code landed when, and makes it possible for all project contributors (even non-technical ones) to access this information. - ### Closing Pull Requests Sometimes, a pull request may not be mergeable, no matter how much additional effort is applied to it (e.g. out of scope). In these cases, it’s best to communicate with the contributor graciously while describing why the pull request was closed, this encourages productive future involvement. @@ -144,19 +143,19 @@ Make sure to: If you’d like a template to follow: -> Thanks ____ for the time you’ve spent on this pull request. +> Thanks \_\_\_\_ for the time you’ve spent on this pull request. > -> I’m closing this pull request because ____. To clarify further, ____. +> I’m closing this pull request because \_\_\_\_. To clarify further, \_\_\_\_. > -> For more details, please see ____ and ____. +> For more details, please see \_\_\_\_ and \_\_\_\_. ## Teams Two GitHub teams are used in the project. -* [Gutenberg Core](https://github.com/orgs/WordPress/teams/gutenberg-core): A team composed of people that are actively involved in the project: attending meetings regularly, participating in triage sessions, performing reviews regularly, working on features and bug fixes and performing plugin and npm releases. +- [Gutenberg Core](https://github.com/orgs/WordPress/teams/gutenberg-core): A team composed of people that are actively involved in the project: attending meetings regularly, participating in triage sessions, performing reviews regularly, working on features and bug fixes and performing plugin and npm releases. -* [Gutenberg](https://github.com/orgs/WordPress/teams/gutenberg): A team composed of contributors with at least 2–3 meaningful contributions to the project. +- [Gutenberg](https://github.com/orgs/WordPress/teams/gutenberg): A team composed of contributors with at least 2–3 meaningful contributions to the project. If you meet this criteria of several meaningful contributions having been accepted into the repository and would like to be added to the Gutenberg team, feel free to ask in the [#core-editor Slack channel](https://make.wordpress.org/chat/). @@ -166,6 +165,6 @@ We use [GitHub projects](https://github.com/WordPress/gutenberg/projects) to kee Some key projects include: -* [Phase 2](https://github.com/WordPress/gutenberg/projects/13) - Development tasks needed for Phase 2 of Gutenberg. -* [Phase 2 design](https://github.com/WordPress/gutenberg/projects/21) - Tasks for design in Phase 2. Note: specific projects may have their own boards. -* [Ideas](https://github.com/WordPress/gutenberg/projects/8) - Project containing tickets that, while closed for the time being, can be revisited in the future. +- [Phase 2](https://github.com/WordPress/gutenberg/projects/13) - Development tasks needed for Phase 2 of Gutenberg. +- [Phase 2 design](https://github.com/WordPress/gutenberg/projects/21) - Tasks for design in Phase 2. Note: specific projects may have their own boards. +- [Ideas](https://github.com/WordPress/gutenberg/projects/8) - Project containing tickets that, while closed for the time being, can be revisited in the future. diff --git a/docs/contributors/roadmap.md b/docs/contributors/roadmap.md index 10b92083e2bd0a..ae7aa5ea797731 100644 --- a/docs/contributors/roadmap.md +++ b/docs/contributors/roadmap.md @@ -8,24 +8,24 @@ Gutenberg is already in use by millions of sites through WordPress, so in order ## Projects -- **Block Registry** — define an entry point for block identification. ([See active RFC](https://github.com/WordPress/gutenberg/pull/13693).) -- **Live Component Library** — a place to visualize and interact with the UI components and block tools included in the packages. -- **Modular Editor** — allow loading the block editor in several contexts without a dependency to a post object. (Ongoing [pending tasks](https://github.com/WordPress/gutenberg/issues/14043).) -- **Better Validation** — continue to refine the mechanisms used in validating editor content. (See in depth overview at [#11440](https://github.com/WordPress/gutenberg/issues/11440) and [#7604](https://github.com/WordPress/gutenberg/issues/7604).) -- **Block Areas** — build support for areas of blocks that fall outside the content (including relationship with templates, registration, storage, and so on). ([See overview](https://github.com/WordPress/gutenberg/issues/13489).) -- **Multi-Block Editing** — allow modifying attributes of multiple blocks of the same kind at once. -- **Rich Text Roadmap** — continue to develop the capabilities of the rich text package. ([See overview](https://github.com/WordPress/gutenberg/issues/13778).) -- **Common Block Functionality** — coalesce into a preferred mechanism for creating and sharing chunks of functionality (block alignment, color tools, etc) across blocks with a simple and intuitive code interface. (Suggested exploration: React Hooks, [see overview](https://github.com/WordPress/gutenberg/issues/15450).) -- **Responsive Images** — propose mechanisms for handling flexible image sources that can be optimized for loading and takes into account their placement on a page (within main content, a column, sidebar, etc). -- **Async Loading** — propose a strategy for loading block code only when necessary in the editor without overhead for the developer or disrupting the user experience. -- **Styles** — continue to develop the mechanisms for managing block style variations and other styling solutions. (See overview at [#7551](https://github.com/WordPress/gutenberg/issues/7551) and [#9534](https://github.com/WordPress/gutenberg/issues/9534).) -- **Bundling Front-end Assets** — explore ways in which front-end styles for blocks could be assembled based on which blocks are used in a given page response. ([See overview](https://github.com/WordPress/gutenberg/issues/5445).) -- **Transforms API** — improve the transform API to allow advanced use-cases: support for async-transforms, access to the block editor settings and bring consistency between the different types of transforms. ([See related issue](https://github.com/WordPress/gutenberg/issues/14755).) +- **Block Registry** — define an entry point for block identification. ([See active RFC](https://github.com/WordPress/gutenberg/pull/13693).) +- **Live Component Library** — a place to visualize and interact with the UI components and block tools included in the packages. +- **Modular Editor** — allow loading the block editor in several contexts without a dependency to a post object. (Ongoing [pending tasks](https://github.com/WordPress/gutenberg/issues/14043).) +- **Better Validation** — continue to refine the mechanisms used in validating editor content. (See in depth overview at [#11440](https://github.com/WordPress/gutenberg/issues/11440) and [#7604](https://github.com/WordPress/gutenberg/issues/7604).) +- **Block Areas** — build support for areas of blocks that fall outside the content (including relationship with templates, registration, storage, and so on). ([See overview](https://github.com/WordPress/gutenberg/issues/13489).) +- **Multi-Block Editing** — allow modifying attributes of multiple blocks of the same kind at once. +- **Rich Text Roadmap** — continue to develop the capabilities of the rich text package. ([See overview](https://github.com/WordPress/gutenberg/issues/13778).) +- **Common Block Functionality** — coalesce into a preferred mechanism for creating and sharing chunks of functionality (block alignment, color tools, etc) across blocks with a simple and intuitive code interface. (Suggested exploration: React Hooks, [see overview](https://github.com/WordPress/gutenberg/issues/15450).) +- **Responsive Images** — propose mechanisms for handling flexible image sources that can be optimized for loading and takes into account their placement on a page (within main content, a column, sidebar, etc). +- **Async Loading** — propose a strategy for loading block code only when necessary in the editor without overhead for the developer or disrupting the user experience. +- **Styles** — continue to develop the mechanisms for managing block styles and other styling solutions. (See overview at [#7551](https://github.com/WordPress/gutenberg/issues/7551) and [#9534](https://github.com/WordPress/gutenberg/issues/9534).) +- **Bundling Front-end Assets** — explore ways in which front-end styles for blocks could be assembled based on which blocks are used in a given page response. ([See overview](https://github.com/WordPress/gutenberg/issues/5445).) +- **Transforms API** — improve the transform API to allow advanced use-cases: support for async-transforms, access to the block editor settings and bring consistency between the different types of transforms. ([See related issue](https://github.com/WordPress/gutenberg/issues/14755).) ## Timeline The projects outlined above indicate areas of interest but not necessarily development priorities. Sometimes, a product need will accelerate a resolution (as is the case of the block registry), other times community interest might be the driving force. -- 2019 Q1: Block Registry — First phase. Required for plugin directory "meta" project. -- 2019 Q2: Modular Editor — Requirement for most of phase 2. -- 2019 Q3: Block Areas. +- 2019 Q1: Block Registry — First phase. Required for plugin directory "meta" project. +- 2019 Q2: Modular Editor — Requirement for most of phase 2. +- 2019 Q3: Block Areas. diff --git a/docs/explanations/architecture/README.md b/docs/explanations/architecture/README.md index caf7b64c3ffdc2..723bce3ce4e2f4 100644 --- a/docs/explanations/architecture/README.md +++ b/docs/explanations/architecture/README.md @@ -2,12 +2,12 @@ Let’s look at the big picture and the architectural and UX principles of the block editor and the Gutenberg repository. -- [Key Concepts](/docs/explanations/architecture/key-concepts.md) -- [Data Format And Data Flow](/docs/explanations/architecture/data-flow.md) -- [Understand the repository folder structure](/docs/contributors/folder-structure.md). -- [Modularity and WordPress Packages](/docs/explanations/architecture/modularity.md). -- [Block Editor Performance](/docs/explanations/architecture/performance.md). -- What are the decision decisions behind the Data Module? -- [Why is Puppeteer the tool of choice for end-to-end tests?](/docs/explanations/architecture/automated-testing.md) -- [What's the difference between the different editor packages? What's the purpose of each package?](/docs/explanations/architecture/modularity.md#whats-the-difference-between-the-different-editor-packages-whats-the-purpose-of-each-package) -- [Template and template parts flows](/docs/explanations/architecture/full-site-editing-templates.md) +- [Key Concepts](/docs/explanations/architecture/key-concepts.md) +- [Data Format And Data Flow](/docs/explanations/architecture/data-flow.md) +- [Understand the repository folder structure](/docs/contributors/folder-structure.md). +- [Modularity and WordPress Packages](/docs/explanations/architecture/modularity.md). +- [Block Editor Performance](/docs/explanations/architecture/performance.md). +- What are the decision decisions behind the Data Module? +- [Why is Puppeteer the tool of choice for end-to-end tests?](/docs/explanations/architecture/automated-testing.md) +- [What's the difference between the different editor packages? What's the purpose of each package?](/docs/explanations/architecture/modularity.md#whats-the-difference-between-the-different-editor-packages-whats-the-purpose-of-each-package) +- [Template and template parts flows](/docs/explanations/architecture/full-site-editing-templates.md) diff --git a/docs/explanations/architecture/data-flow.md b/docs/explanations/architecture/data-flow.md index 07957382ec1bf2..e000cd33b46317 100644 --- a/docs/explanations/architecture/data-flow.md +++ b/docs/explanations/architecture/data-flow.md @@ -9,11 +9,7 @@ A block editor post is not the artifact it produces, namely the `post_content`. The input and output of the block editor is a tree of block objects with the current format: ```js -const value = [ - block1, - block2, - block3 -]; +const value = [ block1, block2, block3 ]; ``` ### The block object @@ -22,60 +18,60 @@ Each block object has an id, a set of attributes and potentially a list of child ```js const block = { - clientId, // unique string identifier. - type, // The block type (paragraph, image...) - attributes, // (key, value) set of attributes representing the direct properties/content of the current block. - innerBlocks // An array of child blocks or inner blocks. -} + clientId, // unique string identifier. + type, // The block type (paragraph, image...) + attributes, // (key, value) set of attributes representing the direct properties/content of the current block. + innerBlocks, // An array of child blocks or inner blocks. +}; ``` -Note the attributes keys and types, the allowed inner blocks are defined by the block type. For example, the core quote block has a `cite` string attribute representing the cite content while a heading block has a numeric `level` attribute, representing the level of the heading (1 to 6). +Note the attributes keys and types, the allowed inner blocks are defined by the block type. For example, the core quote block has a `cite` string attribute representing the cite content while a heading block has a numeric `level` attribute, representing the level of the heading (1 to 6). During the lifecycle of the block in the editor, the block object can receive extra metadata: - - `isValid`: A boolean representing whether the block is valid or not; - - `originalContent`: The original HTML serialization of the block. +- `isValid`: A boolean representing whether the block is valid or not; +- `originalContent`: The original HTML serialization of the block. **Examples** ```js // A simple paragraph block. const paragraphBlock1 = { - clientId: "51828be1-5f0d-4a6b-8099-f4c6f897e0a3", - type: "core/paragraph", - attributes: { - content: "This is the content of the paragraph block", - dropCap: true - } -} + clientId: '51828be1-5f0d-4a6b-8099-f4c6f897e0a3', + type: 'core/paragraph', + attributes: { + content: 'This is the content of the paragraph block', + dropCap: true, + }, +}; // A separator block. const separatorBlock = { - clientId: "51828be1-5f0d-4a6b-8099-f4c6f897e0a4", - type: "core/separator", - attributes: {} -} + clientId: '51828be1-5f0d-4a6b-8099-f4c6f897e0a4', + type: 'core/separator', + attributes: {}, +}; // A columns block with a paragraph block on each column. const columnsBlock = { - clientId: "51828be1-5f0d-4a6b-8099-f4c6f897e0a7", - type: "core/columns", - attributes: {}, - innerBlocks: [ - { - clientId: "51828be1-5f0d-4a6b-8099-f4c6f897e0a5", - type: "core/column", - attributes: {}, - innerBlocks: [ paragraphBlock1 ], - }, - { - clientId: "51828be1-5f0d-4a6b-8099-f4c6f897e0a6", - type: "core/column", - attributes: {}, - innerBlocks: [ paragraphBlock2 ], - } - ] -} + clientId: '51828be1-5f0d-4a6b-8099-f4c6f897e0a7', + type: 'core/columns', + attributes: {}, + innerBlocks: [ + { + clientId: '51828be1-5f0d-4a6b-8099-f4c6f897e0a5', + type: 'core/column', + attributes: {}, + innerBlocks: [ paragraphBlock1 ], + }, + { + clientId: '51828be1-5f0d-4a6b-8099-f4c6f897e0a6', + type: 'core/column', + attributes: {}, + innerBlocks: [ paragraphBlock2 ], + }, + ], +}; ``` ## Serialization and Parsing diff --git a/docs/explanations/architecture/full-site-editing-templates.md b/docs/explanations/architecture/full-site-editing-templates.md index 11e8728ba1aa3f..10f1ac3d537ad8 100644 --- a/docs/explanations/architecture/full-site-editing-templates.md +++ b/docs/explanations/architecture/full-site-editing-templates.md @@ -22,22 +22,22 @@ The synchronization consists of duplicating the theme templates in the `wp_templ This means: - - The rendering/fetching of templates only need to consider the custom post type templates. It is not necessary to fetch the template files from the theme folder directly. The synchronization will ensure these are duplicated in the CPT. - - Untouched theme templates have the `auto-draft` status. - - Edited theme templates have the `publish` status. +- The rendering/fetching of templates only need to consider the custom post type templates. It is not necessary to fetch the template files from the theme folder directly. The synchronization will ensure these are duplicated in the CPT. +- Untouched theme templates have the `auto-draft` status. +- Edited theme templates have the `publish` status. The synchronization is important for two different flows: - - When editing the template and template parts, the site editor frontend fetches the edited and available templates through the REST API. This means that for all `GET` API requests performed to the `wp-templates` and `wp-template-parts` endpoint synchronization is required. - - When rendering a template (sometimes referred to as "resolving a template"): this is the algorithm that WordPress follows to traverse the template hierarchy and find the right template to render for the current page being loaded. - - When exporting a block-based theme, we need to export all its templates back as files. The synchronization is required to simplify the operation and only export the CPT templates. +- When editing the template and template parts, the site editor frontend fetches the edited and available templates through the REST API. This means that for all `GET` API requests performed to the `wp-templates` and `wp-template-parts` endpoint synchronization is required. +- When rendering a template (sometimes referred to as "resolving a template"): this is the algorithm that WordPress follows to traverse the template hierarchy and find the right template to render for the current page being loaded. +- When exporting a block-based theme, we need to export all its templates back as files. The synchronization is required to simplify the operation and only export the CPT templates. ## Switching themes Since block-based themes make use of templates that can refer to each other and that can be saved to a custom post type, it becomes possible to mix templates and template parts from different themes. For example: - - A user might like the "header" template part of theme A and would like to use it in theme B. - - A user might like the "contact" template from theme A and would like to use it in theme B. +- A user might like the "header" template part of theme A and would like to use it in theme B. +- A user might like the "contact" template from theme A and would like to use it in theme B. Enabling these flows will require well thought UIs and experience. For the current phase of Full-site editing, we're starting by forbidding these possibilities and making template and template-parts theme specific. diff --git a/docs/explanations/architecture/key-concepts.md b/docs/explanations/architecture/key-concepts.md index 1aca3b60ff1ee8..770d90462a7b22 100644 --- a/docs/explanations/architecture/key-concepts.md +++ b/docs/explanations/architecture/key-concepts.md @@ -36,14 +36,14 @@ Given a block type, a block variation is a predefined set of its initial attribu **More on Blocks** -- **[Block API](/docs/reference-guides/block-api/README.md)** -- **[Tutorial: Building A Custom Block](/docs/getting-started/tutorials/create-block/README.md)** +- **[Block API](/docs/reference-guides/block-api/README.md)** +- **[Tutorial: Building A Custom Block](/docs/getting-started/tutorials/create-block/README.md)** ## Reusable Blocks -A reusable blocks is a block (or multiple blocks) that can be inserted and edited globally at once. If a reusable block is edited in one place, those changes are reflected across all posts and pages that that block is used. Examples of reusable blocks include a block consisting of a heading whose content and a custom color that would be appear on multiple pages of the site and sidebar widgets that would appear on every page. +A reusable blocks is a block (or multiple blocks) that can be inserted and edited globally at once. If a reusable block is edited in one place, those changes are reflected across all posts and pages that that block is used. Examples of reusable blocks include a block consisting of a heading whose content and a custom color that would be appear on multiple pages of the site and sidebar widgets that would appear on every page. -Any edits to a reusable block will appear on every other use of that block, saving time from having to make the same edit on different posts. +Any edits to a reusable block will appear on every other use of that block, saving time from having to make the same edit on different posts. In technical details, reusable blocks are stored as a hidden post type (`wp_block`) and are dynamic blocks that "ref" or reference the `post_id` and return the `post_content` for that block. diff --git a/docs/explanations/architecture/performance.md b/docs/explanations/architecture/performance.md index a886beaf73850b..bd6753b6664221 100644 --- a/docs/explanations/architecture/performance.md +++ b/docs/explanations/architecture/performance.md @@ -4,11 +4,11 @@ Performance is a key feature for editor applications and the Block editor is not ## Metrics -To ensure the block editor stays performant across releases and development, we monitor some key metrics using [performance testing](/docs/contributors/code/testing-overview.md#performance-testing). +To ensure the block editor stays performant across releases and development, we monitor some key metrics using [performance testing](/docs/contributors/code/testing-overview.md#performance-testing). **Loading Time:** The time it takes to load an editor page. **Typing Time:** The time it takes for the browser to respond while typing on the editor. -**Block Selection Time:** The time it takes for the browser to respond after a user selects block. (Inserting a block is also equivalent to selecting a block. Monitoring the selection is sufficient to cover both metrics). +**Block Selection Time:** The time it takes for the browser to respond after a user selects block. (Inserting a block is also equivalent to selecting a block. Monitoring the selection is sufficient to cover both metrics). ## Key Performance Decisions and Solutions @@ -26,5 +26,4 @@ Based on the idea that **when editing a given block, it is very rare that an upd ## Going further - - [Journey towards a performant editor](https://riad.blog/2020/02/14/a-journey-towards-a-performant-web-editor/) - +- [Journey towards a performant editor](https://riad.blog/2020/02/14/a-journey-towards-a-performant-web-editor/) diff --git a/docs/getting-started/README.md b/docs/getting-started/README.md index 82eb07d95d9858..e3b8b1dc274e7e 100644 --- a/docs/getting-started/README.md +++ b/docs/getting-started/README.md @@ -2,8 +2,8 @@ ## [Tutorials](/docs/getting-started/tutorials/README.md) -- [Development Environment](/docs/getting-started/tutorials/devenv/README.md) -- [Create a Block Tutorial](/docs/getting-started/tutorials/create-block/README.md) +- [Development Environment](/docs/getting-started/tutorials/devenv/README.md) +- [Create a Block Tutorial](/docs/getting-started/tutorials/create-block/README.md) ## [Glossary](/docs/getting-started/glossary.md) diff --git a/docs/getting-started/faq.md b/docs/getting-started/faq.md index aba712e9b0b17d..5a685ce6053b7a 100644 --- a/docs/getting-started/faq.md +++ b/docs/getting-started/faq.md @@ -4,15 +4,15 @@ What follows is a set of questions that have come up from the last few years of ## What is Gutenberg? -“Gutenberg” is the name of the project to create a new editor experience for WordPress — contributors have been working on it since January 2017 and it’s one of the most significant changes to WordPress in years. It’s built on the idea of using “blocks” to write and design posts and pages. This will serve as the foundation for future improvements to WordPress, including blocks as a way not just to design posts and pages, but also entire sites. The overall goal is to simplify the first-time user experience of WordPress — for those who are writing, editing, publishing, and designing web pages. The editing experience is intended to give users a better visual representation of what their post or page will look like when they hit publish. Originally, this was the kickoff goal: +“Gutenberg” is the name of the project to create a new editor experience for WordPress — contributors have been working on it since January 2017 and it’s one of the most significant changes to WordPress in years. It’s built on the idea of using “blocks” to write and design posts and pages. This will serve as the foundation for future improvements to WordPress, including blocks as a way not just to design posts and pages, but also entire sites. The overall goal is to simplify the first-time user experience of WordPress — for those who are writing, editing, publishing, and designing web pages. The editing experience is intended to give users a better visual representation of what their post or page will look like when they hit publish. Originally, this was the kickoff goal: > The editor will endeavour to create a new page and post building experience that makes writing rich posts effortless, and has “blocks” to make it easy what today might take shortcodes, custom HTML, or “mystery meat” embed discovery. Key takeaways include the following points: -- Authoring richly laid-out posts is a key strength of WordPress. -- By embracing blocks as an interaction paradigm, we can unify multiple different interfaces into one. Instead of learning how to write shortcodes and custom HTML, or pasting URLs to embed media, there's a common, reliable flow for inserting any kind of content. -- “Mystery meat” refers to hidden features in software, features that you have to discover. WordPress already supports a large number of blocks and 30+ embeds, so let's surface them. +- Authoring richly laid-out posts is a key strength of WordPress. +- By embracing blocks as an interaction paradigm, we can unify multiple different interfaces into one. Instead of learning how to write shortcodes and custom HTML, or pasting URLs to embed media, there's a common, reliable flow for inserting any kind of content. +- “Mystery meat” refers to hidden features in software, features that you have to discover. WordPress already supports a large number of blocks and 30+ embeds, so let's surface them. Gutenberg is developed on [GitHub](https://github.com/WordPress/gutenberg) under the WordPress organization. The block editor has been available in core WordPress since 5.0. If you want to test upcoming features from Gutenberg project, it is [available in the plugin repository](https://wordpress.org/plugins/gutenberg/). @@ -25,7 +25,7 @@ There are four phases of Gutenberg which you can see on the [official WordPress 3. Collaboration — A more intuitive way to co-author content 4. Multi-lingual — Core implementation for Multi-lingual sites -## When was Gutenberg started? +## When was Gutenberg started? The editor focus started in early 2017 with the first three months spent designing, planning, prototyping, and testing prototypes, to help us inform how to approach this project. The first plugin was launched during WordCamp Europe in June 2017. @@ -37,12 +37,12 @@ Gutenberg was first merged into [WordPress 5.0](https://wordpress.org/news/2018/ The classic WordPress editor is an open text window—it’s always been a wonderful blank canvas for writing, but when it comes to building posts and pages with images, multimedia, embedded content from social media, polls, and other elements, it required a mix of different approaches that were not always intuitive: -- Media library/HTML for images, multimedia and approved files. -- Pasted links for embeds. -- Shortcodes for specialized assets from plugins. -- Featured images for the image at the top of a post or page. -- Excerpts for subheadings. -- Widgets for content on the side of a page. +- Media library/HTML for images, multimedia and approved files. +- Pasted links for embeds. +- Shortcodes for specialized assets from plugins. +- Featured images for the image at the top of a post or page. +- Excerpts for subheadings. +- Widgets for content on the side of a page. As we thought about these uses and how to make them obvious and consistent, we began to embrace the concept of “blocks.” All of the above items could be blocks: easy to search and understand, and easy to dynamically shift around the page. The block concept is very powerful, and when designed thoughtfully, can offer an outstanding editing and publishing experience. Ultimately, the idea with blocks is to create a new common language across WordPress, a new way to connect users to plugins, and replace a number of older content types — things like shortcodes and widgets — that one usually has to be well-versed in the idiosyncrasies of WordPress to understand. @@ -276,11 +276,11 @@ No. [TinyMCE](https://www.tinymce.com/) is only used for the "Classic" block. Gutenberg works in modern browsers, and Internet Explorer 11. -Our [list of supported browsers can be found in the Make WordPress handbook](https://make.wordpress.org/core/handbook/best-practices/browser-support/). By “modern browsers” we generally mean the *current and past two versions* of each major browser. +Our [list of supported browsers can be found in the Make WordPress handbook](https://make.wordpress.org/core/handbook/best-practices/browser-support/). By “modern browsers” we generally mean the _current and past two versions_ of each major browser. ## How do I make my own block? -The best place to start is the [Create a Block Tutorial](https://developer.wordpress.org/block-editor/tutorials/create-block/). +The best place to start is the [Create a Block Tutorial](https://developer.wordpress.org/block-editor/tutorials/create-block/). ## Does Gutenberg involve editing posts/pages in the front-end? @@ -339,7 +339,7 @@ function gutenbergtheme_editor_styles() { add_action( 'enqueue_block_editor_assets', 'gutenbergtheme_editor_styles' ); ``` -*See:* [Editor Styles](/docs/how-to-guides/themes/theme-support.md#editor-styles) +_See:_ [Editor Styles](/docs/how-to-guides/themes/theme-support.md#editor-styles) ## Should I be concerned that Gutenberg will make my plugin obsolete? @@ -355,7 +355,6 @@ There is a “Classic” block, which is virtually the same as the current edito There is also the [Classic Editor plugin](https://wordpress.org/plugins/classic-editor/) which restores the previous editor, see the plugin for more information. The WordPress Core team has committed to supporting the Classic Editor plugin [until December 2021](https://make.wordpress.org/core/2018/11/07/classic-editor-plugin-support-window/). - ## How do custom TinyMCE buttons work in Gutenberg? Custom TinyMCE buttons still work in the “Classic” block, which is a block version of the classic editor you know today. @@ -372,9 +371,9 @@ However we see the block as an evolution of the `[shortcode]`. Instead of having We think so for a variety of reasons including but not limited to: -- Blocks have visual editing built-in which creates a more rich, dynamic experience for building your site. -- Blocks are simply html and don’t persist things the browser doesn't understand on the frontend. In comparison, if you disable a plugin that powers a shortcode, you end up with strange visuals on the frontend (often just showing the shortcode in plain text). -- Blocks will be discovered more readily with the launch of the block directory in a way shortcodes never could be allowing for more people to get more functionality. +- Blocks have visual editing built-in which creates a more rich, dynamic experience for building your site. +- Blocks are simply html and don’t persist things the browser doesn't understand on the frontend. In comparison, if you disable a plugin that powers a shortcode, you end up with strange visuals on the frontend (often just showing the shortcode in plain text). +- Blocks will be discovered more readily with the launch of the block directory in a way shortcodes never could be allowing for more people to get more functionality. Ultimately, Blocks are designed to be visually representative of the final look, and, with the launch of the Block Directory in 5.5, they will become the expected way in which users will discover and insert content in WordPress. @@ -393,6 +392,7 @@ This also [gives us the flexibility](https://github.com/WordPress/gutenberg/issu We suggest you look at the [Gutenberg key concepts](/docs/getting-started/architecture/key-concepts.md) to learn more about how this aspect of the project works. ## How can I parse the post content back out into blocks in PHP or JS? + In JS: ```js @@ -407,4 +407,4 @@ $blocks = parse_blocks( $post_content ); ## WordPress is already the world's most popular publishing platform. Why change the editor at all? -The Editor is where most of the action happens in WordPress’s daily use, and it was a place where we could polish and perfect the block experience in a contained environment. Further, as an open-source project, we believe that it is critical for WordPress to continue to innovate and keep working to make the core experience intuitive and enjoyable for all users. As a community project, Gutenberg has the potential to do just that, and we’re excited to pursue this goal together. If you’d like to test, contribute, or offer feedback, we welcome you to [share what you find on GitHub](https://github.com/WordPress/gutenberg/issues). +The Editor is where most of the action happens in WordPress’s daily use, and it was a place where we could polish and perfect the block experience in a contained environment. Further, as an open-source project, we believe that it is critical for WordPress to continue to innovate and keep working to make the core experience intuitive and enjoyable for all users. As a community project, Gutenberg has the potential to do just that, and we’re excited to pursue this goal together. If you’d like to test, contribute, or offer feedback, we welcome you to [share what you find on GitHub](https://github.com/WordPress/gutenberg/issues). diff --git a/docs/getting-started/history.md b/docs/getting-started/history.md index a0f05a9cb446a3..25e596e9fe946f 100644 --- a/docs/getting-started/history.md +++ b/docs/getting-started/history.md @@ -1,19 +1,21 @@ # History ## Survey + There was a survey done: [https://make.wordpress.org/core/2017/04/07/editor-experience-survey-results/](https://make.wordpress.org/core/2017/04/07/editor-experience-survey-results/) ## Inspiration + This includes a list of historical articles and influences on the Gutenberg project. -- LivingDocs: [https://beta.livingdocs.io/articles](https://beta.livingdocs.io/articles) -- Parrot: [https://intenseminimalism.com/2017/parrot-an-integrated-site-builder-and-editor-concept-for-wordpress/](https://intenseminimalism.com/2017/parrot-an-integrated-site-builder-and-editor-concept-for-wordpress/) -- Apple Keynote -- Slack -- Google Sites v2 +- LivingDocs: [https://beta.livingdocs.io/articles](https://beta.livingdocs.io/articles) +- Parrot: [https://intenseminimalism.com/2017/parrot-an-integrated-site-builder-and-editor-concept-for-wordpress/](https://intenseminimalism.com/2017/parrot-an-integrated-site-builder-and-editor-concept-for-wordpress/) +- Apple Keynote +- Slack +- Google Sites v2 ## Blog posts by the team -- Gutenberg tag on make/core: updates and much more: [https://make.wordpress.org/core/tag/gutenberg/](https://make.wordpress.org/core/tag/gutenberg/) -- Suggested revised timeline: [https://make.wordpress.org/core/2017/08/11/revised-suggested-roadmap-for-gutenberg-and-customization/](https://make.wordpress.org/core/2017/08/11/revised-suggested-roadmap-for-gutenberg-and-customization/) -- Discovering Gutenberg: [https://make.wordpress.org/core/2017/08/08/discovering-gutenberg-and-next-steps/](https://make.wordpress.org/core/2017/08/08/discovering-gutenberg-and-next-steps/) +- Gutenberg tag on make/core: updates and much more: [https://make.wordpress.org/core/tag/gutenberg/](https://make.wordpress.org/core/tag/gutenberg/) +- Suggested revised timeline: [https://make.wordpress.org/core/2017/08/11/revised-suggested-roadmap-for-gutenberg-and-customization/](https://make.wordpress.org/core/2017/08/11/revised-suggested-roadmap-for-gutenberg-and-customization/) +- Discovering Gutenberg: [https://make.wordpress.org/core/2017/08/08/discovering-gutenberg-and-next-steps/](https://make.wordpress.org/core/2017/08/08/discovering-gutenberg-and-next-steps/) diff --git a/docs/getting-started/outreach.md b/docs/getting-started/outreach.md index 7c289f6b07c38e..3bfb29d595bc0d 100644 --- a/docs/getting-started/outreach.md +++ b/docs/getting-started/outreach.md @@ -7,74 +7,80 @@ This includes articles, talks, demos and anything the community is doing to disc A short list of useful articles around defining, extending, and contributing to Gutenberg. ### Overviews of Gutenberg -- [Status Check: Site Editing & Customization](https://make.wordpress.org/core/2020/12/10/status-check-site-editing-and-customization/), Matías Ventura Bausero (December 2020) -- [Embrace the Modularity](https://riad.blog/2020/01/28/embrace-the-modularity/), Riad Benguella (January 2020) -- [The Language of Gutenberg](https://lamda.blog/2018/04/22/the-language-of-gutenberg/), Miguel Fonseca (April 2018) -- [Gutenberg, or the Ship of Theseus](https://matiasventura.com/post/gutenberg-or-the-ship-of-theseus/), Matías Ventura Bausero (October 2017) -- [We Called It Gutenberg for a Reason](https://ma.tt/2017/08/we-called-it-gutenberg-for-a-reason/), Matt Mullenweg (August 2017) -- [How Gutenberg is Changing WordPress Development](https://riad.blog/2017/10/06/how-gutenberg-is-changing-wordpress-development/), Riad Benguella (October 2017) -- [How Gutenberg Will Shape the Future of WordPress](https://www.linkedin.com/pulse/gutenberg-morten-rand-hendriksen/), Morten Rand-Henrikson (August 2017) -You can view this [Index of Gutenberg related posts](https://make.wordpress.org/core/handbook/references/keeping-up-with-gutenberg-index/) for more information. +- [Status Check: Site Editing & Customization](https://make.wordpress.org/core/2020/12/10/status-check-site-editing-and-customization/), Matías Ventura Bausero (December 2020) +- [Embrace the Modularity](https://riad.blog/2020/01/28/embrace-the-modularity/), Riad Benguella (January 2020) +- [The Language of Gutenberg](https://lamda.blog/2018/04/22/the-language-of-gutenberg/), Miguel Fonseca (April 2018) +- [Gutenberg, or the Ship of Theseus](https://matiasventura.com/post/gutenberg-or-the-ship-of-theseus/), Matías Ventura Bausero (October 2017) +- [We Called It Gutenberg for a Reason](https://ma.tt/2017/08/we-called-it-gutenberg-for-a-reason/), Matt Mullenweg (August 2017) +- [How Gutenberg is Changing WordPress Development](https://riad.blog/2017/10/06/how-gutenberg-is-changing-wordpress-development/), Riad Benguella (October 2017) +- [How Gutenberg Will Shape the Future of WordPress](https://www.linkedin.com/pulse/gutenberg-morten-rand-hendriksen/), Morten Rand-Henrikson (August 2017) + +You can view this [Index of Gutenberg related posts](https://make.wordpress.org/core/handbook/references/keeping-up-with-gutenberg-index/) for more information. ### Extending Gutenberg -- [How to Start Block Development with Scaffolding](https://gziolo.pl/2020/12/22/how-to-start-block-development-with-scaffolding/), Grzegorz Ziółkowski (December 2020) -- [Introducing BlockBook for WordPress](https://riad.blog/2020/07/22/introducing-blockbook-for-wordpress/), Riad Benguella (July 2020) -- [AsBlocks: an encrypted collaborative environment](https://riad.blog/2020/06/11/write-as-blocks-in-an-encrypted-collaborative-environment/), Riad Benguella (June 2020) -- [Thoughts on Themes](https://matiasventura.com/post/thoughts-on-themes/), Matías Ventura Bausero (April 2020) -- [Build a Block Series](https://mkaz.blog/code/build-a-block-series-1/), Marcus Kazmierczak (January 2020) -- [With Gutenberg, what happens to my Custom Fields?](https://riad.blog/2017/12/11/with-gutenberg-what-happens-to-my-custom-fields/), Riad Benguella (December 2017) -- [One thousand and one ways to extend Gutenberg today](https://riad.blog/2017/10/16/one-thousand-and-one-way-to-extend-gutenberg-today/), Riad Benguella (October 2017) -- [Gutenberg Plugin Boilerplate](https://github.com/ahmadawais/Gutenberg-Boilerplate/), Ahmad Awais (August 2017) + +- [How to Start Block Development with Scaffolding](https://gziolo.pl/2020/12/22/how-to-start-block-development-with-scaffolding/), Grzegorz Ziółkowski (December 2020) +- [Introducing BlockBook for WordPress](https://riad.blog/2020/07/22/introducing-blockbook-for-wordpress/), Riad Benguella (July 2020) +- [AsBlocks: an encrypted collaborative environment](https://riad.blog/2020/06/11/write-as-blocks-in-an-encrypted-collaborative-environment/), Riad Benguella (June 2020) +- [Thoughts on Themes](https://matiasventura.com/post/thoughts-on-themes/), Matías Ventura Bausero (April 2020) +- [Build a Block Series](https://mkaz.blog/code/build-a-block-series-1/), Marcus Kazmierczak (January 2020) +- [With Gutenberg, what happens to my Custom Fields?](https://riad.blog/2017/12/11/with-gutenberg-what-happens-to-my-custom-fields/), Riad Benguella (December 2017) +- [One thousand and one ways to extend Gutenberg today](https://riad.blog/2017/10/16/one-thousand-and-one-way-to-extend-gutenberg-today/), Riad Benguella (October 2017) +- [Gutenberg Plugin Boilerplate](https://github.com/ahmadawais/Gutenberg-Boilerplate/), Ahmad Awais (August 2017) ### Community Contribution -- [The WordPress block editor: a maintainer’s story](https://riad.blog/2020/10/26/the-wordpress-block-editor-a-maintainers-story/), Riad Benguella (October 2020) -- [Good first issue on Gutenberg](https://mkaz.blog/code/good-first-issue-on-gutenberg/), Marcus Kazmierczak (August 2020) -- [How to Use the New WordPress Block Editor](https://www.codeinwp.com/blog/wordpress-gutenberg-guide/), Colin Newcomer (July 2020) -- [WordPress Gutenberg Developer’s Guide](https://awhitepixel.com/guides/wordpress-gutenberg-developers-guide/), A White Pixel (2020) -- [Gutenberg Block Library](https://editorblockswp.com/library), Danny Cooper (August 2018) -- [A zero-configuration developer toolkit for building WordPress Gutenberg block plugins](https://ahmadawais.com/create-guten-block-toolkit/), Ahmad Awais (January 2018) -- [Contributing to Gutenberg Without Code](https://wordimpress.com/a-pot-stirrer-amongst-chefs-contributing-to-gutenberg-without-code/), Kevin Hoffman (August 2017) -- [Testing Flow in Gutenberg: Instructions for how to contribute to usability testing](https://make.wordpress.org/test/2017/11/22/testing-flow-in-gutenberg/), Anna Harrison (November 2017) + +- [The WordPress block editor: a maintainer’s story](https://riad.blog/2020/10/26/the-wordpress-block-editor-a-maintainers-story/), Riad Benguella (October 2020) +- [Good first issue on Gutenberg](https://mkaz.blog/code/good-first-issue-on-gutenberg/), Marcus Kazmierczak (August 2020) +- [How to Use the New WordPress Block Editor](https://www.codeinwp.com/blog/wordpress-gutenberg-guide/), Colin Newcomer (July 2020) +- [WordPress Gutenberg Developer’s Guide](https://awhitepixel.com/guides/wordpress-gutenberg-developers-guide/), A White Pixel (2020) +- [Gutenberg Block Library](https://editorblockswp.com/library), Danny Cooper (August 2018) +- [A zero-configuration developer toolkit for building WordPress Gutenberg block plugins](https://ahmadawais.com/create-guten-block-toolkit/), Ahmad Awais (January 2018) +- [Contributing to Gutenberg Without Code](https://wordimpress.com/a-pot-stirrer-amongst-chefs-contributing-to-gutenberg-without-code/), Kevin Hoffman (August 2017) +- [Testing Flow in Gutenberg: Instructions for how to contribute to usability testing](https://make.wordpress.org/test/2017/11/22/testing-flow-in-gutenberg/), Anna Harrison (November 2017) ### Article Compilations -- [Full-Site-Editing: MVP and Ultimate Resource List](https://gutenbergtimes.com/full-site-editing/), Birgit Pauli-Haack (February 2021) -- [Theme Shaper posts about Block Themes](https://themeshaper.com/tag/block-based-themes/), various authors (2020-2021) -- [Gutenberg Times Updates](https://gutenbergtimes.com/category/updates/), Birgit Pauli-Haack -- [Curated Collection of Gutenberg Articles, Plugins, Blocks, Tutorials, etc](http://gutenberghub.com/), Munir Kamal -- [Gutenberg articles on ManageWP.org](https://managewp.org/search?q=gutenberg) +- [Full-Site-Editing: MVP and Ultimate Resource List](https://gutenbergtimes.com/full-site-editing/), Birgit Pauli-Haack (February 2021) +- [Theme Shaper posts about Block Themes](https://themeshaper.com/tag/block-based-themes/), various authors (2020-2021) +- [Gutenberg Times Updates](https://gutenbergtimes.com/category/updates/), Birgit Pauli-Haack +- [Curated Collection of Gutenberg Articles, Plugins, Blocks, Tutorials, etc](http://gutenberghub.com/), Munir Kamal +- [Gutenberg articles on ManageWP.org](https://managewp.org/search?q=gutenberg) ## Talks Talks given about Gutenberg, including slides and videos as they are available. ### Slides -- [Growing JavaScript Skills with WordPress](https://gziolo.pl/2019/07/15/growing-javascript-skills-with-wordpress/) at JavaScript for WordPress conference (July 2019) -- [The new core WordPress editor](http://kimb.me/talk-bigwp-london-new-core-wordpress-editor/) at BigWP London (May 2017) -- [Gutenberg Notes](http://haiku2.com/2017/09/bend-wordpress-meetup-gutenberg-notes/) at Bend WordPress Meetup (September 2017) -- [Gutenberg and the Future of Content in WordPress](https://www.slideshare.net/andrewmduthie/gutenberg-and-the-future-of-content-in-wordpress) (September 2017) -- [Head first into Gutenberg](https://speakerdeck.com/prtksxna/head-first-into-gutenberg) at the [WordPress Goa Meet-up](https://www.meetup.com/WordPressGoa/events/245275573/) (December 2017) -- [Gutenberg : vers une approche plus fine du contenu](https://imathi.eu/2018/02/16/gutenberg-vers-une-approche-plus-fine-du-contenu/) at [WP Paris](https://wpparis.fr/) (February 2018) + +- [Growing JavaScript Skills with WordPress](https://gziolo.pl/2019/07/15/growing-javascript-skills-with-wordpress/) at JavaScript for WordPress conference (July 2019) +- [The new core WordPress editor](http://kimb.me/talk-bigwp-london-new-core-wordpress-editor/) at BigWP London (May 2017) +- [Gutenberg Notes](http://haiku2.com/2017/09/bend-wordpress-meetup-gutenberg-notes/) at Bend WordPress Meetup (September 2017) +- [Gutenberg and the Future of Content in WordPress](https://www.slideshare.net/andrewmduthie/gutenberg-and-the-future-of-content-in-wordpress) (September 2017) +- [Head first into Gutenberg](https://speakerdeck.com/prtksxna/head-first-into-gutenberg) at the [WordPress Goa Meet-up](https://www.meetup.com/WordPressGoa/events/245275573/) (December 2017) +- [Gutenberg : vers une approche plus fine du contenu](https://imathi.eu/2018/02/16/gutenberg-vers-une-approche-plus-fine-du-contenu/) at [WP Paris](https://wpparis.fr/) (February 2018) ### Videos -- [All `Gutenberg` tagged Talks at WordPress.tv](https://wordpress.tv/tag/gutenberg/) -- [Themes of the Future](https://wordpress.tv/2021/01/21/eileen-violini-themes-of-the-future-the-new-frontier-of-gutenberg-block-based-themes-and-theme-development/), Eileen Violini (January 2021) -- [Content Creation in WordPress using Gutenberg](https://wordpress.tv/2021/02/06/sayed-taqui-content-creation-in-wordpress-using-gutenberg/), -Sayed Taqui (January 2021) -- [Updates on WordPress Site-Editor (FSE) and Themes](https://www.youtube.com/watch?v=z-5OJq-OBjI&t), Gutenberg Times (January 2021) -- [State of the Word 2020 FSE Demo](https://youtu.be/QI3qCoiuG3w?t=1279), Matt Mullenweg (December 2020) -- [Full Site Editing! It's Coming, But Will Change How We Use WordPress?](https://www.youtube.com/watch?v=JHxsDSAImn0), WPCrafter.com (December 2020) -- [Advanced Layouts with the Block Editor](https://wordpress.tv/2020/12/06/advanced-layouts-with-the-block-editor/), Mel Choyce (December 2020) -- [State of the Word 2019 Gutenberg Demo](https://www.youtube.com/watch?v=LezbkeV059Q), Matt Mullenweg (December 2019) -- [Beyond Gutenberg](https://wordpress.tv/2018/07/09/matias-ventura-beyond-gutenberg/), Matías Ventura Bausero (July 2018) -- [Anatomy of a block: Gutenberg design patterns](https://wordpress.tv/2018/07/08/tammie-lister-anatomy-of-a-block-gutenberg-design-patterns/), Tammie Lister (July 2018) -- [State of the Word 2017 Gutenberg Demo](https://youtu.be/XOY3ZUO6P0k?t=2100), Matt Mullenweg with demo by Matías Ventura Bausero (December 2017) -- [Gutenberg is Coming (Don’t Be Afraid)](https://training.ithemes.com/webinar/gutenberg-is-coming-dont-be-afraid/), iThemes Training (September 2017) + +- [All `Gutenberg` tagged Talks at WordPress.tv](https://wordpress.tv/tag/gutenberg/) +- [Themes of the Future](https://wordpress.tv/2021/01/21/eileen-violini-themes-of-the-future-the-new-frontier-of-gutenberg-block-based-themes-and-theme-development/), Eileen Violini (January 2021) +- [Content Creation in WordPress using Gutenberg](https://wordpress.tv/2021/02/06/sayed-taqui-content-creation-in-wordpress-using-gutenberg/), + Sayed Taqui (January 2021) +- [Updates on WordPress Site-Editor (FSE) and Themes](https://www.youtube.com/watch?v=z-5OJq-OBjI&t), Gutenberg Times (January 2021) +- [State of the Word 2020 FSE Demo](https://youtu.be/QI3qCoiuG3w?t=1279), Matt Mullenweg (December 2020) +- [Full Site Editing! It's Coming, But Will Change How We Use WordPress?](https://www.youtube.com/watch?v=JHxsDSAImn0), WPCrafter.com (December 2020) +- [Advanced Layouts with the Block Editor](https://wordpress.tv/2020/12/06/advanced-layouts-with-the-block-editor/), Mel Choyce (December 2020) +- [State of the Word 2019 Gutenberg Demo](https://www.youtube.com/watch?v=LezbkeV059Q), Matt Mullenweg (December 2019) +- [Beyond Gutenberg](https://wordpress.tv/2018/07/09/matias-ventura-beyond-gutenberg/), Matías Ventura Bausero (July 2018) +- [Anatomy of a block: Gutenberg design patterns](https://wordpress.tv/2018/07/08/tammie-lister-anatomy-of-a-block-gutenberg-design-patterns/), Tammie Lister (July 2018) +- [State of the Word 2017 Gutenberg Demo](https://youtu.be/XOY3ZUO6P0k?t=2100), Matt Mullenweg with demo by Matías Ventura Bausero (December 2017) +- [Gutenberg is Coming (Don’t Be Afraid)](https://training.ithemes.com/webinar/gutenberg-is-coming-dont-be-afraid/), iThemes Training (September 2017) ## Learn WordPress Courses You can access all courses [here](https://learn.wordpress.org/). -- [Registering Block Patterns](https://learn.wordpress.org/workshop/registering-block-patterns/), Daisy Olsen (January 2021) -- [Intro to Gutenberg Block Development](https://learn.wordpress.org/workshop/intro-to-gutenberg-block-development/), Jonathan Bossenger (August 2020) -- [Intro to Publishing with the Block Editor](https://learn.wordpress.org/workshop/intro-to-publishing-with-the-block-editor/), Erica Varlese (August 2020) + +- [Registering Block Patterns](https://learn.wordpress.org/workshop/registering-block-patterns/), Daisy Olsen (January 2021) +- [Intro to Gutenberg Block Development](https://learn.wordpress.org/workshop/intro-to-gutenberg-block-development/), Jonathan Bossenger (August 2020) +- [Intro to Publishing with the Block Editor](https://learn.wordpress.org/workshop/intro-to-publishing-with-the-block-editor/), Erica Varlese (August 2020) diff --git a/docs/getting-started/tutorials/create-block/attributes.md b/docs/getting-started/tutorials/create-block/attributes.md index a0d0a8b6bf189e..768231c867d4e6 100644 --- a/docs/getting-started/tutorials/create-block/attributes.md +++ b/docs/getting-started/tutorials/create-block/attributes.md @@ -57,13 +57,13 @@ import './editor.scss'; export default function Edit( { attributes, setAttributes } ) { return ( -
- setAttributes( { message: val } ) } - /> -
+
+ setAttributes( { message: val } ) } + /> +
); } ``` diff --git a/docs/getting-started/tutorials/create-block/author-experience.md b/docs/getting-started/tutorials/create-block/author-experience.md index 6fec2823f0db22..911baa512bb45f 100644 --- a/docs/getting-started/tutorials/create-block/author-experience.md +++ b/docs/getting-started/tutorials/create-block/author-experience.md @@ -18,8 +18,8 @@ export default function Edit( { attributes, className, setAttributes } ) { return (
- { attributes.message ? -
Message: { attributes.message }
: -
-

No Message.

- setAttributes( { message: val } ) } - /> -
- } -
- ); +return ( +
+ { attributes.message ? ( +
Message: { attributes.message }
+ ) : ( +
+

No Message.

+ setAttributes( { message: val } ) } + /> +
+ ) } +
+); ``` There is a problem with the above, if we only use the `attributes.message` check, as soon as we type in the text field it would disappear since the message would then be set to a value. So we need to pair with an additional `isSelected` parameter. @@ -80,7 +81,7 @@ import { __ } from '@wordpress/i18n'; export default function Edit( { attributes, isSelected, setAttributes } ) { return ( -
+
{ attributes.message && ! isSelected ? (
{ attributes.message }
) : ( @@ -131,13 +132,11 @@ import './editor.scss'; export default function Edit( { attributes, setAttributes } ) { return ( - - setAttributes( { message: val } ) - } - /> + setAttributes( { message: val } ) } + /> ); } ``` diff --git a/docs/getting-started/tutorials/create-block/block-anatomy.md b/docs/getting-started/tutorials/create-block/block-anatomy.md index 6bead9b71b89e8..de12300e38fde3 100644 --- a/docs/getting-started/tutorials/create-block/block-anatomy.md +++ b/docs/getting-started/tutorials/create-block/block-anatomy.md @@ -38,6 +38,7 @@ The results of the edit function is what the editor will render to the editor pa The results of the save function is what the editor will insert into the **post_content** field when the post is saved. The post_content field is the field in the WordPress database used to store the content of the post. Most of the properties are set in the `block.json` file. + ```json { "apiVersion": 2, @@ -67,7 +68,7 @@ The **category** specified is a string and must be one of: "common, formatting, If you look at the generated `src/save.js` file, the block title and description are wrapped in a function that looks like this: ```js -__( 'Gutenpride – hello from the saved content!', 'gutenpride' ) +__( 'Gutenpride – hello from the saved content!', 'gutenpride' ); ``` This is an internationalization wrapper that allows for the string "Gutenpride" to be translated. The second parameter, "gutenpride" is called the text domain and gives context for where the string is from. The JavaScript internationalization, often abbreviated i18n, matches the core WordPress internationalization process. See the [Internationalization in Plugin Developer Handbook](https://developer.wordpress.org/plugins/internationalization/) for more details. diff --git a/docs/getting-started/tutorials/create-block/block-code.md b/docs/getting-started/tutorials/create-block/block-code.md index 03e2ba676e486a..441d847e582515 100644 --- a/docs/getting-started/tutorials/create-block/block-code.md +++ b/docs/getting-started/tutorials/create-block/block-code.md @@ -17,7 +17,7 @@ function create_block_gutenpride_block_init() { add_action( 'init', 'create_block_gutenpride_block_init' ); ``` -This function handles that all style en js files in the `build` folder get handles that are passed on to the `wp_register_style` function. +This function checks the `block.json` file for js and css files, and will pass them on to [enqueue](https://developer.wordpress.org/themes/basics/including-css-javascript/) these files, so they are loaded on the appropriate pages. The `build/index.css` is compiled from `src/editor.scss` and loads only within the editor, and after the `style-index.css`. The `build/style-index.css` is compiled from `src/style.scss` and loads in both the editor and front-end — published post view. diff --git a/docs/getting-started/tutorials/devenv/README.md b/docs/getting-started/tutorials/devenv/README.md index 9f348942ea92cc..3d793d0c139a62 100644 --- a/docs/getting-started/tutorials/devenv/README.md +++ b/docs/getting-started/tutorials/devenv/README.md @@ -22,6 +22,7 @@ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash Quit and restart terminal Install the long-term support (lts) version of node. + ``` nvm install --lts ``` @@ -30,7 +31,7 @@ nvm install --lts First download, install, and start [Docker Desktop](https://www.docker.com/products/docker-desktop) following the instructions for your OS. -- Install WordPress environment tool +- Install WordPress environment tool ``` npm -g install @wordpress/env @@ -38,18 +39,16 @@ npm -g install @wordpress/env Start the environment from an existing plugin or theme directory, or a new working directory: - ``` - wp-env start - ``` +``` +wp-env start +``` You will have a full WordPress site installed, navigate to: http://localhost:8888/ using your browser, log in to the WordPress dashboard at http://localhost:8888/wp-admin/ using Username "admin" and Password "password", without the quotes. - **3. Code Editor** You can use any text editor to write code. For example, [Visual Studio Code](https://code.visualstudio.com/) is a popular open-source editor. You can follow instructions on their site to install it for your OS. - ## Node Development Tools The tools needed for development are **Node** and **NPM**. **Nodejs** is a runtime environment that allows running JavaScript outside of the browser. NPM is the Node Package Manager, it is used for installing dependencies and running scripts. The script `npx` is also installed with Nodejs—this script is used to run packages not yet installed—we will use `npx` to bootstrap a block. @@ -115,7 +114,7 @@ There are several ways to run WordPress locally on your own computer, or you cou The WordPress [wp-env package](https://www.npmjs.com/package/@wordpress/env) lets you set up a local WordPress environment for building and testing plugins and themes, without any additional configuration. -The `wp-env` tool uses Docker to create a virtual machine to that runs the WordPress site. There are instructions available for installing Docker on [Windows 10 Pro](https://docs.docker.com/docker-for-windows/install/), [all other versions of Windows](https://docs.docker.com/toolbox/toolbox_install_windows/), [macOS](https://docs.docker.com/docker-for-mac/install/), and [Linux](https://docs.docker.com/v17.12/install/linux/docker-ce/ubuntu/#install-using-the-convenience-script). If using Ubuntu, see our additional notes for [help installing Docker on Ubuntu](/docs/getting-started/tutorials/devenv/docker-ubuntu.md). +The `wp-env` tool uses Docker to create a virtual machine to that runs the WordPress site. There are instructions available for installing Docker on [Windows 10 Pro](https://docs.docker.com/docker-for-windows/install/), [other versions of Windows 10](https://docs.docker.com/docker-for-windows/wsl/), [macOS](https://docs.docker.com/docker-for-mac/install/), and [Linux](https://docs.docker.com/v17.12/install/linux/docker-ce/ubuntu/#install-using-the-convenience-script). If using Ubuntu, see our additional notes for [help installing Docker on Ubuntu](/docs/getting-started/tutorials/devenv/docker-ubuntu.md). After you have installed Docker, go ahead and install the `wp-env` tool. This command will install the tool globally, which means you can run it from any directory: @@ -150,18 +149,16 @@ If you run `wp-env start` from a directory that is not a plugin or theme, a gene You can use the `.wp-env.json` configuration file to create an environment that works with multiple plugins and/or themes. See the [@wordpress/env package for additional details](/packages/env/README.md#wp-envjson). - #### Troubleshooting A common issue when running `wp-env` is `Error while running docker-compose command.` -- Check that Docker Desktop is started and running. -- Check Docker Desktop dashboard for logs, restart, or remove existing VMs. +- Check that Docker Desktop is started and running. +- Check Docker Desktop dashboard for logs, restart, or remove existing VMs. If you see the error: `Host is already in use by another container` -- The container is already running, or another one is. You can stop an existing container running use `wp-env stop` from the directory you started it. - +- The container is already running, or another one is. You can stop an existing container running use `wp-env stop` from the directory you started it. ### Alternative to Docker @@ -189,29 +186,28 @@ Here are a few instructions if you need to start over, or want to remove what wa ### Local Environment -* If you just want to reset and clean the WordPress database: +- If you just want to reset and clean the WordPress database: ``` wp-env clean all ``` -* To remove the local environment completely for a specific project: +- To remove the local environment completely for a specific project: ``` wp-env destroy ``` -* To completely uninstall wp-env tool: +- To completely uninstall wp-env tool: ``` npm -g uninstall @wordpress/env ``` -* To uninstall Docker, or Visual Studio Code use your OS method to remove packages. For example, on Windows run "Add or remove programs". You can additionally uninstall from the Docker Desktop app, click the bug icon at the top to switch to this Troubleshoot screen. Click Uninstall or remove. +- To uninstall Docker, or Visual Studio Code use your OS method to remove packages. For example, on Windows run "Add or remove programs". You can additionally uninstall from the Docker Desktop app, click the bug icon at the top to switch to this Troubleshoot screen. Click Uninstall or remove. ![Docker Troubleshoot Screenshot](https://developer.wordpress.org/files/2020/08/docker-uninstall-screen.png) - ### Uninstall Node/NVM To uninstall Node/NVM, delete the NVM directory, this is typically installed at `$HOME/.nvm`, delete using diff --git a/docs/getting-started/tutorials/devenv/docker-ubuntu.md b/docs/getting-started/tutorials/devenv/docker-ubuntu.md index adffe7e39ec114..f26ca0826140ef 100644 --- a/docs/getting-started/tutorials/devenv/docker-ubuntu.md +++ b/docs/getting-started/tutorials/devenv/docker-ubuntu.md @@ -3,14 +3,14 @@ This article covers setting up the local WordPress development environment using Docker on Ubuntu. For Ubuntu 20.04.1, the standard docker binaries in the repository work as needed: - + ``` sudo apt install docker.io docker-compose ``` -For earlier versions of Ubuntu, the docker binaries included in repositories did not support the features needed for the WordPress environment. +For earlier versions of Ubuntu, the docker binaries included in repositories did not support the features needed for the WordPress environment. -- For Ubuntu prior to 20.04.1, follow these [directions from Docker to install](https://docs.docker.com/install/linux/docker-ce/ubuntu/). Additionally `docker-compose` is required, you may need to install separately, see [ Docker compose documentation](https://docs.docker.com/compose/install/). +- For Ubuntu prior to 20.04.1, follow these [directions from Docker to install](https://docs.docker.com/install/linux/docker-ce/ubuntu/). Additionally `docker-compose` is required, you may need to install separately, see [ Docker compose documentation](https://docs.docker.com/compose/install/). ## Troubleshooting diff --git a/docs/how-to-guides/accessibility.md b/docs/how-to-guides/accessibility.md index ab6c0d0066b1dc..f38e8c4e81834c 100644 --- a/docs/how-to-guides/accessibility.md +++ b/docs/how-to-guides/accessibility.md @@ -12,6 +12,6 @@ For setting up navigation between different regions, see the [navigateRegions pa Read more regarding landmark design from W3C: -- [General Principles of Landmark Design](https://www.w3.org/TR/wai-aria-practices-1.1/#general-principles-of-landmark-design) -- [ARIA Landmarks Example](https://www.w3.org/TR/wai-aria-practices/examples/landmarks/) -- [HTML5 elements that by default define ARIA landmarks](https://www.w3.org/TR/wai-aria-practices/examples/landmarks/HTML5.html) +- [General Principles of Landmark Design](https://www.w3.org/TR/wai-aria-practices-1.1/#general-principles-of-landmark-design) +- [ARIA Landmarks Example](https://www.w3.org/TR/wai-aria-practices/examples/landmarks/) +- [HTML5 elements that by default define ARIA landmarks](https://www.w3.org/TR/wai-aria-practices/examples/landmarks/HTML5.html) diff --git a/docs/how-to-guides/backward-compatibility/README.md b/docs/how-to-guides/backward-compatibility/README.md index 8035d003e977fd..96615fe793a505 100644 --- a/docs/how-to-guides/backward-compatibility/README.md +++ b/docs/how-to-guides/backward-compatibility/README.md @@ -2,43 +2,44 @@ Historically, WordPress has been known for preserving backward compatibility across versions. Gutenberg follows this example wherever possible in its production public APIs. There are rare occasions where breaking backward compatibility is unavoidable and in those cases the breakage: -* Should be constrained as much as possible to a small surface area of the API. -* Should be documented as clearly as possible to third-party developers using Dev Notes. +- Should be constrained as much as possible to a small surface area of the API. +- Should be documented as clearly as possible to third-party developers using Dev Notes. ## What qualifies as a production public API -The Gutenberg code base is composed of two different types of packages: - - **production packages**: these are packages that are shipped as WordPress scripts (example: wp-components, wp-editor...). - - **development packages**: these are made up of developer tools that can be used by third-party developers to lint, test, format and build their themes and plugins (example: @wordpress/scrips, @wordpress/env...). Typically, these are consumed as npm dependencies in third-party projects. +The Gutenberg code base is composed of two different types of packages: + +- **production packages**: these are packages that are shipped as WordPress scripts (example: wp-components, wp-editor...). +- **development packages**: these are made up of developer tools that can be used by third-party developers to lint, test, format and build their themes and plugins (example: @wordpress/scrips, @wordpress/env...). Typically, these are consumed as npm dependencies in third-party projects. Backward compatibility guarantees only apply to the production packages, as updates happen through WordPress upgrades. - + Production packages use the `wp` global variable to provide APIs to third-party developers. These APIs can be JavaScript functions, variables and React components. ### How to preserve backward compatibility for a JavaScript function -* The name of the function should not change. -* The order of the arguments of the function should not change. -* The function's returned value type should not change. -* Changes to arguments (new arguments, modification of semantics) is possible if we guarantee that all previous calls are still possible. +- The name of the function should not change. +- The order of the arguments of the function should not change. +- The function's returned value type should not change. +- Changes to arguments (new arguments, modification of semantics) is possible if we guarantee that all previous calls are still possible. ### How to preserve backward compatibility for a React Component -* The name of the component should not change. -* The props of the component should not be removed. -* Existing prop values should continue to be supported. If a component accepts a function as a prop, we can update the component to accept a new type for the same prop, but it shouldn't break existing usage. -* Adding new props is allowed. -* React Context dependencies can only be added or removed if we ensure the previous context contract is not breaking. +- The name of the component should not change. +- The props of the component should not be removed. +- Existing prop values should continue to be supported. If a component accepts a function as a prop, we can update the component to accept a new type for the same prop, but it shouldn't break existing usage. +- Adding new props is allowed. +- React Context dependencies can only be added or removed if we ensure the previous context contract is not breaking. ### How to preserve backward compatibility for a Block -* Existing usage of the block should not break or be marked as invalid when the editor is loaded. -* The styling of the existing blocks should be guaranteed. -* Markup changes should be limited to the minimum possible, but if a block needs to change its saved markup, making previous versions invalid, a [**deprecated version**](/docs/reference-guides/block-api/block-deprecation.md) of the block should be added. +- Existing usage of the block should not break or be marked as invalid when the editor is loaded. +- The styling of the existing blocks should be guaranteed. +- Markup changes should be limited to the minimum possible, but if a block needs to change its saved markup, making previous versions invalid, a [**deprecated version**](/docs/reference-guides/block-api/block-deprecation.md) of the block should be added. ## Class names and DOM updates -Class names and DOM nodes used inside the tree of React components are not considered part of the public API and can be modified. +Class names and DOM nodes used inside the tree of React components are not considered part of the public API and can be modified. Changes to these should be done with caution as it can affect the styling and behavior of third-party code (Even if they should not rely on these in the first place). Keep the old ones if possible. If not, document the changes and write a dev note. @@ -51,6 +52,7 @@ To encourage third-party developers to adopt the new APIs instead, we can use th Make it more clear when the feature was deprecated. Use the `since` and `plugin` options of the helper method. Example: + ```js deprecated( 'wp.components.ClipboardButton', { since: '10.3', @@ -62,15 +64,16 @@ deprecated( 'wp.components.ClipboardButton', { ## Dev Notes Dev notes are [posts published on the make/core site](https://make.wordpress.org/core/tag/dev-notes/) prior to WordPress releases to inform third-party developers about important changes to the developer APIs, these changes can include: -* New APIs. -* Changes to existing APIs that might affect existing plugins and themes. (Example: classname changes...) -* Unavoidable backward compatibility breakage, with reasoning and migration flows. -* Important deprecations (even without breakage), with reasoning and migration flows. + +- New APIs. +- Changes to existing APIs that might affect existing plugins and themes. (Example: classname changes...) +- Unavoidable backward compatibility breakage, with reasoning and migration flows. +- Important deprecations (even without breakage), with reasoning and migration flows. ### Dev Note Workflow -* When working on a pull request and the need for a dev note is discovered, add the **Needs Dev Note** label to the PR. -* If possible, add a comment to the PR explaining why the dev note is needed. -* When the first beta of the upcoming WordPress release is shipped, go through the list of merged PRs included in the release that are tagged with the **Needs Dev Note** label. -* For each one of these PRs, write a dev note and coordinate with the WordPress release leads to publish the dev note. -* Once the dev note for a PR is published, remove the **Needs Dev Note** label from the PR. +- When working on a pull request and the need for a dev note is discovered, add the **Needs Dev Note** label to the PR. +- If possible, add a comment to the PR explaining why the dev note is needed. +- When the first beta of the upcoming WordPress release is shipped, go through the list of merged PRs included in the release that are tagged with the **Needs Dev Note** label. +- For each one of these PRs, write a dev note and coordinate with the WordPress release leads to publish the dev note. +- Once the dev note for a PR is published, remove the **Needs Dev Note** label from the PR. diff --git a/docs/how-to-guides/backward-compatibility/meta-box.md b/docs/how-to-guides/backward-compatibility/meta-box.md index ebffb327ffe7fe..28839e4256a683 100644 --- a/docs/how-to-guides/backward-compatibility/meta-box.md +++ b/docs/how-to-guides/backward-compatibility/meta-box.md @@ -4,9 +4,9 @@ This is a brief document detailing how meta box support works in the block edito ### Testing, Converting, and Maintaining Existing Meta Boxes -Before converting meta boxes to blocks, it may be easier to test if a meta box works with the block editor, and explicitly mark it as such. +Before converting meta boxes to blocks, it may be easier to test if a meta box works with the block editor, and explicitly mark it as such. -If a meta box *doesn't* work with the block editor, and updating it to work correctly is not an option, the next step is to add the `__block_editor_compatible_meta_box` argument to the meta box declaration: +If a meta box _doesn't_ work with the block editor, and updating it to work correctly is not an option, the next step is to add the `__block_editor_compatible_meta_box` argument to the meta box declaration: ```php add_meta_box( 'my-meta-box', 'My Meta Box', 'my_meta_box_callback', @@ -50,8 +50,8 @@ Ideally, this could be done at instantiation of the editor and help simplify thi When rendering the block editor, the meta boxes are rendered to a hidden div `#metaboxes`. -*The Redux store will hold all meta boxes as inactive by default*. When -`INITIALIZE_META_BOX_STATE` comes in, the store will update any active meta box areas by setting the `isActive` flag to `true`. Once this happens React will check for the new props sent in by Redux on the `MetaBox` component. If that `MetaBox` is now active, instead of rendering null, a `MetaBoxArea` component will be rendered. The `MetaBox` component is the container component that mediates between the `MetaBoxArea` and the Redux Store. *If no meta boxes are active, nothing happens. This will be the default behavior, as all core meta boxes have been stripped.* +_The Redux store will hold all meta boxes as inactive by default_. When +`INITIALIZE_META_BOX_STATE` comes in, the store will update any active meta box areas by setting the `isActive` flag to `true`. Once this happens React will check for the new props sent in by Redux on the `MetaBox` component. If that `MetaBox` is now active, instead of rendering null, a `MetaBoxArea` component will be rendered. The `MetaBox` component is the container component that mediates between the `MetaBoxArea` and the Redux Store. _If no meta boxes are active, nothing happens. This will be the default behavior, as all core meta boxes have been stripped._ #### MetaBoxArea Component @@ -73,8 +73,8 @@ This page mimics the `post.php` post form, so when it is submitted it will fire Most PHP meta boxes should continue to work in the block editor, but some meta boxes that include advanced functionality could break. Here are some common reasons why meta boxes might not work as expected in the block editor: -- Plugins relying on selectors that target the post title, post content fields, and other metaboxes (of the old editor). -- Plugins relying on TinyMCE's API because there's no longer a single TinyMCE instance to talk to in the block editor. -- Plugins making updates to their DOM on "submit" or on "save". +- Plugins relying on selectors that target the post title, post content fields, and other metaboxes (of the old editor). +- Plugins relying on TinyMCE's API because there's no longer a single TinyMCE instance to talk to in the block editor. +- Plugins making updates to their DOM on "submit" or on "save". -Please also note that if your plugin triggers a PHP warning or notice to be output on the page, this will cause the HTML document type (``) to be output incorrectly. This will cause the browser to render using "Quirks Mode", which is a compatibility layer that gets enabled when the browser doesn't know what type of document it is parsing. The block editor is not meant to work in this mode, but it can _appear_ to be working just fine. If you encounter issues such as *meta boxes overlaying the editor* or other layout issues, please check the raw page source of your document to see that the document type definition is the first thing output on the page. There will also be a warning in the JavaScript console, noting the issue. +Please also note that if your plugin triggers a PHP warning or notice to be output on the page, this will cause the HTML document type (``) to be output incorrectly. This will cause the browser to render using "Quirks Mode", which is a compatibility layer that gets enabled when the browser doesn't know what type of document it is parsing. The block editor is not meant to work in this mode, but it can _appear_ to be working just fine. If you encounter issues such as _meta boxes overlaying the editor_ or other layout issues, please check the raw page source of your document to see that the document type definition is the first thing output on the page. There will also be a warning in the JavaScript console, noting the issue. diff --git a/docs/how-to-guides/block-based-theme/README.md b/docs/how-to-guides/block-based-theme/README.md index 6497fd437bf559..d39dd3b0caaa46 100644 --- a/docs/how-to-guides/block-based-theme/README.md +++ b/docs/how-to-guides/block-based-theme/README.md @@ -12,11 +12,11 @@ This tutorial is up to date as of Gutenberg version 9.1. ## Table of Contents - 1. [What is needed to create a block-based theme?](/docs/how-to-guides/block-based-themes/README.md#what-is-needed-to-create-a-block-based-theme) - 2. [Creating the theme](/docs/how-to-guides/block-based-themes/README.md#creating-the-theme) - 3. [Creating the templates and template parts](/docs/how-to-guides/block-based-themes/README.md#creating-the-templates-and-template-parts) - 4. [experimental-theme.json - Global styles](/docs/how-to-guides/block-based-themes/README.md#experimental-theme-json-global-styles) - 5. [Adding blocks](/docs/how-to-guides/block-based-themes/block-based-themes-2-adding-blocks.md) +1. [What is needed to create a block-based theme?](/docs/how-to-guides/block-based-themes/README.md#what-is-needed-to-create-a-block-based-theme) +2. [Creating the theme](/docs/how-to-guides/block-based-themes/README.md#creating-the-theme) +3. [Creating the templates and template parts](/docs/how-to-guides/block-based-themes/README.md#creating-the-templates-and-template-parts) +4. [experimental-theme.json - Global styles](/docs/how-to-guides/block-based-themes/README.md#experimental-theme-json-global-styles) +5. [Adding blocks](/docs/how-to-guides/block-based-themes/block-based-themes-2-adding-blocks.md) ## What is needed to create a block-based theme? @@ -64,10 +64,10 @@ Create a `style.css` file. The file header in the `style.css` file has [the same ``` /* Theme Name: My first theme -Theme URI: +Theme URI: Author: The WordPress team Author URI: https://wordpress.org/ -Description: +Description: Tags: Version: 1.0.0 Requires at least: 5.0 @@ -103,12 +103,12 @@ if ( ! function_exists( 'myfirsttheme_setup' ) ) : * support post thumbnails. */ function myfirsttheme_setup() { - + /** * Add default posts and comments RSS feed links to . */ add_theme_support( 'automatic-feed-links' ); - + /** * Enable support for post thumbnails and featured images. */ @@ -148,7 +148,7 @@ add_action( 'wp_enqueue_scripts', 'myfirsttheme_scripts' ); ``` Create an `index.php` file. -This file is used as a fallback if the theme is activated when full site editing is not enabled. +This file is used as a fallback if the theme is activated when full site editing is not enabled. You may leave the file empty for this tutorial. Your theme should now include the following files and folders: @@ -172,7 +172,7 @@ Inside the block-templates folder, create an `index.html` file. In `index.html`, include the template parts by adding two HTML comments. -The HTML comments starts with `wp:template-part` which is the name of the template-part block type. Inside the curly brackets are two keys and their values: The slug of the template part, and the theme name. +The HTML comments starts with `wp:template-part` which is the name of the template-part block type. Inside the curly brackets are two keys and their values: The slug of the template part, and the theme text domain. ``` @@ -180,7 +180,7 @@ The HTML comments starts with `wp:template-part` which is the name of the templa ``` -If you used a different theme name, adjust the value for the theme key. +If you used a different theme name, adjust the value for the theme text domain. Eventually, you will be able to create and combine templates and template parts directly in the site editor. @@ -189,9 +189,10 @@ Eventually, you will be able to create and combine templates and template parts The purpose of the `experimental-theme.json` file is to make it easier to style blocks by setting defaults. It is used to: - * Create CSS variables (also called CSS custom properties) that can be used to style blocks both on the front and in the editor. - * Set global styles. - * Set styles for individual block types. + +- Create CSS variables (also called CSS custom properties) that can be used to style blocks both on the front and in the editor. +- Set global styles. +- Set styles for individual block types. [The documentation for global styles contains a list of available block and style combinations.](https://developer.wordpress.org/block-editor/developers/themes/theme-json/) @@ -238,10 +239,11 @@ Add the following global presets to the `experimental-theme.json` file: ``` This code generates the following variables: + ``` --wp--preset--color--strong-magenta: #a156b4; --wp--preset--color--very-dark-gray: #444; - + --wp--custom--line-height--small: 1.3; --wp--custom--line-height--medium: 2; --wp--custom--line-height--large: 2.5; @@ -251,6 +253,7 @@ This code generates the following variables: This example will add the dark grey color as the website background color. Add the code inside the globals, after the presets: + ``` "styles": { "color": { diff --git a/docs/how-to-guides/block-based-theme/block-based-themes-2-adding-blocks.md b/docs/how-to-guides/block-based-theme/block-based-themes-2-adding-blocks.md index c1e5a2d6a4658c..f377eac9d180c8 100644 --- a/docs/how-to-guides/block-based-theme/block-based-themes-2-adding-blocks.md +++ b/docs/how-to-guides/block-based-theme/block-based-themes-2-adding-blocks.md @@ -4,8 +4,8 @@ Each template or template part contains the [block grammar](https://developer.wo There is more than one way to add blocks to the theme files: -- Adding and editing blocks in the site editor and exporting the theme. -- Adding block HTML and comments to the HTML files manually. +- Adding and editing blocks in the site editor and exporting the theme. +- Adding block HTML and comments to the HTML files manually. ## Working with blocks and templates in the site editor @@ -35,7 +35,6 @@ Select the index template again to view the template parts together in the page To add a post loop to the index template, add a **query** block. The query block includes the query loop and the query pagination. The default loop displays the post title and post content. The query loop and query pagination are also available as individual blocks. - ## Saving templates and template parts When you have made your changes, click on the **update design** button in the upper right corner, @@ -49,7 +48,6 @@ When you save changes in the site editor, the files in the active theme are not ![The template parts view in the admin area displays a list of all saved template parts](https://wordpress.org/gutenberg/files/2020/07/block-based-themes-appearance-template-parts.png) - ## Exporting changes Saved templates and template parts can be exported as a partial theme from the Tools menu in the site editor. The block HTML code can then be copied to the theme that you are editing. diff --git a/docs/how-to-guides/block-tutorial/applying-styles-with-stylesheets.md b/docs/how-to-guides/block-tutorial/applying-styles-with-stylesheets.md index c65d2ec46f8bce..85c5f5313aff80 100644 --- a/docs/how-to-guides/block-tutorial/applying-styles-with-stylesheets.md +++ b/docs/how-to-guides/block-tutorial/applying-styles-with-stylesheets.md @@ -6,6 +6,7 @@ The editor will automatically generate a class name for each block type to simpl {% codetabs %} {% ESNext %} + ```jsx import { registerBlockType } from '@wordpress/blocks'; import { useBlockProps } from '@wordpress/block-editor'; @@ -24,19 +25,29 @@ registerBlockType( 'gutenberg-examples/example-02-stylesheets', { edit() { const blockProps = useBlockProps(); - return

Hello World, step 2 (from the editor, in green).

; + return ( +

+ Hello World, step 2 (from the editor, in green). +

+ ); }, save() { const blockProps = useBlockProps.save(); - return

Hello World, step 2 (from the frontend, in red).

; + return ( +

+ Hello World, step 2 (from the frontend, in red). +

+ ); }, } ); ``` + {% ES5 %} + ```js -( function( blocks, element, blockEditor ) { +( function ( blocks, element, blockEditor ) { var el = element.createElement; blocks.registerBlockType( 'gutenberg-examples/example-02-stylesheets', { @@ -45,7 +56,7 @@ registerBlockType( 'gutenberg-examples/example-02-stylesheets', { icon: 'universal-access-alt', category: 'design', example: {}, - edit: function( props ) { + edit: function ( props ) { var blockProps = blockEditor.useBlockProps(); return el( 'p', @@ -53,7 +64,7 @@ registerBlockType( 'gutenberg-examples/example-02-stylesheets', { 'Hello World, step 2 (from the editor, in green).' ); }, - save: function() { + save: function () { var blockProps = blockEditor.useBlockProps.save(); return el( 'p', @@ -62,12 +73,9 @@ registerBlockType( 'gutenberg-examples/example-02-stylesheets', { ); }, } ); -}( - window.wp.blocks, - window.wp.element, - window.wp.blockEditor, -) ); +} )( window.wp.blocks, window.wp.element, window.wp.blockEditor ); ``` + {% end %} The class name is generated using the block's name prefixed with `wp-block-`, replacing the `/` namespace separator with a single `-`. @@ -134,7 +142,7 @@ function gutenberg_examples_02_register_block() { wp_style_add_data( 'gutenberg-examples-02', 'path', dirname( __FILE__ ) . '/style.css' ); register_block_type( 'gutenberg-examples/example-02-stylesheets', array( - 'apiVersion' => 2, + 'api_version' => 2, 'style' => 'gutenberg-examples-02', 'editor_style' => 'gutenberg-examples-02-editor', 'editor_script' => 'gutenberg-examples-02', diff --git a/docs/how-to-guides/block-tutorial/block-controls-toolbar-and-sidebar.md b/docs/how-to-guides/block-tutorial/block-controls-toolbar-and-sidebar.md index 5e50c08322c9bd..c39df76df8f3b1 100644 --- a/docs/how-to-guides/block-tutorial/block-controls-toolbar-and-sidebar.md +++ b/docs/how-to-guides/block-tutorial/block-controls-toolbar-and-sidebar.md @@ -12,6 +12,7 @@ You can also customize the toolbar to include controls specific to your block ty {% codetabs %} {% ESNext %} + ```jsx import { registerBlockType } from '@wordpress/blocks'; @@ -44,17 +45,19 @@ registerBlockType( 'gutenberg-examples/example-04-controls-esnext', { alignment: 'right', }, }, - edit: ( {attributes, setAttributes} ) => { + edit: ( { attributes, setAttributes } ) => { const onChangeContent = ( newContent ) => { setAttributes( { content: newContent } ); }; const onChangeAlignment = ( newAlignment ) => { - setAttributes( { alignment: newAlignment === undefined ? 'none' : newAlignment } ); + setAttributes( { + alignment: newAlignment === undefined ? 'none' : newAlignment, + } ); }; return ( -
+
{ +
` @@ -19,6 +19,7 @@ The following code example shows how to create a dynamic block that shows only t {% codetabs %} {% ESNext %} + ```jsx import { registerBlockType } from '@wordpress/blocks'; import { withSelect } from '@wordpress/data'; @@ -45,16 +46,17 @@ registerBlockType( 'gutenberg-examples/example-dynamic', { { posts[ 0 ].title.rendered } - ) } + ) }
- ) - + ); } ), } ); ``` + {% ES5 %} + ```js -( function( blocks, element, data, blockEditor ) { +( function ( blocks, element, data, blockEditor ) { var el = element.createElement, registerBlockType = blocks.registerBlockType, withSelect = data.withSelect, @@ -65,11 +67,11 @@ registerBlockType( 'gutenberg-examples/example-dynamic', { title: 'Example: last post', icon: 'megaphone', category: 'widgets', - edit: withSelect( function( select ) { + edit: withSelect( function ( select ) { return { posts: select( 'core' ).getEntityRecords( 'postType', 'post' ), }; - } )( function( props ) { + } )( function ( props ) { var blockProps = useBlockProps(); var content; if ( ! props.posts ) { @@ -78,27 +80,20 @@ registerBlockType( 'gutenberg-examples/example-dynamic', { content = 'No posts'; } else { var post = props.posts[ 0 ]; - content = el( - 'a', - { href: post.link }, - post.title.rendered - ); + content = el( 'a', { href: post.link }, post.title.rendered ); } - return el( - 'div', - blockProps, - content - ); + return el( 'div', blockProps, content ); } ), } ); -}( +} )( window.wp.blocks, window.wp.element, window.wp.data, - window.wp.blockEditor, -) ); + window.wp.blockEditor +); ``` + {% end %} Because it is a dynamic block it doesn't need to override the default `save` implementation on the client. Instead, it needs a server component. The contents in the front of your site depend on the function called by the `render_callback` property of `register_block_type`. @@ -139,7 +134,7 @@ function gutenberg_examples_dynamic() { ); register_block_type( 'gutenberg-examples/example-dynamic', array( - 'apiVersion' => 2, + 'api_version' => 2, 'editor_script' => 'gutenberg-examples-dynamic', 'render_callback' => 'gutenberg_examples_dynamic_render_callback' ) ); @@ -151,18 +146,19 @@ add_action( 'init', 'gutenberg_examples_dynamic' ); There are a few things to notice: -* The `edit` function still shows a representation of the block in the editor's context (this could be very different from the rendered version, it's up to the block's author) -* The built-in `save` function just returns `null` because the rendering is performed server-side. -* The server-side rendering is a function taking the block and the block inner content as arguments, and returning the markup (quite similar to shortcodes) +- The `edit` function still shows a representation of the block in the editor's context (this could be very different from the rendered version, it's up to the block's author) +- The built-in `save` function just returns `null` because the rendering is performed server-side. +- The server-side rendering is a function taking the block and the block inner content as arguments, and returning the markup (quite similar to shortcodes) ## Live rendering in the block editor Gutenberg 2.8 added the [``](/packages/server-side-render/README.md) block which enables rendering to take place on the server using PHP rather than in JavaScript. -*Server-side render is meant as a fallback; client-side rendering in JavaScript is always preferred (client rendering is faster and allows better editor manipulation).* +_Server-side render is meant as a fallback; client-side rendering in JavaScript is always preferred (client rendering is faster and allows better editor manipulation)._ {% codetabs %} {% ESNext %} + ```jsx import { registerBlockType } from '@wordpress/blocks'; import ServerSideRender from '@wordpress/server-side-render'; @@ -174,10 +170,10 @@ registerBlockType( 'gutenberg-examples/example-dynamic', { icon: 'megaphone', category: 'widgets', - edit: function( props ) { + edit: function ( props ) { const blockProps = useBlockProps(); return ( -
+
{ - const { attributes: { content }, setAttributes, className } = props; + const { + attributes: { content }, + setAttributes, + className, + } = props; const blockProps = useBlockProps(); const onChangeContent = ( newContent ) => { setAttributes( { content: newContent } ); @@ -92,13 +97,21 @@ registerBlockType( 'gutenberg-examples/example-03-editable-esnext', { }, save: ( props ) => { const blockProps = useBlockProps.save(); - return ; + return ( + + ); }, } ); ``` + {% ES5 %} + ```js -( function( blocks, blockEditor, element ) { +( function ( blocks, blockEditor, element ) { var el = element.createElement; var RichText = blockEditor.RichText; var useBlockProps = blockEditor.useBlockProps; @@ -121,7 +134,7 @@ registerBlockType( 'gutenberg-examples/example-03-editable-esnext', { content: 'Hello World', }, }, - edit: function( props ) { + edit: function ( props ) { var blockProps = useBlockProps(); var content = props.attributes.content; function onChangeContent( newContent ) { @@ -138,18 +151,18 @@ registerBlockType( 'gutenberg-examples/example-03-editable-esnext', { ); }, - save: function( props ) { + save: function ( props ) { var blockProps = useBlockProps.save(); - return el( RichText.Content, Object.assign( blockProps, { - tagName: 'p', - value: props.attributes.content, - } ) ); + return el( + RichText.Content, + Object.assign( blockProps, { + tagName: 'p', + value: props.attributes.content, + } ) + ); }, } ); -}( - window.wp.blocks, - window.wp.blockEditor, - window.wp.element -) ); +} )( window.wp.blocks, window.wp.blockEditor, window.wp.element ); ``` + {% end %} diff --git a/docs/how-to-guides/block-tutorial/nested-blocks-inner-blocks.md b/docs/how-to-guides/block-tutorial/nested-blocks-inner-blocks.md index 744aa7f2a89e28..3c6e8cb2418aa9 100644 --- a/docs/how-to-guides/block-tutorial/nested-blocks-inner-blocks.md +++ b/docs/how-to-guides/block-tutorial/nested-blocks-inner-blocks.md @@ -8,6 +8,7 @@ Here is the basic InnerBlocks usage. {% codetabs %} {% ESNext %} + ```js import { registerBlockType } from '@wordpress/blocks'; import { InnerBlocks, useBlockProps } from '@wordpress/block-editor'; @@ -36,9 +37,11 @@ registerBlockType( 'gutenberg-examples/example-06', { }, } ); ``` + {% ES5 %} + ```js -( function( blocks, element, blockEditor ) { +( function ( blocks, element, blockEditor ) { var el = element.createElement; var InnerBlocks = blockEditor.InnerBlocks; var useBlockProps = blockEditor.useBlockProps; @@ -47,32 +50,21 @@ registerBlockType( 'gutenberg-examples/example-06', { title: 'Example: Inner Blocks', category: 'design', - edit: function() { + edit: function () { var blockProps = useBlockProps(); - return el( - 'div', - blockProps, - el( InnerBlocks ) - ); + return el( 'div', blockProps, el( InnerBlocks ) ); }, - save: function() { + save: function () { var blockProps = useBlockProps.save(); - return el( - 'div', - blockProps, - el( InnerBlocks.Content ) - ); + return el( 'div', blockProps, el( InnerBlocks.Content ) ); }, } ); -} ( - window.wp.blocks, - window.wp.element, - window.wp.blockEditor, -) ); +} )( window.wp.blocks, window.wp.element, window.wp.blockEditor ); ``` + {% end %} ## Allowed Blocks @@ -82,18 +74,15 @@ Using the `ALLOWED_BLOCKS` property, you can define the set of blocks allowed in ```js const ALLOWED_BLOCKS = [ 'core/image', 'core/paragraph' ]; //... - +; ``` ## Orientation By default, `InnerBlocks` expects its blocks to be shown in a vertical list. A valid use-case is to style InnerBlocks to appear horizontally. When blocks are styled in such a way, the `orientation` prop can be used to indicate a horizontal layout: + ```js - + ``` Specifying this prop will result in the block movers being shown horizontally, and also ensure drag and drop works correctly. @@ -104,6 +93,7 @@ Use the template property to define a set of blocks that prefill the InnerBlocks {% codetabs %} {% ESNext %} + ```js const MY_TEMPLATE = [ [ 'core/image', {} ], @@ -122,7 +112,9 @@ const MY_TEMPLATE = [ ); }, ``` + {% ES5 %} + ```js const MY_TEMPLATE = [ [ 'core/image', {} ], @@ -142,6 +134,7 @@ const MY_TEMPLATE = [ ); }, ``` + {% end %} Use the `templateLock` property to lock down the template. Using `all` locks the template complete, no changes can be made. Using `insert` prevents additional blocks to be inserted, but existing blocks can be reordered. See [templateLock documentation](https://github.com/WordPress/gutenberg/tree/HEAD/packages/block-editor/src/components/inner-blocks/README.md#templatelock) for additional information. @@ -152,7 +145,6 @@ Unrelated to `InnerBlocks` but worth mentioning here, you can create a [post tem The `InnerBlocks` template is for the component in the single block that you created, the rest of the post can include any blocks the user likes. Using a post template, can lock the entire post to just the template you define. - ```php add_action( 'init', function() { $post_type_object = get_post_type_object( 'post' ); @@ -176,5 +168,5 @@ export const settings = { icon, description: __( 'A single column within a columns block.' ), //... -} +}; ``` diff --git a/docs/how-to-guides/block-tutorial/writing-your-first-block-type.md b/docs/how-to-guides/block-tutorial/writing-your-first-block-type.md index 55faf6d69f7571..f6f6c681621210 100644 --- a/docs/how-to-guides/block-tutorial/writing-your-first-block-type.md +++ b/docs/how-to-guides/block-tutorial/writing-your-first-block-type.md @@ -6,7 +6,7 @@ Blocks containing static content are implemented entirely in JavaScript using th ## Enqueuing Block Scripts -While the block's editor behaviors are implemented in JavaScript, you'll need to register your block server-side to ensure that the script is enqueued when the editor loads. Register scripts and styles using [`wp_register_script`](https://developer.wordpress.org/reference/functions/wp_register_script/) and [`wp_register_style`](https://developer.wordpress.org/reference/functions/wp_register_style/), then assign these as handles associated with your block using the `script`, `style`, `editor_script`, and `editor_style` block type registration settings. +While the block's editor behaviors are implemented in JavaScript, you'll need to register your block server-side to ensure that the script is enqueued when the editor loads. Register scripts and styles using [`wp_register_script`](https://developer.wordpress.org/reference/functions/wp_register_script/) and [`wp_register_style`](https://developer.wordpress.org/reference/functions/wp_register_style/), then assign these as handles associated with your block using the `script`, `style`, `editor_script`, and `editor_style` block type registration settings. The `editor_script` and `editor_style` files will only be enqueued in the editor, while the `script` and `style` will be enqueued both in the editor and when viewing a post on the front of your site. @@ -28,7 +28,7 @@ function gutenberg_examples_01_register_block() { ); register_block_type( 'gutenberg-examples/example-01-basic-esnext', array( - 'apiVersion' => 2, + 'api_version' => 2, 'editor_script' => 'gutenberg-examples-01-esnext', ) ); @@ -36,13 +36,12 @@ function gutenberg_examples_01_register_block() { add_action( 'init', 'gutenberg_examples_01_register_block' ); ``` -Note the above example, shows using the [wp-scripts build step](/docs/how-to-guides/javascript/js-build-setup/) that automatically sets dependencies and versions the file. +Note the above example, shows using the [wp-scripts build step](/docs/how-to-guides/javascript/js-build-setup/) that automatically sets dependencies and versions the file. If you were using the ES5 code, you would specify `array( 'wp-blocks', 'wp-element' )` as the dependency array. See the [example 01](https://github.com/WordPress/gutenberg-examples/blob/HEAD/01-basic/index.php) in Gutenberg Examples repository for full syntax. -- __`wp-blocks`__ includes block type registration and related functions -- __`wp-element`__ includes the [WordPress Element abstraction](/packages/element/README.md) for describing the structure of your blocks - +- **`wp-blocks`** includes block type registration and related functions +- **`wp-element`** includes the [WordPress Element abstraction](/packages/element/README.md) for describing the structure of your blocks ## Registering the Block @@ -50,6 +49,7 @@ With the script enqueued, let's look at the implementation of the block itself: {% codetabs %} {% ESNext %} + ```jsx import { registerBlockType } from '@wordpress/blocks'; import { useBlockProps } from '@wordpress/block-editor'; @@ -69,18 +69,26 @@ registerBlockType( 'gutenberg-examples/example-01-basic-esnext', { edit() { const blockProps = useBlockProps( { style: blockStyle } ); - return
Hello World, step 1 (from the editor).
; + return ( +
Hello World, step 1 (from the editor).
+ ); }, save() { const blockProps = useBlockProps.save( { style: blockStyle } ); - return
Hello World, step 1 (from the frontend).
; + return ( +
+ Hello World, step 1 (from the frontend). +
+ ); }, } ); ``` + {% ES5 %} + ```js -( function( blocks, element, blockEditor ) { +( function ( blocks, element, blockEditor ) { var el = element.createElement; var useBlockProps = blockEditor.useBlockProps; @@ -96,7 +104,7 @@ registerBlockType( 'gutenberg-examples/example-01-basic-esnext', { icon: 'universal-access-alt', category: 'design', example: {}, - edit: function() { + edit: function () { var blockProps = useBlockProps( { style: blockStyle } ); return el( 'p', @@ -104,7 +112,7 @@ registerBlockType( 'gutenberg-examples/example-01-basic-esnext', { 'Hello World, step 1 (from the editor).' ); }, - save: function() { + save: function () { var blockProps = useBlockProps.save( { style: blockStyle } ); return el( 'p', @@ -113,12 +121,9 @@ registerBlockType( 'gutenberg-examples/example-01-basic-esnext', { ); }, } ); -}( - window.wp.blocks, - window.wp.element, - window.wp.blockEditor -) ); +} )( window.wp.blocks, window.wp.element, window.wp.blockEditor ); ``` + {% end %} _By now you should be able to see `Hello World, step 1 (from the editor).` in the admin side and `Hello World, step 1 (from the frontend).` on the frontend side._ diff --git a/docs/how-to-guides/designers/animation.md b/docs/how-to-guides/designers/animation.md index ea861c8bb1a22d..346ebb937cafdb 100644 --- a/docs/how-to-guides/designers/animation.md +++ b/docs/how-to-guides/designers/animation.md @@ -6,21 +6,21 @@ Animation can help reinforce a sense of hierarchy and spatial orientation. This ### Point of Origin -- Animation can help anchor an interface element. For example a menu can scale up from the button that opened it. -- Animation can help give a sense of place; for example a sidebar can animate in from the side, implying it was always hidden off-screen. -- Design your animations as if you're working with real-world materials. Imagine your user interface elements are made of real materials — when not on screen, where are they? Use animation to help express that. +- Animation can help anchor an interface element. For example a menu can scale up from the button that opened it. +- Animation can help give a sense of place; for example a sidebar can animate in from the side, implying it was always hidden off-screen. +- Design your animations as if you're working with real-world materials. Imagine your user interface elements are made of real materials — when not on screen, where are they? Use animation to help express that. ### Speed -- Animations should never block a user interaction. They should be fast, almost always complete in less than 0.2 seconds. -- A user should not have to wait for an animation to finish before they can interact. -- Animations should be performant. Use `transform` CSS properties when you can, these render elements on the GPU, making them smooth. -- If an animation can't be made fast & performant, leave it out. +- Animations should never block a user interaction. They should be fast, almost always complete in less than 0.2 seconds. +- A user should not have to wait for an animation to finish before they can interact. +- Animations should be performant. Use `transform` CSS properties when you can, these render elements on the GPU, making them smooth. +- If an animation can't be made fast & performant, leave it out. ### Simple -- Don't bounce if the material isn't made of rubber. -- Don't rotate, fold, or animate on a curved path. Keep it simple. +- Don't bounce if the material isn't made of rubber. +- Don't rotate, fold, or animate on a curved path. Keep it simple. ### Consistency @@ -30,10 +30,10 @@ Reuse animations if one already exists for your task. ## Accessibility Considerations -- Animations should be subtle. Be cognizant of users with [vestibular disorders triggered by motion](https://www.ncbi.nlm.nih.gov/pubmed/29017000). -- Don't animate elements that are currently reporting content to adaptive technology (e.g., an `aria-live` region that's receiving updates). This can cause confusion wherein the technology tries to parse a region that's actively changing. -- Avoid animations that aren't directly triggered by user behaviors. -- Whenever possible, ensure that animations respect the OS-level "Reduce Motion" settings. This can be done by utilizing the [`prefers-reduced-motion`](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion) media query. Gutenberg includes a `@reduce-motion` mixin for this, to be used alongside rules that include a CSS `animate` property. +- Animations should be subtle. Be cognizant of users with [vestibular disorders triggered by motion](https://www.ncbi.nlm.nih.gov/pubmed/29017000). +- Don't animate elements that are currently reporting content to adaptive technology (e.g., an `aria-live` region that's receiving updates). This can cause confusion wherein the technology tries to parse a region that's actively changing. +- Avoid animations that aren't directly triggered by user behaviors. +- Whenever possible, ensure that animations respect the OS-level "Reduce Motion" settings. This can be done by utilizing the [`prefers-reduced-motion`](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion) media query. Gutenberg includes a `@reduce-motion` mixin for this, to be used alongside rules that include a CSS `animate` property. ## Inventory of Reused Animations diff --git a/docs/how-to-guides/designers/block-design.md b/docs/how-to-guides/designers/block-design.md index fdc6abb4369bdf..2a71b611b94270 100644 --- a/docs/how-to-guides/designers/block-design.md +++ b/docs/how-to-guides/designers/block-design.md @@ -37,14 +37,14 @@ Setup states, sometimes referred to as "placeholders", can be used to walk users A setup state is **not** necessary if: -- You can provide good default content in the block that will meet most people’s needs. -- That default content is easy to edit and customize. +- You can provide good default content in the block that will meet most people’s needs. +- That default content is easy to edit and customize. Use a setup state if: -- There isn’t a clear default state that would work for most users. -- You need to gather input from the user that doesn’t have a 1-1 relationship with the live preview of the block (for example, if you need the user to input an API key to render content). -- You need more information from the user in order to render useful default content. +- There isn’t a clear default state that would work for most users. +- You need to gather input from the user that doesn’t have a 1-1 relationship with the live preview of the block (for example, if you need the user to input an API key to render content). +- You need more information from the user in order to render useful default content. For blocks that do have setup states, once the user has gone through the setup process, the placeholder is replaced with the live preview state of that block. @@ -70,9 +70,9 @@ A block should have a straightforward, short name so users can easily find it in When referring to a block in documentation or UI, use title case for the block title and lowercase for the "block" descriptor. For example: -- Paragraph block -- Latest Posts block -- Media & Text block +- Paragraph block +- Latest Posts block +- Media & Text block Blocks should have an identifying icon, ideally using a single color. Try to avoid using the same icon used by an existing block. The core block icons are based on [Material Design Icons](https://material.io/tools/icons/). Look to that icon set, or to [Dashicons](https://developer.wordpress.org/resource/dashicons/) for style inspiration. @@ -88,13 +88,13 @@ Avoid long, multi-line block names. Every block should include a description that clearly explains the block's function. The description will display in the Settings Sidebar. -You can add a description by using the description attribute in the [registerBlockType function](/docs/reference-guides/block-api/block-registration.md). +You can add a description by using the description attribute in the [registerBlockType function](/docs/reference-guides/block-api/block-registration.md). Stick to a single imperative sentence with an action + subject format. Examples: -- Start with the building block of all narrative. -- Introduce new sections and organize content to help visitors (and search engines) understand the structure of your content. -- Create a bulleted or numbered list. +- Start with the building block of all narrative. +- Introduce new sections and organize content to help visitors (and search engines) understand the structure of your content. +- Create a bulleted or numbered list. ![A screenshot of a short block description](https://raw.githubusercontent.com/WordPress/gutenberg/HEAD/docs/how-to-guides/designers/assets/block-descriptions-do.png) **Do:** @@ -158,13 +158,13 @@ The most basic unit of the editor. The Paragraph block is a simple input field. ### Placeholder: -- Simple placeholder text that reads “Type / to choose a block”. The placeholder disappears when the block is selected. +- Simple placeholder text that reads “Type / to choose a block”. The placeholder disappears when the block is selected. ### Selected state: -- Block Toolbar: Has a switcher to perform transformations to headings, etc. -- Block Toolbar: Has basic text alignments -- Block Toolbar: Has inline formatting options, bold, italic, strikethrough, and link +- Block Toolbar: Has a switcher to perform transformations to headings, etc. +- Block Toolbar: Has basic text alignments +- Block Toolbar: Has inline formatting options, bold, italic, strikethrough, and link ### Image @@ -174,21 +174,21 @@ Basic image block. ### Placeholder: -- A generic gray placeholder block with options to upload an image, drag and drop an image directly on it, or pick an image from the media library. +- A generic gray placeholder block with options to upload an image, drag and drop an image directly on it, or pick an image from the media library. ### Selected state: -- Block Toolbar: Alignments, including wide and full-width if the theme supports it. -- Block Toolbar: Edit Image, to open the Media Library -- Block Toolbar: Link button -- When an image is uploaded, a caption input field appears with a “Write caption…” placeholder text below the image: +- Block Toolbar: Alignments, including wide and full-width if the theme supports it. +- Block Toolbar: Edit Image, to open the Media Library +- Block Toolbar: Link button +- When an image is uploaded, a caption input field appears with a “Write caption…” placeholder text below the image: ![Image Block](https://cldup.com/6YYXstl_xX-3000x3000.png) ### Block settings: -- Has description: “They're worth 1,000 words! Insert a single image.” -- Has options for changing or adding alt text and adding additional custom CSS classes. +- Has description: “They're worth 1,000 words! Insert a single image.” +- Has options for changing or adding alt text and adding additional custom CSS classes. _Future improvements to the Image block could include getting rid of the media modal in place of letting users select images directly from the placeholder itself. In general, try to avoid modals._ @@ -202,14 +202,14 @@ Has no placeholder as it works immediately upon insertion. The default inserted ### Selected state: -- Block Toolbar: Alignments -- Block Toolbar: Options for picking list view or grid view +- Block Toolbar: Alignments +- Block Toolbar: Options for picking list view or grid view _Note that the Block Toolbar does not include the Block Chip in this case, since there are no similar blocks to switch to._ ### Block settings: -- Has description: “Display a list of your most recent posts.” -- Has options for post order, narrowing the list by category, changing the default number of posts to show, and showing the post date. +- Has description: “Display a list of your most recent posts.” +- Has options for post order, narrowing the list by category, changing the default number of posts to show, and showing the post date. _Latest Posts is fully functional as soon as it’s inserted because it comes with good defaults._ diff --git a/docs/how-to-guides/designers/design-resources.md b/docs/how-to-guides/designers/design-resources.md index a4f01f98b18a86..235951e4839e98 100644 --- a/docs/how-to-guides/designers/design-resources.md +++ b/docs/how-to-guides/designers/design-resources.md @@ -1,11 +1,13 @@ # Resources ## Figma + The [WordPress Design team](https://make.wordpress.org/design/) uses [Figma](https://www.figma.com/) to collaborate and share work. If you'd like to contribute, join the [#design channel](https://app.slack.com/client/T024MFP4J/C02S78ZAL) in [Slack](https://make.wordpress.org/chat/) and ask the team to set you up with a free Figma account. This will give you access to a helpful library of components used in WordPress. They are stable, fully supported, up to date, and ready for use in designs and prototypes. ### How to contribute ### Resources for learning how to use Figma + [Getting started with Figma](https://help.figma.com/category/9-getting-started) [Top Online Tutorials to Learn Figma for UI/UX Design](https://medium.com/quick-design/top-online-tutorials-to-learn-figma-for-ui-ux-design-4e9c6721a72d) @@ -13,6 +15,7 @@ The [WordPress Design team](https://make.wordpress.org/design/) uses [Figma](htt [Take a Tour Around Figma](https://help.figma.com/article/12-getting-familiar-with-figma) ### Learning how to use files and projects + [Getting started with Figma files and projects](https://help.figma.com/article/298-getting-started-with-files-and-projects) [What are files?](https://help.figma.com/article/298-getting-started-with-files-and-projects#files) @@ -24,6 +27,7 @@ The [WordPress Design team](https://make.wordpress.org/design/) uses [Figma](htt [FAQ](https://help.figma.com/article/298-getting-started-with-files-and-projects#faq) ### Learning how to use components + [Getting started with components](https://help.figma.com/article/66-components) [What are components?](https://help.figma.com/article/66-components#components) @@ -31,6 +35,7 @@ The [WordPress Design team](https://make.wordpress.org/design/) uses [Figma](htt [Video tutorial](https://help.figma.com/article/66-components#videos) ### Learning how to use WordPress Figma libraries + **How to turn on the WordPress Components library in Figma** ![How to turn on Figma libraries gif](https://wordpress.org/gutenberg/files/2019/08/figma-howtoturnonlibraries.gif) @@ -47,5 +52,4 @@ The [WordPress Design team](https://make.wordpress.org/design/) uses [Figma](htt WordPress components in Figma mirror the live React components. Documentation for how to refine or contribute to WordPress components in React is coming soon. - If you have questions, please don’t hesitate to ask in the #design channel on the WordPress community Slack. diff --git a/docs/how-to-guides/designers/user-interface.md b/docs/how-to-guides/designers/user-interface.md index 1d688e27838d64..d1e59c3c15d62b 100644 --- a/docs/how-to-guides/designers/user-interface.md +++ b/docs/how-to-guides/designers/user-interface.md @@ -10,13 +10,13 @@ The **Toolbar** contains document-level actions: Editor/Select modes, save statu The **Content Area** contains the document itself. -The **Settings Sidebar** contains additional settings for the document (tags, categories, schedule etc.) and for blocks in the “Block” tab. A cog button in the toolbar hides the Settings Sidebar, allowing the user to enjoy a more immersive writing experience. On small screens, the sidebar is hidden by default. +The **Settings Sidebar** contains additional settings for the document (tags, categories, schedule etc.) and for blocks in the “Block” tab. A cog button in the toolbar hides the Settings Sidebar, allowing the user to enjoy a more immersive writing experience. On small screens, the sidebar is hidden by default. ## The Block -The block itself is the most basic unit of the editor. Generally speaking, everything is a block. Users build posts and pages using blocks, mimicking the vertical flow of the underlying HTML markup. +The block itself is the most basic unit of the editor. Generally speaking, everything is a block. Users build posts and pages using blocks, mimicking the vertical flow of the underlying HTML markup. -By surfacing each section of the document as a manipulatable block, we surface block-specific features contextually. This is inspired by desktop app conventions, and allows for a breadth of advanced features without weighing down the UI. +By surfacing each section of the document as a manipulatable block, we surface block-specific features contextually. This is inspired by desktop app conventions, and allows for a breadth of advanced features without weighing down the UI. A selected block shows a number of contextual actions: @@ -42,19 +42,19 @@ Please note that selection and focus can be different. An image block can be sel The sidebar has two tabs, Document and Block: -- The **Document Tab** shows metadata and settings for the post or page being edited. -- The **Block Tab** shows metadata and settings for the currently selected block. +- The **Document Tab** shows metadata and settings for the post or page being edited. +- The **Block Tab** shows metadata and settings for the currently selected block. -Each tab has sets of editable fields (**Sidebar Sections**) that users can toggle open or closed. +Each tab has sets of editable fields (**Sidebar Sections**) that users can toggle open or closed. If a block requires advanced configuration, those settings should live in the Settings Sidebar. Don’t put anything in the sidebar block tab that is necessary for the basic operation of your block; your user might dismiss the sidebar for an immersive writing experience. Pick good defaults, and make important actions available in the block toolbar. Actions that could go in the block tab of the sidebar could be: -- Drop cap, for text -- Number of columns for galleries -- Number of posts, or category, in the “Latest Posts” block -- Any configuration that you don’t need access to in order to perform basic tasks +- Drop cap, for text +- Number of columns for galleries +- Number of posts, or category, in the “Latest Posts” block +- Any configuration that you don’t need access to in order to perform basic tasks ## Block Library diff --git a/docs/how-to-guides/feature-flags.md b/docs/how-to-guides/feature-flags.md index 7f7a165d13a3ac..db27255f12ddb7 100644 --- a/docs/how-to-guides/feature-flags.md +++ b/docs/how-to-guides/feature-flags.md @@ -2,7 +2,7 @@ With phase 2 of the Gutenberg project there's a need for improved control over how code changes are released. Newer features developed for phase 2 and beyond should only be released to the Gutenberg plugin, while improvements and bug fixes should still continue to make their way into core releases. -The technique for handling this is known as a 'feature flag'. +The technique for handling this is known as a 'feature flag'. ## Introducing `process.env.GUTENBERG_PHASE` @@ -17,16 +17,18 @@ function myPhaseTwoFeature() { // implementation } -export const phaseTwoFeature = process.env.GUTENBERG_PHASE === 2 ? myPhaseTwoFeature : undefined; +export const phaseTwoFeature = + process.env.GUTENBERG_PHASE === 2 ? myPhaseTwoFeature : undefined; ``` In phase 1 environments the `phaseTwoFeature` export will be `undefined`. If you're attempting to import and call a phase 2 feature, be sure to wrap the call to the function in an if statement to avoid an error: + ```js import { phaseTwoFeature } from '@wordpress/foo'; -if ( process.env.GUTENBERG_PHASE === 2) { +if ( process.env.GUTENBERG_PHASE === 2 ) { phaseTwoFeature(); } ``` @@ -36,6 +38,7 @@ if ( process.env.GUTENBERG_PHASE === 2) { During the webpack build, any instances of `process.env.GUTENBERG_PHASE` will be replaced using webpack's define plugin (https://webpack.js.org/plugins/define-plugin/). If you write the following code: + ```js if ( process.env.GUTENBERG_PHASE === 2 ) { phaseTwoFeature(); @@ -43,6 +46,7 @@ if ( process.env.GUTENBERG_PHASE === 2 ) { ``` When building the codebase for the plugin the variable will be replaced with the number literal `2`: + ```js if ( 2 === 2 ) { phaseTwoFeature(); @@ -52,6 +56,7 @@ if ( 2 === 2 ) { Any code within the body of the if statement will be executed within the gutenberg plugin since `2 === 2` evaluates to `true`. For core, the `process.env.GUTENBERG_PHASE` variable is replaced with `1`, so the built code will look like: + ```js if ( 1 === 2 ) { phaseTwoFeature(); @@ -62,21 +67,24 @@ if ( 1 === 2 ) { ### Dead Code Elimination -When building code for production, webpack 'minifies' code (https://en.wikipedia.org/wiki/Minification_(programming)), removing the amount of unnecessary JavaScript as much as possible. One of the steps involves something known as 'dead code elimination'. +When building code for production, webpack 'minifies' code (https://en.wikipedia.org/wiki/Minification_(programming)), removing the amount of unnecessary JavaScript as much as possible. One of the steps involves something known as 'dead code elimination'. When the following code is encountered, webpack determines that the surrounding `if`statement is unnecessary: + ```js if ( 2 === 2 ) { phaseTwoFeature(); } ``` - The condition will always evaluates to `true`, so can be removed leaving just the code in the body: - ```js - phaseTwoFeature(); - ``` +The condition will always evaluates to `true`, so can be removed leaving just the code in the body: + +```js +phaseTwoFeature(); +``` Similarly when building for core, the condition in the following `if` statement always resolves to false: + ```js if ( 1 === 2 ) { phaseTwoFeature(); @@ -89,7 +97,7 @@ The minification process will remove the entire `if` statement including the bod #### Why should I only use `===` or `!==` when comparing `process.env.GUTENBERG_PHASE` and not `>`, `>=`, `<` or `<=`? -This is a restriction due to the behaviour of the greater than or less than operators in JavaScript when `process.env.GUTENBERG_PHASE` is undefined, as might be the case for third party users of WordPress npm packages. Both `process.env.GUTENBERG_PHASE < 2` and `process.env.GUTENBERG_PHASE > 1` resolve to false. When writing `if ( process.env.GUTENBERG_PHASE > 1 )`, the intention might be to avoid executing the phase 2 code in the following `if` statement's body. That's fine since it will evaluate to false. +This is a restriction due to the behaviour of the greater than or less than operators in JavaScript when `process.env.GUTENBERG_PHASE` is undefined, as might be the case for third party users of WordPress npm packages. Both `process.env.GUTENBERG_PHASE < 2` and `process.env.GUTENBERG_PHASE > 1` resolve to false. When writing `if ( process.env.GUTENBERG_PHASE > 1 )`, the intention might be to avoid executing the phase 2 code in the following `if` statement's body. That's fine since it will evaluate to false. However, the following code doesn't quite have the intended behaviour: diff --git a/docs/how-to-guides/format-api/1-register-format.md b/docs/how-to-guides/format-api/1-register-format.md index acf118f9701e14..ddef1b23d20bba 100644 --- a/docs/how-to-guides/format-api/1-register-format.md +++ b/docs/how-to-guides/format-api/1-register-format.md @@ -29,35 +29,35 @@ Then add a new file named `my-custom-format.js` with the following contents: {% codetabs %} {% ES5 %} + ```js -( function( wp ) { - wp.richText.registerFormatType( - 'my-custom-format/sample-output', { - title: 'Sample output', - tagName: 'samp', - className: null, - } - ); +( function ( wp ) { + wp.richText.registerFormatType( 'my-custom-format/sample-output', { + title: 'Sample output', + tagName: 'samp', + className: null, + } ); } )( window.wp ); ``` + {% ESNext %} + ```js import { registerFormatType } from '@wordpress/rich-text'; -registerFormatType( - 'my-custom-format/sample-output', { - title: 'Sample output', - tagName: 'samp', - className: null, - } -); +registerFormatType( 'my-custom-format/sample-output', { + title: 'Sample output', + tagName: 'samp', + className: null, +} ); ``` + {% end %} Make that plugin available in your WordPress setup and activate it. Then, load a new page/post. The list of available format types is maintained in the `core/rich-text` store. You can query the store to check that your custom format is now available. To do so, run this code in your browser's console: - wp.data.select( 'core/rich-text' ).getFormatTypes(); + wp.data.select( 'core/rich-text' ).getFormatTypes(); It'll return an array containing the format types, including your own. diff --git a/docs/how-to-guides/format-api/2-toolbar-button.md b/docs/how-to-guides/format-api/2-toolbar-button.md index 4d64c1e7dcee38..ddc10df8c9877a 100644 --- a/docs/how-to-guides/format-api/2-toolbar-button.md +++ b/docs/how-to-guides/format-api/2-toolbar-button.md @@ -6,53 +6,53 @@ Paste this code in `my-custom-format.js`: {% codetabs %} {% ES5 %} + ```js -( function( wp ) { - var MyCustomButton = function( props ) { - return wp.element.createElement( - wp.editor.RichTextToolbarButton, { - icon: 'editor-code', - title: 'Sample output', - onClick: function() { - console.log( 'toggle format' ); - }, - } - ); - } - wp.richText.registerFormatType( - 'my-custom-format/sample-output', { +( function ( wp ) { + var MyCustomButton = function ( props ) { + return wp.element.createElement( wp.editor.RichTextToolbarButton, { + icon: 'editor-code', title: 'Sample output', - tagName: 'samp', - className: null, - edit: MyCustomButton, - } - ); + onClick: function () { + console.log( 'toggle format' ); + }, + } ); + }; + wp.richText.registerFormatType( 'my-custom-format/sample-output', { + title: 'Sample output', + tagName: 'samp', + className: null, + edit: MyCustomButton, + } ); } )( window.wp ); ``` + {% ESNext %} + ```js import { registerFormatType } from '@wordpress/rich-text'; import { RichTextToolbarButton } from '@wordpress/block-editor'; -const MyCustomButton = props => { - return { - console.log( 'toggle format' ); - } } - /> +const MyCustomButton = ( props ) => { + return ( + { + console.log( 'toggle format' ); + } } + /> + ); }; -registerFormatType( - 'my-custom-format/sample-output', { - title: 'Sample output', - tagName: 'samp', - className: null, - edit: MyCustomButton, - } -); +registerFormatType( 'my-custom-format/sample-output', { + title: 'Sample output', + tagName: 'samp', + className: null, + edit: MyCustomButton, +} ); ``` + {% end %} **Important**: note that this code is using two new utilities (`wp.element.createElement`, and `wp.editor.RichTextToolbarButton`) so don't forget adding the corresponding `wp-element` and `wp-editor` packages to the dependencies array in the PHP file along with the existing `wp-rich-text`. @@ -71,29 +71,28 @@ The following sample code renders the previously shown button only on Paragraph {% codetabs %} {% ES5 %} + ```js -( function( wp ) { +( function ( wp ) { var withSelect = wp.data.withSelect; var ifCondition = wp.compose.ifCondition; var compose = wp.compose.compose; - var MyCustomButton = function( props ) { - return wp.element.createElement( - wp.editor.RichTextToolbarButton, { - icon: 'editor-code', - title: 'Sample output', - onClick: function() { - console.log( 'toggle format' ); - }, - } - ); - } + var MyCustomButton = function ( props ) { + return wp.element.createElement( wp.editor.RichTextToolbarButton, { + icon: 'editor-code', + title: 'Sample output', + onClick: function () { + console.log( 'toggle format' ); + }, + } ); + }; var ConditionalButton = compose( - withSelect( function( select ) { + withSelect( function ( select ) { return { - selectedBlock: select( 'core/editor' ).getSelectedBlock() - } + selectedBlock: select( 'core/editor' ).getSelectedBlock(), + }; } ), - ifCondition( function( props ) { + ifCondition( function ( props ) { return ( props.selectedBlock && props.selectedBlock.name === 'core/paragraph' @@ -101,56 +100,56 @@ The following sample code renders the previously shown button only on Paragraph } ) )( MyCustomButton ); - wp.richText.registerFormatType( - 'my-custom-format/sample-output', { - title: 'Sample output', - tagName: 'samp', - className: null, - edit: ConditionalButton, - } - ); + wp.richText.registerFormatType( 'my-custom-format/sample-output', { + title: 'Sample output', + tagName: 'samp', + className: null, + edit: ConditionalButton, + } ); } )( window.wp ); ``` + {% ESNext %} + ```js import { compose, ifCondition } from '@wordpress/compose'; import { registerFormatType } from '@wordpress/rich-text'; import { RichTextToolbarButton } from '@wordpress/block-editor'; import { withSelect } from '@wordpress/data'; -const MyCustomButton = props => { - return { - console.log( 'toggle format' ); - } } - /> +const MyCustomButton = ( props ) => { + return ( + { + console.log( 'toggle format' ); + } } + /> + ); }; const ConditionalButton = compose( - withSelect( function( select ) { + withSelect( function ( select ) { return { - selectedBlock: select( 'core/editor' ).getSelectedBlock() - } + selectedBlock: select( 'core/editor' ).getSelectedBlock(), + }; } ), - ifCondition( function( props ) { + ifCondition( function ( props ) { return ( - props.selectedBlock && - props.selectedBlock.name === 'core/paragraph' + props.selectedBlock && props.selectedBlock.name === 'core/paragraph' ); } ) )( MyCustomButton ); -registerFormatType( - 'my-custom-format/sample-output', { - title: 'Sample output', - tagName: 'samp', - className: null, - edit: ConditionalButton, - } -); +registerFormatType( 'my-custom-format/sample-output', { + title: 'Sample output', + tagName: 'samp', + className: null, + edit: ConditionalButton, +} ); ``` + {% end %} Don't forget adding `wp-compose` and `wp-data` to the dependencies array in the PHP script. diff --git a/docs/how-to-guides/format-api/3-apply-format.md b/docs/how-to-guides/format-api/3-apply-format.md index 25dd678114eeb7..da1d4192692601 100644 --- a/docs/how-to-guides/format-api/3-apply-format.md +++ b/docs/how-to-guides/format-api/3-apply-format.md @@ -8,61 +8,63 @@ Update `my-custom-format.js` with this new code: {% codetabs %} {% ES5 %} + ```js -( function( wp ) { - var MyCustomButton = function( props ) { - return wp.element.createElement( - wp.blockEditor.RichTextToolbarButton, { - icon: 'editor-code', - title: 'Sample output', - onClick: function() { - props.onChange( wp.richText.toggleFormat( - props.value, - { type: 'my-custom-format/sample-output' } - ) ); - }, - isActive: props.isActive, - } - ); - } - wp.richText.registerFormatType( - 'my-custom-format/sample-output', { +( function ( wp ) { + var MyCustomButton = function ( props ) { + return wp.element.createElement( wp.blockEditor.RichTextToolbarButton, { + icon: 'editor-code', title: 'Sample output', - tagName: 'samp', - className: null, - edit: MyCustomButton, - } - ); + onClick: function () { + props.onChange( + wp.richText.toggleFormat( props.value, { + type: 'my-custom-format/sample-output', + } ) + ); + }, + isActive: props.isActive, + } ); + }; + wp.richText.registerFormatType( 'my-custom-format/sample-output', { + title: 'Sample output', + tagName: 'samp', + className: null, + edit: MyCustomButton, + } ); } )( window.wp ); ``` + {% ESNext %} + ```js import { registerFormatType, toggleFormat } from '@wordpress/rich-text'; import { RichTextToolbarButton } from '@wordpress/block-editor'; const MyCustomButton = ( props ) => { - return { - props.onChange( toggleFormat( - props.value, - { type: 'my-custom-format/sample-output' } - ) ); - } } - isActive={ props.isActive } - />; + return ( + { + props.onChange( + toggleFormat( props.value, { + type: 'my-custom-format/sample-output', + } ) + ); + } } + isActive={ props.isActive } + /> + ); }; -registerFormatType( - 'my-custom-format/sample-output', { - title: 'Sample output', - tagName: 'samp', - className: null, - edit: MyCustomButton, - } -); +registerFormatType( 'my-custom-format/sample-output', { + title: 'Sample output', + tagName: 'samp', + className: null, + edit: MyCustomButton, +} ); ``` + {% end %} Now, let's check that is working as intended: reload the post/page, make a text selection, click the button, and then change to HTML view to confirm that the tag was effectively applied. diff --git a/docs/how-to-guides/internationalization.md b/docs/how-to-guides/internationalization.md index 65ad0e204b6803..fde7b183c7306b 100644 --- a/docs/how-to-guides/internationalization.md +++ b/docs/how-to-guides/internationalization.md @@ -4,7 +4,7 @@ Internationalization is the process to provide multiple language support to software, in this case WordPress. Internationalization is often abbreviated as **i18n**, where 18 stands for the number of letters between the first _i_ and the last _n_. -Providing i18n support to your plugin and theme allows it to reach the largest possible audience, even without requiring you to provide the additional language translations. When you upload your software to WordPress.org, all JS and PHP files will automatically be parsed. Any detected translation strings are added to [translate.wordpress.org](https://translate.wordpress.org/) to allow the community to translate, ensuring WordPress plugins and themes are available in as many languages as possible. +Providing i18n support to your plugin and theme allows it to reach the largest possible audience, even without requiring you to provide the additional language translations. When you upload your software to WordPress.org, all JS and PHP files will automatically be parsed. Any detected translation strings are added to [translate.wordpress.org](https://translate.wordpress.org/) to allow the community to translate, ensuring WordPress plugins and themes are available in as many languages as possible. For PHP, WordPress has a long established process, see [How to Internationalize Your Plugin](https://developer.wordpress.org/plugins/internationalization/how-to-internationalize-your-plugin/). The release of WordPress 5.0 brings a similar process for translation to JavaScript code. @@ -28,17 +28,18 @@ function myguten_block_init() { ); register_block_type( 'myguten/simple', array( - 'apiVersion' => 2, + 'api_version' => 2, 'editor_script' => 'myguten-script', ) ); } add_action( 'init', 'myguten_block_init' ); ``` -In your code, you can include the i18n functions. The most common function is **__** (a double underscore) which provides translation of a simple string. Here is a basic block example: +In your code, you can include the i18n functions. The most common function is **\_\_** (a double underscore) which provides translation of a simple string. Here is a basic block example: {% codetabs %} {% ESNext %} + ```js import { __ } from '@wordpress/i18n'; import { registerBlockType } from '@wordpress/blocks'; @@ -52,25 +53,19 @@ registerBlockType( 'myguten/simple', { edit: () => { const blockProps = useBlockProps( { style: { color: 'red' } } ); - return ( -

- { __( 'Hello World', 'myguten' ) } -

- ); + return

{ __( 'Hello World', 'myguten' ) }

; }, save: () => { const blockProps = useBlockProps.save( { style: { color: 'red' } } ); - return ( -

- { __( 'Hello World', 'myguten' ) } -

- ); + return

{ __( 'Hello World', 'myguten' ) }

; }, } ); ``` + {% ES5 %} + ```js const { __ } = wp.i18n; const el = wp.element.createElement; @@ -81,35 +76,28 @@ registerBlockType( 'myguten/simple', { title: __( 'Simple Block', 'myguten' ), category: 'widgets', - edit: function() { + edit: function () { const blockProps = useBlockProps( { style: { color: 'red' } } ); - - return el( - 'p', - blockProps, - __( 'Hello World', 'myguten' ) - ); + + return el( 'p', blockProps, __( 'Hello World', 'myguten' ) ); }, - save: function() { + save: function () { const blockProps = useBlockProps.save( { style: { color: 'red' } } ); - return el( - 'p', - blockProps, - __( 'Hello World', 'myguten' ) - ); + return el( 'p', blockProps, __( 'Hello World', 'myguten' ) ); }, } ); ``` + {% end %} In the above example, the function will use the first argument for the string to be translated. The second argument is the text domain which must match the text domain slug specified by your plugin. Common functions available, these mirror their PHP counterparts are: -- `__( 'Hello World', 'my-text-domain' )` - Translate a certain string. -- `_n( '%s Comment', '%s Comments', numberOfComments, 'my-text-domain' )` - Translate and retrieve the singular or plural form based on the supplied number. -- `_x( 'Default', 'block style', 'my-text-domain' )` - Translate a certain string with some additional context. +- `__( 'Hello World', 'my-text-domain' )` - Translate a certain string. +- `_n( '%s Comment', '%s Comments', numberOfComments, 'my-text-domain' )` - Translate and retrieve the singular or plural form based on the supplied number. +- `_x( 'Default', 'block style', 'my-text-domain' )` - Translate a certain string with some additional context. **Note:** Every string displayed to the user should be wrapped in an i18n function. @@ -125,7 +113,7 @@ After all strings in your code is wrapped, the final step is to tell WordPress y This is all you need to make your plugin JavaScript code translatable. -When you set script translations for a handle WordPress will automatically figure out if a translations file exists on translate.wordpress.org, and if so ensure that it's loaded into `wp.i18n` before your script runs. With translate.wordpress.org, plugin authors also do not need to worry about setting up their own infrastructure for translations and can rely on a global community with dozens of active locales. Read more about [WordPress Translations](https://make.wordpress.org/meta/handbook/documentation/translations/). +When you set script translations for a handle WordPress will automatically figure out if a translations file exists on translate.wordpress.org, and if so ensure that it's loaded into `wp.i18n` before your script runs. With translate.wordpress.org, plugin authors also do not need to worry about setting up their own infrastructure for translations and can rely on a global community with dozens of active locales. Read more about [WordPress Translations](https://make.wordpress.org/meta/handbook/documentation/translations/). ## Provide Your Own Translations @@ -135,7 +123,7 @@ You can create and ship your own translations with your plugin, if you have suff The translation files must be in the JED 1.x JSON format. -To create a JED translation file, first you need to extract the strings from the text. Typically, the language files all live in a directory called `languages` in your plugin. Using [WP-CLI](https://wp-cli.org/), you create a `.pot` file using the following command from within your plugin directory: +To create a JED translation file, first you need to extract the strings from the text. Typically, the language files all live in a directory called `languages` in your plugin. Using [WP-CLI](https://wp-cli.org/), you create a `.pot` file using the following command from within your plugin directory: ``` mkdir languages @@ -226,29 +214,24 @@ This will generate the JSON file `myguten-eo-[md5].json` with the contents: ```json { - "translation-revision-date": "2019-04-26T13:30:11-07:00", - "generator": "WP-CLI/2.2.0", - "source": "block.js", - "domain": "messages", - "locale_data": { - "messages": { - "": { - "domain": "messages", - "lang": "eo", - "plural-forms": "nplurals=2; plural=(n != 1);" - }, - "Simple Block": [ - "Simpla Bloko" - ], - "Hello World": [ - "Salunton mondo" - ] - } - } + "translation-revision-date": "2019-04-26T13:30:11-07:00", + "generator": "WP-CLI/2.2.0", + "source": "block.js", + "domain": "messages", + "locale_data": { + "messages": { + "": { + "domain": "messages", + "lang": "eo", + "plural-forms": "nplurals=2; plural=(n != 1);" + }, + "Simple Block": [ "Simpla Bloko" ], + "Hello World": [ "Salunton mondo" ] + } + } } ``` - ### Load Translation File The final part is to tell WordPress where it can look to find the translation file. The `wp_set_script_translations` function accepts an optional third argument that is the path it will first check for translations. For example: diff --git a/docs/how-to-guides/javascript/extending-the-block-editor.md b/docs/how-to-guides/javascript/extending-the-block-editor.md index 0a32b380318a82..75442628f83ac5 100644 --- a/docs/how-to-guides/javascript/extending-the-block-editor.md +++ b/docs/how-to-guides/javascript/extending-the-block-editor.md @@ -1,6 +1,6 @@ # Extending the Block Editor -Let's look at using the [Block Style Variation example](/docs/reference-guides/filters/block-filters.md#block-style-variations) to extend the editor. This example allows you to add your own custom CSS class name to any core block type. +Let's look at using the [Block Style example](/docs/reference-guides/filters/block-filters.md#block-styles) to extend the editor. This example allows you to add your own custom CSS class name to any core block type. Replace the existing `console.log()` code in your `myguten.js` file with: @@ -34,14 +34,12 @@ See [Packages](/docs/reference-guides/packages.md) for list of available package After you have updated both JavaScript and PHP files, go to the block editor and create a new post. -Add a quote block, and in the right sidebar under Styles, you will see your new Fancy Quote style listed. +Add a quote block, and in the right sidebar under Styles, you will see your new Fancy Quote style listed. Click the Fancy Quote to select and apply that style to your quote block: - ![Fancy Quote Style in Inspector](https://raw.githubusercontent.com/WordPress/gutenberg/HEAD/docs/assets/fancy-quote-in-inspector.png) - Even if you Preview or Publish the post you will not see a visible change. However, if you look at the source, you will see the `is-style-fancy-quote` class name is now attached to your quote block. Let's add some style. In your plugin folder, create a `style.css` file with: diff --git a/docs/how-to-guides/javascript/loading-javascript.md b/docs/how-to-guides/javascript/loading-javascript.md index c029d198c08f2e..80150f14445a1d 100644 --- a/docs/how-to-guides/javascript/loading-javascript.md +++ b/docs/how-to-guides/javascript/loading-javascript.md @@ -30,7 +30,7 @@ If your code is registered and enqueued correctly, you should see a message in y ![Console Log Message Success](https://raw.githubusercontent.com/WordPress/gutenberg/HEAD/docs/assets/js-tutorial-console-log-success.png) -**Note for Theme Developers:** The above method of enqueuing is used for plugins. If you are extending the block editor for your theme there is a minor difference, you will use the `get_template_directory_uri()` function instead of `plugins_url()`. So for a theme, the enqueue example is: +**Note for Theme Developers:** The above method of enqueuing is used for plugins. If you are extending the block editor for your theme there is a minor difference, you will use the `get_template_directory_uri()` function instead of `plugins_url()`. So for a theme, the enqueue example is: ```php function myguten_enqueue() { diff --git a/docs/how-to-guides/javascript/plugins-background.md b/docs/how-to-guides/javascript/plugins-background.md index 2b1ed5d5f56422..617cbe64e05ede 100644 --- a/docs/how-to-guides/javascript/plugins-background.md +++ b/docs/how-to-guides/javascript/plugins-background.md @@ -1,10 +1,10 @@ # Plugins Background -The primary means of extending WordPress is the plugin. The WordPress [Plugin Basics](https://developer.wordpress.org/plugins/plugin-basics/) documentation provides details on building a plugin. +The primary means of extending WordPress is the plugin. The WordPress [Plugin Basics](https://developer.wordpress.org/plugins/plugin-basics/) documentation provides details on building a plugin. The quickest way to start is to create a new directory in `wp-content/plugins/` to contain your plugin code. For this example, call it `myguten-plugin`. -Inside this new directory, create a file called `myguten-plugin.php`. This is the server-side code that runs when your plugin is active. +Inside this new directory, create a file called `myguten-plugin.php`. This is the server-side code that runs when your plugin is active. For now, add the following code in the file: @@ -15,7 +15,7 @@ Plugin Name: Fancy Quote */ ``` -To summarize, you should have a directory `wp-content/plugins/myguten-plugin/` which has the single file `myguten-plugin.php`. +To summarize, you should have a directory `wp-content/plugins/myguten-plugin/` which has the single file `myguten-plugin.php`. Once that is in place, go to your plugins list in `wp-admin` and you should see your plugin listed. diff --git a/docs/how-to-guides/javascript/scope-your-code.md b/docs/how-to-guides/javascript/scope-your-code.md index 802e4872cf8d58..39d52cd6ab934b 100644 --- a/docs/how-to-guides/javascript/scope-your-code.md +++ b/docs/how-to-guides/javascript/scope-your-code.md @@ -63,9 +63,9 @@ With this trick, the different files won't override each other's variables. Unfo It turns out there are a few ways to execute anonymous functions in JavaScript, but the most popular is this: ```js -( function() { +( function () { // your code goes here -} )( ) +} )(); ``` You wrap your function between parentheses, and then call it like any other named function. This pattern is known as [Immediately-Invoked Function Expression](http://benalman.com/news/2010/11/immediately-invoked-function-expression/), or IIFE for short. @@ -73,27 +73,27 @@ You wrap your function between parentheses, and then call it like any other name This is `first.js` written as an IIFE: ```js -( function() { +( function () { var pluginName = 'MyPlugin'; console.log( 'Plugin name is ', pluginName ); -} )( ) +} )(); ``` And this is `second.js`: ```js -( function() { +( function () { var pluginName = 'DifferentPlugin'; console.log( 'Plugin name is ', pluginName ); -} )( ) +} )(); ``` And this is `third.js`: ```js -( function() { +( function () { console.log( 'Plugin name is ', pluginName ); -} )( ) +} )(); ``` The code in `first.js` and `second.js` is unaffected by other variables in the global scope, so it's safe and deterministic. @@ -101,9 +101,9 @@ The code in `first.js` and `second.js` is unaffected by other variables in the g On the other hand, `third.js` doesn't declare a `pluginName` variable, but needs to be provided one. IIFEs still allow you to take a variable from the global scope and pass it into your function. Provided that there was a global `window.pluginName` variable, we could rewrite `third.js` as: ```js -( function( name ) { +( function ( name ) { console.log( 'Plugin name is ', name ); -} )( window.pluginName ) +} )( window.pluginName ); ``` ## Future Changes diff --git a/docs/how-to-guides/javascript/troubleshooting.md b/docs/how-to-guides/javascript/troubleshooting.md index 7fe4784bf30ab3..fc43ad0fec368f 100644 --- a/docs/how-to-guides/javascript/troubleshooting.md +++ b/docs/how-to-guides/javascript/troubleshooting.md @@ -47,7 +47,7 @@ wp.data.select( 'core/block-editor' ).getBlockCount(); ### Using the `debugger` statement -If you would like to pause code execution at a certain line of code, you can write `debugger;` anywhere in your code. Once the browser sees the statement `debugger;`, it will pause execution of your code. This allows you to inspect all variables around the `debugger` statement, which is very useful. [See this MDN page for more information](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/debugger). +If you would like to pause code execution at a certain line of code, you can write `debugger;` anywhere in your code. Once the browser sees the statement `debugger;`, it will pause execution of your code. This allows you to inspect all variables around the `debugger` statement, which is very useful. [See this MDN page for more information](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/debugger). ## Confirm JavaScript is loading diff --git a/docs/how-to-guides/metabox/README.md b/docs/how-to-guides/metabox/README.md index a35a9edac92a3d..69c3870a97b21c 100644 --- a/docs/how-to-guides/metabox/README.md +++ b/docs/how-to-guides/metabox/README.md @@ -10,9 +10,8 @@ Here are two mini-tutorials for creating similar functionality to meta boxes in The first method is to use Blocks to store extra data with a post. The data is stored in a post meta field, similar to how meta boxes store information. -* [Store Post Meta with a Block](/docs/how-to-guides/metabox/meta-block-1-intro.md) +- [Store Post Meta with a Block](/docs/how-to-guides/metabox/meta-block-1-intro.md) ## Sidebar Plugin If you are interested in working with the post meta outside the editor, check out the [Sidebar Tutorial](/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-0.md/). - diff --git a/docs/how-to-guides/metabox/meta-block-1-intro.md b/docs/how-to-guides/metabox/meta-block-1-intro.md index 1b01662588eb75..5111ca356972cd 100644 --- a/docs/how-to-guides/metabox/meta-block-1-intro.md +++ b/docs/how-to-guides/metabox/meta-block-1-intro.md @@ -14,4 +14,3 @@ Before starting this tutorial, you will need a plugin to hold your code. Please 2. [Add Meta Block](/docs/how-to-guides/metabox/meta-block-3-add.md) 3. [Use Post Meta Data](/docs/how-to-guides/metabox/meta-block-4-use-data.md) 4. [Finishing Touches](/docs/how-to-guides/metabox/meta-block-5-finishing.md) - diff --git a/docs/how-to-guides/metabox/meta-block-3-add.md b/docs/how-to-guides/metabox/meta-block-3-add.md index 034de8a6c913a3..09a1e74337f7b5 100644 --- a/docs/how-to-guides/metabox/meta-block-3-add.md +++ b/docs/how-to-guides/metabox/meta-block-3-add.md @@ -10,6 +10,7 @@ Add this code to your JavaScript file (this tutorial will call the file `myguten {% codetabs %} {% ESNext %} + ```js import { registerBlockType } from '@wordpress/blocks'; import { TextControl } from '@wordpress/components'; @@ -28,14 +29,10 @@ registerBlockType( 'myguten/meta-block', { ( select ) => select( 'core/editor' ).getCurrentPostType(), [] ); - const [ meta, setMeta ] = useEntityProp( - 'postType', - postType, - 'meta' - ); - const metaFieldValue = meta['myguten_meta_block_field']; + const [ meta, setMeta ] = useEntityProp( 'postType', postType, 'meta' ); + const metaFieldValue = meta[ 'myguten_meta_block_field' ]; function updateMetaValue( newValue ) { - setMeta( { ...meta, 'myguten_meta_block_field': newValue } ); + setMeta( { ...meta, myguten_meta_block_field: newValue } ); } return ( @@ -56,9 +53,11 @@ registerBlockType( 'myguten/meta-block', { }, } ); ``` + {% ES5 %} + ```js -( function( wp ) { +( function ( wp ) { var el = wp.element.createElement; var registerBlockType = wp.blocks.registerBlockType; var TextControl = wp.components.TextControl; @@ -71,32 +70,21 @@ registerBlockType( 'myguten/meta-block', { icon: 'smiley', category: 'text', - edit: function( props ) { + edit: function ( props ) { var blockProps = useBlockProps(); - var postType = useSelect( - function( select ) { - return select( 'core/editor' ).getCurrentPostType(); - }, - [] - ); - var entityProp = useEntityProp( - 'postType', - postType, - 'meta' - ); + var postType = useSelect( function ( select ) { + return select( 'core/editor' ).getCurrentPostType(); + }, [] ); + var entityProp = useEntityProp( 'postType', postType, 'meta' ); var meta = entityProp[ 0 ]; var setMeta = entityProp[ 1 ]; - var metaFieldValue = meta['myguten_meta_block_field']; + var metaFieldValue = meta[ 'myguten_meta_block_field' ]; function updateMetaValue( newValue ) { setMeta( - Object.assign( - {}, - meta, - { - 'myguten_meta_block_field': newValue, - } - ) + Object.assign( {}, meta, { + myguten_meta_block_field: newValue, + } ) ); } @@ -113,12 +101,13 @@ registerBlockType( 'myguten/meta-block', { // No information saved to the block // Data is saved to post meta via attributes - save: function() { + save: function () { return null; }, } ); } )( window.wp ); ``` + {% end %} **Important:** Before you test, you need to enqueue your JavaScript file and its dependencies. Note the WordPress packages used above are `wp.element`, `wp.blocks`, `wp.components`, `wp.data`, and `wp.coreData`. Each of these need to be included in the array of dependencies. Update the `myguten-meta-block.php` file adding the enqueue function: diff --git a/docs/how-to-guides/metabox/meta-block-4-use-data.md b/docs/how-to-guides/metabox/meta-block-4-use-data.md index 0c5cc84fa246d3..b445e07c0a8a09 100644 --- a/docs/how-to-guides/metabox/meta-block-4-use-data.md +++ b/docs/how-to-guides/metabox/meta-block-4-use-data.md @@ -36,8 +36,7 @@ function myguten_render_paragraph( $block_attributes, $content ) { } register_block_type( 'core/paragraph', array( - 'apiVersion' => 2, + 'api_version' => 2, 'render_callback' => 'myguten_render_paragraph', ) ); ``` - diff --git a/docs/how-to-guides/metabox/meta-block-5-finishing.md b/docs/how-to-guides/metabox/meta-block-5-finishing.md index a5b02757ccaa98..d190369c43fae1 100644 --- a/docs/how-to-guides/metabox/meta-block-5-finishing.md +++ b/docs/how-to-guides/metabox/meta-block-5-finishing.md @@ -17,4 +17,3 @@ add_action( 'init', 'myguten_register_template' ); ``` You can also add other block types in the array, including placeholders, or even lock down a post to a set of specific blocks. Templates are a powerful tool for controlling the editing experience, see the documentation linked above for more. - diff --git a/docs/how-to-guides/notices/README.md b/docs/how-to-guides/notices/README.md index de9867307b5acd..b81519e798a3ed 100644 --- a/docs/how-to-guides/notices/README.md +++ b/docs/how-to-guides/notices/README.md @@ -44,7 +44,7 @@ In the block editor, here's an example of the "Post published" notice: Producing an equivalent "Post published" notice would require code like this: ```js -( function( wp ) { +( function ( wp ) { wp.data.dispatch( 'core/notices' ).createNotice( 'success', // Can be one of: success, info, warning, error. 'Post published.', // Text string to display. @@ -66,10 +66,10 @@ You'll want to use this _Notices Data API_ when producing a notice from within t To better understand the specific code example above: -* `wp` is WordPress global window variable. -* `wp.data` is an object provided by the block editor for accessing the block editor data store. -* `wp.data.dispatch('core/notices')` accesses functionality registered to the block editor data store by the Notices package. -* `createNotice()` is a function offered by the Notices package to register a new notice. The block editor reads from the notice data store in order to know which notices to display. +- `wp` is WordPress global window variable. +- `wp.data` is an object provided by the block editor for accessing the block editor data store. +- `wp.data.dispatch('core/notices')` accesses functionality registered to the block editor data store by the Notices package. +- `createNotice()` is a function offered by the Notices package to register a new notice. The block editor reads from the notice data store in order to know which notices to display. Check out the [_Loading JavaScript_](/docs/how-to-guides/javascript/loading-javascript.md) tutorial for a primer on how to load your custom JavaScript into the block editor. diff --git a/docs/how-to-guides/platform/README.md b/docs/how-to-guides/platform/README.md index 67e909a5cad60c..c6d85fa6d12fc0 100644 --- a/docs/how-to-guides/platform/README.md +++ b/docs/how-to-guides/platform/README.md @@ -1,4 +1,3 @@ - # Gutenberg as a Development Platform The Gutenberg Project is not only building a better editor for WordPress, but also creating a platform to build upon. This platform consists of a set of JavaScript packages and tools that you can use in your web application. [View the list packages available on npm](https://www.npmjs.com/org/wordpress). @@ -21,9 +20,7 @@ Usage in React: import { Button } from '@wordpress/components'; function MyApp() { - return ( - - ); + return ; } ``` @@ -46,7 +43,7 @@ You can then add a scripts section to your package.json file, for example: ```json "scripts": { "build": "wp-scripts build", - "format:js": "wp-scripts format-js", + "format": "wp-scripts format", "lint:js": "wp-scripts lint-js", "start": "wp-scripts start" } @@ -61,4 +58,3 @@ You can also play with the [Gutenberg Example #03](https://github.com/WordPress/ The [`@wordpress/block-editor` package](https://developer.wordpress.org/block-editor/packages/packages-block-editor/) allows you to create and use standalone block editors. You can learn more by reading the [tutorial "Building a custom block editor"](/docs/reference-guides/platform/custom-block-editor/README.md). - diff --git a/docs/how-to-guides/platform/custom-block-editor/README.md b/docs/how-to-guides/platform/custom-block-editor/README.md index 65623044f31d53..22a53e7224415f 100644 --- a/docs/how-to-guides/platform/custom-block-editor/README.md +++ b/docs/how-to-guides/platform/custom-block-editor/README.md @@ -2,17 +2,18 @@ The purpose of [this tutorial](/docs/reference-guides/platform/custom-block-editor/tutorial.md) is to step through the fundamentals of creating a custom instance of a "block editor". -![alt text](https://wordpress.org/gutenberg/files/2020/03/editor.png "The Standalone Editor instance populated with example Blocks within a custom WP Admin page.") +![alt text](https://wordpress.org/gutenberg/files/2020/03/editor.png 'The Standalone Editor instance populated with example Blocks within a custom WP Admin page.') -The editor you will see in this tutorial (as above) is **__not__ the same Block Editor you are familiar with when creating Posts** in with WordPress. Rather it is an entirely **custom block editor instance** built using the lower-level [`@wordpress/block-editor`](https://developer.wordpress.org/block-editor/packages/packages-block-editor/) package (and friends). +The editor you will see in this tutorial (as above) is **_not_ the same Block Editor you are familiar with when creating Posts** in with WordPress. Rather it is an entirely **custom block editor instance** built using the lower-level [`@wordpress/block-editor`](https://developer.wordpress.org/block-editor/packages/packages-block-editor/) package (and friends). ## Following this tutorial To follow along with this tutorial, you can [download the accompanying WordPress plugin](https://github.com/getdave/standalone-block-editor) which includes all of the examples for you to try on your own site. ## Code Syntax + Code snippets are provided in "ESNext". ESNext refers to the next versions of the language standard, plus JSX syntax. Note that it is not required to use ESNext to create blocks or extend the editor, you can use classic JavaScript. However, once familiar with ESNext, developers find it is easier to read and write, thus most code examples you'll find use the ESNext syntax. -* [Start custom block editor tutorial](/docs/reference-guides/platform/custom-block-editor/tutorial.md) +- [Start custom block editor tutorial](/docs/reference-guides/platform/custom-block-editor/tutorial.md) diff --git a/docs/how-to-guides/platform/custom-block-editor/tutorial.md b/docs/how-to-guides/platform/custom-block-editor/tutorial.md index 62702baab2e2ca..a76bc2d11d8d8a 100644 --- a/docs/how-to-guides/platform/custom-block-editor/tutorial.md +++ b/docs/how-to-guides/platform/custom-block-editor/tutorial.md @@ -5,23 +5,23 @@ of a "block editor" using the `@wordpress/block-editor` package. ## Table of Contents -* [Introduction](#introduction). -* [What we're going to be building](#what-were-going-to-be-building). -* [Plugin setup and organization](#plugin-setup-and-organization). -* [The "Core" of the Editor](#the-core-of-the-editor). -* [Creating the custom "Block Editor" page in WP Admin](#creating-the-custom-block-editor-page-in-wp-admin). -* [Registering and Rendering our custom block editor](#registering-and-rendering-our-custom-block-editor). -* [Reviewing the `` component](#reviewing-the-editor-component). -* [The custom ``](#the-custom-blockeditor). -* [Reviewing the Sidebar](#reviewing-the-sidebar). -* [Block Persistence](#block-persistence). -* [Wrapping up](#wrapping-up). +- [Introduction](#introduction). +- [What we're going to be building](#what-were-going-to-be-building). +- [Plugin setup and organization](#plugin-setup-and-organization). +- [The "Core" of the Editor](#the-core-of-the-editor). +- [Creating the custom "Block Editor" page in WP Admin](#creating-the-custom-block-editor-page-in-wp-admin). +- [Registering and Rendering our custom block editor](#registering-and-rendering-our-custom-block-editor). +- [Reviewing the `` component](#reviewing-the-editor-component). +- [The custom ``](#the-custom-blockeditor). +- [Reviewing the Sidebar](#reviewing-the-sidebar). +- [Block Persistence](#block-persistence). +- [Wrapping up](#wrapping-up). ## Introduction The Gutenberg codebase is complex, with many packages and components, but at its core it is a tool for managing and editing blocks. Therefore, when working on the editor it is important to gain a better understanding of how block editing works at a _fundamental_ level. -To do this, this tutorial will walk you through building a **fully functioning, __custom__ block editor "instance"** within WordPress, introducing you to the key packages and components along the way. +To do this, this tutorial will walk you through building a **fully functioning, **custom** block editor "instance"** within WordPress, introducing you to the key packages and components along the way. By the end of this article, you should have gained a good understanding of how the block editor works and some of the knowledge required to put together your own block editor instances. @@ -29,34 +29,32 @@ By the end of this article, you should have gained a good understanding of how t We're going to be creating an (almost) fully functioning Block Editor instance. -![alt text](https://wordpress.org/gutenberg/files/2020/03/editor.png "The Standalone Editor instance populated with example Blocks within a custom WP Admin page.") +![alt text](https://wordpress.org/gutenberg/files/2020/03/editor.png 'The Standalone Editor instance populated with example Blocks within a custom WP Admin page.') This block editor will not be the same _Block Editor_ you are familiar with when creating `Post`s in WP Admin. Rather it will be an entirely custom instance which will live within a custom WP Admin page called (imaginatively) "Block Editor". Our editor will have the following features: -* Ability to add and edit all Core Blocks. -* Familiar visual styles and main/sidebar layout. -* _Basic_ block persistence between page reloads. +- Ability to add and edit all Core Blocks. +- Familiar visual styles and main/sidebar layout. +- _Basic_ block persistence between page reloads. With that in mind, let's start taking our first steps towards building this. - - ## Plugin setup and organization Our custom editor is going to be built as a WordPress Plugin. To keep things simple. we'll call this `Standalone Block Editor Demo` because that is what it does. Nice! Let's take a look at our Plugin file structure: -![alt text](https://wordpress.org/gutenberg/files/2020/03/repo-files.png "Screenshot showing file structure of the Plugin at https://github.com/getdave/standalone-block-editor.") +![alt text](https://wordpress.org/gutenberg/files/2020/03/repo-files.png 'Screenshot showing file structure of the Plugin at https://github.com/getdave/standalone-block-editor.') Here's a brief summary of what's going on: -* `plugin.php` - standard Plugin "entry" file with comment meta data. Requires `init.php`. -* `init.php` - handles the initialization of the main Plugin logic. We'll be spending a lot of time here. -* `src/` (directory) - this is where our JavaScript (and CSS) source files will live. These files are _not_ directly enqueued by the Plugin. -* `webpack.config.js` - a custom Webpack config extending the defaults provided by the `@wordpress/scripts` npm package to allow for custom CSS styles (via Sass). +- `plugin.php` - standard Plugin "entry" file with comment meta data. Requires `init.php`. +- `init.php` - handles the initialization of the main Plugin logic. We'll be spending a lot of time here. +- `src/` (directory) - this is where our JavaScript (and CSS) source files will live. These files are _not_ directly enqueued by the Plugin. +- `webpack.config.js` - a custom Webpack config extending the defaults provided by the `@wordpress/scripts` npm package to allow for custom CSS styles (via Sass). The only item not shown above is the `build/` directory, which is where our _compiled_ JS and CSS files will be outputted by `@wordpress/scripts` ready to be enqueued by our Plugin. @@ -83,6 +81,7 @@ As a first step, we need to create a custom page within WP Admin. **Note**: if you're already comfortable with the process of creating custom Admin pages in WordPress you might want to [skip ahead](#registering-and-rendering-our-custom-block-editor). ### Registering the Page + To do this we [register our custom admin page](https://developer.wordpress.org/reference/functions/add_menu_page/) using the standard WP `add_menu_page()` helper: ```php @@ -214,16 +213,19 @@ import './styles.scss'; Next, once the DOM is ready we run a function which: -* Grabs our editor settings from `window.getdaveSbeSettings` (inlined from PHP - - see above). -* Registers all the Core Gutenberg Blocks using `registerCoreBlocks`. -* Renders an `` component into the waiting `
` on our custom Admin page. +- Grabs our editor settings from `window.getdaveSbeSettings` (inlined from PHP - + see above). +- Registers all the Core Gutenberg Blocks using `registerCoreBlocks`. +- Renders an `` component into the waiting `
` on our custom Admin page. ```jsx -domReady( function() { +domReady( function () { const settings = window.getdaveSbeSettings || {}; registerCoreBlocks(); - render( , document.getElementById( 'getdave-sbe-block-editor' ) ); + render( + , + document.getElementById( 'getdave-sbe-block-editor' ) + ); } ); ``` @@ -236,6 +238,7 @@ Let's take a closer look at the `` component we saw being used above. Despite its name, this _is not_ the actual core of the block editor. Rather it is a _wrapper_ component we've created to contain the components which form the main body of our custom editor. ### Dependencies + The first thing we do inside `` is to pull in some dependencies. ```jsx @@ -252,6 +255,7 @@ The most important of these are the internal components `BlockEditor` and `Sideb The remaining components are largely static elements which form the layout and surrounding UI of the editor (eg: header and notice areas). ### Editor Render + With these components available we can proceed to define our `` component. ```jsx @@ -278,18 +282,19 @@ Here we are scaffolding the core of the editor's layout alongside a few speciali Let's examine these in more detail: -* `` - enables the use of the ["Slot/Fill" - pattern](/docs/reference-guides/slotfills/README.md) through our component tree. -* `` - enables the use of [dropzones for drag and drop functionality](https://github.com/WordPress/gutenberg/tree/e38dbe958c04d8089695eb686d4f5caff2707505/packages/components/src/drop-zone). -* `` - custom component. Provides a "snack bar" Notice that will be rendered if any messages are dispatched to `core/notices` store. -* `
` - renders the static title "Standalone Block Editor" at the top of the - editor UI. -* `` - our custom block editor component. This is where things get - interesting. We'll focus a little more on this in a moment. -* `` - renders a slot into which ``s can be rendered - using the Slot/Fill mechanic. +- `` - enables the use of the ["Slot/Fill" + pattern](/docs/reference-guides/slotfills/README.md) through our component tree. +- `` - enables the use of [dropzones for drag and drop functionality](https://github.com/WordPress/gutenberg/tree/e38dbe958c04d8089695eb686d4f5caff2707505/packages/components/src/drop-zone). +- `` - custom component. Provides a "snack bar" Notice that will be rendered if any messages are dispatched to `core/notices` store. +- `
` - renders the static title "Standalone Block Editor" at the top of the + editor UI. +- `` - our custom block editor component. This is where things get + interesting. We'll focus a little more on this in a moment. +- `` - renders a slot into which ``s can be rendered + using the Slot/Fill mechanic. ### Keyboard Navigation + With this basic component structure in place the only remaining thing left to do is wrap everything in [the `navigateRegions` HOC](https://github.com/WordPress/gutenberg/tree/e38dbe958c04d8089695eb686d4f5caff2707505/packages/components/src/higher-order/navigate-regions) to provide keyboard navigation between the different "regions" in the layout. @@ -312,33 +317,33 @@ complex of the components we have encountered thus far. There's a lot going on so let's break this down! ### Understanding the render + To start, let's focus on what is being rendered by the `` component: ```js // src/components/block-editor/index.js return ( -
- - - - -
- - - - - - -
-
- -
+
+ + + + +
+ + + + + + +
+
+
); ``` @@ -358,10 +363,10 @@ them to _render_ and _manage_ the Blocks and their behaviors within the editor. // src/components/block-editor/index.js ``` @@ -373,11 +378,11 @@ Internally it does this by subscribing to the provided `registry` (via the [`wit For the purposes of our simple project these features allow us to: -* Store the array of current blocks in state as `blocks`. -* Update the `blocks` state in memory on `onInput` by calling the hook setter - `updateBlocks(blocks)`. -* Handle basic persistence of blocks into `localStorage` using `onChange`. This is [fired when block updates are considered - "committed"](https://github.com/WordPress/gutenberg/tree/HEAD/packages/block-editor/src/components/provider#onchange). +- Store the array of current blocks in state as `blocks`. +- Update the `blocks` state in memory on `onInput` by calling the hook setter + `updateBlocks(blocks)`. +- Handle basic persistence of blocks into `localStorage` using `onChange`. This is [fired when block updates are considered + "committed"](https://github.com/WordPress/gutenberg/tree/HEAD/packages/block-editor/src/components/provider#onchange). It's also worth recalling that the component accepts a `settings` prop. This accepts the editor settings which we inlined as JSON within `init.php` earlier. This configures features such as custom colors, available image sizes and [much more](https://github.com/WordPress/gutenberg/tree/4c472c3443513d070a50ba1e96f3a476861447b3/packages/block-editor#SETTINGS_DEFAULTS). @@ -398,21 +403,26 @@ The hierarchy of these components can be _approximated_ as follows: ```jsx // Pseudo code - example purposes only - /* renders a list of Blocks from the rootClientId. */ - /* renders a single "Block" from the BlockList. */ - /* renders the standard editable area of a Block. */ - /* renders the Block UI as defined by its `edit()` implementation. */ - - + + /* renders a list of Blocks from the rootClientId. */ + + /* renders a single "Block" from the BlockList. */ + + /* renders the standard editable area of a Block. */ + /* renders the Block UI as defined by its `edit()` implementation. + */ + + ``` + Here's roughly how this works together to render our list of blocks: -* `` loops over all the Block clientIds and -renders each via [``](https://github.com/WordPress/gutenberg/blob/e38dbe958c04d8089695eb686d4f5caff2707505/packages/block-editor/src/components/block-list/block.js). -* `` in turn renders the individual "Block" -via it's own subcomponent [``](https://github.com/WordPress/gutenberg/blob/def076809d25e2ad680beda8b9205ab9dea45a0f/packages/block-editor/src/components/block-edit/index.js). -* Finally [the Block itself](https://github.com/WordPress/gutenberg/blob/def076809d25e2ad680beda8b9205ab9dea45a0f/packages/block-editor/src/components/block-edit/edit.js) is rendered using the `Component` placeholder component. +- `` loops over all the Block clientIds and + renders each via [``](https://github.com/WordPress/gutenberg/blob/e38dbe958c04d8089695eb686d4f5caff2707505/packages/block-editor/src/components/block-list/block.js). +- `` in turn renders the individual "Block" + via it's own subcomponent [``](https://github.com/WordPress/gutenberg/blob/def076809d25e2ad680beda8b9205ab9dea45a0f/packages/block-editor/src/components/block-edit/index.js). +- Finally [the Block itself](https://github.com/WordPress/gutenberg/blob/def076809d25e2ad680beda8b9205ab9dea45a0f/packages/block-editor/src/components/block-edit/edit.js) is rendered using the `Component` placeholder component. These are some of the most complex and involved components within the `@wordpress/block-editor` package. That said, if you want to have a strong grasp of how the editor works at a fundamental level, I strongly advise making a study of these components. I leave this as an exercise for the reader! @@ -424,12 +434,14 @@ Jumping back to our own custom `` component, it is also worth notin // src/components/block-editor/index.js
- /* 1. */ - /* 2. */ - /* 3. */ - - - + /* 1. */ + + /* 2. */ + + /* 3. */ + + +
``` @@ -439,7 +451,6 @@ These provide other important elements of functionality for our editor instance. 2. [``](https://github.com/WordPress/gutenberg/blob/e38dbe958c04d8089695eb686d4f5caff2707505/packages/block-editor/src/components/writing-flow/index.js) - handles selection, focus management and navigation across blocks. 3. [``](https://github.com/WordPress/gutenberg/tree/e38dbe958c04d8089695eb686d4f5caff2707505/packages/block-editor/src/components/observe-typing)- used to manage the editor's internal `isTyping` flag. This is used in various places, most commonly to show/hide the Block toolbar in response to typing. - ## Reviewing the Sidebar Also within the render of our ``, is our `` component. @@ -465,7 +476,7 @@ This is used - alongside other things - to display advanced Block settings via t ```jsx - + ``` @@ -496,11 +507,9 @@ This might seem overly complex, but it is required in order that `` can have access to information about the current Block. Without Slot/Fill this setup would be extremely difficult to achieve. - Aside: [``](https://github.com/WordPress/gutenberg/blob/def076809d25e2ad680beda8b9205ab9dea45a0f/packages/block-editor/src/components/block-inspector/index.js) - itself actually renders a `Slot` for [``](https://github.com/WordPress/gutenberg/tree/HEAD/packages/block-editor/src/components/inspector-controls -). This is what allows you [render a `` component inside +itself actually renders a `Slot` for [``](https://github.com/WordPress/gutenberg/tree/HEAD/packages/block-editor/src/components/inspector-controls). This is what allows you [render a `` component inside the `edit()` definition for your block](https://github.com/WordPress/gutenberg/blob/def076809d25e2ad680beda8b9205ab9dea45a0f/packages/block-library/src/paragraph/edit.js#L127) and have it display within Gutenberg's sidebar. I recommend looking into this component in more detail. @@ -513,7 +522,7 @@ We've come a long way on our journey to create a custom block editor. But there one major area left to touch upon - Block persistance; that is the act of having our Blocks saved and **available _between_ page refreshes**. -![alt text](https://wordpress.org/gutenberg/files/2020/03/block-persistance.gif "Screencapture showing added Blocks being restored between page refreshes.") +![alt text](https://wordpress.org/gutenberg/files/2020/03/block-persistance.gif 'Screencapture showing added Blocks being restored between page refreshes.') As this is only an _experiment_ we've opted to utilise the browser's `localStorage` API to handle saving Block data. In a real-world scenario however @@ -522,6 +531,7 @@ you'd like choose a more reliable and robust system (eg: a database). That said, let's take a closer look at how we're handling saving our Blocks. ### Storing blocks in state + Opening `src/components/block-editor/index.js` we will notice we have created some state to store our Blocks as an array: @@ -542,8 +552,8 @@ hooked up to a function `persistBlocks()` which is defined as follows: // src/components/block-editor/index.js function persistBlocks( newBlocks ) { - updateBlocks( newBlocks ); - window.localStorage.setItem( 'getdavesbeBlocks', serialize( newBlocks ) ); + updateBlocks( newBlocks ); + window.localStorage.setItem( 'getdavesbeBlocks', serialize( newBlocks ) ); } ``` @@ -578,25 +588,25 @@ friend the `useEffect` hook to handle this. // src/components/block-editor/index.js useEffect( () => { - const storedBlocks = window.localStorage.getItem( 'getdavesbeBlocks' ); - - if ( storedBlocks && storedBlocks.length ) { - updateBlocks( () => parse( storedBlocks ) ); - createInfoNotice( 'Blocks loaded', { - type: 'snackbar', - isDismissible: true, - } ); - } + const storedBlocks = window.localStorage.getItem( 'getdavesbeBlocks' ); + + if ( storedBlocks && storedBlocks.length ) { + updateBlocks( () => parse( storedBlocks ) ); + createInfoNotice( 'Blocks loaded', { + type: 'snackbar', + isDismissible: true, + } ); + } }, [] ); ``` In this handler, we: -* Grab the serialized block data from local storage. -* Convert the serialized blocks back to JavaScript objects using the `parse()` - utility. -* Call the state setter `updateBlocks` causing the `blocks` value to be updated - in state to reflect the blocks retrieved from LocalStorage. +- Grab the serialized block data from local storage. +- Convert the serialized blocks back to JavaScript objects using the `parse()` + utility. +- Call the state setter `updateBlocks` causing the `blocks` value to be updated + in state to reflect the blocks retrieved from LocalStorage. As a result of these operations the controlled `` component is updated with the blocks restored from LocalStorage causing the editor to @@ -611,7 +621,3 @@ If you've made it this far then congratulations! I hope you now have a better un In addition, you've reviewed an working example of the code required to implement your own custom functioning block editor. This information should prove useful, especially as Gutenberg expands beyond editing just the `Post` and into Widgets, Full Site Editing and beyond! The full code for the custom functioning block editor we've just built is [available on Github](https://github.com/getdave/standalone-block-editor). I encourage you to download and try it out for yourself. Experiment, then and take things even further! - - - - diff --git a/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-0.md b/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-0.md index fa33fb682c874f..750a12236d6605 100644 --- a/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-0.md +++ b/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-0.md @@ -2,7 +2,7 @@ This tutorial starts with you having an existing plugin setup and ready to add PHP and JavaScript code. Please, refer to [Getting started with JavaScript](/docs/how-to-guides/javascript/) tutorial for an introduction to WordPress plugins and how to use JavaScript to extend the block editor. - In the next sections, you're going to create a custom sidebar for a plugin that contains a text control so the user can update a value that is stored in the `post_meta` table. +In the next sections, you're going to create a custom sidebar for a plugin that contains a text control so the user can update a value that is stored in the `post_meta` table. 1. [Get a sidebar up and running](/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-1-up-and-running.md) 2. [Tweak the sidebar style and add controls](/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-2-styles-and-controls.md) diff --git a/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-1-up-and-running.md b/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-1-up-and-running.md index f908c59e6d194a..180eafb52e9488 100644 --- a/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-1-up-and-running.md +++ b/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-1-up-and-running.md @@ -7,14 +7,15 @@ The first step in the journey is to tell the editor that there is a new plugin t Add the following code to a JavaScript file called `plugin-sidebar.js` and save it within your plugin's directory: ```js -( function( wp ) { +( function ( wp ) { var registerPlugin = wp.plugins.registerPlugin; var PluginSidebar = wp.editPost.PluginSidebar; var el = wp.element.createElement; registerPlugin( 'my-plugin-sidebar', { - render: function() { - return el( PluginSidebar, + render: function () { + return el( + PluginSidebar, { name: 'my-plugin-sidebar', icon: 'admin-post', diff --git a/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-2-styles-and-controls.md b/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-2-styles-and-controls.md index 841c9f1153446a..581cd5c4e0f6fa 100644 --- a/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-2-styles-and-controls.md +++ b/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-2-styles-and-controls.md @@ -5,32 +5,34 @@ After the sidebar is up and running, the next step is to fill it up with the nec To visualize and edit the meta field value you'll use an input component. The `@wordpress/components` package contains many components available for you to reuse, and, specifically, the [TextControl](/packages/components/src/text-control/README.md) is aimed at creating an input field: ```js -( function( wp ) { +( function ( wp ) { var registerPlugin = wp.plugins.registerPlugin; var PluginSidebar = wp.editPost.PluginSidebar; var el = wp.element.createElement; var Text = wp.components.TextControl; registerPlugin( 'my-plugin-sidebar', { - render: function() { - return el( PluginSidebar, + render: function () { + return el( + PluginSidebar, { name: 'my-plugin-sidebar', icon: 'admin-post', title: 'My plugin sidebar', }, - el( 'div', + el( + 'div', { className: 'plugin-sidebar-content' }, el( Text, { label: 'Meta Block Field', value: 'Initial value', - onChange: function( content ) { + onChange: function ( content ) { console.log( 'content changed to ', content ); }, } ) ) ); - } + }, } ); } )( window.wp ); ``` @@ -39,8 +41,8 @@ Update the `plugin-sidebar.js` with this new code. Notice that it uses a new uti It introduces a few changes from the previous section: -* Added the CSS class `plugin-sidebar-content` to the `div` element to be able to add some styles. -* Substituted the raw _Meta field_ text with a `TextControl` component wrapped within the `div` element. +- Added the CSS class `plugin-sidebar-content` to the `div` element to be able to add some styles. +- Substituted the raw _Meta field_ text with a `TextControl` component wrapped within the `div` element. With the new CSS class available you can now give the sidebar a bit of breath. Create a new file in your plugin directory called `plugin-sidebar.css` with the following contents: diff --git a/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-4-initialize-input.md b/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-4-initialize-input.md index 94e7e52db98ccd..106bd31925e44a 100644 --- a/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-4-initialize-input.md +++ b/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-4-initialize-input.md @@ -3,36 +3,38 @@ Now that the field is available in the editor store, it can be surfaced to the UI. The first step will be to extract the input control to a separate function so you can expand its functionality while the code stays clear. ```js -( function( wp ) { +( function ( wp ) { var registerPlugin = wp.plugins.registerPlugin; var PluginSidebar = wp.editPost.PluginSidebar; var el = wp.element.createElement; var Text = wp.components.TextControl; - var MetaBlockField = function() { + var MetaBlockField = function () { return el( Text, { label: 'Meta Block Field', value: 'Initial value', - onChange: function( content ) { + onChange: function ( content ) { console.log( 'content changed to ', content ); }, } ); - } + }; registerPlugin( 'my-plugin-sidebar', { - render: function() { - return el( PluginSidebar, + render: function () { + return el( + PluginSidebar, { name: 'my-plugin-sidebar', icon: 'admin-post', title: 'My plugin sidebar', }, - el( 'div', + el( + 'div', { className: 'plugin-sidebar-content' }, el( MetaBlockField ) ) ); - } + }, } ); } )( window.wp ); ``` @@ -42,59 +44,61 @@ Now you can focus solely on the `MetaBlockField` component. The goal is to initi WordPress has [some utilities to work with data](/packages/data/README.md) from the stores. The first you're going to use is [withSelect](/packages/data/README.md#withselect-mapselecttoprops-function-function), whose signature is: ```js -withSelect( - // a function that takes `select` as input - // and returns an object containing data -)( - // a function that takes the previous data as input - // and returns a component -); +withSelect()(); +// a function that takes `select` as input +// and returns an object containing data +// a function that takes the previous data as input +// and returns a component ``` `withSelect` is used to pass data to other components, and update them when the original data changes. Let's update the code to use it: ```js -( function( wp ) { +( function ( wp ) { var registerPlugin = wp.plugins.registerPlugin; var PluginSidebar = wp.editPost.PluginSidebar; var el = wp.element.createElement; var Text = wp.components.TextControl; var withSelect = wp.data.withSelect; - var mapSelectToProps = function( select ) { + var mapSelectToProps = function ( select ) { return { - metaFieldValue: select( 'core/editor' ) - .getEditedPostAttribute( 'meta' ) - [ 'sidebar_plugin_meta_block_field' ] - } - } + metaFieldValue: select( 'core/editor' ).getEditedPostAttribute( + 'meta' + )[ 'sidebar_plugin_meta_block_field' ], + }; + }; - var MetaBlockField = function( props ) { + var MetaBlockField = function ( props ) { return el( Text, { label: 'Meta Block Field', value: props.metaFieldValue, - onChange: function( content ) { + onChange: function ( content ) { console.log( 'content has changed to ', content ); }, } ); - } + }; - var MetaBlockFieldWithData = withSelect( mapSelectToProps )( MetaBlockField ); + var MetaBlockFieldWithData = withSelect( mapSelectToProps )( + MetaBlockField + ); registerPlugin( 'my-plugin-sidebar', { - render: function() { - return el( PluginSidebar, + render: function () { + return el( + PluginSidebar, { name: 'my-plugin-sidebar', icon: 'admin-post', title: 'My plugin sidebar', }, - el( 'div', + el( + 'div', { className: 'plugin-sidebar-content' }, el( MetaBlockFieldWithData ) ) ); - } + }, } ); } )( window.wp ); ``` @@ -103,16 +107,16 @@ Copy this code to the JavaScript file. Note that it now uses the `wp.data.withSe This is how the code changes from the previous section: -* The `MetaBlockField` function has now a `props` argument as input. It contains the data object returned by the `mapSelectToProps` function, which it uses to initialize its value property. -* The component rendered within the `div` element was also updated, the plugin now uses `MetaBlockFieldWithData`. This will be updated every time the original data changes. -* [getEditedPostAttribute](/docs/reference-guides/data/data-core-editor.md#geteditedpostattribute) is used to retrieve data instead of [getCurrentPost](/docs/reference-guides/data/data-core-editor.md#getcurrentpost) because it returns the most recent values of the post, including user editions that haven't been yet saved. +- The `MetaBlockField` function has now a `props` argument as input. It contains the data object returned by the `mapSelectToProps` function, which it uses to initialize its value property. +- The component rendered within the `div` element was also updated, the plugin now uses `MetaBlockFieldWithData`. This will be updated every time the original data changes. +- [getEditedPostAttribute](/docs/reference-guides/data/data-core-editor.md#geteditedpostattribute) is used to retrieve data instead of [getCurrentPost](/docs/reference-guides/data/data-core-editor.md#getcurrentpost) because it returns the most recent values of the post, including user editions that haven't been yet saved. Update the code and open the sidebar. The input's content is no longer `Initial value` but a void string. Users can't type values yet, but let's check that the component is updated if the value in the store changes. Open the browser's console, execute ```js -wp.data.dispatch( 'core/editor' ).editPost( - { meta: { sidebar_plugin_meta_block_field: 'hello world!' } } -); +wp.data + .dispatch( 'core/editor' ) + .editPost( { meta: { sidebar_plugin_meta_block_field: 'hello world!' } } ); ``` and observe how the contents of the input component change! diff --git a/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-5-update-meta.md b/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-5-update-meta.md index ac5a9884cae9fa..4fadd285f69423 100644 --- a/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-5-update-meta.md +++ b/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-5-update-meta.md @@ -5,7 +5,7 @@ The last step in the journey is to update the meta field when the input content `withDispatch` works similarly to `withSelect`. It takes two functions, the first returns an object with data, and the second takes that data object as input and returns a new UI component. Let's see how to use it: ```js -( function( wp ) { +( function ( wp ) { var registerPlugin = wp.plugins.registerPlugin; var PluginSidebar = wp.editPost.PluginSidebar; var el = wp.element.createElement; @@ -13,60 +13,66 @@ The last step in the journey is to update the meta field when the input content var withSelect = wp.data.withSelect; var withDispatch = wp.data.withDispatch; - var mapSelectToProps = function( select ) { + var mapSelectToProps = function ( select ) { return { - metaFieldValue: select( 'core/editor' ) - .getEditedPostAttribute( 'meta' ) - [ 'sidebar_plugin_meta_block_field' ], - } - } + metaFieldValue: select( 'core/editor' ).getEditedPostAttribute( + 'meta' + )[ 'sidebar_plugin_meta_block_field' ], + }; + }; - var mapDispatchToProps = function( dispatch ) { + var mapDispatchToProps = function ( dispatch ) { return { - setMetaFieldValue: function( value ) { - dispatch( 'core/editor' ).editPost( - { meta: { sidebar_plugin_meta_block_field: value } } - ); - } - } - } - - var MetaBlockField = function( props ) { + setMetaFieldValue: function ( value ) { + dispatch( 'core/editor' ).editPost( { + meta: { sidebar_plugin_meta_block_field: value }, + } ); + }, + }; + }; + + var MetaBlockField = function ( props ) { return el( Text, { label: 'Meta Block Field', value: props.metaFieldValue, - onChange: function( content ) { + onChange: function ( content ) { props.setMetaFieldValue( content ); }, } ); - } + }; - var MetaBlockFieldWithData = withSelect( mapSelectToProps )( MetaBlockField ); - var MetaBlockFieldWithDataAndActions = withDispatch( mapDispatchToProps )( MetaBlockFieldWithData ); + var MetaBlockFieldWithData = withSelect( mapSelectToProps )( + MetaBlockField + ); + var MetaBlockFieldWithDataAndActions = withDispatch( mapDispatchToProps )( + MetaBlockFieldWithData + ); registerPlugin( 'my-plugin-sidebar', { - render: function() { - return el( PluginSidebar, + render: function () { + return el( + PluginSidebar, { name: 'my-plugin-sidebar', icon: 'admin-post', title: 'My plugin sidebar', }, - el( 'div', + el( + 'div', { className: 'plugin-sidebar-content' }, el( MetaBlockFieldWithDataAndActions ) ) ); - } + }, } ); } )( window.wp ); ``` Here's how it changed from the previous section: -* Added a new `mapDispatchToProps` function that will be passed to `withDispatch`. It takes `dispatch` as input and returns an object containing functions to update the internal data structures of the editor. These functions are also known as _actions_. -* By calling `setMetaFieldValue` every time the user types something within the input control, we're effectively updating the editor store on each key stroke. -* The `props` argument to the `MetaBlockField` component contains now the data passed by `mapSelectToProps` and the actions passed by `mapDispatchToProps`. +- Added a new `mapDispatchToProps` function that will be passed to `withDispatch`. It takes `dispatch` as input and returns an object containing functions to update the internal data structures of the editor. These functions are also known as _actions_. +- By calling `setMetaFieldValue` every time the user types something within the input control, we're effectively updating the editor store on each key stroke. +- The `props` argument to the `MetaBlockField` component contains now the data passed by `mapSelectToProps` and the actions passed by `mapDispatchToProps`. Copy this new code to the JavaScript file, load the sidebar and see how the input value gets updated as you type. You may want to check that the internal data structures are updated as well. Type something in the input control, and execute the following instruction in your browser's console: diff --git a/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-6-finishing-touches.md b/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-6-finishing-touches.md index b399c2e59189d5..cd2d2f2d45c018 100644 --- a/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-6-finishing-touches.md +++ b/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-6-finishing-touches.md @@ -5,7 +5,7 @@ Your JavaScript code now works as expected, here are a few ways to simplify and The first step is to convert the functions `mapSelectToProps` and `mapDispatchToProps` to anonymous functions that get passed directly to `withSelect` and `withData`, respectively: ```js -( function( wp ) { +( function ( wp ) { var registerPlugin = wp.plugins.registerPlugin; var PluginSidebar = wp.editPost.PluginSidebar; var el = wp.element.createElement; @@ -13,50 +13,50 @@ The first step is to convert the functions `mapSelectToProps` and `mapDispatchTo var withSelect = wp.data.withSelect; var withDispatch = wp.data.withDispatch; - var MetaBlockField = function( props ) { + var MetaBlockField = function ( props ) { return el( Text, { label: 'Meta Block Field', value: props.metaFieldValue, - onChange: function( content ) { + onChange: function ( content ) { props.setMetaFieldValue( content ); }, } ); - } + }; - var MetaBlockFieldWithData = withSelect( function( select ) { + var MetaBlockFieldWithData = withSelect( function ( select ) { return { - metaFieldValue: select( 'core/editor' ) - .getEditedPostAttribute( 'meta' ) - [ 'sidebar_plugin_meta_block_field' ], - } + metaFieldValue: select( 'core/editor' ).getEditedPostAttribute( + 'meta' + )[ 'sidebar_plugin_meta_block_field' ], + }; } )( MetaBlockField ); - var MetaBlockFieldWithDataAndActions = withDispatch( - function( dispatch ) { - return { - setMetaFieldValue: function( value ) { - dispatch( 'core/editor' ).editPost( - { meta: { sidebar_plugin_meta_block_field: value } } - ); - } - } - } - )( MetaBlockFieldWithData ); + var MetaBlockFieldWithDataAndActions = withDispatch( function ( dispatch ) { + return { + setMetaFieldValue: function ( value ) { + dispatch( 'core/editor' ).editPost( { + meta: { sidebar_plugin_meta_block_field: value }, + } ); + }, + }; + } )( MetaBlockFieldWithData ); registerPlugin( 'my-plugin-sidebar', { - render: function() { - return el( PluginSidebar, + render: function () { + return el( + PluginSidebar, { name: 'my-plugin-sidebar', icon: 'admin-post', title: 'My plugin sidebar', }, - el( 'div', + el( + 'div', { className: 'plugin-sidebar-content' }, el( MetaBlockFieldWithDataAndActions ) ) ); - } + }, } ); } )( window.wp ); ``` @@ -64,7 +64,7 @@ The first step is to convert the functions `mapSelectToProps` and `mapDispatchTo Next, merge `MetaBlockField`, `MetaBlockFieldWithData`, and `MetaBlockFieldWithDataAndActions` into one function called `MetaBlockField` that gets passed to the `div` element. The `@wordpress/compose` package offers an utility to concatenate functions called `compose`. Don't forget adding `wp-compose` to the dependencies array in the PHP script. ```js -( function( wp ) { +( function ( wp ) { var registerPlugin = wp.plugins.registerPlugin; var PluginSidebar = wp.editPost.PluginSidebar; var el = wp.element.createElement; @@ -74,46 +74,48 @@ Next, merge `MetaBlockField`, `MetaBlockFieldWithData`, and `MetaBlockFieldWithD var compose = wp.compose.compose; var MetaBlockField = compose( - withDispatch( function( dispatch ) { + withDispatch( function ( dispatch ) { return { - setMetaFieldValue: function( value ) { - dispatch( 'core/editor' ).editPost( - { meta: { sidebar_plugin_meta_block_field: value } } - ); - } - } + setMetaFieldValue: function ( value ) { + dispatch( 'core/editor' ).editPost( { + meta: { sidebar_plugin_meta_block_field: value }, + } ); + }, + }; } ), - withSelect( function( select ) { + withSelect( function ( select ) { return { - metaFieldValue: select( 'core/editor' ) - .getEditedPostAttribute( 'meta' ) - [ 'sidebar_plugin_meta_block_field' ], - } + metaFieldValue: select( 'core/editor' ).getEditedPostAttribute( + 'meta' + )[ 'sidebar_plugin_meta_block_field' ], + }; } ) - )( function( props ) { + )( function ( props ) { return el( Text, { label: 'Meta Block Field', value: props.metaFieldValue, - onChange: function( content ) { + onChange: function ( content ) { props.setMetaFieldValue( content ); }, } ); } ); registerPlugin( 'my-plugin-sidebar', { - render: function() { - return el( PluginSidebar, + render: function () { + return el( + PluginSidebar, { name: 'my-plugin-sidebar', icon: 'admin-post', title: 'My plugin sidebar', }, - el( 'div', + el( + 'div', { className: 'plugin-sidebar-content' }, el( MetaBlockField ) ) ); - } + }, } ); } )( window.wp ); ``` @@ -122,24 +124,21 @@ Finally, extract the meta field name (`sidebar_plugin_meta_block_field`) from th ```js // ... -var MetaBlockFieldWithData = withSelect( - function( select, props ) { - console.log( props.metaFieldName ); - } -)( MetaBlockField ); +var MetaBlockFieldWithData = withSelect( function ( select, props ) { + console.log( props.metaFieldName ); +} )( MetaBlockField ); // ... - el( - MetaBlockFieldWithData, - { metaFieldName: 'sidebar_plugin_meta_block_field' } - ) +el( MetaBlockFieldWithData, { + metaFieldName: 'sidebar_plugin_meta_block_field', +} ); // ... ``` Notice how the `metaFieldName` can be accessed within `withSelect`. Let's change the code to take advantage of that: ```js -( function( wp ) { +( function ( wp ) { var registerPlugin = wp.plugins.registerPlugin; var PluginSidebar = wp.editPost.PluginSidebar; var el = wp.element.createElement; @@ -149,48 +148,50 @@ Notice how the `metaFieldName` can be accessed within `withSelect`. Let's change var compose = wp.compose.compose; var MetaBlockField = compose( - withDispatch( function( dispatch, props ) { + withDispatch( function ( dispatch, props ) { return { - setMetaFieldValue: function( value ) { - dispatch( 'core/editor' ).editPost( - { meta: { [ props.fieldName ]: value } } - ); - } - } + setMetaFieldValue: function ( value ) { + dispatch( 'core/editor' ).editPost( { + meta: { [ props.fieldName ]: value }, + } ); + }, + }; } ), - withSelect( function( select, props ) { + withSelect( function ( select, props ) { return { - metaFieldValue: select( 'core/editor' ) - .getEditedPostAttribute( 'meta' ) - [ props.fieldName ], - } + metaFieldValue: select( 'core/editor' ).getEditedPostAttribute( + 'meta' + )[ props.fieldName ], + }; } ) - )( function( props ) { + )( function ( props ) { return el( Text, { label: 'Meta Block Field', value: props.metaFieldValue, - onChange: function( content ) { + onChange: function ( content ) { props.setMetaFieldValue( content ); }, } ); } ); registerPlugin( 'my-plugin-sidebar', { - render: function() { - return el( PluginSidebar, + render: function () { + return el( + PluginSidebar, { name: 'my-plugin-sidebar', icon: 'admin-post', title: 'My plugin sidebar', }, - el( 'div', + el( + 'div', { className: 'plugin-sidebar-content' }, - el( MetaBlockField, - { fieldName: 'sidebar_plugin_meta_block_field' } - ) + el( MetaBlockField, { + fieldName: 'sidebar_plugin_meta_block_field', + } ) ) ); - } + }, } ); } )( window.wp ); ``` diff --git a/docs/how-to-guides/themes/block-based-themes.md b/docs/how-to-guides/themes/block-based-themes.md index 3368d80fcfff33..6eb8608b0e02fe 100644 --- a/docs/how-to-guides/themes/block-based-themes.md +++ b/docs/how-to-guides/themes/block-based-themes.md @@ -124,6 +124,16 @@ As we're still early in the process, the number of blocks specifically dedicated One of the most important aspects of themes (if not the most important) is the styling. While initially you'll be able to provide styles and enqueue them using the same hooks themes have always used, the [Global Styles](/docs/how-to-guides/themes/theme-json.md) effort will provide a scaffolding for adding many theme styles in the future. +## Classic Themes + +Users of classic themes can also build custom block templates and use theme in their Pages and Custom Post Types that supports Page Templates. + +Theme authors can opt-out of this feature by removing the `block-templates` theme support in their `functions.php` file. + +```php +remove_theme_support( 'block-templates' ); +``` + ## Resources - [Full Site Editing](https://github.com/WordPress/gutenberg/labels/%5BFeature%5D%20Full%20Site%20Editing) label. diff --git a/docs/how-to-guides/themes/theme-json.md b/docs/how-to-guides/themes/theme-json.md index 39d61730386f9e..26c93887774c3e 100644 --- a/docs/how-to-guides/themes/theme-json.md +++ b/docs/how-to-guides/themes/theme-json.md @@ -178,7 +178,10 @@ The settings section has the following structure and default values: "wideSize": "1000px", } "border": { - "customRadius": false /* true to opt-in */ + "customColor": false, /* true to opt-in */ + "customRadius": false, + "customStyle": false, + "customWidth": false }, "color": { "custom": true, /* false to opt-out, as in add_theme_support('disable-custom-colors') */ @@ -359,7 +362,10 @@ Each block declares which style properties it exposes via the [block supports me "styles": { "some/block/selector": { "border": { - "radius": "value" + "color": "value", + "radius": "value", + "style": "value", + "width": "value" }, "color": { "background": "value", @@ -464,16 +470,16 @@ There's a growing need to add more theme metadata to the theme.json. This sectio } ``` -**templateParts**: within this field themes can list the template parts present in the `block-template-parts` folder. For example, for a template part named `my-template-part.html`, the `theme.json` can declare the area term for the template part entity which is responsible for rendering the corresponding block variation (Header block, Footer block, etc.) in the editor. Defining this area term in the json will allow the setting to persist across all uses of that template part entity, as opposed to a block attribute that would only affect one block. Defining area as a block attribute is not recommended as this is only used 'behind the scenes' to aid in bridging the gap between placeholder flows and entity creation. +**templateParts**: within this field themes can list the template parts present in the `block-template-parts` folder. For example, for a template part named `my-template-part.html`, the `theme.json` can declare the area term for the template part entity which is responsible for rendering the corresponding block variation (Header block, Footer block, etc.) in the editor. Defining this area term in the json will allow the setting to persist across all uses of that template part entity, as opposed to a block attribute that would only affect one block. Defining area as a block attribute is not recommended as this is only used 'behind the scenes' to aid in bridging the gap between placeholder flows and entity creation. -Currently block variations exist for "header" and "footer" values of the area term, any other values and template parts not defined in the json will default to the general template part block. Variations will be denoted by specific icons within the editor's interface, will default to the corresponding semantic HTML element for the wrapper (this can also be overridden by the `tagName` attribute set on the template part block), and will contextualize the template part allowing more custom flows in future editor improvements. +Currently block variations exist for "header" and "footer" values of the area term, any other values and template parts not defined in the json will default to the general template part block. Variations will be denoted by specific icons within the editor's interface, will default to the corresponding semantic HTML element for the wrapper (this can also be overridden by the `tagName` attribute set on the template part block), and will contextualize the template part allowing more custom flows in future editor improvements. ```json { "templateParts": [ { "name": "my-template-part" /* Mandatory */, - "area": "header" /* Optional, will be set to 'uncategorized' by default and trigger no block variation */, + "area": "header" /* Optional, will be set to 'uncategorized' by default and trigger no block variation */ } ] } diff --git a/docs/how-to-guides/themes/theme-support.md b/docs/how-to-guides/themes/theme-support.md index 1b434af064b1d9..8b925dcd1dc134 100644 --- a/docs/how-to-guides/themes/theme-support.md +++ b/docs/how-to-guides/themes/theme-support.md @@ -4,12 +4,12 @@ The new Blocks include baseline support in all themes, enhancements to opt-in to There are a few new concepts to consider when building themes: -- **Editor Color Palette** - A default set of colors is provided, but themes can register their own and optionally lock users into picking from the defined palette. -- **Editor Text Size Palette** - A default set of sizes is provided, but themes can register their own and optionally lock users into picking from preselected sizes. -- **Responsive Embeds** - Themes must opt-in to responsive embeds. -- **Frontend & Editor Styles** - To get the most out of blocks, theme authors will want to make sure Core styles look good and opt-in, or write their own styles to best fit their theme. -- **Block Tools** - Themes can opt-in to several block tools like line height, custom units. -- **Core Block Patterns** - Themes can opt-out of the default block patterns. +- **Editor Color Palette** - A default set of colors is provided, but themes can register their own and optionally lock users into picking from the defined palette. +- **Editor Text Size Palette** - A default set of sizes is provided, but themes can register their own and optionally lock users into picking from preselected sizes. +- **Responsive Embeds** - Themes must opt-in to responsive embeds. +- **Frontend & Editor Styles** - To get the most out of blocks, theme authors will want to make sure Core styles look good and opt-in, or write their own styles to best fit their theme. +- **Block Tools** - Themes can opt-in to several block tools like line height, custom units. +- **Core Block Patterns** - Themes can opt-out of the default block patterns. By default, blocks provide their styles to enable basic support for blocks in themes without any change. They also [provide opt-in opinionated styles](#default-block-styles). Themes can add/override these styles, or they can provide no styles at all, and rely fully on what the blocks provide. @@ -188,11 +188,14 @@ Themes are responsible for creating the classes that apply the gradients. So to ```css .has-vivid-cyan-blue-to-vivid-purple-gradient-background { - background: linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%); + background: linear-gradient( + 135deg, + rgba( 6, 147, 227, 1 ) 0%, + rgb( 155, 81, 224 ) 100% + ); } ``` - ### Block Font Sizes: Blocks may allow the user to configure the font sizes they use, e.g., the paragraph block. The block provides a default set of font sizes, but a theme can overwrite it and provide its own: @@ -305,7 +308,7 @@ The block editor supports the theme's [editor styles](https://codex.wordpress.or In the classic editor, the editor stylesheet is loaded directly into the iframe of the WYSIWYG editor, with no changes. The block editor, however, doesn't use iframes. To make sure your styles are applied only to the content of the editor, we automatically transform your editor styles by selectively rewriting or adjusting certain CSS selectors. This also allows the block editor to leverage your editor style in block variation previews. -For example, if you write `body { ... }` in your editor style, this is rewritten to `.editor-styles-wrapper { ... }`. This also means that you should _not_ target any of the editor class names directly. +For example, if you write `body { ... }` in your editor style, this is rewritten to `.editor-styles-wrapper { ... }`. This also means that you should _not_ target any of the editor class names directly. Because it works a little differently, you need to opt-in to this by adding an extra snippet to your theme, in addition to the add_editor_style function: @@ -348,12 +351,12 @@ To change the main column width of the editor, add the following CSS to `style-e } /* Width of "wide" blocks */ -.wp-block[data-align="wide"] { +.wp-block[data-align='wide'] { max-width: 1080px; } /* Width of "full-wide" blocks */ -.wp-block[data-align="full"] { +.wp-block[data-align='full'] { max-width: none; } ``` @@ -386,7 +389,7 @@ add_theme_support('custom-spacing'); ## Experimental — Link color control -Using the Gutenberg plugin (version 8.3 or later), link color control is available to the Paragraph, Heading, Group, Columns, and Media & Text blocks. This is off by default, and requires the theme to opt in by declaring support: +Using the Gutenberg plugin (version 8.3 or later), link color control is available to the Paragraph, Heading, Group, Columns, and Media & Text blocks. This is off by default, and requires the theme to opt in by declaring support: ```php add_theme_support('experimental-link-color'); @@ -410,6 +413,6 @@ If the theme styles the link color in its stylesheets (editor and front-end), it ```css a { - color: var(--wp--style--color--link); + color: var( --wp--style--color--link ); } ``` diff --git a/docs/manifest.json b/docs/manifest.json index c72f2673adf4b1..6cac717debbb98 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -438,15 +438,15 @@ "parent": "reference-guides" }, { - "title": "Block Registration", - "slug": "block-registration", - "markdown_source": "../docs/reference-guides/block-api/block-registration.md", + "title": "Annotations", + "slug": "block-annotations", + "markdown_source": "../docs/reference-guides/block-api/block-annotations.md", "parent": "block-api" }, { - "title": "Edit and Save", - "slug": "block-edit-save", - "markdown_source": "../docs/reference-guides/block-api/block-edit-save.md", + "title": "API Versions", + "slug": "block-api-versions", + "markdown_source": "../docs/reference-guides/block-api/block-api-versions.md", "parent": "block-api" }, { @@ -456,63 +456,63 @@ "parent": "block-api" }, { - "title": "Block Context", + "title": "Context", "slug": "block-context", "markdown_source": "../docs/reference-guides/block-api/block-context.md", "parent": "block-api" }, { - "title": "Deprecated Blocks", + "title": "Deprecation", "slug": "block-deprecation", "markdown_source": "../docs/reference-guides/block-api/block-deprecation.md", "parent": "block-api" }, { - "title": "Block Supports", - "slug": "block-supports", - "markdown_source": "../docs/reference-guides/block-api/block-supports.md", + "title": "Edit and Save", + "slug": "block-edit-save", + "markdown_source": "../docs/reference-guides/block-api/block-edit-save.md", "parent": "block-api" }, { - "title": "Block Transforms", - "slug": "block-transforms", - "markdown_source": "../docs/reference-guides/block-api/block-transforms.md", + "title": "Metadata", + "slug": "block-metadata", + "markdown_source": "../docs/reference-guides/block-api/block-metadata.md", "parent": "block-api" }, { - "title": "Templates", - "slug": "block-templates", - "markdown_source": "../docs/reference-guides/block-api/block-templates.md", + "title": "Patterns", + "slug": "block-patterns", + "markdown_source": "../docs/reference-guides/block-api/block-patterns.md", "parent": "block-api" }, { - "title": "Block Type Metadata", - "slug": "block-metadata", - "markdown_source": "../docs/reference-guides/block-api/block-metadata.md", + "title": "Registration", + "slug": "block-registration", + "markdown_source": "../docs/reference-guides/block-api/block-registration.md", "parent": "block-api" }, { - "title": "Block Variations", - "slug": "block-variations", - "markdown_source": "../docs/reference-guides/block-api/block-variations.md", + "title": "Supports", + "slug": "block-supports", + "markdown_source": "../docs/reference-guides/block-api/block-supports.md", "parent": "block-api" }, { - "title": "Block Patterns", - "slug": "block-patterns", - "markdown_source": "../docs/reference-guides/block-api/block-patterns.md", + "title": "Templates", + "slug": "block-templates", + "markdown_source": "../docs/reference-guides/block-api/block-templates.md", "parent": "block-api" }, { - "title": "Annotations", - "slug": "block-annotations", - "markdown_source": "../docs/reference-guides/block-api/block-annotations.md", + "title": "Transforms", + "slug": "block-transforms", + "markdown_source": "../docs/reference-guides/block-api/block-transforms.md", "parent": "block-api" }, { - "title": "Block API Versions", - "slug": "versions", - "markdown_source": "../docs/reference-guides/block-api/versions.md", + "title": "Variations", + "slug": "block-variations", + "markdown_source": "../docs/reference-guides/block-api/block-variations.md", "parent": "block-api" }, { @@ -1889,4 +1889,4 @@ "markdown_source": "../docs/contributors/roadmap.md", "parent": "contributors" } -] \ No newline at end of file +] diff --git a/docs/reference-guides/README.md b/docs/reference-guides/README.md index 37cc9b8fc77ca5..787e6144098fa8 100644 --- a/docs/reference-guides/README.md +++ b/docs/reference-guides/README.md @@ -2,19 +2,19 @@ ## [Block API Reference](/docs/reference-guides/block-api/README.md) -- [Block registration](/docs/reference-guides/block-api/block-registration.md) -- [Edit and Save](/docs/reference-guides/block-api/block-edit-save.md) +- [Annotations](/docs/reference-guides/block-api/block-annotations.md) +- [API Versions](/docs/reference-guides/block-api/block-api-versions.md) - [Attributes](/docs/reference-guides/block-api/block-attributes.md) - [Context](/docs/reference-guides/block-api/block-context.md) - [Deprecation](/docs/reference-guides/block-api/block-deprecation.md) +- [Edit and Save](/docs/reference-guides/block-api/block-edit-save.md) +- [Patterns](/docs/reference-guides/block-api/block-patterns.md) +- [Registration](/docs/reference-guides/block-api/block-registration.md) - [Supports](/docs/reference-guides/block-api/block-supports.md) -- [Transformations](/docs/reference-guides/block-api/block-transforms.md) - [Templates](/docs/reference-guides/block-api/block-templates.md) +- [Transformations](/docs/reference-guides/block-api/block-transforms.md) - [Metadata](/docs/reference-guides/block-api/block-metadata.md) -- [Block Variations](/docs/reference-guides/block-api/block-variations.md) -- [Block Patterns](/docs/reference-guides/block-api/block-patterns.md) -- [Annotations](/docs/reference-guides/block-api/block-annotations.md) -- [Versions](/docs/reference-guides/block-api/versions.md) +- [Variations](/docs/reference-guides/block-api/block-variations.md) ## [Filter Reference](/docs/reference-guides/filters/README.md) diff --git a/docs/reference-guides/block-api/README.md b/docs/reference-guides/block-api/README.md index 7769a442740a78..e2de21d99f85e0 100644 --- a/docs/reference-guides/block-api/README.md +++ b/docs/reference-guides/block-api/README.md @@ -4,16 +4,16 @@ Blocks are the fundamental element of the editor. They are the primary way in wh The following sections will walk you through the existing block APIs: -- [Block registration](/docs/reference-guides/block-api/block-registration.md) -- [Edit and Save](/docs/reference-guides/block-api/block-edit-save.md) +- [API Versions](/docs/reference-guides/block-api/block-api-versions.md) +- [Annotations](/docs/reference-guides/block-api/block-annotations.md) - [Attributes](/docs/reference-guides/block-api/block-attributes.md) - [Context](/docs/reference-guides/block-api/block-context.md) - [Deprecation](/docs/reference-guides/block-api/block-deprecation.md) +- [Edit and Save](/docs/reference-guides/block-api/block-edit-save.md) +- [Patterns](/docs/reference-guides/block-api/block-patterns.md) +- [Registration](/docs/reference-guides/block-api/block-registration.md) - [Supports](/docs/reference-guides/block-api/block-supports.md) - [Transformations](/docs/reference-guides/block-api/block-transforms.md) - [Templates](/docs/reference-guides/block-api/block-templates.md) - [Metadata](/docs/reference-guides/block-api/block-metadata.md) -- [Block Variations](/docs/reference-guides/block-api/block-variations.md) -- [Block Patterns](/docs/reference-guides/block-api/block-patterns.md) -- [Annotations](/docs/reference-guides/block-api/block-annotations.md) -- [Versions](/docs/reference-guides/block-api/versions.md) +- [Variations](/docs/reference-guides/block-api/block-variations.md) diff --git a/docs/reference-guides/block-api/block-annotations.md b/docs/reference-guides/block-api/block-annotations.md index e2d3f6408272e8..1138db3c99363b 100644 --- a/docs/reference-guides/block-api/block-annotations.md +++ b/docs/reference-guides/block-api/block-annotations.md @@ -10,9 +10,9 @@ To see the API for yourself the easiest way is to have a block that is at least ```js wp.data.dispatch( 'core/annotations' ).addAnnotation( { - source: "my-annotations-plugin", - blockClientId: wp.data.select( 'core/editor' ).getBlockOrder()[0], - richTextIdentifier: "content", + source: 'my-annotations-plugin', + blockClientId: wp.data.select( 'core/editor' ).getBlockOrder()[ 0 ], + richTextIdentifier: 'content', range: { start: 50, end: 100, @@ -40,9 +40,9 @@ It is also possible to annotate a block completely. In that case just provide th ```js wp.data.dispatch( 'core/annotations' ).addAnnotation( { - source: "my-annotations-plugin", - blockClientId: wp.data.select( 'core/editor' ).getBlockOrder()[0], - selector: "block", + source: 'my-annotations-plugin', + blockClientId: wp.data.select( 'core/editor' ).getBlockOrder()[ 0 ], + selector: 'block', } ); ``` diff --git a/docs/reference-guides/block-api/block-api-versions.md b/docs/reference-guides/block-api/block-api-versions.md new file mode 100644 index 00000000000000..6b2e858aae70c3 --- /dev/null +++ b/docs/reference-guides/block-api/block-api-versions.md @@ -0,0 +1,12 @@ +# API Versions + +This document lists the changes made between the different API versions. + +## Version 2 (>= WordPress 5.6) + +- To render the block element wrapper for the block's `edit` implementation, the block author must use the `useBlockProps()` hook. +- The generated class names and styles are no longer added automatically to the saved markup for static blocks when `save` is processed. To include them, the block author must explicitly use `useBlockProps.save()` and add to their block wrapper. + +## Version 1 + +Initial version. diff --git a/docs/reference-guides/block-api/block-attributes.md b/docs/reference-guides/block-api/block-attributes.md index b5cdb3399b3380..70f8e83192d1c9 100644 --- a/docs/reference-guides/block-api/block-attributes.md +++ b/docs/reference-guides/block-api/block-attributes.md @@ -6,13 +6,13 @@ The only required field for an attribute is the `type` field. It indicates the t Accepted values in the `type` field MUST be one of the following: -* null -* boolean -* object -* array -* number -* string -* integer +- null +- boolean +- object +- array +- number +- string +- integer See [WordPress's REST API documentation](https://developer.wordpress.org/rest-api/extending-the-rest-api/schema/) for additional details. @@ -30,7 +30,6 @@ The selector specified can be an HTML tag, or anything queryable such as a class Under the hood, attribute sources are a superset of the functionality provided by [hpq](https://github.com/aduth/hpq), a small library used to parse and query HTML markup into an object shape. - ### `attribute` Use `attribute` to extract the value of an attribute from markup. @@ -186,6 +185,7 @@ From here, meta attributes can be read and written by a block using the same int {% codetabs %} {% ESNext %} + ```js edit( { attributes, setAttributes } ) { function onChange( event ) { @@ -195,7 +195,9 @@ edit( { attributes, setAttributes } ) { return ; }, ``` + {% ES5 %} + ```js edit: function( props ) { function onChange( event ) { @@ -208,6 +210,7 @@ edit: function( props ) { } ); }, ``` + {% end %} ### Considerations @@ -225,8 +228,8 @@ add_action( 'init', 'gutenberg_my_block_init' ); Furthermore, be aware that WordPress defaults to: -- not treating a meta datum as being unique, instead returning an array of values; -- treating that datum as a string. +- not treating a meta datum as being unique, instead returning an array of values; +- treating that datum as a string. If either behavior is not desired, the same `register_post_meta` call can be complemented with the `single` and/or `type` parameters as follows: diff --git a/docs/reference-guides/block-api/block-context.md b/docs/reference-guides/block-api/block-context.md index b9639a6670c3f9..0dc32fb0d88562 100644 --- a/docs/reference-guides/block-api/block-context.md +++ b/docs/reference-guides/block-api/block-context.md @@ -1,4 +1,4 @@ -# Block Context +# Context Block context is a feature which enables ancestor blocks to provide values which can be consumed by descendent blocks within its own hierarchy. Those descendent blocks can inherit these values without resorting to hard-coded values and without an explicit awareness of the block which provides those values. @@ -73,16 +73,18 @@ register_block_type( 'my-plugin/record-title', array( ``` ## Example + 1. Create `record` block. + ``` npm init @wordpress/block --namespace my-plugin record cd record ``` -2. Edit `src/index.js`. Insert `recordId` attribute and `providesContext` property in `registerBlockType` function and add registration of `record-title` block at the bottom. -```js -registerBlockType('my-plugin/record', { +2. Edit `src/index.js`. Insert `recordId` attribute and `providesContext` property in `registerBlockType` function and add registration of `record-title` block at the bottom. +```js +registerBlockType( 'my-plugin/record', { // ... cut ... attributes: { @@ -104,46 +106,46 @@ registerBlockType('my-plugin/record', { * @see ./save.js */ save, -}); +} ); -registerBlockType('my-plugin/record-title', { +registerBlockType( 'my-plugin/record-title', { title: 'Record Title', category: 'widgets', - usesContext: ['my-plugin/recordId'], + usesContext: [ 'my-plugin/recordId' ], - edit({ context }) { - return 'The record ID: ' + context['my-plugin/recordId']; + edit( { context } ) { + return 'The record ID: ' + context[ 'my-plugin/recordId' ]; }, save() { return null; - } -}); + }, +} ); ``` -3. Edit `src/edit.js`. Replace `Edit` function by following code. +3. Edit `src/edit.js`. Replace `Edit` function by following code. ```js import { TextControl } from '@wordpress/components'; import { InnerBlocks } from '@wordpress/block-editor'; -export default function Edit(props) { - const MY_TEMPLATE = [ - ['my-plugin/record-title', {}], - ]; - const { attributes: { recordId }, setAttributes } = props; +export default function Edit( props ) { + const MY_TEMPLATE = [ [ 'my-plugin/record-title', {} ] ]; + const { + attributes: { recordId }, + setAttributes, + } = props; return (
setAttributes({ recordId: Number(val) })} - /> - + setAttributes( { recordId: Number( val ) } ) + } /> +
); } @@ -152,12 +154,11 @@ export default function Edit(props) { 4. Edit `src/save.js`. Replace `save` function by following code. ```js -export default function save(props) { - return

The record ID: {props.attributes.recordId}

; +export default function save( props ) { + return

The record ID: { props.attributes.recordId }

; } ``` 5. Create new post and add `record` block. If you type number in the above box, you'll see the same number is shown in below box. ![Block Context Example](https://user-images.githubusercontent.com/8876600/93000215-c8570380-f561-11ea-9bd0-0b2bd0ca1752.png) - diff --git a/docs/reference-guides/block-api/block-deprecation.md b/docs/reference-guides/block-api/block-deprecation.md index e15f1a76cde0de..663f38a227a0a0 100644 --- a/docs/reference-guides/block-api/block-deprecation.md +++ b/docs/reference-guides/block-api/block-deprecation.md @@ -1,9 +1,9 @@ -# Deprecated Blocks +# Deprecation When updating static blocks markup and attributes, block authors need to consider existing posts using the old versions of their block. To provide a good upgrade path, you can choose one of the following strategies: - - Do not deprecate the block and create a new one (a different name) - - Provide a "deprecated" version of the block allowing users opening these in the block editor to edit them using the updated block. +- Do not deprecate the block and create a new one (a different name) +- Provide a "deprecated" version of the block allowing users opening these in the block editor to edit them using the updated block. A block can have several deprecated versions. A deprecation will be tried if the current state of a parsed block is invalid, or if the deprecation defines an `isEligible` function that returns true. @@ -17,31 +17,34 @@ For blocks with multiple deprecations, it may be easier to save each deprecation {% codetabs %} {% ESNext %} + ```js const v1 = {}; const v2 = {}; const v3 = {}; const deprecated = [ v3, v2, v1 ]; - ``` + {% ES5 %} + ```js var v1 = {}; var v2 = {}; var v3 = {}; var deprecated = [ v3, v2, v1 ]; ``` + {% end %} It is also recommended to keep [fixtures](https://github.com/WordPress/gutenberg/blob/HEAD/packages/e2e-tests/fixtures/blocks/README.md) which contain the different versions of the block content to allow you to easily test that new deprecations and migrations are working across all previous versions of the block. Deprecations are defined on a block type as its `deprecated` property, an array of deprecation objects where each object takes the form: -- `attributes` (Object): The [attributes definition](/docs/reference-guides/block-api/block-attributes.md) of the deprecated form of the block. -- `supports` (Object): The [supports definition](/docs/reference-guides/block-api/block-registration.md) of the deprecated form of the block. -- `save` (Function): The [save implementation](/docs/reference-guides/block-api/block-edit-save.md) of the deprecated form of the block. -- `migrate` (Function, Optional): A function which, given the old attributes and inner blocks is expected to return either the new attributes or a tuple array of `[ attributes, innerBlocks ]` compatible with the block. As mentioned above, a deprecation's `migrate` will not be run if its `save` function does not return a valid block so you will need to make sure your migrations are available in all the deprecations where they are relevant. -- `isEligible` (Function, Optional): A function which, given the attributes and inner blocks of the parsed block, returns true if the deprecation can handle the block migration even if the block is valid. This is particularly useful in cases where a block is technically valid even once deprecated, and requires updates to its attributes or inner blocks. This function is not called when the results of all previous deprecations' `save` functions were invalid. +- `attributes` (Object): The [attributes definition](/docs/reference-guides/block-api/block-attributes.md) of the deprecated form of the block. +- `supports` (Object): The [supports definition](/docs/reference-guides/block-api/block-registration.md) of the deprecated form of the block. +- `save` (Function): The [save implementation](/docs/reference-guides/block-api/block-edit-save.md) of the deprecated form of the block. +- `migrate` (Function, Optional): A function which, given the old attributes and inner blocks is expected to return either the new attributes or a tuple array of `[ attributes, innerBlocks ]` compatible with the block. As mentioned above, a deprecation's `migrate` will not be run if its `save` function does not return a valid block so you will need to make sure your migrations are available in all the deprecations where they are relevant. +- `isEligible` (Function, Optional): A function which, given the attributes and inner blocks of the parsed block, returns true if the deprecation can handle the block migration even if the block is valid. This is particularly useful in cases where a block is technically valid even once deprecated, and requires updates to its attributes or inner blocks. This function is not called when the results of all previous deprecations' `save` functions were invalid. It's important to note that `attributes`, `supports`, and `save` are not automatically inherited from the current version, since they can impact parsing and serialization of a block, so they must be defined on the deprecated object in order to be processed during a migration. @@ -49,17 +52,17 @@ It's important to note that `attributes`, `supports`, and `save` are not automat {% codetabs %} {% ESNext %} + ```js const { registerBlockType } = wp.blocks; const attributes = { text: { type: 'string', default: 'some random value', - } + }, }; registerBlockType( 'gutenberg/block-with-deprecated-version', { - // ... other block properties go here attributes, @@ -75,11 +78,13 @@ registerBlockType( 'gutenberg/block-with-deprecated-version', { save( props ) { return

{ props.attributes.text }

; }, - } - ] + }, + ], } ); ``` + {% ES5 %} + ```js var el = wp.element.createElement, registerBlockType = wp.blocks.registerBlockType, @@ -87,16 +92,15 @@ var el = wp.element.createElement, text: { type: 'string', default: 'some random value', - } + }, }; registerBlockType( 'gutenberg/block-with-deprecated-version', { - // ... other block properties go here attributes: attributes, - save: function( props ) { + save: function ( props ) { return el( 'div', {}, props.attributes.text ); }, @@ -104,18 +108,18 @@ registerBlockType( 'gutenberg/block-with-deprecated-version', { { attributes: attributes, - save: function( props ) { + save: function ( props ) { return el( 'p', {}, props.attributes.text ); }, - } - ] + }, + ], } ); ``` + {% end %} In the example above we updated the markup of the block to use a `div` instead of `p`. - ## Changing the attributes set Sometimes, you need to update the attributes set to rename or modify old attributes. @@ -124,18 +128,18 @@ Sometimes, you need to update the attributes set to rename or modify old attribu {% codetabs %} {% ESNext %} + ```js const { registerBlockType } = wp.blocks; registerBlockType( 'gutenberg/block-with-deprecated-version', { - // ... other block properties go here attributes: { content: { type: 'string', default: 'some random value', - } + }, }, save( props ) { @@ -148,39 +152,40 @@ registerBlockType( 'gutenberg/block-with-deprecated-version', { text: { type: 'string', default: 'some random value', - } + }, }, migrate( { text } ) { return { - content: text + content: text, }; }, save( props ) { return

{ props.attributes.text }

; }, - } - ] + }, + ], } ); ``` + {% ES5 %} + ```js var el = wp.element.createElement, registerBlockType = wp.blocks.registerBlockType; registerBlockType( 'gutenberg/block-with-deprecated-version', { - // ... other block properties go here attributes: { content: { type: 'string', default: 'some random value', - } + }, }, - save: function( props ) { + save: function ( props ) { return el( 'div', {}, props.attributes.content ); }, @@ -190,27 +195,27 @@ registerBlockType( 'gutenberg/block-with-deprecated-version', { text: { type: 'string', default: 'some random value', - } + }, }, - migrate: function( attributes ) { + migrate: function ( attributes ) { return { - content: attributes.text + content: attributes.text, }; }, - save: function( props ) { + save: function ( props ) { return el( 'p', {}, props.attributes.text ); }, - } - ] + }, + ], } ); ``` + {% end %} In the example above we updated the markup of the block to use a `div` instead of `p` and rename the `text` attribute to `content`. - ## Changing the innerBlocks Situations may exist where when migrating the block we may need to add or remove innerBlocks. @@ -220,12 +225,12 @@ E.g: a block wants to migrate a title attribute to a paragraph innerBlock. {% codetabs %} {% ESNext %} + ```js const { registerBlockType } = wp.blocks; const { omit } = lodash; registerBlockType( 'gutenberg/block-with-deprecated-version', { - // ... block properties go here save( props ) { @@ -242,7 +247,7 @@ registerBlockType( 'gutenberg/block-with-deprecated-version', { }, }, - migrate( attributes, innerBlocks ) { + migrate( attributes, innerBlocks ) { return [ omit( attributes, 'title' ), [ @@ -258,18 +263,19 @@ registerBlockType( 'gutenberg/block-with-deprecated-version', { save( props ) { return

{ props.attributes.title }

; }, - } - ] + }, + ], } ); ``` + {% ES5 %} + ```js var el = wp.element.createElement, registerBlockType = wp.blocks.registerBlockType, omit = lodash.omit; registerBlockType( 'gutenberg/block-with-deprecated-version', { - // ... block properties go here deprecated: [ @@ -282,7 +288,7 @@ registerBlockType( 'gutenberg/block-with-deprecated-version', { }, }, - migrate: function( attributes, innerBlocks ) { + migrate: function ( attributes, innerBlocks ) { return [ omit( attributes, 'title' ), [ @@ -294,15 +300,16 @@ registerBlockType( 'gutenberg/block-with-deprecated-version', { ]; }, - save: function( props ) { + save: function ( props ) { return el( 'p', {}, props.attributes.title ); }, - } - ] + }, + ], } ); ``` + {% end %} In the example above we updated the block to use an inner Paragraph block with a title instead of a title attribute. -*Above are example cases of block deprecation. For more, real-world examples, check for deprecations in the [core block library](https://github.com/WordPress/gutenberg/tree/HEAD/packages/block-library/src). Core blocks have been updated across releases and contain simple and complex deprecations.* +_Above are example cases of block deprecation. For more, real-world examples, check for deprecations in the [core block library](https://github.com/WordPress/gutenberg/tree/HEAD/packages/block-library/src). Core blocks have been updated across releases and contain simple and complex deprecations._ diff --git a/docs/reference-guides/block-api/block-edit-save.md b/docs/reference-guides/block-api/block-edit-save.md index db4db3ca490783..90f94f85a36a6c 100644 --- a/docs/reference-guides/block-api/block-edit-save.md +++ b/docs/reference-guides/block-api/block-edit-save.md @@ -8,40 +8,40 @@ The `edit` function describes the structure of your block in the context of the {% codetabs %} {% ESNext %} + ```jsx -import { useBlockProps } from '@wordpress/block-editor'; +import { useBlockProps } from '@wordpress/block-editor'; // ... const blockSettings = { apiVersion: 2, - - // ... + + // ... edit: () => { const blockProps = useBlockProps(); - return
Your block.
; - } + return
Your block.
; + }, }; ``` + {% ES5 %} + ```js var blockSettings = { apiVersion: 2, // ... - edit: function() { + edit: function () { var blockProps = wp.blockEditor.useBlockProps(); - return wp.element.createElement( - 'div', - blockProps, - 'Your block.' - ); - } + return wp.element.createElement( 'div', blockProps, 'Your block.' ); + }, }; ``` + {% end %} ### block wrapper props @@ -52,40 +52,44 @@ If the element wrapper needs any extra custom HTML attributes, these need to be {% codetabs %} {% ESNext %} + ```jsx -import { useBlockProps } from '@wordpress/block-editor'; +import { useBlockProps } from '@wordpress/block-editor'; // ... const blockSettings = { apiVersion: 2, - - // ... + + // ... edit: () => { - const blockProps = useBlockProps( { className: 'my-random-classname' } ); + const blockProps = useBlockProps( { + className: 'my-random-classname', + } ); return
Your block.
; - } + }, }; ``` + {% ES5 %} + ```js var blockSettings = { apiVersion: 2, // ... - edit: function() { - var blockProps = wp.blockEditor.useBlockProps( { className: 'my-random-classname' } ); + edit: function () { + var blockProps = wp.blockEditor.useBlockProps( { + className: 'my-random-classname', + } ); - return wp.element.createElement( - 'div', - blockProps, - 'Your block.' - ); - } + return wp.element.createElement( 'div', blockProps, 'Your block.' ); + }, }; ``` + {% end %} ### attributes @@ -98,14 +102,17 @@ In this case, assuming we had defined an attribute of `content` during block reg {% codetabs %} {% ESNext %} + ```js edit: ( { attributes } ) => { const blockProps = useBlockProps(); return
{ attributes.content }
; -} +}; ``` + {% ES5 %} + ```js edit: function( props ) { var blockProps = wp.blockEditor.useBlockProps(); @@ -117,6 +124,7 @@ edit: function( props ) { ); } ``` + {% end %} The value of `attributes.content` will be displayed inside the `div` when inserting the block in the editor. @@ -127,6 +135,7 @@ The isSelected property is an object that communicates whether the block is curr {% codetabs %} {% ESNext %} + ```jsx edit: ( { attributes, isSelected } ) => { const blockProps = useBlockProps(); @@ -134,14 +143,16 @@ edit: ( { attributes, isSelected } ) => { return (
Your block. - { isSelected && + { isSelected && ( Shows only when the block is selected. - } + ) }
); -} +}; ``` + {% ES5 %} + ```js edit: function( props ) { var blockProps = wp.blockEditor.useBlockProps(); @@ -160,6 +171,7 @@ edit: function( props ) { ); } ``` + {% end %} ### setAttributes @@ -168,6 +180,7 @@ This function allows the block to update individual attributes based on user int {% codetabs %} {% ESNext %} + ```jsx edit: ( { attributes, setAttributes, isSelected } ) => { const blockProps = useBlockProps(); @@ -180,14 +193,16 @@ edit: ( { attributes, setAttributes, isSelected } ) => { return (
{ content } - { isSelected && + { isSelected && ( - } + ) }
); -} +}; ``` + {% ES5 %} + ```js edit: function( props ) { var blockProps = wp.blockEditor.useBlockProps(); @@ -212,16 +227,19 @@ edit: function( props ) { ); }, ``` + {% end %} When using attributes that are objects or arrays it's a good idea to copy or clone the attribute prior to updating it: {% codetabs %} {% ESNext %} + ```js // Good - a new array is created from the old list attribute and a new list item: const { list } = attributes; -const addListItem = ( newListItem ) => setAttributes( { list: [ ...list, newListItem ] } ); +const addListItem = ( newListItem ) => + setAttributes( { list: [ ...list, newListItem ] } ); // Bad - the list from the existing attribute is modified directly to add the new list item: const { list } = attributes; @@ -230,22 +248,25 @@ const addListItem = ( newListItem ) => { setAttributes( { list } ); }; ``` + {% ES5 %} + ```js // Good - cloning the old list var newList = attributes.list.slice(); -var addListItem = function( newListItem ) { +var addListItem = function ( newListItem ) { setAttributes( { list: newList.concat( [ newListItem ] ) } ); }; // Bad - the list from the existing attribute is modified directly to add the new list item: var list = attributes.list; -var addListItem = function( newListItem ) { +var addListItem = function ( newListItem ) { list.push( newListItem ); setAttributes( { list: list } ); }; ``` + {% end %} Why do this? In JavaScript, arrays and objects are passed by reference, so this practice ensures changes won't affect other code that might hold references to the same data. Furthermore, the Gutenberg project follows the philosophy of the Redux library that [state should be immutable](https://redux.js.org/faq/immutable-data#what-are-the-benefits-of-immutability)—data should not be changed directly, but instead a new version of the data created containing the changes. @@ -256,14 +277,17 @@ The `save` function defines the way in which the different attributes should be {% codetabs %} {% ESNext %} + ```jsx save: () => { const blockProps = useBlockProps.save(); return
Your block.
; -} +}; ``` + {% ES5 %} + ```js save: function() { var blockProps = wp.blockEditor.useBlockProps.save(); @@ -275,6 +299,7 @@ save: function() { ); } ``` + {% end %} For most blocks, the return value of `save` should be an [instance of WordPress Element](/packages/element/README.md) representing how the block is to appear on the front of the site. @@ -285,8 +310,9 @@ _Note:_ The save function should be a pure function that depends only on the att It can not have any side effect or retrieve information from another source, e.g. it is not possible to use the data module inside it `select( store ).selector( ... )`. This is because if the external information changes, the block may be flagged as invalid when the post is later edited ([read more about Validation](#validation)). If there is a need to have other information as part of the save, developers can consider one of these two alternatives: - - Use [dynamic blocks](/docs/how-to-guides/block-tutorial/creating-dynamic-blocks.md) and dynamically retrieve the required information on the server. - - Store the external value as an attribute which is dynamically updated in the block's `edit` function as changes occur. + +- Use [dynamic blocks](/docs/how-to-guides/block-tutorial/creating-dynamic-blocks.md) and dynamically retrieve the required information on the server. +- Store the external value as an attribute which is dynamically updated in the block's `edit` function as changes occur. For [dynamic blocks](/docs/how-to-guides/block-tutorial/creating-dynamic-blocks.md), the return value of `save` could represent a cached copy of the block's content to be shown only in case the plugin implementing the block is ever disabled. @@ -302,14 +328,17 @@ As with `edit`, the `save` function also receives an object argument including a {% codetabs %} {% ESNext %} + ```jsx save: ( { attributes } ) => { const blockProps = useBlockProps.save(); - + return
{ attributes.content }
; -} +}; ``` + {% ES5 %} + ```js save: function( props ) { var blockProps = wp.blockEditor.useBlockProps.save(); @@ -321,19 +350,20 @@ save: function( props ) { ); } ``` -{% end %} +{% end %} When saving your block, you want to save the attributes in the same format specified by the attribute source definition. If no attribute source is specified, the attribute will be saved to the block's comment delimiter. See the [Block Attributes documentation](/docs/reference-guides/block-api/block-attributes.md) for more details. ## Examples -Here are a couple examples of using attributes, edit, and save all together. For a full working example, see the [Introducing Attributes and Editable Fields](/docs/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields.md) section of the Block Tutorial. +Here are a couple examples of using attributes, edit, and save all together. For a full working example, see the [Introducing Attributes and Editable Fields](/docs/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields.md) section of the Block Tutorial. ### Saving Attributes to Child Elements {% codetabs %} {% ESNext %} + ```jsx attributes: { content: { @@ -365,7 +395,9 @@ save: ( { attributes } ) => { return
{ attributes.content }
; }, ``` + {% ES5 %} + ```js attributes: { content: { @@ -402,6 +434,7 @@ save: function( props ) { return wp.element.createElement( 'div', blockProps, props.attributes.content ); }, ``` + {% end %} ### Saving Attributes via Serialization @@ -412,6 +445,7 @@ This example could be for a dynamic block, such as the [Latest Posts block](http {% codetabs %} {% ESNext %} + ```jsx attributes: { postsToShow: { @@ -439,7 +473,9 @@ save: () => { return null; } ``` + {% ES5 %} + ```js attributes: { postsToShow: { @@ -449,8 +485,8 @@ attributes: { edit: function( props ) { var blockProps = wp.blockEditor.useBlockProps(); - - return wp.element.createEleement( + + return wp.element.createEleement( 'div', blockProps, wp.element.createElement( @@ -470,8 +506,8 @@ save: function() { return null; } ``` -{% end %} +{% end %} ## Validation @@ -485,11 +521,11 @@ Clicking **Attempt Block Recovery** button will attempt recovery action as much Clicking the "3-dot" menu on the side of the block displays three options: -- **Resolve**: Open Resolve Block dialog box with two buttons: - - **Convert to HTML**: Protects the original markup from the saved post content and convert the block from its original type to the HTML block type, enabling the user to modify the HTML markup directly. - - **Convert to Blocks**: Protects the original markup from the saved post content and convert the block from its original type to the validated block type. -- **Convert to HTML**: Protects the original markup from the saved post content and convert the block from its original type to the HTML block type, enabling the user to modify the HTML markup directly. -- **Convert to Classic Block**: Protects the original markup from the saved post content as correct. Since the block will be converted from its original type to the Classic block type, it will no longer be possible to edit the content using controls available for the original block type. +- **Resolve**: Open Resolve Block dialog box with two buttons: + - **Convert to HTML**: Protects the original markup from the saved post content and convert the block from its original type to the HTML block type, enabling the user to modify the HTML markup directly. + - **Convert to Blocks**: Protects the original markup from the saved post content and convert the block from its original type to the validated block type. +- **Convert to HTML**: Protects the original markup from the saved post content and convert the block from its original type to the HTML block type, enabling the user to modify the HTML markup directly. +- **Convert to Classic Block**: Protects the original markup from the saved post content as correct. Since the block will be converted from its original type to the Classic block type, it will no longer be possible to edit the content using controls available for the original block type. ### Validation FAQ diff --git a/docs/reference-guides/block-api/block-metadata.md b/docs/reference-guides/block-api/block-metadata.md index ccbcb925950b11..35e014595b0c8a 100644 --- a/docs/reference-guides/block-api/block-metadata.md +++ b/docs/reference-guides/block-api/block-metadata.md @@ -1,4 +1,4 @@ -# Block Type Metadata +# Metadata To register a new block type using metadata that can be shared between codebase that uses JavaScript and PHP, start by creating a `block.json` file. This file: @@ -283,7 +283,7 @@ See [the block context documentation](/docs/reference-guides/block-api/block-con It contains as set of options to control features used in the editor. See the [the supports documentation](/docs/reference-guides/block-api/block-supports.md) for more details. -### Style Variations +### Block Styles - Type: `array` - Optional @@ -300,9 +300,9 @@ It contains as set of options to control features used in the editor. See the [t } ``` -Block styles can be used to provide alternative styles to block. It works by adding a class name to the block's wrapper. Using CSS, a theme developer can target the class name for the style variation if it is selected. +Block styles can be used to provide alternative styles to block. It works by adding a class name to the block's wrapper. Using CSS, a theme developer can target the class name for the block style if it is selected. -Plugins and Themes can also register [custom block style](/docs/reference-guides/filters/block-filters.md#block-style-variations) for existing blocks. +Plugins and Themes can also register [custom block style](/docs/reference-guides/filters/block-filters.md#block-styles) for existing blocks. ### Example diff --git a/docs/reference-guides/block-api/block-patterns.md b/docs/reference-guides/block-api/block-patterns.md index 2987118a0479e4..4122651b7713a1 100644 --- a/docs/reference-guides/block-api/block-patterns.md +++ b/docs/reference-guides/block-api/block-patterns.md @@ -1,4 +1,4 @@ -# Block Patterns +# Patterns Block Patterns are predefined block layouts, ready to insert and tweak. @@ -11,12 +11,13 @@ The editor comes with a list of built-in block patterns. Theme and plugin author The `register_block_pattern` function receives the name of the pattern as the first argument and an array describing properties of the pattern as the second argument. The properties of the block pattern include: - - `title` (required): A human-readable title for the pattern. - - `content` (required): Raw HTML content for the pattern. - - `description`: A visually hidden text used to describe the pattern in the inserter. A description is optional but it is strongly encouraged when the title does not fully describe what the pattern does. - - `categories`: An array of pattern categories used to group block patterns. Block patterns can be shown on multiple categories. - - `keywords`: An array of aliases or keywords that help users discover the pattern while searching. - - `viewportWidth`: An integer specifying the width of the pattern in the inserter. + +- `title` (required): A human-readable title for the pattern. +- `content` (required): Raw HTML content for the pattern. +- `description`: A visually hidden text used to describe the pattern in the inserter. A description is optional but it is strongly encouraged when the title does not fully describe what the pattern does. +- `categories`: An array of pattern categories used to group block patterns. Block patterns can be shown on multiple categories. +- `keywords`: An array of aliases or keywords that help users discover the pattern while searching. +- `viewportWidth`: An integer specifying the width of the pattern in the inserter. ```php register_block_pattern( @@ -50,7 +51,8 @@ Block patterns can be grouped using categories. The block editor comes with bund The `register_block_pattern_category` function receives the name of the category as the first argument and an array describing properties of the category as the second argument. The properties of the pattern categories include: - - `label` (required): A human-readable label for the pattern category. + +- `label` (required): A human-readable label for the pattern category. ```php register_block_pattern_category( diff --git a/docs/reference-guides/block-api/block-registration.md b/docs/reference-guides/block-api/block-registration.md index 34baf7a7e124d1..23723ffe2f1efa 100644 --- a/docs/reference-guides/block-api/block-registration.md +++ b/docs/reference-guides/block-api/block-registration.md @@ -1,4 +1,8 @@ -# Block Registration +# Registration + +Block registration API reference. + +**Note:** You can use the functions documented on this page, but a flexible method to register new block types is to use the block.json metadata file. See [metadata documentation for complete information](/docs/reference-guides/block-api/block-metadata.md). ## `registerBlockType` @@ -117,7 +121,7 @@ keywords: [ __( 'image' ), __( 'photo' ), __( 'pics' ) ], - **Type:** `Array` -Block styles can be used to provide alternative styles to block. It works by adding a class name to the block’s wrapper. Using CSS, a theme developer can target the class name for the style variation if it is selected. +Block styles can be used to provide alternative styles to block. It works by adding a class name to the block’s wrapper. Using CSS, a theme developer can target the class name for the block style if it is selected. ```js // Register block styles. @@ -139,7 +143,7 @@ styles: [ ], ``` -Plugins and Themes can also register [custom block style](/docs/reference-guides/filters/block-filters.md#block-style-variations) for existing blocks. +Plugins and Themes can also register [custom block style](/docs/reference-guides/filters/block-filters.md#block-styles) for existing blocks. #### attributes (optional) @@ -225,7 +229,7 @@ example: { - **Type:** `Object[]` -Similarly to how the block's style variations can be declared, a block type can define block variations that the user can pick from. The difference is that, rather than changing only the visual appearance, this field provides a way to apply initial custom attributes and inner blocks at the time when a block is inserted. See the [Block Variations API](/docs/reference-guides/block-api/block-variations.md) for more details. +Similarly to how the block's styles can be declared, a block type can define block variations that the user can pick from. The difference is that, rather than changing only the visual appearance, this field provides a way to apply initial custom attributes and inner blocks at the time when a block is inserted. See the [Block Variations API](/docs/reference-guides/block-api/block-variations.md) for more details. #### supports (optional) diff --git a/docs/reference-guides/block-api/block-supports.md b/docs/reference-guides/block-api/block-supports.md index 5b01f69086bfa1..8409d8a2d37933 100644 --- a/docs/reference-guides/block-api/block-supports.md +++ b/docs/reference-guides/block-api/block-supports.md @@ -1,4 +1,4 @@ -# Block Supports +# Supports Block Supports is the API that allows a block to declare features used in the editor. @@ -6,38 +6,38 @@ Some block supports — for example, `anchor` or `className` — apply their att ## anchor -- Type: `boolean` -- Default value: `false` +- Type: `boolean` +- Default value: `false` Anchors let you link directly to a specific block on a page. This property adds a field to define an id for the block and a button to copy the direct link. ```js // Declare support for anchor links. supports: { - anchor: true + anchor: true; } ``` ## align -- Type: `boolean` or `array` -- Default value: `false` +- Type: `boolean` or `array` +- Default value: `false` This property adds block controls which allow to change block's alignment. _Important: It doesn't work with dynamic blocks yet._ ```js supports: { - // Declare support for block's alignment. - // This adds support for all the options: - // left, center, right, wide, and full. - align: true + // Declare support for block's alignment. + // This adds support for all the options: + // left, center, right, wide, and full. + align: true; } ``` ```js supports: { - // Declare support for specific alignment options. - align: [ 'left', 'right', 'full' ] + // Declare support for specific alignment options. + align: [ 'left', 'right', 'full' ]; } ``` @@ -54,40 +54,40 @@ attributes: { ## alignWide -- Type: `boolean` -- Default value: `true` +- Type: `boolean` +- Default value: `true` This property allows to enable [wide alignment](/docs/how-to-guides/themes/theme-support.md#wide-alignment) for your theme. To disable this behavior for a single block, set this flag to `false`. ```js supports: { - // Remove the support for wide alignment. - alignWide: false + // Remove the support for wide alignment. + alignWide: false; } ``` ## className -- Type: `boolean` -- Default value: `true` +- Type: `boolean` +- Default value: `true` By default, the class `.wp-block-your-block-name` is added to the root element of your saved markup. This helps having a consistent mechanism for styling blocks that themes and plugins can rely on. If, for whatever reason, a class is not desired on the markup, this functionality can be disabled. ```js supports: { - // Remove the support for the generated className. - className: false + // Remove the support for the generated className. + className: false; } ``` ## color -- Type: `Object` -- Default value: null -- Subproperties: - - `background`: type `boolean`, default value `true` - - `gradients`: type `boolean`, default value `false` - - `text`: type `boolean`, default value `true` +- Type: `Object` +- Default value: null +- Subproperties: + - `background`: type `boolean`, default value `true` + - `gradients`: type `boolean`, default value `false` + - `text`: type `boolean`, default value `true` This value signals that a block supports some of the CSS style properties related to color. When it does, the block editor will show UI controls for the user to set their values. @@ -97,9 +97,10 @@ Note that the `text` and `background` keys have a default value of `true`, so if ```js supports: { - color: { // This also enables text and background UI controls. - gradients: true // Enable gradients UI control. - } + color: { + // This also enables text and background UI controls. + gradients: true; // Enable gradients UI control. + } } ``` @@ -116,7 +117,7 @@ supports: { When the block has support for a specific color property, the attributes definition is extended to include some attributes. -- `style`: attribute of `object` type with no default assigned. This is added when any of support color properties are declared. It stores the custom values set by the user. The block can apply a default style by specifying its own `style` attribute with a default e.g.: +- `style`: attribute of `object` type with no default assigned. This is added when any of support color properties are declared. It stores the custom values set by the user. The block can apply a default style by specifying its own `style` attribute with a default e.g.: ```js attributes: { @@ -133,7 +134,7 @@ attributes: { } ``` -- When `background` support is declared: it'll be added a new `backgroundColor` attribute of type `string` with no default assigned. It stores the preset values set by the user. The block can apply a default background color by specifying its own attribute with a default e.g.: +- When `background` support is declared: it'll be added a new `backgroundColor` attribute of type `string` with no default assigned. It stores the preset values set by the user. The block can apply a default background color by specifying its own attribute with a default e.g.: ```js attributes: { @@ -144,7 +145,7 @@ attributes: { } ``` -- When `gradients` support is declared: it'll be added a new `gradient` attribute of type `string` with no default assigned. It stores the preset values set by the user. The block can apply a default text color by specifying its own attribute with a default e.g.: +- When `gradients` support is declared: it'll be added a new `gradient` attribute of type `string` with no default assigned. It stores the preset values set by the user. The block can apply a default text color by specifying its own attribute with a default e.g.: ```js attributes: { @@ -155,7 +156,7 @@ attributes: { } ``` -- When `text` support is declared: it'll be added a new `textColor` attribute of type `string` with no default assigned. It stores the preset values set by the user. The block can apply a default text color by specifying its own attribute with a default e.g.: +- When `text` support is declared: it'll be added a new `textColor` attribute of type `string` with no default assigned. It stores the preset values set by the user. The block can apply a default text color by specifying its own attribute with a default e.g.: ```js attributes: { @@ -168,36 +169,36 @@ attributes: { ## customClassName -- Type: `boolean` -- Default value: `true` +- Type: `boolean` +- Default value: `true` This property adds a field to define a custom className for the block's wrapper. ```js supports: { - // Remove the support for the custom className. - customClassName: false + // Remove the support for the custom className. + customClassName: false; } ``` ## defaultStylePicker -- Type: `boolean` -- Default value: `true` +- Type: `boolean` +- Default value: `true` When the style picker is shown, a dropdown is displayed so the user can select a default style for this block type. If you prefer not to show the dropdown, set this property to `false`. ```js supports: { - // Remove the Default Style picker. - defaultStylePicker: false + // Remove the Default Style picker. + defaultStylePicker: false; } ``` ## fontSize -- Type: `boolean` -- Default value: `false` +- Type: `boolean` +- Default value: `false` This value signals that a block supports the font-size CSS style property. When it does, the block editor will show an UI control for the user to set its value. @@ -212,7 +213,7 @@ supports: { When the block declares support for `fontSize`, the attributes definition is extended to include two new attributes: `fontSize` and `style`: -- `fontSize`: attribute of `string` type with no default assigned. It stores the preset values set by the user. The block can apply a default fontSize by specifying its own `fontSize` attribute with a default e.g.: +- `fontSize`: attribute of `string` type with no default assigned. It stores the preset values set by the user. The block can apply a default fontSize by specifying its own `fontSize` attribute with a default e.g.: ```js attributes: { @@ -223,7 +224,7 @@ attributes: { } ``` -- `style`: attribute of `object` type with no default assigned. It stores the custom values set by the user. The block can apply a default style by specifying its own `style` attribute with a default e.g.: +- `style`: attribute of `object` type with no default assigned. It stores the custom values set by the user. The block can apply a default style by specifying its own `style` attribute with a default e.g.: ```js attributes: { @@ -240,36 +241,36 @@ attributes: { ## html -- Type: `boolean` -- Default value: `true` +- Type: `boolean` +- Default value: `true` By default, a block's markup can be edited individually. To disable this behavior, set `html` to `false`. ```js supports: { - // Remove support for an HTML mode. - html: false + // Remove support for an HTML mode. + html: false; } ``` ## inserter -- Type: `boolean` -- Default value: `true` +- Type: `boolean` +- Default value: `true` By default, all blocks will appear in the inserter. To hide a block so that it can only be inserted programmatically, set `inserter` to `false`. ```js supports: { - // Hide this block from the inserter. - inserter: false + // Hide this block from the inserter. + inserter: false; } ``` ## lineHeight -- Type: `boolean` -- Default value: `false` +- Type: `boolean` +- Default value: `false` This value signals that a block supports the line-height CSS style property. When it does, the block editor will show an UI control for the user to set its value if [the theme declares support](/docs/how-to-guides/themes/theme-support.md#supporting-custom-line-heights). @@ -297,38 +298,38 @@ attributes: { ## multiple -- Type: `boolean` -- Default value: `true` +- Type: `boolean` +- Default value: `true` A non-multiple block can be inserted into each post, one time only. For example, the built-in 'More' block cannot be inserted again if it already exists in the post being edited. A non-multiple block's icon is automatically dimmed (unclickable) to prevent multiple instances. ```js supports: { - // Use the block just once per post - multiple: false + // Use the block just once per post + multiple: false; } ``` ## reusable -- Type: `boolean` -- Default value: `true` +- Type: `boolean` +- Default value: `true` A block may want to disable the ability of being converted into a reusable block. By default all blocks can be converted to a reusable block. If supports reusable is set to false, the option to convert the block into a reusable block will not appear. ```js supports: { - // Don't allow the block to be converted into a reusable block. - reusable: false + // Don't allow the block to be converted into a reusable block. + reusable: false; } ``` ## spacing -- Type: `Object` -- Default value: null -- Subproperties: - - `padding`: type `boolean`, default value `false` +- Type: `Object` +- Default value: null +- Subproperties: + - `padding`: type `boolean`, default value `false` This value signals that a block supports some of the CSS style properties related to spacing. When it does, the block editor will show UI controls for the user to set their values, if [the theme declares support](/docs/how-to-guides/themes/theme-support.md##cover-block-padding). @@ -340,4 +341,4 @@ supports: { When the block declares support for a specific spacing property, the attributes definition is extended to include the `style` attribute. -- `style`: attribute of `object` type with no default assigned. This is added when `padding` support is declared. It stores the custom values set by the user. +- `style`: attribute of `object` type with no default assigned. This is added when `padding` support is declared. It stores the custom values set by the user. diff --git a/docs/reference-guides/block-api/block-templates.md b/docs/reference-guides/block-api/block-templates.md index b5a01daccd1908..d76c072aa3e20d 100644 --- a/docs/reference-guides/block-api/block-templates.md +++ b/docs/reference-guides/block-api/block-templates.md @@ -4,14 +4,14 @@ A block template is defined as a list of block items. Such blocks can have prede The scope of templates include: -- Setting a default state dynamically on the client. (like `defaultBlock`) -- Registered as a default for a given post type. +- Setting a default state dynamically on the client. (like `defaultBlock`) +- Registered as a default for a given post type. Planned additions: -- Saved and assigned to pages as "page templates". -- Defined in a `template.php` file or pulled from a custom post type (`wp_templates`) that is site specific. -- As the equivalent of the theme hierarchy. +- Saved and assigned to pages as "page templates". +- Defined in a `template.php` file or pulled from a custom post type (`wp_templates`) that is site specific. +- As the equivalent of the theme hierarchy. ## API @@ -50,13 +50,13 @@ registerBlockType( 'myplugin/template', { edit: ( props ) => { return el( InnerBlocks, { template: BLOCKS_TEMPLATE, - templateLock: false - }); + templateLock: false, + } ); }, save: ( props ) => { return el( InnerBlocks.Content, {} ); }, -}); +} ); ``` See the [Meta Block Tutorial](/docs/how-to-guides/metabox/meta-block-5-finishing.md) for a full example of a template in use. @@ -69,7 +69,6 @@ For example, [packages/block-library/src/heading/block.json](https://github.com/ If you don't have the Gutenberg plugin installed, you can find `block.json` files inside `wp-includes/blocks/heading/block.json`. - ## Custom Post types A custom post type can register its own template during registration: @@ -114,10 +113,10 @@ function myplugin_register_template() { add_action( 'init', 'myplugin_register_template' ); ``` -*Options:* +_Options:_ -- `all` — prevents all operations. It is not possible to insert new blocks, move existing blocks, or delete blocks. -- `insert` — prevents inserting or removing blocks, but allows moving existing blocks. +- `all` — prevents all operations. It is not possible to insert new blocks, move existing blocks, or delete blocks. +- `insert` — prevents inserting or removing blocks, but allows moving existing blocks. Lock settings can be inherited by InnerBlocks. If `templateLock` is not set in an InnerBlocks area, the locking of the parent InnerBlocks area is used. If the block is a top level block, the locking configuration of the current post type is used. diff --git a/docs/reference-guides/block-api/block-transforms.md b/docs/reference-guides/block-api/block-transforms.md index 0be77a7c4f52c6..1078608345e526 100644 --- a/docs/reference-guides/block-api/block-transforms.md +++ b/docs/reference-guides/block-api/block-transforms.md @@ -1,4 +1,4 @@ -# Block Transforms +# Transforms Block Transforms is the API that allows a block to be transformed _from_ and _to_ other blocks, as well as _from_ other entities. Existing entities that work with this API include shortcodes, files, regular expressions, and raw DOM nodes. @@ -8,26 +8,30 @@ A block declares which transformations it supports via the optional `transforms` ```js export const settings = { - title: 'My Block Title', - description: 'My block description', - /* ... */ - transforms: { - from: [ /* supported from transforms */ ], - to: [ /* supported to transforms */ ], - } -} + title: 'My Block Title', + description: 'My block description', + /* ... */ + transforms: { + from: [ + /* supported from transforms */ + ], + to: [ + /* supported to transforms */ + ], + }, +}; ``` ## Transformations Types This section goes through the existing types of transformations blocks support: -* block -* enter -* files -* prefix -* raw -* shortcode +- block +- enter +- files +- prefix +- raw +- shortcode ### Block @@ -35,12 +39,12 @@ This type of transformations support both _from_ and _to_ directions, allowing b A transformation of type `block` is an object that takes the following parameters: -- **type** _(string)_: the value `block`. -- **blocks** _(array)_: a list of known block types. It also accepts the wildcard value (`"*"`), meaning that the transform is available to _all_ block types (eg: all blocks can transform into `core/group`). -- **transform** _(function)_: a callback that receives the attributes and inner blocks of the block being processed. It should return a block object or an array of block objects. -- **isMatch** _(function, optional)_: a callback that receives the block attributes and should return a boolean. Returning `false` from this function will prevent the transform from being available and displayed as an option to the user. -- **isMultiBlock** _(boolean, optional)_: whether the transformation can be applied when multiple blocks are selected. If true, the `transform` function's first parameter will be an array containing each selected block's attributes, and the second an array of each selected block's inner blocks. False by default. -- **priority** _(number, optional)_: controls the priority with which a transformation is applied, where a lower value will take precedence over higher values. This behaves much like a [WordPress hook](https://codex.wordpress.org/Plugin_API#Hook_to_WordPress). Like hooks, the default priority is `10` when not otherwise set. +- **type** _(string)_: the value `block`. +- **blocks** _(array)_: a list of known block types. It also accepts the wildcard value (`"*"`), meaning that the transform is available to _all_ block types (eg: all blocks can transform into `core/group`). +- **transform** _(function)_: a callback that receives the attributes and inner blocks of the block being processed. It should return a block object or an array of block objects. +- **isMatch** _(function, optional)_: a callback that receives the block attributes and should return a boolean. Returning `false` from this function will prevent the transform from being available and displayed as an option to the user. +- **isMultiBlock** _(boolean, optional)_: whether the transformation can be applied when multiple blocks are selected. If true, the `transform` function's first parameter will be an array containing each selected block's attributes, and the second an array of each selected block's inner blocks. False by default. +- **priority** _(number, optional)_: controls the priority with which a transformation is applied, where a lower value will take precedence over higher values. This behaves much like a [WordPress hook](https://codex.wordpress.org/Plugin_API#Hook_to_WordPress). Like hooks, the default priority is `10` when not otherwise set. **Example: from Paragraph block to Heading block** @@ -48,6 +52,7 @@ To declare this transformation we add the following code into the heading block {% codetabs %} {% ESNext %} + ```js transforms: { from: [ @@ -63,7 +68,9 @@ transforms: { ] }, ``` + {% ES5 %} + ```js transforms: { from: [ @@ -79,6 +86,7 @@ transforms: { ] }, ``` + {% end %} **Example: blocks that have InnerBlocks** @@ -87,6 +95,7 @@ A block with InnerBlocks can also be transformed from and to another block with {% codetabs %} {% ESNext %} + ```js transforms: { to: [ @@ -104,7 +113,9 @@ transforms: { ], }, ``` + {% ES5 %} + ```js transforms: { to: [ @@ -122,6 +133,7 @@ transforms: { ], }, ``` + {% end %} ### Enter @@ -130,10 +142,10 @@ This type of transformations support the _from_ direction, allowing blocks to be A transformation of type `enter` is an object that takes the following parameters: -- **type** _(string)_: the value `enter`. -- **regExp** _(RegExp)_: the Regular Expression to use as a matcher. If the value matches, the transformation will be applied. -- **transform** _(function)_: a callback that receives the value that has been entered. It should return a block object or an array of block objects. -- **priority** _(number, optional)_: controls the priority with which a transform is applied, where a lower value will take precedence over higher values. This behaves much like a [WordPress hook](https://codex.wordpress.org/Plugin_API#Hook_to_WordPress). Like hooks, the default priority is `10` when not otherwise set. +- **type** _(string)_: the value `enter`. +- **regExp** _(RegExp)_: the Regular Expression to use as a matcher. If the value matches, the transformation will be applied. +- **transform** _(function)_: a callback that receives the value that has been entered. It should return a block object or an array of block objects. +- **priority** _(number, optional)_: controls the priority with which a transform is applied, where a lower value will take precedence over higher values. This behaves much like a [WordPress hook](https://codex.wordpress.org/Plugin_API#Hook_to_WordPress). Like hooks, the default priority is `10` when not otherwise set. **Example: from --- to Separator block** @@ -141,31 +153,35 @@ To create a separator block when the user types the hypen three times and then h {% codetabs %} {% ESNext %} + ```js transforms = { - from: [ - { - type: 'enter', - regExp: /^-{3,}$/, - transform: () => createBlock( 'core/separator' ), - }, - ] -} + from: [ + { + type: 'enter', + regExp: /^-{3,}$/, + transform: () => createBlock( 'core/separator' ), + }, + ], +}; ``` + {% ES5 %} + ```js transforms = { - from: [ - { - type: 'enter', - regExp: /^-{3,}$/, - transform: function( value ) { - return createBlock( 'core/separator' ); - }, - }, - ] -} + from: [ + { + type: 'enter', + regExp: /^-{3,}$/, + transform: function ( value ) { + return createBlock( 'core/separator' ); + }, + }, + ], +}; ``` + {% end %} ### Files @@ -174,10 +190,10 @@ This type of transformations support the _from_ direction, allowing blocks to be A transformation of type `files` is an object that takes the following parameters: -- **type** _(string)_: the value `files`. -- **transform** _(function)_: a callback that receives the array of files being processed. It should return a block object or an array of block objects. -- **isMatch** _(function, optional)_: a callback that receives the array of files being processed and should return a boolean. Returning `false` from this function will prevent the transform from being applied. -- **priority** _(number, optional)_: controls the priority with which a transform is applied, where a lower value will take precedence over higher values. This behaves much like a [WordPress hook](https://codex.wordpress.org/Plugin_API#Hook_to_WordPress). Like hooks, the default priority is `10` when not otherwise set. +- **type** _(string)_: the value `files`. +- **transform** _(function)_: a callback that receives the array of files being processed. It should return a block object or an array of block objects. +- **isMatch** _(function, optional)_: a callback that receives the array of files being processed and should return a boolean. Returning `false` from this function will prevent the transform from being applied. +- **priority** _(number, optional)_: controls the priority with which a transform is applied, where a lower value will take precedence over higher values. This behaves much like a [WordPress hook](https://codex.wordpress.org/Plugin_API#Hook_to_WordPress). Like hooks, the default priority is `10` when not otherwise set. **Example: from file to File block** @@ -185,57 +201,61 @@ To create a File block when the user drops a file into the editor we can use the {% codetabs %} {% ESNext %} + ```js transforms: { - from: [ - { - type: 'files', - isMatch: ( files ) => files.length === 1, - // By defining a lower priority than the default of 10, - // we make that the File block to be created as a fallback, - // if no other transform is found. - priority: 15, - transform: ( files ) => { - const file = files[ 0 ]; - const blobURL = createBlobURL( file ); - // File will be uploaded in componentDidMount() - return createBlock( 'core/file', { - href: blobURL, - fileName: file.name, - textLinkHref: blobURL, - } ); - }, - }, - ]; + from: [ + { + type: 'files', + isMatch: ( files ) => files.length === 1, + // By defining a lower priority than the default of 10, + // we make that the File block to be created as a fallback, + // if no other transform is found. + priority: 15, + transform: ( files ) => { + const file = files[ 0 ]; + const blobURL = createBlobURL( file ); + // File will be uploaded in componentDidMount() + return createBlock( 'core/file', { + href: blobURL, + fileName: file.name, + textLinkHref: blobURL, + } ); + }, + }, + ]; } ``` + {% ES5 %} + ```js transforms: { - from: [ - { - type: 'files', - isMatch: function( files ) { - return files.length === 1; - }, - // By defining a lower priority than the default of 10, - // we make that the File block to be created as a fallback, - // if no other transform is found. - priority: 15, - transform: function( files ) { - var file = files[ 0 ]; - var blobURL = createBlobURL( file ); - // File will be uploaded in componentDidMount() - return createBlock( 'core/file', { - href: blobURL, - fileName: file.name, - textLinkHref: blobURL, - } ); - }, - }, - ]; + from: [ + { + type: 'files', + isMatch: function ( files ) { + return files.length === 1; + }, + // By defining a lower priority than the default of 10, + // we make that the File block to be created as a fallback, + // if no other transform is found. + priority: 15, + transform: function ( files ) { + var file = files[ 0 ]; + var blobURL = createBlobURL( file ); + // File will be uploaded in componentDidMount() + return createBlock( 'core/file', { + href: blobURL, + fileName: file.name, + textLinkHref: blobURL, + } ); + }, + }, + ]; } ``` + {% end %} ### Prefix @@ -244,10 +264,10 @@ This type of transformations support the _from_ direction, allowing blocks to be A transformation of type `prefix` is an object that takes the following parameters: -- **type** _(string)_: the value `files`. -- **prefix** _(string)_: the character or sequence of characters that match this transfrom. -- **transform** _(function)_: a callback that receives the content introduced. It should return a block object or an array of block objects. -- **priority** _(number, optional)_: controls the priority with which a transform is applied, where a lower value will take precedence over higher values. This behaves much like a [WordPress hook](https://codex.wordpress.org/Plugin_API#Hook_to_WordPress). Like hooks, the default priority is `10` when not otherwise set. +- **type** _(string)_: the value `files`. +- **prefix** _(string)_: the character or sequence of characters that match this transfrom. +- **transform** _(function)_: a callback that receives the content introduced. It should return a block object or an array of block objects. +- **priority** _(number, optional)_: controls the priority with which a transform is applied, where a lower value will take precedence over higher values. This behaves much like a [WordPress hook](https://codex.wordpress.org/Plugin_API#Hook_to_WordPress). Like hooks, the default priority is `10` when not otherwise set. **Example: from text to custom block** @@ -255,37 +275,41 @@ If we want to create a custom block when the user types the question mark, we co {% codetabs %} {% ESNext %} + ```js transforms: { - from: [ - { - type: 'prefix', - prefix: '?', - transform( content ) { - return createBlock( 'my-plugin/question', { - content, - } ); - }, - }, - ]; + from: [ + { + type: 'prefix', + prefix: '?', + transform( content ) { + return createBlock( 'my-plugin/question', { + content, + } ); + }, + }, + ]; } ``` + {% ES5 %} + ```js transforms: { - from: [ - { - type: 'prefix', - prefix: '?', - transform: function( content ) { - return createBlock( 'my-plugin/question', { - content, - } ); - }, - }, - ]; + from: [ + { + type: 'prefix', + prefix: '?', + transform: function ( content ) { + return createBlock( 'my-plugin/question', { + content, + } ); + }, + }, + ]; } ``` + {% end %} ### Raw @@ -294,12 +318,12 @@ This type of transformations support the _from_ direction, allowing blocks to be A transformation of type `raw` is an object that takes the following parameters: -- **type** _(string)_: the value `raw`. -- **transform** _(function, optional)_: a callback that receives the node being processed. It should return a block object or an array of block objects. -- **schema** _(object|function, optional)_: it defines the attributes and children of the node that will be preserved on paste, according to its [HTML content model](https://html.spec.whatwg.org/multipage/dom.html#content-models). Take a look at [pasteHandler](/packages/blocks/README.md#pasteHandler) for more info. -- **selector** _(string, optional)_: a CSS selector string to determine whether the element matches according to the [element.matches](https://developer.mozilla.org/en-US/docs/Web/API/Element/matches) method. The transform won't be executed if the element doesn't match. This is a shorthand and alternative to using `isMatch`, which, if present, will take precedence. -- **isMatch** _(function, optional)_: a callback that receives the node being processed and should return a boolean. Returning `false` from this function will prevent the transform from being applied. -- **priority** _(number, optional)_: controls the priority with which a transform is applied, where a lower value will take precedence over higher values. This behaves much like a [WordPress hook](https://codex.wordpress.org/Plugin_API#Hook_to_WordPress). Like hooks, the default priority is `10` when not otherwise set. +- **type** _(string)_: the value `raw`. +- **transform** _(function, optional)_: a callback that receives the node being processed. It should return a block object or an array of block objects. +- **schema** _(object|function, optional)_: it defines the attributes and children of the node that will be preserved on paste, according to its [HTML content model](https://html.spec.whatwg.org/multipage/dom.html#content-models). Take a look at [pasteHandler](/packages/blocks/README.md#pasteHandler) for more info. +- **selector** _(string, optional)_: a CSS selector string to determine whether the element matches according to the [element.matches](https://developer.mozilla.org/en-US/docs/Web/API/Element/matches) method. The transform won't be executed if the element doesn't match. This is a shorthand and alternative to using `isMatch`, which, if present, will take precedence. +- **isMatch** _(function, optional)_: a callback that receives the node being processed and should return a boolean. Returning `false` from this function will prevent the transform from being applied. +- **priority** _(number, optional)_: controls the priority with which a transform is applied, where a lower value will take precedence over higher values. This behaves much like a [WordPress hook](https://codex.wordpress.org/Plugin_API#Hook_to_WordPress). Like hooks, the default priority is `10` when not otherwise set. **Example: from URLs to Embed block** @@ -307,6 +331,7 @@ If we want to create an Embed block when the user pastes some URL in the editor, {% codetabs %} {% ESNext %} + ```js transforms: { from: [ @@ -324,7 +349,9 @@ transforms: { ], } ``` + {% ES5 %} + ```js transforms: { from: [ @@ -343,6 +370,7 @@ transforms: { ], } ``` + {% end %} ### Shortcode @@ -351,11 +379,11 @@ This type of transformations support the _from_ direction, allowing blocks to be A transformation of type `shortcode` is an object that takes the following parameters: -- **type** _(string)_: the value `shortcode`. -- **tag** _(string|array)_: the shortcode tag or list of shortcode aliases this transform can work with. -- **attributes** _(object)_: object representing where the block attributes should be sourced from, according to the attributes shape defined by the [block configuration object](./block-registration.md). If a particular attribute contains a `shortcode` key, it should be a function that receives the shortcode attributes as the first arguments and the [WPShortcodeMatch](/packages/shortcode/README.md#next) as second, and returns a value for the attribute that will be sourced in the block's comment. -- **isMatch** _(function, optional)_: a callback that receives the shortcode attributes per the [Shortcode API](https://codex.wordpress.org/Shortcode_API) and should return a boolean. Returning `false` from this function will prevent the shortcode to be transformed into this block. -- **priority** _(number, optional)_: controls the priority with which a transform is applied, where a lower value will take precedence over higher values. This behaves much like a [WordPress hook](https://codex.wordpress.org/Plugin_API#Hook_to_WordPress). Like hooks, the default priority is `10` when not otherwise set. +- **type** _(string)_: the value `shortcode`. +- **tag** _(string|array)_: the shortcode tag or list of shortcode aliases this transform can work with. +- **attributes** _(object)_: object representing where the block attributes should be sourced from, according to the attributes shape defined by the [block configuration object](./block-registration.md). If a particular attribute contains a `shortcode` key, it should be a function that receives the shortcode attributes as the first arguments and the [WPShortcodeMatch](/packages/shortcode/README.md#next) as second, and returns a value for the attribute that will be sourced in the block's comment. +- **isMatch** _(function, optional)_: a callback that receives the shortcode attributes per the [Shortcode API](https://codex.wordpress.org/Shortcode_API) and should return a boolean. Returning `false` from this function will prevent the shortcode to be transformed into this block. +- **priority** _(number, optional)_: controls the priority with which a transform is applied, where a lower value will take precedence over higher values. This behaves much like a [WordPress hook](https://codex.wordpress.org/Plugin_API#Hook_to_WordPress). Like hooks, the default priority is `10` when not otherwise set. **Example: from shortcode to block** @@ -363,6 +391,7 @@ An existing shortcode can be transformed into its block counterpart. {% codetabs %} {% ESNext %} + ```js transforms: { from: [ @@ -396,7 +425,9 @@ transforms: { ] }, ``` + {% ES5 %} + ```js transforms: { from: [ @@ -431,4 +462,5 @@ transforms: { ] }, ``` + {% end %} diff --git a/docs/reference-guides/block-api/block-variations.md b/docs/reference-guides/block-api/block-variations.md index b7b82140dedf9a..262d6b4af978d7 100644 --- a/docs/reference-guides/block-api/block-variations.md +++ b/docs/reference-guides/block-api/block-variations.md @@ -1,4 +1,4 @@ -# Block Variations +# Variations Block Variations is the API that allows a block to have similar versions of it, but all these versions share some common functionality. Each block variation is differentiated from the others by setting some initial attributes or inner blocks. Then at the time when a block is inserted these attributes and/or inner blocks are applied. @@ -50,9 +50,9 @@ An object describing a variation defined for the block type can contain the foll - `keywords` (optional, type `string[]`) - An array of terms (which can be translated) that help users discover the variation while searching. - `isActive` (optional, type `Function`) - A function that accepts a block's attributes and the variation's attributes and determines if a variation is active. This function doesn't try to find a match dynamically based on all block's attributes, as in many cases some attributes are irrelevant. An example would be for `embed` block where we only care about `providerNameSlug` attribute's value. -The main difference between style variations and block variations is that a style variation just applies a `css class` to the block, so it can be styled in an alternative way. If we want to apply initial attributes or inner blocks, we fall in block variation territory. +The main difference between block styles and block variations is that a block style just applies a CSS class to the block, so it can be styled in an alternative way. If we want to apply initial attributes or inner blocks, we fall in block variation territory. -It's also possible to override the default block style variation using the `className` attribute when defining block variations. +It's also possible to override the default block style using the `className` attribute when defining block variations. ```js variations: [ @@ -70,7 +70,6 @@ variations: [ It's worth mentioning that setting the `isActive` property can be useful for cases you want to use information from the block variation, after a block's creation. For example, this API is used in `useBlockDisplayInformation` hook to fetch and display proper information on places like the `BlockCard` or `Breadcrumbs` components. - Block variations can be declared during a block's registration by providing the `variations` key with a proper array of variations, as defined above. In addition, there are ways to register and unregister a `block variation` for a block, after its registration. To add a block variation use `wp.blocks.registerBlockVariation()`. @@ -80,11 +79,10 @@ _Example:_ ```js wp.blocks.registerBlockVariation( 'core/embed', { name: 'custom', - attributes: { providerNameSlug: 'custom' } + attributes: { providerNameSlug: 'custom' }, } ); ``` - To remove a block variation use `wp.blocks.unregisterBlockVariation()`. _Example:_ diff --git a/docs/reference-guides/block-api/versions.md b/docs/reference-guides/block-api/versions.md deleted file mode 100644 index cd78b5873dba66..00000000000000 --- a/docs/reference-guides/block-api/versions.md +++ /dev/null @@ -1,12 +0,0 @@ -# Block API Versions - -This document lists the changes made between the different API versions. - -## Version 2 (>= WordPress 5.6) - -- To render the block element wrapper for the block's `edit` implementation, the block author must use the `useBlockProps()` hook. -- The generated class names and styles are no longer added automatically to the saved markup for static blocks when `save` is processed. To include them, the block author must explicitly use `useBlockProps.save()` and add to their block wrapper. - -## Version 1 - -Initial version. \ No newline at end of file diff --git a/docs/reference-guides/data/README.md b/docs/reference-guides/data/README.md index d03590a09dcc85..0b191107fd7763 100644 --- a/docs/reference-guides/data/README.md +++ b/docs/reference-guides/data/README.md @@ -1,11 +1,11 @@ # Data Module Reference - - [**core**: WordPress Core Data](/docs/reference-guides/data/data-core.md) - - [**core/annotations**: Annotations](/docs/reference-guides/data/data-core-annotations.md) - - [**core/blocks**: Block Types Data](/docs/reference-guides/data/data-core-blocks.md) - - [**core/block-editor**: The Block Editor’s Data](/docs/reference-guides/data/data-core-block-editor.md) - - [**core/editor**: The Post Editor’s Data](/docs/reference-guides/data/data-core-editor.md) - - [**core/edit-post**: The Editor’s UI Data](/docs/reference-guides/data/data-core-edit-post.md) - - [**core/notices**: Notices Data](/docs/reference-guides/data/data-core-notices.md) - - [**core/nux**: The NUX (New User Experience) Data](/docs/reference-guides/data/data-core-nux.md) - - [**core/viewport**: The Viewport Data](/docs/reference-guides/data/data-core-viewport.md) \ No newline at end of file +- [**core**: WordPress Core Data](/docs/reference-guides/data/data-core.md) +- [**core/annotations**: Annotations](/docs/reference-guides/data/data-core-annotations.md) +- [**core/blocks**: Block Types Data](/docs/reference-guides/data/data-core-blocks.md) +- [**core/block-editor**: The Block Editor’s Data](/docs/reference-guides/data/data-core-block-editor.md) +- [**core/editor**: The Post Editor’s Data](/docs/reference-guides/data/data-core-editor.md) +- [**core/edit-post**: The Editor’s UI Data](/docs/reference-guides/data/data-core-edit-post.md) +- [**core/notices**: Notices Data](/docs/reference-guides/data/data-core-notices.md) +- [**core/nux**: The NUX (New User Experience) Data](/docs/reference-guides/data/data-core-nux.md) +- [**core/viewport**: The Viewport Data](/docs/reference-guides/data/data-core-viewport.md) diff --git a/docs/reference-guides/data/data-core-annotations.md b/docs/reference-guides/data/data-core-annotations.md index 0b5840c617d1e4..7b347df85a7f51 100644 --- a/docs/reference-guides/data/data-core-annotations.md +++ b/docs/reference-guides/data/data-core-annotations.md @@ -16,5 +16,4 @@ Nothing to document. Nothing to document. - diff --git a/docs/reference-guides/data/data-core-block-editor.md b/docs/reference-guides/data/data-core-block-editor.md index f7bd0bc226c674..bf14e516719958 100644 --- a/docs/reference-guides/data/data-core-block-editor.md +++ b/docs/reference-guides/data/data-core-block-editor.md @@ -162,10 +162,10 @@ _Returns_ Returns the insertion point. This will be: -1) The insertion point manually set using setInsertionPoint() or +1. The insertion point manually set using setInsertionPoint() or showInsertionPoint(); or -2) The point after the current block selection, if there is a selection; or -3) The point at the end of the block list. +2. The point after the current block selection, if there is a selection; or +3. The point at the end of the block list. Components like will default to inserting blocks at this point. @@ -711,7 +711,7 @@ Returns the defined block template _Parameters_ -- _state_ `boolean`: +- _state_ `boolean`: _Returns_ @@ -1034,7 +1034,7 @@ Returns whether the blocks matches the template or not. _Parameters_ -- _state_ `boolean`: +- _state_ `boolean`: _Returns_ @@ -1060,8 +1060,8 @@ Generator that triggers an action used to duplicate a list of blocks. _Parameters_ -- _clientIds_ `string[]`: -- _updateSelection_ `boolean`: +- _clientIds_ `string[]`: +- _updateSelection_ `boolean`: # **enterFormattedText** @@ -1102,7 +1102,7 @@ Generator used to insert an empty block before a given block. _Parameters_ -- _clientId_ `string`: +- _clientId_ `string`: # **insertBeforeBlock** @@ -1110,7 +1110,7 @@ Generator used to insert an empty block after a given block. _Parameters_ -- _clientId_ `string`: +- _clientId_ `string`: # **insertBlock** @@ -1138,7 +1138,7 @@ _Parameters_ - _blocks_ `Object[]`: Block objects to insert. - _index_ `?number`: Index at which block should be inserted. - _rootClientId_ `?string`: Optional root client ID of block list on which to insert. -- _updateSelection_ `?boolean`: If true block selection will be updated. If false, block selection will not change. Defaults to true. +- _updateSelection_ `?boolean`: If true block selection will be updated. If false, block selection will not change. Defaults to true. - _initialPosition_ `0|-1|null`: Initial focus position. Setting it to null prevent focusing the inserted block. - _meta_ `?Object`: Optional Meta values to be passed to the action object. @@ -1578,5 +1578,4 @@ _Parameters_ - _blocks_ `Array`: Array of blocks. - diff --git a/docs/reference-guides/data/data-core-blocks.md b/docs/reference-guides/data/data-core-blocks.md index 2e8c236bbf13a9..64949ca0f7b9e4 100644 --- a/docs/reference-guides/data/data-core-blocks.md +++ b/docs/reference-guides/data/data-core-blocks.md @@ -416,5 +416,4 @@ _Returns_ - `Object`: Action object. - diff --git a/docs/reference-guides/data/data-core-edit-post.md b/docs/reference-guides/data/data-core-edit-post.md index 63e1f1ba6b69f0..b238dbe264fc40 100644 --- a/docs/reference-guides/data/data-core-edit-post.md +++ b/docs/reference-guides/data/data-core-edit-post.md @@ -503,5 +503,4 @@ _Returns_ - `Object`: Action object. - diff --git a/docs/reference-guides/data/data-core-editor.md b/docs/reference-guides/data/data-core-editor.md index 4fbce4a3c1b932..87a14b0b1482f8 100644 --- a/docs/reference-guides/data/data-core-editor.md +++ b/docs/reference-guides/data/data-core-editor.md @@ -367,7 +367,7 @@ Return the current block list. _Parameters_ -- _state_ `Object`: +- _state_ `Object`: _Returns_ @@ -379,7 +379,7 @@ Returns the current selection. _Parameters_ -- _state_ `Object`: +- _state_ `Object`: _Returns_ @@ -393,7 +393,7 @@ Returns the current selection end. _Parameters_ -- _state_ `Object`: +- _state_ `Object`: _Returns_ @@ -407,7 +407,7 @@ Returns the current selection start. _Parameters_ -- _state_ `Object`: +- _state_ `Object`: _Returns_ @@ -1070,7 +1070,7 @@ _Related_ # **autosave** -Action generator used in signalling that the post should autosave. This +Action generator used in signalling that the post should autosave. This includes server-side autosaving (default) and client-side (a.k.a. local) autosaving (e.g. on the Web, the post might be committed to Session Storage). @@ -1340,7 +1340,7 @@ Action generator for saving the current post in the editor. _Parameters_ -- _options_ `Object`: +- _options_ `Object`: # **selectBlock** @@ -1513,5 +1513,4 @@ _Returns_ - `Object`: Action object. - diff --git a/docs/reference-guides/data/data-core-keyboard-shortcuts.md b/docs/reference-guides/data/data-core-keyboard-shortcuts.md index 9211b1c4808370..044bd248ecb12a 100644 --- a/docs/reference-guides/data/data-core-keyboard-shortcuts.md +++ b/docs/reference-guides/data/data-core-keyboard-shortcuts.md @@ -115,5 +115,4 @@ _Returns_ - `Object`: action. - diff --git a/docs/reference-guides/data/data-core-notices.md b/docs/reference-guides/data/data-core-notices.md index 87066f5e0f4c37..5e2675afeb447a 100644 --- a/docs/reference-guides/data/data-core-notices.md +++ b/docs/reference-guides/data/data-core-notices.md @@ -134,5 +134,4 @@ _Returns_ - `Object`: Action object. - diff --git a/docs/reference-guides/data/data-core-nux.md b/docs/reference-guides/data/data-core-nux.md index 2abad5d1f52775..3f65bbc359c8a2 100644 --- a/docs/reference-guides/data/data-core-nux.md +++ b/docs/reference-guides/data/data-core-nux.md @@ -96,5 +96,4 @@ _Returns_ - `Object`: Action object. - diff --git a/docs/reference-guides/data/data-core-viewport.md b/docs/reference-guides/data/data-core-viewport.md index 4f776c53efbca7..c84524dc9b2f48 100644 --- a/docs/reference-guides/data/data-core-viewport.md +++ b/docs/reference-guides/data/data-core-viewport.md @@ -46,5 +46,4 @@ _Returns_ - `Object`: Action object. - diff --git a/docs/reference-guides/data/data-core.md b/docs/reference-guides/data/data-core.md index 4f9f16e4eab8a9..c2545d9645e242 100644 --- a/docs/reference-guides/data/data-core.md +++ b/docs/reference-guides/data/data-core.md @@ -706,5 +706,4 @@ _Parameters_ Action triggered to undo the last edit to an entity record, if any. - diff --git a/docs/reference-guides/filters/autocomplete-filters.md b/docs/reference-guides/filters/autocomplete-filters.md index 584e2019a1d178..e832335d365d88 100644 --- a/docs/reference-guides/filters/autocomplete-filters.md +++ b/docs/reference-guides/filters/autocomplete-filters.md @@ -10,6 +10,7 @@ Here is an example of using the `editor.Autocomplete.completers` filter to add a {% codetabs %} {% ESNext %} + ```jsx // Our completer const acronymCompleter = { @@ -44,7 +45,9 @@ wp.hooks.addFilter( appendAcronymCompleter ); ``` + {% ES5 %} + ```js // Our completer var acronymCompleter = { @@ -55,14 +58,14 @@ var acronymCompleter = { { letters: 'AFAIK', expansion: 'As Far As I Know' }, { letters: 'IIRC', expansion: 'If I Recall Correctly' }, ], - getOptionKeywords: function( abbr ) { + getOptionKeywords: function ( abbr ) { var expansionWords = abbr.expansion.split( /\s+/ ); return [ abbr.letters ].concat( expansionWords ); }, - getOptionLabel: function( acronym ) { + getOptionLabel: function ( acronym ) { return acronym.letters; }, - getOptionCompletion: function( abbr ) { + getOptionCompletion: function ( abbr ) { return wp.element.createElement( 'abbr', { title: abbr.expansion }, @@ -73,9 +76,9 @@ var acronymCompleter = { // Our filter function function appendAcronymCompleter( completers, blockName ) { - return blockName === 'my-plugin/foo' ? - completers.concat( acronymCompleter ) : - completers; + return blockName === 'my-plugin/foo' + ? completers.concat( acronymCompleter ) + : completers; } // Adding the filter @@ -85,4 +88,5 @@ wp.hooks.addFilter( appendAcronymCompleter ); ``` + {% end %} diff --git a/docs/reference-guides/filters/block-filters.md b/docs/reference-guides/filters/block-filters.md index 963f7937734c16..632ade0b36051c 100644 --- a/docs/reference-guides/filters/block-filters.md +++ b/docs/reference-guides/filters/block-filters.md @@ -2,24 +2,24 @@ To modify the behavior of existing blocks, WordPress exposes several APIs: -### Block Style Variations +### Block Styles -Block Style Variations allow providing alternative styles to existing blocks. They work by adding a className to the block's wrapper. This className can be used to provide an alternative styling for the block if the style variation is selected. See the [Getting Started with JavaScript tutorial](/docs/how-to-guides/javascript/) for a full example. +Block Styles allow providing alternative styles to existing blocks. They work by adding a className to the block's wrapper. This className can be used to provide an alternative styling for the block if the block style is selected. See the [Getting Started with JavaScript tutorial](/docs/how-to-guides/javascript/) for a full example. _Example:_ ```js wp.blocks.registerBlockStyle( 'core/quote', { name: 'fancy-quote', - label: 'Fancy Quote' + label: 'Fancy Quote', } ); ``` -The example above registers a block style variation named `fancy-quote` to the `core/quote` block. When the user selects this block style variation from the styles selector, an `is-style-fancy-quote` className will be added to the block's wrapper. +The example above registers a block style named `fancy-quote` to the `core/quote` block. When the user selects this block style from the styles selector, an `is-style-fancy-quote` className will be added to the block's wrapper. -By adding `isDefault: true` you can mark the registered style variation as the one that is recognized as active when no custom class name is provided. It also means that there will be no custom class name added to the HTML output for the style that is marked as default. +By adding `isDefault: true` you can mark the registered block style as the one that is recognized as active when no custom class name is provided. It also means that there will be no custom class name added to the HTML output for the style that is marked as default. -To remove a block style variation use `wp.blocks.unregisterBlockStyle()`. +To remove a block style use `wp.blocks.unregisterBlockStyle()`. _Example:_ @@ -27,7 +27,7 @@ _Example:_ wp.blocks.unregisterBlockStyle( 'core/quote', 'large' ); ``` -The above removes the variation named `large` from the `core/quote` block. +The above removes the block style named `large` from the `core/quote` block. **Important:** When unregistering a block style, there can be a [race condition](https://en.wikipedia.org/wiki/Race_condition) on which code runs first: registering the style, or unregistering the style. You want your unregister code to run last. The way to do that is specify the component that is registering the style as a dependency, in this case `wp-edit-post`. Additionally, using `wp.domReady()` ensures the unregister code runs once the dom is loaded. @@ -48,7 +48,7 @@ add_action( 'enqueue_block_editor_assets', 'myguten_enqueue' ); The JavaScript code in `myguten.js`: ```js -wp.domReady( function() { +wp.domReady( function () { wp.blocks.unregisterBlockStyle( 'core/quote', 'large' ); } ); ``` @@ -64,13 +64,16 @@ To simplify the process of registering and unregistering block styles, two serve The `register_block_style` function receives the name of the block as the first argument and an array describing properties of the style as the second argument. The properties of the style array must include `name` and `label`: - - `name`: The identifier of the style used to compute a CSS class. - - `label`: A human-readable label for the style. -Besides the two mandatory properties, the styles properties array should also include an `inline_style` or a `style_handle` property: +- `name`: The identifier of the style used to compute a CSS class. +- `label`: A human-readable label for the style. - - `inline_style`: Contains inline CSS code that registers the CSS class required for the style. - - `style_handle`: Contains the handle to an already registered style that should be enqueued in places where block styles are needed. +Besides the two mandatory properties, the styles properties array should also include an `inline_style` or a `style_handle` property: + +- `inline_style`: Contains inline CSS code that registers the CSS class required for the style. +- `style_handle`: Contains the handle to an already registered style that should be enqueued in places where block styles are needed. + +It is also possible to set the `is_default` property to `true` to mark one of the block styles as the default one. The following code sample registers a style for the quote block named "Blue Quote", and provides an inline style that makes quote blocks with the "Blue Quote" style have blue color: @@ -85,7 +88,7 @@ register_block_style( ); ``` -Alternatively, if a stylesheet was already registered which contains the CSS for the style variation, it is possible to just pass the stylesheet's handle so `register_block_style` function will make sure it is enqueue. +Alternatively, if a stylesheet was already registered which contains the CSS for the block style, it is possible to just pass the stylesheet's handle so `register_block_style` function will make sure it is enqueue. The following code sample provides an example of this use case: @@ -110,7 +113,7 @@ register_block_style( The function's first argument is the registered name of the block, and the name of the style as the second argument. -The following code sample unregisters the style named 'fancy-quote' from the quote block: +The following code sample unregisters the style named 'fancy-quote' from the quote block: ```php unregister_block_style( 'core/quote', 'fancy-quote' ); @@ -138,7 +141,7 @@ function addListBlockClassName( settings, name ) { return lodash.assign( {}, settings, { supports: lodash.assign( {}, settings.supports, { - className: true + className: true, } ), } ); } @@ -178,12 +181,10 @@ wp.hooks.addFilter( ); ``` -_Note:_ A [block validation](/docs/reference-guides/block-api/block-edit-save.md#validation) error will occur if this filter modifies existing content the next time the post is edited. The editor verifies that the content stored in the post matches the content output by the `save()` function. +_Note:_ A [block validation](/docs/reference-guides/block-api/block-edit-save.md#validation) error will occur if this filter modifies existing content the next time the post is edited. The editor verifies that the content stored in the post matches the content output by the `save()` function. To avoid this validation error, use `render_block` server-side to modify existing post content instead of this filter. See [render_block documentation](https://developer.wordpress.org/reference/hooks/render_block/). - - #### `blocks.getBlockDefaultClassName` Generated HTML classes for blocks follow the `wp-block-{name}` nomenclature. This filter allows to provide an alternative class name. @@ -193,9 +194,7 @@ _Example:_ ```js // Our filter function function setBlockCustomClassName( className, blockName ) { - return blockName === 'core/code' ? - 'my-plugin-code' : - className; + return blockName === 'core/code' ? 'my-plugin-code' : className; } // Adding the filter @@ -222,57 +221,63 @@ _Example:_ {% codetabs %} {% ESNext %} + ```js const { createHigherOrderComponent } = wp.compose; const { Fragment } = wp.element; const { InspectorControls } = wp.blockEditor; const { PanelBody } = wp.components; -const withInspectorControls = createHigherOrderComponent( ( BlockEdit ) => { +const withInspectorControls = createHigherOrderComponent( ( BlockEdit ) => { return ( props ) => { return ( - - My custom control - + My custom control ); }; -}, "withInspectorControl" ); +}, 'withInspectorControl' ); -wp.hooks.addFilter( 'editor.BlockEdit', 'my-plugin/with-inspector-controls', withInspectorControls ); +wp.hooks.addFilter( + 'editor.BlockEdit', + 'my-plugin/with-inspector-controls', + withInspectorControls +); ``` + {% ES5 %} + ```js var el = wp.element.createElement; -var withInspectorControls = wp.compose.createHigherOrderComponent( function( BlockEdit ) { - return function( props ) { +var withInspectorControls = wp.compose.createHigherOrderComponent( function ( + BlockEdit +) { + return function ( props ) { return el( wp.element.Fragment, {}, - el( - BlockEdit, - props - ), + el( BlockEdit, props ), el( wp.blockEditor.InspectorControls, {}, - el( - wp.components.PanelBody, - {}, - 'My custom control' - ) + el( wp.components.PanelBody, {}, 'My custom control' ) ) ); }; -}, 'withInspectorControls' ); +}, +'withInspectorControls' ); -wp.hooks.addFilter( 'editor.BlockEdit', 'my-plugin/with-inspector-controls', withInspectorControls ); +wp.hooks.addFilter( + 'editor.BlockEdit', + 'my-plugin/with-inspector-controls', + withInspectorControls +); ``` + {% end %} #### `editor.BlockListBlock` @@ -283,45 +288,61 @@ _Example:_ {% codetabs %} {% ESNext %} + ```js const { createHigherOrderComponent } = wp.compose; -const withClientIdClassName = createHigherOrderComponent( ( BlockListBlock ) => { - return ( props ) => { - return ; - }; -}, 'withClientIdClassName' ); +const withClientIdClassName = createHigherOrderComponent( + ( BlockListBlock ) => { + return ( props ) => { + return ( + + ); + }; + }, + 'withClientIdClassName' +); -wp.hooks.addFilter( 'editor.BlockListBlock', 'my-plugin/with-client-id-class-name', withClientIdClassName ); +wp.hooks.addFilter( + 'editor.BlockListBlock', + 'my-plugin/with-client-id-class-name', + withClientIdClassName +); ``` + {% ES5 %} + ```js var el = wp.element.createElement; -var withClientIdClassName = wp.compose.createHigherOrderComponent( function( BlockListBlock ) { - return function( props ) { - var newProps = lodash.assign( - {}, - props, - { - className: "block-" + props.clientId, - } - ); +var withClientIdClassName = wp.compose.createHigherOrderComponent( function ( + BlockListBlock +) { + return function ( props ) { + var newProps = lodash.assign( {}, props, { + className: 'block-' + props.clientId, + } ); - return el( - BlockListBlock, - newProps - ); + return el( BlockListBlock, newProps ); }; -}, 'withClientIdClassName' ); +}, +'withClientIdClassName' ); -wp.hooks.addFilter( 'editor.BlockListBlock', 'my-plugin/with-client-id-class-name', withClientIdClassName ); +wp.hooks.addFilter( + 'editor.BlockListBlock', + 'my-plugin/with-client-id-class-name', + withClientIdClassName +); ``` + {% end %} #### `media.crossOrigin` -Used to set or modify the `crossOrigin` attribute for foreign-origin media elements (i.e ``, `