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 12a2176511cbe2..6e7143b3c561e3 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -4,21 +4,21 @@ **License for Contributions (on and after April 15, 2021)** -All code contributed to the Gutenberg project is dual-licensed, -and released under both of the following licenses: +All code contributed to the Gutenberg project is dual-licensed, +and released under both of the following licenses: -the GNU General Public License as published by the Free Software Foundation; +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”). +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 +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”). +later version (the “GPL”). This program incorporates work covered by the following copyright and permission notices: @@ -39,8 +39,7 @@ and WordPress is released under the GPL - -### Dual License +### Dual License **We are currently in the process of changing Gutenberg’s software license from GPL to a dual license: GPL and MPL.** @@ -64,14 +63,14 @@ 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: + 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”). --- @@ -181,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 @@ -228,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 @@ -241,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 @@ -446,87 +439,87 @@ 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. +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. +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. +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. +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 +means -* **(a)** that the initial Contributor has attached the notice described +- **(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 +- **(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. +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. +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. +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. +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: +means any of the following: -* **(a)** any file in Source Code Form that results from an addition to, +- **(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 +- **(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. +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. +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. +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. - +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 @@ -535,12 +528,12 @@ License. Each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: -* **(a)** under intellectual property rights (other than patent or trademark) +- **(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 +- **(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. @@ -558,13 +551,13 @@ 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; +- **(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 +- **(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 +- **(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, @@ -595,7 +588,6 @@ equivalents. 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 @@ -612,13 +604,13 @@ Form. If You distribute Covered Software in Executable Form then: -* **(a)** such Covered Software must also be made available in Source Code +- **(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 +- **(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. @@ -657,7 +649,6 @@ 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 @@ -670,7 +661,6 @@ 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 @@ -699,7 +689,6 @@ 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” @@ -732,7 +721,6 @@ prior to termination shall survive termination. > 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 @@ -742,7 +730,6 @@ 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 @@ -752,7 +739,6 @@ 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 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/docs/README.md b/docs/README.md index ab5f7f2a4dc726..7a3486e4099e25 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/how-to-guides/accessibility.md) -- [Internationalization](/docs/how-to-guides/internationalization.md) +- [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/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 bd4ea844529cc1..ba25adcb62c8f0 100644 --- a/docs/contributors/code/getting-started-with-code-contribution.md +++ b/docs/contributors/code/getting-started-with-code-contribution.md @@ -4,21 +4,22 @@ The following guide is for setting up your local environment to contribute to th ## Prerequisites -- 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. +- 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. -- 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 +- 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/). +- [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 @@ -28,12 +29,14 @@ $ 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 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. 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. @@ -69,6 +72,7 @@ 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/ @@ -76,6 +80,7 @@ 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) @@ -92,10 +97,12 @@ Explore the [package documentation](/packages/env/README.md) for additional comm 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 If you run into an issue, check the [troubleshooting section in `wp-env` documentation](/packages/env/README.md#troubleshooting-common-problems). + ### Using Local or MAMP 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. @@ -118,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 @@ -128,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 @@ -191,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 cdf88bf510f943..a7a2d8f4833f2b 100644 --- a/docs/contributors/code/git-workflow.md +++ b/docs/contributors/code/git-workflow.md @@ -5,18 +5,19 @@ This documentation is intended to help you get started using git with Gutenberg. 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. @@ -24,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) @@ -74,17 +73,16 @@ 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 For example, `add/gallery-block` means you're working on adding a new gallery block. @@ -123,7 +121,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/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..2e9740dbb886b6 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. @@ -33,14 +33,14 @@ Help requests or 'how to' questions should be posted in a relevant support forum 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/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. [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..30f8a8814e1790 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 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).) ## 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/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..ae63552573428f 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: @@ -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..6b11393c30e7dd 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 `-`. 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`. @@ -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..e879e132839834 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. @@ -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..e19f1cd094075c 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. @@ -35,10 +35,11 @@ function myguten_block_init() { 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..9ab5b9f658c28a 100644 --- a/docs/how-to-guides/javascript/extending-the-block-editor.md +++ b/docs/how-to-guides/javascript/extending-the-block-editor.md @@ -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..6e65783bf71d64 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 @@ -40,4 +40,3 @@ register_block_type( 'core/paragraph', array( '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..d46ce8ea4ba0a0 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 ; } ``` @@ -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/theme-json.md b/docs/how-to-guides/themes/theme-json.md index 39d61730386f9e..d1f0df50ed148d 100644 --- a/docs/how-to-guides/themes/theme-json.md +++ b/docs/how-to-guides/themes/theme-json.md @@ -464,16 +464,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/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-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..c8c295e2bde412 100644 --- a/docs/reference-guides/block-api/block-context.md +++ b/docs/reference-guides/block-api/block-context.md @@ -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..6cfbfcafa33ecf 100644 --- a/docs/reference-guides/block-api/block-deprecation.md +++ b/docs/reference-guides/block-api/block-deprecation.md @@ -2,8 +2,8 @@ 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-patterns.md b/docs/reference-guides/block-api/block-patterns.md index 2987118a0479e4..5c1fe895515eb2 100644 --- a/docs/reference-guides/block-api/block-patterns.md +++ b/docs/reference-guides/block-api/block-patterns.md @@ -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-supports.md b/docs/reference-guides/block-api/block-supports.md index 5b01f69086bfa1..565b1f0bbbd8e2 100644 --- a/docs/reference-guides/block-api/block-supports.md +++ b/docs/reference-guides/block-api/block-supports.md @@ -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..beab2fae18dcfc 100644 --- a/docs/reference-guides/block-api/block-transforms.md +++ b/docs/reference-guides/block-api/block-transforms.md @@ -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..b4200496f5c0c6 100644 --- a/docs/reference-guides/block-api/block-variations.md +++ b/docs/reference-guides/block-api/block-variations.md @@ -50,7 +50,7 @@ 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 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. It's also possible to override the default block style variation using the `className` attribute when defining block 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 index cd78b5873dba66..18b56f15dd093e 100644 --- a/docs/reference-guides/block-api/versions.md +++ b/docs/reference-guides/block-api/versions.md @@ -4,9 +4,9 @@ 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. +- 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 +Initial version. 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/editor-filters.md b/docs/reference-guides/filters/editor-filters.md index b9701a30b2e24d..8a97569da6148d 100644 --- a/docs/reference-guides/filters/editor-filters.md +++ b/docs/reference-guides/filters/editor-filters.md @@ -9,11 +9,15 @@ Used to modify the image size displayed in the Post Featured Image component. It _Example:_ ```js -var withImageSize = function( size, mediaId, postId ) { +var withImageSize = function ( size, mediaId, postId ) { return 'large'; }; -wp.hooks.addFilter( 'editor.PostFeaturedImage.imageSize', 'my-plugin/with-image-size', withImageSize ); +wp.hooks.addFilter( + 'editor.PostFeaturedImage.imageSize', + 'my-plugin/with-image-size', + withImageSize +); ``` ### `editor.PostPreview.interstitialMarkup` @@ -23,16 +27,21 @@ Filters the interstitial message shown when generating previews. _Example:_ ```js -var customPreviewMessage = function() { - return 'Post preview is being generated!'; +var customPreviewMessage = function () { + return 'Post preview is being generated!'; }; -wp.hooks.addFilter( 'editor.PostPreview.interstitialMarkup', 'my-plugin/custom-preview-message', customPreviewMessage ); +wp.hooks.addFilter( + 'editor.PostPreview.interstitialMarkup', + 'my-plugin/custom-preview-message', + customPreviewMessage +); ``` ## Editor settings ### `block_editor_settings` + This is a PHP filter which is applied before sending settings to the WordPress block editor. You may find details about this filter [on its WordPress Code Reference page](https://developer.wordpress.org/reference/hooks/block_editor_settings/). @@ -42,12 +51,13 @@ The filter will send any setting to the initialized Editor, which means any edit ### Available default editor settings #### `richEditingEnabled` + If it is `true` the user can edit the content using the visual editor. It is set by default to the return value of the [`user_can_richedit`](https://developer.wordpress.org/reference/functions/user_can_richedit/) function. It checks if the user can access the visual editor and whether it’s supported by the user’s browser. - #### `codeEditingEnabled` + Default `true`. Indicates whether the user can access the code editor **in addition** to the visual editor. If set to false the user will not be able to switch between visual and code editor. The option in the settings menu will not be available and the keyboard shortcut for switching editor types will not fire. diff --git a/docs/reference-guides/filters/i18n-filters.md b/docs/reference-guides/filters/i18n-filters.md index 6c9de963517d26..5a1a365de53da2 100644 --- a/docs/reference-guides/filters/i18n-filters.md +++ b/docs/reference-guides/filters/i18n-filters.md @@ -2,10 +2,10 @@ The i18n functions (`__()`, `_x()`, `_n()` and `_nx()`) provide translations of strings for use in your code. The values returned by these functions are filterable if you need to override them, using the following filters: -- `i18n.gettext` -- `i18n.gettext_with_context` -- `i18n.ngettext` -- `i18n.ngettext_with_context` +- `i18n.gettext` +- `i18n.gettext_with_context` +- `i18n.ngettext` +- `i18n.ngettext_with_context` ## Filter Arguments @@ -15,7 +15,7 @@ The filters are passed the following arguments, in line with their PHP equivalen ```jsx function i18nGettextCallback( translation, text, domain ) { - return translation; + return translation; } ``` @@ -23,7 +23,7 @@ function i18nGettextCallback( translation, text, domain ) { ```jsx function i18nGettextWithContextCallback( translation, text, context, domain ) { - return translation; + return translation; } ``` @@ -33,7 +33,7 @@ function i18nGettextWithContextCallback( translation, text, context, domain ) { function i18nNgettextCallback( translation, single, plural, number, domain ) { return translation; } -```` +``` ### i18n.ngettext_with_context @@ -48,7 +48,7 @@ function i18nNgettextWithContextCallback( ) { return translation; } -```` +``` ## Basic Example @@ -65,29 +65,29 @@ function myPluginGettextFilter( translation, text, domain ) { // Adding the filter wp.hooks.addFilter( - 'i18n.gettext', - 'my-plugin/override-add-to-reusable-blocks-label', - myPluginGettextFilter + 'i18n.gettext', + 'my-plugin/override-add-to-reusable-blocks-label', + myPluginGettextFilter ); ``` ## Using 'text domain'-specific filters -Filters that are specific to the text domain you're operating on are generally preferred for performance reasons (since your callback will only be run for strings in the relevant text domain). +Filters that are specific to the text domain you're operating on are generally preferred for performance reasons (since your callback will only be run for strings in the relevant text domain). To attach to a text domain-specific filter append an underscore and the text-domain to the standard filter name. For example, if filtering a string where the text domain is "woocommerce", you would use one of the following filters: -- `i18n.gettext_woocommerce` -- `i18n.gettext_with_context_woocommerce` -- `i18n.ngettext_woocommerce` -- `i18n.ngettext_with_context_woocommerce` +- `i18n.gettext_woocommerce` +- `i18n.gettext_with_context_woocommerce` +- `i18n.ngettext_woocommerce` +- `i18n.ngettext_with_context_woocommerce` For example: ```jsx // Define our filter callback. function myPluginGettextFilter( translation, text, domain ) { - if ( text === "You’ve fulfilled all your orders" ) { + if ( text === 'You’ve fulfilled all your orders' ) { return 'All packed up and ready to go. Good job!'; } return translation; @@ -95,15 +95,15 @@ function myPluginGettextFilter( translation, text, domain ) { // Adding the filter wp.hooks.addFilter( - 'i18n.gettext_woocommerce', - 'my-plugin/override-fulfilled-all-orders-text', - myPluginGettextFilter + 'i18n.gettext_woocommerce', + 'my-plugin/override-fulfilled-all-orders-text', + myPluginGettextFilter ); ``` -*Note*: To apply a filter where the text-domain is `undefined` (for example WordPress core strings), then use the name "default" to construct the filter name. +_Note_: To apply a filter where the text-domain is `undefined` (for example WordPress core strings), then use the name "default" to construct the filter name. -- `i18n.gettext_default` -- `i18n.gettext_with_context_default` -- `i18n.ngettext_default` -- `i18n.ngettext_with_context_default` +- `i18n.gettext_default` +- `i18n.gettext_with_context_default` +- `i18n.ngettext_default` +- `i18n.ngettext_with_context_default` diff --git a/docs/reference-guides/packages.md b/docs/reference-guides/packages.md index fda7d986209efd..aa66d3c0af74da 100644 --- a/docs/reference-guides/packages.md +++ b/docs/reference-guides/packages.md @@ -17,9 +17,9 @@ wp_enqueue_script( ``` After the dependency is declared, you can access the module in your JavaScript code using the global `wp` like so: + ```js const { PlainText } = wp.editor; - ``` ## Using the Packages via npm @@ -35,6 +35,5 @@ npm install @wordpress/block-editor --save Once installed, you can access the component in your code using: ```js -import { PlainText } from '@wordpress/block-editor'; +import { PlainText } from '@wordpress/block-editor'; ``` - diff --git a/docs/reference-guides/richtext.md b/docs/reference-guides/richtext.md index a955eb1f2d8e0d..c34e36ff6b7473 100644 --- a/docs/reference-guides/richtext.md +++ b/docs/reference-guides/richtext.md @@ -4,9 +4,9 @@ RichText is a component that allows developers to render a [`contenteditable` in The RichText component is extremely powerful because it provides built-in functionality you won't find in other components: -* **Consistent Styling in the Admin and Frontend:** The editable container can be set to any block-level element, such as a `div`, `h2` or `p` tag. This allows the styles you apply in style.css to more easily apply on the frontend and admin, without having to rewrite them in editor.css. -* **Cohesive Placeholder Text:** Before the user writes their content, it's easy to include placeholder text that's already styled to match the rest of the block editor. -* **Control Over Formatting Options:** It's possible to dictate exactly which formatting options you want to allow for the RichText field. For example, you can dictate whether to allow the user to make text bold, italics or both. +- **Consistent Styling in the Admin and Frontend:** The editable container can be set to any block-level element, such as a `div`, `h2` or `p` tag. This allows the styles you apply in style.css to more easily apply on the frontend and admin, without having to rewrite them in editor.css. +- **Cohesive Placeholder Text:** Before the user writes their content, it's easy to include placeholder text that's already styled to match the rest of the block editor. +- **Control Over Formatting Options:** It's possible to dictate exactly which formatting options you want to allow for the RichText field. For example, you can dictate whether to allow the user to make text bold, italics or both. Unlike other components that exist in the [Component Reference](/packages/components/README.md) section, RichText lives separately because it only makes sense within the block editor, and not within other areas of WordPress. @@ -18,15 +18,16 @@ For a list of the possible properties to pass your RichText component, [check ou There are a number of core blocks using the RichText component. The JavaScript edit function linked below for each block can be used as a best practice reference while creating your own blocks. -* **[Button](https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-library/src/button/edit.js):** RichText is used to enter the button's text. -* **[Heading](https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-library/src/heading/edit.js):** RichText is used to enter the heading's text. -* **[Quote](https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-library/src/quote/edit.js):** RichText is used in two places, for both the quotation and citation text. -* **[Search](https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-library/src/search/edit.js):** RichText is used in two places, for both the label above the search field and the submit button text. +- **[Button](https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-library/src/button/edit.js):** RichText is used to enter the button's text. +- **[Heading](https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-library/src/heading/edit.js):** RichText is used to enter the heading's text. +- **[Quote](https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-library/src/quote/edit.js):** RichText is used in two places, for both the quotation and citation text. +- **[Search](https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-library/src/search/edit.js):** RichText is used in two places, for both the label above the search field and the submit button text. ## Example {% codetabs %} {% ESNext %} + ```js import { registerBlockType } from '@wordpress/blocks'; import { useBlockProps, RichText } from '@wordpress/block-editor'; @@ -64,7 +65,9 @@ registerBlockType( /* ... */, { } } ); ``` + {% ES5 %} + ```js wp.blocks.registerBlockType( /* ... */, { // ... @@ -100,6 +103,7 @@ wp.blocks.registerBlockType( /* ... */, { } } ); ``` + {% end %} ## Common Issues & Solutions @@ -127,11 +131,10 @@ If you want to limit the formats allowed, you can specify using `allowedFormats` ### Disable Specific Format Types in Editor -The RichText component uses formats to display inline elements, for example images within the paragraph block. If you just want to disable a format from the editor, you can use the `unregisterFormatType` function. For example to disable inline images, use: +The RichText component uses formats to display inline elements, for example images within the paragraph block. If you just want to disable a format from the editor, you can use the `unregisterFormatType` function. For example to disable inline images, use: ``` wp.richText.unregisterFormatType( 'core/image' ); ``` To apply, you would need to enqueue the above script in your plugin or theme. See the JavaScript tutorial for [how to load JavaScript in WordPress](https://developer.wordpress.org/block-editor/tutorials/javascript/loading-javascript/). - diff --git a/docs/reference-guides/slotfills/README.md b/docs/reference-guides/slotfills/README.md index 130b058c5db657..5c7af9a39e3b1f 100644 --- a/docs/reference-guides/slotfills/README.md +++ b/docs/reference-guides/slotfills/README.md @@ -49,9 +49,7 @@ export const { Fill, Slot } = createSlotFill( 'PluginPostStatusInfo' ); const PluginPostStatusInfo = ( { children, className } ) => ( - - { children } - + { children } ); @@ -97,12 +95,12 @@ const PostStatus = ( { isOpened, onTogglePanel } ) => ( The following SlotFills are available in the `edit-post` package. Please refer to the individual items below for usage and example details: -* [MainDashboardButton](/docs/reference-guides/slotfills/main-dashboard-button.md) -* [PluginBlockSettingsMenuItem](/docs/reference-guides/slotfills/plugin-block-settings-menu-item.md) -* [PluginDocumentSettingPanel](/docs/reference-guides/slotfills/plugin-document-setting-panel.md) -* [PluginMoreMenuItem](/docs/reference-guides/slotfills/plugin-more-menu-item.md) -* [PluginPostPublishPanel](/docs/reference-guides/slotfills/plugin-post-publish-panel.md) -* [PluginPostStatusInfo](/docs/reference-guides/slotfills/plugin-post-status-info.md) -* [PluginPrePublishPanel](/docs/reference-guides/slotfills/plugin-pre-publish-panel.md) -* [PluginSidebar](/docs/reference-guides/slotfills/plugin-sidebar.md) -* [PluginSidebarMoreMenuItem](/docs/reference-guides/slotfills/plugin-sidebar-more-menu-item.md) +- [MainDashboardButton](/docs/reference-guides/slotfills/main-dashboard-button.md) +- [PluginBlockSettingsMenuItem](/docs/reference-guides/slotfills/plugin-block-settings-menu-item.md) +- [PluginDocumentSettingPanel](/docs/reference-guides/slotfills/plugin-document-setting-panel.md) +- [PluginMoreMenuItem](/docs/reference-guides/slotfills/plugin-more-menu-item.md) +- [PluginPostPublishPanel](/docs/reference-guides/slotfills/plugin-post-publish-panel.md) +- [PluginPostStatusInfo](/docs/reference-guides/slotfills/plugin-post-status-info.md) +- [PluginPrePublishPanel](/docs/reference-guides/slotfills/plugin-pre-publish-panel.md) +- [PluginSidebar](/docs/reference-guides/slotfills/plugin-sidebar.md) +- [PluginSidebarMoreMenuItem](/docs/reference-guides/slotfills/plugin-sidebar-more-menu-item.md) diff --git a/docs/reference-guides/slotfills/main-dashboard-button.md b/docs/reference-guides/slotfills/main-dashboard-button.md index 3392eed131218f..a333b0f39a4e16 100644 --- a/docs/reference-guides/slotfills/main-dashboard-button.md +++ b/docs/reference-guides/slotfills/main-dashboard-button.md @@ -1,6 +1,6 @@ # MainDashboardButton -This slot allows replacing the default main dashboard button in the post editor and site editor. +This slot allows replacing the default main dashboard button in the post editor and site editor. It's used for returning back to main wp-admin dashboard when editor is in fullscreen mode. ## Examples @@ -11,14 +11,12 @@ This will override the W icon button in the header. ```js import { registerPlugin } from '@wordpress/plugins'; -import { - __experimentalMainDashboardButton as MainDashboardButton, -} from '@wordpress/edit-post'; +import { __experimentalMainDashboardButton as MainDashboardButton } from '@wordpress/edit-post'; const MainDashboardButtonTest = () => ( - - Custom main dashboard button content - + + Custom main dashboard button content + ); registerPlugin( 'main-dashboard-button-test', { @@ -37,11 +35,10 @@ import { } from '@wordpress/edit-post'; import { close } from '@wordpress/icons'; - const MainDashboardButtonIconTest = () => ( - - - + + + ); registerPlugin( 'main-dashboard-button-icon-test', { @@ -55,21 +52,17 @@ In the site editor this slot refers to the "back to dashboard" button in the nav ```js import { registerPlugin } from '@wordpress/plugins'; -import { - __experimentalMainDashboardButton as MainDashboardButton, -} from '@wordpress/edit-site'; -import { - __experimentalNavigationBackButton as NavigationBackButton, -} from '@wordpress/components'; +import { __experimentalMainDashboardButton as MainDashboardButton } from '@wordpress/edit-site'; +import { __experimentalNavigationBackButton as NavigationBackButton } from '@wordpress/components'; const MainDashboardButtonIconTest = () => ( - - - + + + ); registerPlugin( 'main-dashboard-button-icon-test', { diff --git a/docs/reference-guides/slotfills/plugin-block-settings-menu-item.md b/docs/reference-guides/slotfills/plugin-block-settings-menu-item.md index 0c1e490f60ef1d..8e17893b546421 100644 --- a/docs/reference-guides/slotfills/plugin-block-settings-menu-item.md +++ b/docs/reference-guides/slotfills/plugin-block-settings-menu-item.md @@ -27,4 +27,4 @@ registerPlugin( 'block-settings-menu-group-test', { ## Location -![Location](https://raw.githubusercontent.com/WordPress/gutenberg/HEAD/docs/assets/plugin-block-settings-menu-item-screenshot.png?raw=true "PluginBlockSettingsMenuItem Location") +![Location](https://raw.githubusercontent.com/WordPress/gutenberg/HEAD/docs/assets/plugin-block-settings-menu-item-screenshot.png?raw=true 'PluginBlockSettingsMenuItem Location') diff --git a/docs/reference-guides/slotfills/plugin-document-setting-panel.md b/docs/reference-guides/slotfills/plugin-document-setting-panel.md index d9cdf56e69ece6..fcec1d4344354c 100644 --- a/docs/reference-guides/slotfills/plugin-document-setting-panel.md +++ b/docs/reference-guides/slotfills/plugin-document-setting-panel.md @@ -4,10 +4,10 @@ This SlotFill allows registering a UI to edit Document settings. ## Available Props -* __name__ `string`: A string identifying the panel. -* __className__ `string`: An optional class name added to the sidebar body. -* __title__ `string`: Title displayed at the top of the sidebar. -* __icon__ `(string|Element)`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element. +- **name** `string`: A string identifying the panel. +- **className** `string`: An optional class name added to the sidebar body. +- **title** `string`: Title displayed at the top of the sidebar. +- **icon** `(string|Element)`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element. ## Example @@ -30,6 +30,7 @@ registerPlugin( 'plugin-document-setting-panel-demo', { icon: 'palmtree', } ); ``` + ## Accessing a panel programmatically Custom panels are namespaced with the plugin name that was passed to `registerPlugin`. @@ -38,5 +39,9 @@ In order to access the panels using function such as `wp.data.dispatch( 'core/ed To programmatically toggle the custom panel added in the example above, use the following: ```js -wp.data.dispatch( 'core/edit-post' ).toggleEditorPanelOpened( 'plugin-document-setting-panel-demo/custom-panel' ); +wp.data + .dispatch( 'core/edit-post' ) + .toggleEditorPanelOpened( + 'plugin-document-setting-panel-demo/custom-panel' + ); ``` diff --git a/docs/reference-guides/slotfills/plugin-post-publish-panel.md b/docs/reference-guides/slotfills/plugin-post-publish-panel.md index bc05328f4f5544..59972af3505ec9 100644 --- a/docs/reference-guides/slotfills/plugin-post-publish-panel.md +++ b/docs/reference-guides/slotfills/plugin-post-publish-panel.md @@ -22,4 +22,3 @@ registerPlugin( 'post-publish-panel-test', { ## Location ![post publish panel](https://raw.githubusercontent.com/WordPress/gutenberg/HEAD/docs/assets/plugin-post-publish-panel.png?raw=true) - diff --git a/docs/reference-guides/slotfills/plugin-post-status-info.md b/docs/reference-guides/slotfills/plugin-post-status-info.md index 3cf62b772350c9..ce45f981c6b938 100644 --- a/docs/reference-guides/slotfills/plugin-post-status-info.md +++ b/docs/reference-guides/slotfills/plugin-post-status-info.md @@ -20,4 +20,3 @@ registerPlugin( 'post-status-info-test', { render: PluginPostStatusInfoTest } ); ## Location ![Location in the Status & visibility panel](https://raw.githubusercontent.com/WordPress/gutenberg/HEAD/docs/assets/plugin-post-status-info-location.png?raw=true) - diff --git a/docs/reference-guides/slotfills/plugin-pre-publish-panel.md b/docs/reference-guides/slotfills/plugin-pre-publish-panel.md index 5c71d43161f619..d15e39bf09f4ce 100644 --- a/docs/reference-guides/slotfills/plugin-pre-publish-panel.md +++ b/docs/reference-guides/slotfills/plugin-pre-publish-panel.md @@ -22,4 +22,3 @@ registerPlugin( 'pre-publish-panel-test', { ## Location ![Prepublish panel](https://raw.githubusercontent.com/WordPress/gutenberg/HEAD/docs/assets/plugin-pre-publish-panel.png?raw=true) - diff --git a/packages/a11y/CHANGELOG.md b/packages/a11y/CHANGELOG.md index 2301181288a6c7..f12bda946e1fc8 100644 --- a/packages/a11y/CHANGELOG.md +++ b/packages/a11y/CHANGELOG.md @@ -8,20 +8,20 @@ ### New feature -- Include TypeScript type declarations ([#18942](https://github.com/WordPress/gutenberg/pull/18942)) +- Include TypeScript type declarations ([#18942](https://github.com/WordPress/gutenberg/pull/18942)) ## 2.0.0 (2018-09-05) ### Breaking Change -- Change how required built-ins are polyfilled with Babel 7 ([#9171](https://github.com/WordPress/gutenberg/pull/9171)). If you're using an environment that has limited or no support for ES2015+ such as lower versions of IE then using [core-js](https://github.com/zloirock/core-js) or [@babel/polyfill](https://babeljs.io/docs/en/next/babel-polyfill) will add support for these methods. +- Change how required built-ins are polyfilled with Babel 7 ([#9171](https://github.com/WordPress/gutenberg/pull/9171)). If you're using an environment that has limited or no support for ES2015+ such as lower versions of IE then using [core-js](https://github.com/zloirock/core-js) or [@babel/polyfill](https://babeljs.io/docs/en/next/babel-polyfill) will add support for these methods. ## 1.1.0 (2018-07-12) ### New feature -- Updated build to work with Babel 7 ([#7832](https://github.com/WordPress/gutenberg/pull/7832)) +- Updated build to work with Babel 7 ([#7832](https://github.com/WordPress/gutenberg/pull/7832)) ### Polish -- Moved `@WordPress/packages` repository to `@WordPress/gutenberg` ([#7805](https://github.com/WordPress/gutenberg/pull/7805)) +- Moved `@WordPress/packages` repository to `@WordPress/gutenberg` ([#7805](https://github.com/WordPress/gutenberg/pull/7805)) diff --git a/packages/api-fetch/CHANGELOG.md b/packages/api-fetch/CHANGELOG.md index d93d9693f5d3d5..122cd586fe490d 100644 --- a/packages/api-fetch/CHANGELOG.md +++ b/packages/api-fetch/CHANGELOG.md @@ -4,37 +4,37 @@ ### Bug Fixes -- Align exported type names with the DefinitelyTyped type names and actually export those types. +- Align exported type names with the DefinitelyTyped type names and actually export those types. ## 3.23.0 (2021-04-06) ### New Feature -- Publish TypeScript definitions. +- Publish TypeScript definitions. ## 3.22.0 (2021-03-17) ## 3.8.1 (2019-04-22) -- Added deprecation to `useApiFetch` hook. -- Added `@wordpress/deprecation` package to add deprecation notice to `useApiFetch` hook. +- Added deprecation to `useApiFetch` hook. +- Added `@wordpress/deprecation` package to add deprecation notice to `useApiFetch` hook. ## 3.8.0 (2019-12-19) ### Bug Fixes -- Resolves an issue with `createPreloadingMiddleware` where the preloaded data is assumed to be provided with keys matching the internal normalized value. +- Resolves an issue with `createPreloadingMiddleware` where the preloaded data is assumed to be provided with keys matching the internal normalized value. ## 3.0.0 (2019-03-06) ### Breaking Changes -- A created nonce middleware will no longer automatically listen for `heartbeat.tick` actions. Assign to the new `nonce` middleware property instead. +- A created nonce middleware will no longer automatically listen for `heartbeat.tick` actions. Assign to the new `nonce` middleware property instead. ### New Feature -- The function returned by `createNonceMiddleware` includes an assignable `nonce` property corresponding to the active nonce to be used. -- Default fetch handler can be overridden with a custom fetch handler +- The function returned by `createNonceMiddleware` includes an assignable `nonce` property corresponding to the active nonce to be used. +- Default fetch handler can be overridden with a custom fetch handler ## 2.2.6 (2018-12-12) @@ -52,16 +52,16 @@ ### New Feature -- Always request data in the user's locale ([#10862](https://github.com/WordPress/gutenberg/pull/10862)). +- Always request data in the user's locale ([#10862](https://github.com/WordPress/gutenberg/pull/10862)). ## 2.1.0 (2018-10-22) ### New Feature -- Support `per_page=-1` paginated requests. +- Support `per_page=-1` paginated requests. ## 2.0.0 (2018-09-05) ### Breaking Change -- Change how required built-ins are polyfilled with Babel 7 ([#9171](https://github.com/WordPress/gutenberg/pull/9171)). If you're using an environment that has limited or no support for ES2015+ such as lower versions of IE then using [core-js](https://github.com/zloirock/core-js) or [@babel/polyfill](https://babeljs.io/docs/en/next/babel-polyfill) will add support for these methods. +- Change how required built-ins are polyfilled with Babel 7 ([#9171](https://github.com/WordPress/gutenberg/pull/9171)). If you're using an environment that has limited or no support for ES2015+ such as lower versions of IE then using [core-js](https://github.com/zloirock/core-js) or [@babel/polyfill](https://babeljs.io/docs/en/next/babel-polyfill) will add support for these methods. diff --git a/packages/api-fetch/README.md b/packages/api-fetch/README.md index 7e6341e950eb20..3fd2db8605ec94 100644 --- a/packages/api-fetch/README.md +++ b/packages/api-fetch/README.md @@ -18,7 +18,7 @@ _This package assumes that your code will run in an **ES2015+** environment. If import apiFetch from '@wordpress/api-fetch'; // GET -apiFetch( { path: '/wp/v2/posts' } ).then( posts => { +apiFetch( { path: '/wp/v2/posts' } ).then( ( posts ) => { console.log( posts ); } ); @@ -27,7 +27,7 @@ apiFetch( { path: '/wp/v2/posts/1', method: 'POST', data: { title: 'New Post Title' }, -} ).then( res => { +} ).then( ( res ) => { console.log( res ); } ); ``` @@ -82,7 +82,7 @@ The `api-fetch` package provides built-in middlewares you can use to provide a ` ```js import apiFetch from '@wordpress/api-fetch'; -const nonce = "nonce value"; +const nonce = 'nonce value'; apiFetch.use( apiFetch.createNonceMiddleware( nonce ) ); ``` @@ -93,7 +93,7 @@ The function returned by `createNonceMiddleware` includes a `nonce` property cor ```js import apiFetch from '@wordpress/api-fetch'; -const rootURL = "http://my-wordpress-site/wp-json/"; +const rootURL = 'http://my-wordpress-site/wp-json/'; apiFetch.use( apiFetch.createRootURLMiddleware( rootURL ) ); ``` diff --git a/packages/autop/CHANGELOG.md b/packages/autop/CHANGELOG.md index 7360a715f2bcea..b6ba6555736ff4 100644 --- a/packages/autop/CHANGELOG.md +++ b/packages/autop/CHANGELOG.md @@ -8,38 +8,38 @@ ### New feature -- Include TypeScript type declarations ([#20669](https://github.com/WordPress/gutenberg/pull/20669)) +- Include TypeScript type declarations ([#20669](https://github.com/WordPress/gutenberg/pull/20669)) ## 2.3.0 (2019-05-21) ### Bug Fix -- `removep` will correctly preserve multi-line paragraph tags where attributes are present. +- `removep` will correctly preserve multi-line paragraph tags where attributes are present. ## 2.1.0 (2019-03-06) ### Bug Fix -- `autop` correctly matches whitespace preceding and following block-level elements. +- `autop` correctly matches whitespace preceding and following block-level elements. ## 2.0.0 (2018-09-05) ### Breaking Change -- Change how required built-ins are polyfilled with Babel 7 ([#9171](https://github.com/WordPress/gutenberg/pull/9171)). If you're using an environment that has limited or no support for ES2015+ such as lower versions of IE then using [core-js](https://github.com/zloirock/core-js) or [@babel/polyfill](https://babeljs.io/docs/en/next/babel-polyfill) will add support for these methods. +- Change how required built-ins are polyfilled with Babel 7 ([#9171](https://github.com/WordPress/gutenberg/pull/9171)). If you're using an environment that has limited or no support for ES2015+ such as lower versions of IE then using [core-js](https://github.com/zloirock/core-js) or [@babel/polyfill](https://babeljs.io/docs/en/next/babel-polyfill) will add support for these methods. ## 1.1.0 (2018-07-12) ### New Feature -- Updated build to work with Babel 7 ([#7832](https://github.com/WordPress/gutenberg/pull/7832)) +- Updated build to work with Babel 7 ([#7832](https://github.com/WordPress/gutenberg/pull/7832)) ### Internal -- Moved `@WordPress/packages` repository to `@WordPress/gutenberg` ([#7805](https://github.com/WordPress/gutenberg/pull/7805)) +- Moved `@WordPress/packages` repository to `@WordPress/gutenberg` ([#7805](https://github.com/WordPress/gutenberg/pull/7805)) ## 1.0.6 (2018-05-08) ### Polish -- Documentation: Fix API method typo for `removep`. ([#120](https://github.com/WordPress/packages/pull/120)) +- Documentation: Fix API method typo for `removep`. ([#120](https://github.com/WordPress/packages/pull/120)) diff --git a/packages/babel-preset-default/CHANGELOG.md b/packages/babel-preset-default/CHANGELOG.md index d8f5f0130a2c2a..46433925ebad56 100644 --- a/packages/babel-preset-default/CHANGELOG.md +++ b/packages/babel-preset-default/CHANGELOG.md @@ -16,7 +16,7 @@ ### New Features -- Added `@babel/preset-typescript` so that the preset can by default transpile TypeScript files, too. +- Added `@babel/preset-typescript` so that the preset can by default transpile TypeScript files, too. ## 5.0.0 (2021-01-21) diff --git a/packages/base-styles/README.md b/packages/base-styles/README.md index 8e32525f9a4beb..836196bb5ec457 100644 --- a/packages/base-styles/README.md +++ b/packages/base-styles/README.md @@ -17,26 +17,26 @@ npm install @wordpress/base-styles --save-dev In your application's SCSS file, include styles like so: ```scss -@import "node_modules/@wordpress/base-styles/colors"; -@import "node_modules/@wordpress/base-styles/variables"; -@import "node_modules/@wordpress/base-styles/mixins"; -@import "node_modules/@wordpress/base-styles/breakpoints"; -@import "node_modules/@wordpress/base-styles/animations"; -@import "node_modules/@wordpress/base-styles/z-index"; +@import 'node_modules/@wordpress/base-styles/colors'; +@import 'node_modules/@wordpress/base-styles/variables'; +@import 'node_modules/@wordpress/base-styles/mixins'; +@import 'node_modules/@wordpress/base-styles/breakpoints'; +@import 'node_modules/@wordpress/base-styles/animations'; +@import 'node_modules/@wordpress/base-styles/z-index'; @import 'node_modules/@wordpress/base-styles/default-custom-properties'; ``` If you use [Webpack](https://webpack.js.org/) for your SCSS pipeline, you can use `~` to resolve to `node_modules`: ```scss -@import "~@wordpress/base-styles/colors"; +@import '~@wordpress/base-styles/colors'; ``` To make that work with [`sass`](https://www.npmjs.com/package/sass) or [`node-sass`](https://www.npmjs.com/package/node-sass) NPM modules without Webpack, you'd have to use [includePaths option](https://sass-lang.com/documentation/js-api#includepaths): ```json { - "includePaths": ["node_modules"] + "includePaths": [ "node_modules" ] } ``` diff --git a/packages/blob/CHANGELOG.md b/packages/blob/CHANGELOG.md index 2e37e54682a94b..bd12b7a03757e8 100644 --- a/packages/blob/CHANGELOG.md +++ b/packages/blob/CHANGELOG.md @@ -8,19 +8,19 @@ ### New feature -- Added a new `getBlobTypeByURL` function. Returns the file type of the blob or undefined if not a blob. +- Added a new `getBlobTypeByURL` function. Returns the file type of the blob or undefined if not a blob. ## 2.8.0 (2020-04-15) ### New feature -- Include TypeScript type declarations ([#18942](https://github.com/WordPress/gutenberg/pull/18942)) +- Include TypeScript type declarations ([#18942](https://github.com/WordPress/gutenberg/pull/18942)) ## 2.1.0 (2018-10-19) ### New Features -- Added a new `isBlobURL` function. +- Added a new `isBlobURL` function. ## 2.0.3 (2018-10-18) @@ -28,4 +28,4 @@ ### Breaking Change -- Change how required built-ins are polyfilled with Babel 7 ([#9171](https://github.com/WordPress/gutenberg/pull/9171)). If you're using an environment that has limited or no support for ES2015+ such as lower versions of IE then using [core-js](https://github.com/zloirock/core-js) or [@babel/polyfill](https://babeljs.io/docs/en/next/babel-polyfill) will add support for these methods. +- Change how required built-ins are polyfilled with Babel 7 ([#9171](https://github.com/WordPress/gutenberg/pull/9171)). If you're using an environment that has limited or no support for ES2015+ such as lower versions of IE then using [core-js](https://github.com/zloirock/core-js) or [@babel/polyfill](https://babeljs.io/docs/en/next/babel-polyfill) will add support for these methods. diff --git a/packages/block-editor/CHANGELOG.md b/packages/block-editor/CHANGELOG.md index e0ce647afb14bb..5b420e088ea021 100644 --- a/packages/block-editor/CHANGELOG.md +++ b/packages/block-editor/CHANGELOG.md @@ -4,7 +4,7 @@ ## 5.3.0 (2021-03-17) -- Add `JustifyToolbar` component abstracted out of the Navigation block so can be used elsewhere. +- Add `JustifyToolbar` component abstracted out of the Navigation block so can be used elsewhere. ## 5.2.0 (2020-12-17) diff --git a/packages/block-editor/src/components/alignment-control/README.md b/packages/block-editor/src/components/alignment-control/README.md index 258cc9ea113c41..24aa31aef9dfa6 100644 --- a/packages/block-editor/src/components/alignment-control/README.md +++ b/packages/block-editor/src/components/alignment-control/README.md @@ -31,22 +31,24 @@ const MyAlignmentToolbar = () => ( ); ``` + _Note:_ In this example that we render `AlignmentControl` as a child of the `BlockControls` component. ### Props ### `value` -* **Type:** `String` -* **Default:** `undefined` -* **Options:**: `left`, `center`, `right` + +- **Type:** `String` +- **Default:** `undefined` +- **Options:**: `left`, `center`, `right` The current value of the alignment setting. You may only choose from the `Options` listed above. ### `onChange` -* **Type:** `Function` -A callback function invoked when the toolbar's alignment value is changed via an interaction with any of the toolbar's buttons. Called with the new alignment value (ie: `left`, `center`, `right`, `undefined`) as the only argument. +- **Type:** `Function` +A callback function invoked when the toolbar's alignment value is changed via an interaction with any of the toolbar's buttons. Called with the new alignment value (ie: `left`, `center`, `right`, `undefined`) as the only argument. ## Related components diff --git a/packages/block-editor/src/components/autocomplete/README.md b/packages/block-editor/src/components/autocomplete/README.md index 46fff1bd72b35c..7298e542937aac 100644 --- a/packages/block-editor/src/components/autocomplete/README.md +++ b/packages/block-editor/src/components/autocomplete/README.md @@ -1,5 +1,4 @@ -Autocomplete -============ +# Autocomplete This is an Autocomplete component for use in block UI. It is based on `Autocomplete` from `@wordpress/components` and takes the same props. In addition, it passes its autocompleters through a `editor.Autocomplete.completers` filter to give developers an opportunity to override or extend them. diff --git a/packages/block-editor/src/components/block-alignment-control/README.md b/packages/block-editor/src/components/block-alignment-control/README.md index 116743673ae62a..14f08d1dda9ce6 100644 --- a/packages/block-editor/src/components/block-alignment-control/README.md +++ b/packages/block-editor/src/components/block-alignment-control/README.md @@ -20,10 +20,7 @@ import { BlockAlignmentToolbar } from '@wordpress/block-editor'; const MyBlockAlignmentToolbar = () => ( - + ); ``` diff --git a/packages/block-editor/src/components/block-breadcrumb/README.md b/packages/block-editor/src/components/block-breadcrumb/README.md index 537aa33b2cbbc8..98b432973b33d9 100644 --- a/packages/block-editor/src/components/block-breadcrumb/README.md +++ b/packages/block-editor/src/components/block-breadcrumb/README.md @@ -11,7 +11,6 @@ The block breadcrumb trail displays the hierarchy of the current block selection 1. [Development guidelines](#development-guidelines) 2. [Related components](#related-components) - ## Development guidelines ### Usage @@ -26,4 +25,4 @@ const MyBreadcrumb = () => ; ## Related components -Block Editor components are components that can be used to compose the UI of your block editor. Thus, they can only be used under a [`BlockEditorProvider`](https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/provider/README.md) in the components tree. +Block Editor components are components that can be used to compose the UI of your block editor. Thus, they can only be used under a [`BlockEditorProvider`](https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/provider/README.md) in the components tree. diff --git a/packages/block-editor/src/components/block-compare/README.md b/packages/block-editor/src/components/block-compare/README.md index 3c49b7a1e9e4a6..861d0e6d872df0 100644 --- a/packages/block-editor/src/components/block-compare/README.md +++ b/packages/block-editor/src/components/block-compare/README.md @@ -11,33 +11,33 @@ A button is present on both blocks to then select one or the other. The original object to compare against -- Type: `Object` -- Required: Yes +- Type: `Object` +- Required: Yes ##### convertor A function that returns a new, converted, block when supplied an existing block. The conversion may fix or alter the block in a way that helps with an invalid block. -- Type: `func` -- Required: Yes +- Type: `func` +- Required: Yes ##### convertButtonText Text to show in the convert button -- Type: `string` -- Required: Yes +- Type: `string` +- Required: Yes ##### onKeep Callback when the original block is required -- Type: `func` -- Required: Yes +- Type: `func` +- Required: Yes ##### onConvert Callback when the converted block is required. -- Type: `func` -- Required: Yes +- Type: `func` +- Required: Yes diff --git a/packages/block-editor/src/components/block-context/README.md b/packages/block-editor/src/components/block-context/README.md index acb51b48e14576..9c28b853045ce5 100644 --- a/packages/block-editor/src/components/block-context/README.md +++ b/packages/block-editor/src/components/block-context/README.md @@ -1,5 +1,4 @@ -Block Context -============= +# Block Context Block Context is a React implementation of WordPress's block context. Block context, much like [React's context](https://reactjs.org/docs/context.html), is a method for passing and inheriting values deeply through a hierarchy of blocks. Because of the similarities with React's context, the client-side implementation here is quite minimal. It is complemented by equivalent behaviors in the server-side rendering of a block. @@ -44,14 +43,14 @@ The reason `BlockContext` is only internally available within the `@wordpress/bl ### `value` -- Type: `Record` -- Required: Yes +- Type: `Record` +- Required: Yes Context value to merge with current value. ### `children` -- Type: `ReactNode` -- Required: Yes +- Type: `ReactNode` +- Required: Yes Component children. diff --git a/packages/block-editor/src/components/block-full-height-alignment-control/README.md b/packages/block-editor/src/components/block-full-height-alignment-control/README.md index 3768bece723134..7189e59bf05d69 100644 --- a/packages/block-editor/src/components/block-full-height-alignment-control/README.md +++ b/packages/block-editor/src/components/block-full-height-alignment-control/README.md @@ -1,3 +1,3 @@ # Full Height Toolbar Control -Unlike the block alignment options, `Full Height Alignment` can be applied to a block in an independent way. But also, it works very well together with these block alignment options, where the combination empowers the design-layout capability. \ No newline at end of file +Unlike the block alignment options, `Full Height Alignment` can be applied to a block in an independent way. But also, it works very well together with these block alignment options, where the combination empowers the design-layout capability. diff --git a/packages/block-editor/src/components/block-icon/README.md b/packages/block-editor/src/components/block-icon/README.md index 25025db78660c6..4d7178032b366f 100644 --- a/packages/block-editor/src/components/block-icon/README.md +++ b/packages/block-editor/src/components/block-icon/README.md @@ -11,7 +11,6 @@ The rendered an [Icon](https://github.com/WordPress/gutenberg/tree/HEAD/packages 1. [Development guidelines](#development-guidelines) 2. [Related components](#related-components) - ## Development guidelines ### Usage @@ -21,7 +20,7 @@ Renders a block icon with default style. ```jsx import { BlockIcon } from '@wordpress/block-editor'; -const MyBlockIcon = () => +const MyBlockIcon = () => ; ``` ## Related components diff --git a/packages/block-editor/src/components/block-inspector/README.md b/packages/block-editor/src/components/block-inspector/README.md index 29db59ee02bade..1f9d52482eb210 100644 --- a/packages/block-editor/src/components/block-inspector/README.md +++ b/packages/block-editor/src/components/block-inspector/README.md @@ -8,6 +8,7 @@ The Block inspector is one of the panels that is displayed in the editor; it is 1. [Development guidelines](#development-guidelines) 2. [Related components](#related-components) + ## Development guidelines ### Usage @@ -17,8 +18,9 @@ Render the block inspector component. ```jsx import { BlockInspector } from '@wordpress/block-editor'; -const MyBlockInspector = () => +const MyBlockInspector = () => ; ``` + ## Related components -Block Editor components are components that can be used to compose the UI of your block editor. Thus, they can only be used under a [BlockEditorProvider](https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/provider/README.md) in the components tree. \ No newline at end of file +Block Editor components are components that can be used to compose the UI of your block editor. Thus, they can only be used under a [BlockEditorProvider](https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/provider/README.md) in the components tree. diff --git a/packages/block-editor/src/components/block-media-update-progress/README.md b/packages/block-editor/src/components/block-media-update-progress/README.md index 1302bb237d6f91..97abff477ea24f 100644 --- a/packages/block-editor/src/components/block-media-update-progress/README.md +++ b/packages/block-editor/src/components/block-media-update-progress/README.md @@ -1,5 +1,4 @@ -BlockMediaUpdateProgress -=================== +# BlockMediaUpdateProgress `BlockMediaUpdateProgress` shows a progress bar while the media files associated with a media-containing block are being saved first and uploaded later @@ -9,9 +8,7 @@ Usage example ```jsx import { ImageBackground, Text, View } from 'react-native'; -import { - BlockMediaUpdateProgress, -} from '@wordpress/block-editor'; +import { BlockMediaUpdateProgress } from '@wordpress/block-editor'; function BlockUpdatingProgress( { url, id } ) { return ( @@ -23,11 +20,11 @@ function BlockUpdatingProgress( { url, id } ) { resizeMethod="scale" source={ { uri: url } } > - { isSaveFailed && + { isSaveFailed && ( { retryMessage } - } + ) } ); } } @@ -42,17 +39,17 @@ function BlockUpdatingProgress( { url, id } ) { A collection of media ID that identifies the current collection of files represented in this media container block. -- Type: `Array` -- Required: Yes -- Platform: Mobile +- Type: `Array` +- Required: Yes +- Platform: Mobile ### renderContent Content to be rendered along with the progress bar, usually the thumbnail of the media being uploaded. -- Type: `React components` -- Required: Yes -- Platform: Mobile +- Type: `React components` +- Required: Yes +- Platform: Mobile It passes an object containing the following properties: @@ -62,9 +59,9 @@ It passes an object containing the following properties: Callback called when the progress of the upload is updated. -- Type: `Function` -- Required: No -- Platform: Mobile +- Type: `Function` +- Required: No +- Platform: Mobile The argument of the callback is an object containing the following properties: @@ -74,9 +71,9 @@ The argument of the callback is an object containing the following properties: Callback called when the media file has been uploaded successfully. -- Type: `Function` -- Required: No -- Platform: Mobile +- Type: `Function` +- Required: No +- Platform: Mobile The argument of the callback is an object containing the following properties: @@ -86,19 +83,18 @@ The argument of the callback is an object containing the following properties: Callback called when the media file couldn't be uploaded. -- Type: `Function` -- Required: No -- Platform: Mobile +- Type: `Function` +- Required: No +- Platform: Mobile The argument of the callback is an object containing the following properties: `{ mediaId, progress, state }` - ### onMediaUploadStateReset Callback called when the media upload is reset -- Type: `Function` -- Required: No -- Platform: Mobile +- Type: `Function` +- Required: No +- Platform: Mobile diff --git a/packages/block-editor/src/components/block-mover/README.md b/packages/block-editor/src/components/block-mover/README.md index 379084f763178e..3763b7dbada11f 100644 --- a/packages/block-editor/src/components/block-mover/README.md +++ b/packages/block-editor/src/components/block-mover/README.md @@ -4,13 +4,11 @@ Block movers allow moving blocks inside the editor using up and down buttons. ![Block mover screenshot](https://make.wordpress.org/core/files/2020/08/block-mover-screenshot.png) - ## Table of contents 1. [Development guidelines](#development-guidelines) 2. [Related components](#related-components) - ## Development guidelines ### Usage @@ -30,6 +28,6 @@ Blocks IDs - Type: `Array` - ## Related components -Block Editor components are components that can be used to compose the UI of your block editor. Thus, they can only be used under a [BlockEditorProvider](https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/provider/README.md) in the components tree. \ No newline at end of file + +Block Editor components are components that can be used to compose the UI of your block editor. Thus, they can only be used under a [BlockEditorProvider](https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/provider/README.md) in the components tree. diff --git a/packages/block-editor/src/components/block-navigation/README.md b/packages/block-editor/src/components/block-navigation/README.md index f8a360c91dafef..9491b9ad7ef013 100644 --- a/packages/block-editor/src/components/block-navigation/README.md +++ b/packages/block-editor/src/components/block-navigation/README.md @@ -23,9 +23,7 @@ Renders a block navigation with default syles. ```jsx import { BlockNavigation } from '@wordpress/block-editor'; -const MyNavigation = () => ; +const MyNavigation = () => ; ``` ## Related components diff --git a/packages/block-editor/src/components/block-parent-selector/README.md b/packages/block-editor/src/components/block-parent-selector/README.md index 52651daa913cd3..181e03a20800b6 100644 --- a/packages/block-editor/src/components/block-parent-selector/README.md +++ b/packages/block-editor/src/components/block-parent-selector/README.md @@ -8,7 +8,6 @@ In practice the BlockParentSelector component renders a compon ![Block parent selector test](https://make.wordpress.org/core/files/2020/09/block-parent-selector-test.gif) - ## Table of contents 1. [Development guidelines](#development-guidelines) diff --git a/packages/block-editor/src/components/block-patterns-list/README.md b/packages/block-editor/src/components/block-patterns-list/README.md index 70b93652aef28c..7b30dcecc7bbd4 100644 --- a/packages/block-editor/src/components/block-patterns-list/README.md +++ b/packages/block-editor/src/components/block-patterns-list/README.md @@ -42,7 +42,6 @@ An array of block patterns that can be shown in the block patterns list. An array of shown block patterns objects. - - Type: `Array` - Required: Yes @@ -54,18 +53,21 @@ The performed event after a click on a block pattern. In most cases, the pattern - Required: Yes #### isDraggable + Enables drag and drop functionality to the available block patterns. - Type: `boolean` - Required: No #### orientation + The orientation value determines which arrow keys can be used to move focus. Available options are (`vertical`|`horizontal`). If not provided all arrow keys work. - Type: `string` - Required: No #### label + The aria label for the block patterns list. - Type: `string` diff --git a/packages/block-editor/src/components/block-preview/README.md b/packages/block-editor/src/components/block-preview/README.md index 777fe5c3dd75b7..fb2f6d50fab773 100644 --- a/packages/block-editor/src/components/block-preview/README.md +++ b/packages/block-editor/src/components/block-preview/README.md @@ -1,5 +1,4 @@ -BlockPreview -============ +# BlockPreview `` allows you to preview blocks. @@ -8,44 +7,45 @@ BlockPreview Render the component passing in the required props: ```jsx - + ``` ## Props ### `blocks` -* **Type:** `Array|Object` -* **Default:** `undefined` + +- **Type:** `Array|Object` +- **Default:** `undefined` A block instance (object) or a blocks array you would like to render a preview. ### `viewportWidth` -* **Type:** `Int` -* **Default:** `700` + +- **Type:** `Int` +- **Default:** `700` Width of the preview container in pixels. Controls at what size the blocks will be rendered inside the preview. `viewportWidth` can be used to simulate how blocks look on different device sizes or to make sure make sure multiple previews will be rendered with the same scale, regardless of their content. -### __experimentalScalingDelay -* **Type** `Int` -* **Default** `100ms` +### \_\_experimentalScalingDelay + +- **Type** `Int` +- **Default** `100ms` Defines a delay to be applied before calculating the scale factor and position of the preview block. ### `__experimentalOnReady` -* **Type** `Function` -* **Default:** `noop` + +- **Type** `Function` +- **Default:** `noop` Use this callback as an opportunity to know when the preview is ready. The callback will pass, if available: -* `scale`: the scale factor -* `position`: offsets position (x, y) -* `previewContainerRef`: DOM element reference -* `inlineStyles`: Inline styles applied to the preview container +- `scale`: the scale factor +- `position`: offsets position (x, y) +- `previewContainerRef`: DOM element reference +- `inlineStyles`: Inline styles applied to the preview container Eg: @@ -53,7 +53,9 @@ Eg: { - console.log( `scale ${ scale } applied to the <${ previewContainerRef.current.tagName }> element.` ); + console.log( + `scale ${ scale } applied to the <${ previewContainerRef.current.tagName }> element.` + ); console.log( `at x: ${ position.x }, y: ${ position.y } position.` ); } } /> diff --git a/packages/block-editor/src/components/block-settings-menu-controls/README.md b/packages/block-editor/src/components/block-settings-menu-controls/README.md index c4a6e2491ded5a..84c3cc5e44ed21 100644 --- a/packages/block-editor/src/components/block-settings-menu-controls/README.md +++ b/packages/block-editor/src/components/block-settings-menu-controls/README.md @@ -11,11 +11,7 @@ import MyButton from './my-toggle-button'; function ReusableBlocksMenuItems() { return ( - { ( { onClose } ) => ( - - ) } + { ( { onClose } ) => } ); } diff --git a/packages/block-editor/src/components/block-settings-menu/README.md b/packages/block-editor/src/components/block-settings-menu/README.md index 98b0a33a9ae939..d4583f755be7a3 100644 --- a/packages/block-editor/src/components/block-settings-menu/README.md +++ b/packages/block-editor/src/components/block-settings-menu/README.md @@ -1,5 +1,4 @@ -BlockSettingsMenu -============ +# BlockSettingsMenu This is a menu that allows the user to act on the block (duplicate, remove, etc). @@ -9,5 +8,5 @@ This is the dropdown itself, it covers the bulk of the logic of this component. ## Props -`__experimentalSelectBlock` - A callback. If passed, interacting with dropdown options (such as duplicate) will not update the +`__experimentalSelectBlock` - A callback. If passed, interacting with dropdown options (such as duplicate) will not update the editor selection. Instead, every time a selection change should happen the callback will be called with a proper clientId. diff --git a/packages/block-editor/src/components/block-title/README.md b/packages/block-editor/src/components/block-title/README.md index 1e22d83dba461c..1ea0e963429be6 100644 --- a/packages/block-editor/src/components/block-title/README.md +++ b/packages/block-editor/src/components/block-title/README.md @@ -1,5 +1,4 @@ -Block Title -=========== +# Block Title Renders the block's configured title as a string, or empty if the title cannot be determined. diff --git a/packages/block-editor/src/components/block-toolbar/README.md b/packages/block-editor/src/components/block-toolbar/README.md index 55e7b349670a76..be4c8e15abe097 100644 --- a/packages/block-editor/src/components/block-toolbar/README.md +++ b/packages/block-editor/src/components/block-toolbar/README.md @@ -1,12 +1,11 @@ # Block Toolbar -The `BlockToolbar` component is used to render a toolbar that serves as a wrapper for number of options for each block. +The `BlockToolbar` component is used to render a toolbar that serves as a wrapper for number of options for each block. ![Paragraph block toolbar](https://make.wordpress.org/core/files/2020/09/paragraph-block-toolbar.png) ![Image block toolbar](https://make.wordpress.org/core/files/2020/09/image-block-toolbar.png) - ## Table of contents 1. [Development guidelines](#development-guidelines) @@ -21,7 +20,7 @@ Displays a block toolbar for a selected block. ```jsx import { BlockToolbar } from '@wordpress/block-editor'; -const MyBlockToolbar = () => +const MyBlockToolbar = () => ; ``` ## Related components diff --git a/packages/block-editor/src/components/block-types-list/README.md b/packages/block-editor/src/components/block-types-list/README.md index 8fb67bf7266669..f93352f371f2b6 100644 --- a/packages/block-editor/src/components/block-types-list/README.md +++ b/packages/block-editor/src/components/block-types-list/README.md @@ -24,7 +24,7 @@ Renders a list of blocks types. ```jsx import { BlockTypesList } from '@wordpress/block-editor'; -const MyBlockTypesList = () => ;; +const MyBlockTypesList = () => ; ``` ### Props diff --git a/packages/block-editor/src/components/block-variation-picker/README.md b/packages/block-editor/src/components/block-variation-picker/README.md index 0c2a25bc9881db..117e79a6ee648d 100644 --- a/packages/block-editor/src/components/block-variation-picker/README.md +++ b/packages/block-editor/src/components/block-variation-picker/README.md @@ -21,9 +21,7 @@ Renders the variations of a block. import { BlockVariationPicker } from '@wordpress/block-editor'; const MyBlockVariationPicker = () => ( - + ); ``` diff --git a/packages/block-editor/src/components/block-variation-transforms/README.md b/packages/block-editor/src/components/block-variation-transforms/README.md index cbaee69564ba98..0eb016d493207a 100644 --- a/packages/block-editor/src/components/block-variation-transforms/README.md +++ b/packages/block-editor/src/components/block-variation-transforms/README.md @@ -17,27 +17,17 @@ Renders the block's variations which have the `transform` option set in `scope` ```jsx import { useSelect } from '@wordpress/data'; -import { - __experimentalBlockVariationTransforms as BlockVariationTransforms, -} from '@wordpress/block-editor'; +import { __experimentalBlockVariationTransforms as BlockVariationTransforms } from '@wordpress/block-editor'; const MyBlockVariationTransforms = () => { - const { selectedBlockClientId } = useSelect( - ( select ) => { - const { getSelectedBlockClientId } = select( - 'core/block-editor' - ); - return { - selectedBlockClientId: getSelectedBlockClientId(), - }; - } - ); - - return ( - - ); + const { selectedBlockClientId } = useSelect( ( select ) => { + const { getSelectedBlockClientId } = select( 'core/block-editor' ); + return { + selectedBlockClientId: getSelectedBlockClientId(), + }; + } ); + + return ; }; ``` @@ -47,7 +37,7 @@ const MyBlockVariationTransforms = () => { The block's client id. -- Type: `string` +- Type: `string` ## Related components diff --git a/packages/block-editor/src/components/block-vertical-alignment-control/README.md b/packages/block-editor/src/components/block-vertical-alignment-control/README.md index 284907f09eda90..97cba8de896282 100644 --- a/packages/block-editor/src/components/block-vertical-alignment-control/README.md +++ b/packages/block-editor/src/components/block-vertical-alignment-control/README.md @@ -1,5 +1,4 @@ -BlockVerticalAlignmentControl -============================= +# BlockVerticalAlignmentControl `BlockVerticalAlignmentControl` is a simple component designed to provide _vertical_ alignment UI controls for use within the editor `BlockControls` toolbar. @@ -7,8 +6,7 @@ This builds upon similar patterns to the [`BlockAlignmentControl`](https://githu ## Usage -In a block's `edit` implementation, render a `` component. Then inside of this add the `` where required. - +In a block's `edit` implementation, render a `` component. Then inside of this add the `` where required. ```jsx import { registerBlockType } from '@wordpress/blocks'; @@ -32,11 +30,12 @@ registerBlockType( 'my-plugin/my-block', { edit( { attributes, setAttributes } ) { const blockProps = useBlockProps(); - + const { verticalAlignment } = attributes; // Change handler to set Block `attributes` - const onChange = ( alignment ) => setAttributes( { verticalAlignment: alignment } ); + const onChange = ( alignment ) => + setAttributes( { verticalAlignment: alignment } ); return ( <> @@ -46,37 +45,38 @@ registerBlockType( 'my-plugin/my-block', { value={ verticalAlignment } /> -
- // your Block here -
+
// your Block here
); - } + }, } ); ``` -_Note:_ by default if you do not provide an initial `value` prop for the current alignment value, then no value will be selected (ie: there is no default alignment set). +_Note:_ by default if you do not provide an initial `value` prop for the current alignment value, then no value will be selected (ie: there is no default alignment set). _Note:_ the user can repeatedly click on the toolbar buttons to toggle the alignment values on/off. This is handled within the component. ## Props ### `value` -* **Type:** `String` -* **Default:** `undefined` -* **Options:**: `top`, `center`, `bottom` + +- **Type:** `String` +- **Default:** `undefined` +- **Options:**: `top`, `center`, `bottom` The current value of the alignment setting. You may only choose from the `Options` listed above. ### `onChange` -* **Type:** `Function` + +- **Type:** `Function` A callback function invoked when the toolbar's alignment value is changed via an interaction with any of the toolbar's buttons. Called with the new alignment value (ie: `top`, `center`, `bottom`, `undefined`) as the only argument. Note: the value may be `undefined` if the user has toggled the component "off". ```js -const onChange = ( alignment ) => setAttributes( { verticalAlignment: alignment } ); +const onChange = ( alignment ) => + setAttributes( { verticalAlignment: alignment } ); ``` ## Examples diff --git a/packages/block-editor/src/components/button-block-appender/README.md b/packages/block-editor/src/components/button-block-appender/README.md index 87d917ab50b582..bb09bcb7eac11d 100644 --- a/packages/block-editor/src/components/button-block-appender/README.md +++ b/packages/block-editor/src/components/button-block-appender/README.md @@ -1,7 +1,6 @@ -ButtonBlockAppender -============================= +# ButtonBlockAppender -`ButtonBlockAppender` provides button with a `+` (plus) icon which when clicked will trigger the default Block `Inserter` UI to allow a Block to be inserted. +`ButtonBlockAppender` provides button with a `+` (plus) icon which when clicked will trigger the default Block `Inserter` UI to allow a Block to be inserted. This is typically used as an alternative to the `` component to determine the initial placeholder behaviour for a Block when displayed in the editor UI. @@ -9,9 +8,8 @@ This is typically used as an alternative to the `` compo In a block's `edit` implementation, render a `` component passing in the `rootClientId`. - ```jsx -function render( { clientId }) { +function render( { clientId } ) { return (

Some rendered content here

@@ -21,20 +19,22 @@ function render( { clientId }) { } ``` -_Note:_ +_Note:_ ## Props ### `rootClientId` -* **Type:** `String` -* **Required** `true` -* **Default:** `undefined` + +- **Type:** `String` +- **Required** `true` +- **Default:** `undefined` The `clientId` of the Block from who's root new Blocks should be inserted. This prop is required by the block `Inserter` component. Typically this is the `clientID` of the Block where the prop is being rendered. ### `className` -* **Type:** `String` -* **Default:** `""` + +- **Type:** `String` +- **Default:** `""` A CSS `class` to be _prepended_ to the default class of `"button-block-appender"`. diff --git a/packages/block-editor/src/components/copy-handler/README.md b/packages/block-editor/src/components/copy-handler/README.md index 1599941b9bce2c..44463173b556f2 100644 --- a/packages/block-editor/src/components/copy-handler/README.md +++ b/packages/block-editor/src/components/copy-handler/README.md @@ -4,7 +4,6 @@ The `CopyHandler` component handles the copy/cut and paste events of its childre Concretely, it handles the display of success messages and takes care of copying the block to the clipboard. It uses for that the [serialize function](https://github.com/WordPress/gutenberg/blob/HEAD/packages/blocks/src/api/serializer.js), which outputs HTML augmented with the HTML-comment demarcations to denote blocks. - ![Copy/cut behaviours](https://user-images.githubusercontent.com/150562/81698101-6e341d80-945d-11ea-9bfb-b20781f55033.gif) ## Table of contents @@ -34,7 +33,7 @@ _Note:_ The `CopyHandler` only catches copy/cut and paste events coming from its ### `children` -- Type: `Element` +- Type: `Element` The elements to be rendered and whose `cut`, `copy` and `paste` events we'd like to intercept. diff --git a/packages/block-editor/src/components/editable-text/README.md b/packages/block-editor/src/components/editable-text/README.md index 5d3ff75294870a..148ff2280a65ec 100644 --- a/packages/block-editor/src/components/editable-text/README.md +++ b/packages/block-editor/src/components/editable-text/README.md @@ -6,40 +6,40 @@ Renders an editable text input in which text formatting is not allowed. ### `value: String` -*Required.* String to make editable. +_Required._ String to make editable. ### `onChange( value: String ): Function` -*Required.* Called when the value changes. +_Required._ Called when the value changes. ### `tagName: String` -*Default: `div`.* The [tag name](https://www.w3.org/TR/html51/syntax.html#tag-name) of the editable element. Elements that display inline are not supported. Set to `inline-block` to use tag names that have `inline` as the default. +_Default: `div`._ The [tag name](https://www.w3.org/TR/html51/syntax.html#tag-name) of the editable element. Elements that display inline are not supported. Set to `inline-block` to use tag names that have `inline` as the default. ### `disableLineBreaks: Boolean` -*Optional.* `Text` won't insert line breaks on `Enter` if set to `true`. +_Optional._ `Text` won't insert line breaks on `Enter` if set to `true`. ### `placeholder: String` -*Optional.* Placeholder text to show when the field is empty, similar to the - [`input` and `textarea` attribute of the same name](https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/HTML5_updates#The_placeholder_attribute). +_Optional._ Placeholder text to show when the field is empty, similar to the +[`input` and `textarea` attribute of the same name](https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/HTML5_updates#The_placeholder_attribute). ### `onSplit( value: String ): Function` -*Optional.* Called when the content can be split, where `value` is a piece of content being split off. Here you should create a new block with that content and return it. Note that you also need to provide `onReplace` in order for this to take any effect. +_Optional._ Called when the content can be split, where `value` is a piece of content being split off. Here you should create a new block with that content and return it. Note that you also need to provide `onReplace` in order for this to take any effect. ### `onReplace( blocks: Array ): Function` -*Optional.* Called when the `Text` instance can be replaced with the given blocks. +_Optional._ Called when the `Text` instance can be replaced with the given blocks. ### `onMerge( forward: Boolean ): Function` -*Optional.* Called when blocks can be merged. `forward` is true when merging with the next block, false when merging with the previous block. +_Optional._ Called when blocks can be merged. `forward` is true when merging with the next block, false when merging with the previous block. ### `onRemove( forward: Boolean ): Function` -*Optional.* Called when the block can be removed. `forward` is true when the selection is expected to move to the next block, false to the previous block. +_Optional._ Called when the block can be removed. `forward` is true when the selection is expected to move to the next block, false to the previous block. ## EditableText.Content @@ -49,6 +49,7 @@ Renders an editable text input in which text formatting is not allowed. {% codetabs %} {% ES5 %} + ```js wp.blocks.registerBlockType( /* ... */, { // ... @@ -77,7 +78,9 @@ wp.blocks.registerBlockType( /* ... */, { } } ); ``` + {% ESNext %} + ```js const { registerBlockType } = wp.blocks; const { EditableText } = wp.editor; @@ -107,4 +110,5 @@ registerBlockType( /* ... */, { } } ); ``` + {% end %} diff --git a/packages/block-editor/src/components/image-size-control/README.md b/packages/block-editor/src/components/image-size-control/README.md index 846e455db9123c..f036df4bd478aa 100644 --- a/packages/block-editor/src/components/image-size-control/README.md +++ b/packages/block-editor/src/components/image-size-control/README.md @@ -38,36 +38,36 @@ The component accepts the following props: The currently-selected image size slug (`thumbnail`, `large`, etc). This is used by the parent component to get the specific image, which is used to populate `imageHeight` & `imageWidth`. This is not required, but necessary when `imageSizeOptions` is used. -- Type: `string` -- Required: No +- Type: `string` +- Required: No ### height The height of the image when displayed. -- Type: `number` -- Required: No +- Type: `number` +- Required: No ### width The width of the image when displayed. -- Type: `number` -- Required: No +- Type: `number` +- Required: No ### onChange The function called when the image size changes. It is passed an object with `{ width, height }` (potentially just one if only one dimension changed). -- Type: `Function` -- Required: Yes +- Type: `Function` +- Required: Yes ### onChangeImage The function called when a new image size is selected. It is passed the `slug` as an argument. This is not required, but necessary when `imageSizeOptions` is used. -- Type: `Function` -- Required: No +- Type: `Function` +- Required: No ### imageSizeOptions @@ -83,26 +83,26 @@ An array of image size slugs and labels. Should be of the format: If not provided, the "Image Size" dropdown is not displayed. -- Type: `array` -- Required: No +- Type: `array` +- Required: No ### isResizable A boolean control for showing the resize fields "Image Dimensions". Set this to false if you want images to always be the fixed size of the selected image. -- Type: `boolean` -- Required: No +- Type: `boolean` +- Required: No ### imageWidth The width of the currently selected image, used for calculating the percentage sizes. This will likely be updated when the image size slug changes, but does not control the image display (that's the `width` prop). -- Type: `number` -- Required: Yes +- Type: `number` +- Required: Yes ### imageHeight The height of the currently selected image, used for calculating the percentage sizes. This will likely be updated when the image size slug changes, but does not control the image display (that's the `height` prop). -- Type: `number` -- Required: Yes +- Type: `number` +- Required: Yes diff --git a/packages/block-editor/src/components/inner-blocks/README.md b/packages/block-editor/src/components/inner-blocks/README.md index f841a1fd99c4cb..0f33fe26cb677c 100644 --- a/packages/block-editor/src/components/inner-blocks/README.md +++ b/packages/block-editor/src/components/inner-blocks/README.md @@ -1,5 +1,4 @@ -InnerBlocks -=========== +# InnerBlocks InnerBlocks exports a pair of components which can be used in block implementations to enable nested block content. @@ -34,7 +33,7 @@ registerBlockType( 'my-plugin/my-block', {
); - } + }, } ); ``` @@ -45,8 +44,9 @@ _Note:_ Because the save step will automatically apply props to the element retu ## Props ### `allowedBlocks` -* **Type:** `Boolean|Array` -* **Default:** `true` + +- **Type:** `Boolean|Array` +- **Default:** `true` `allowedBlocks` can contain an array of strings, each string should contain the identifier of a block. When `allowedBlocks` is set it is only possible to insert blocks part of the set specified in the array. @@ -75,14 +75,16 @@ The previous code block restricts all blocks, so only child blocks explicitly re If `allowedBlocks` is set to `true`, all blocks are allowed. `false` means no blocks are allowed. ### `orientation` -* **Type:** `"horizontal"|"vertical"|undefined` + +- **Type:** `"horizontal"|"vertical"|undefined` Indicates whether inner blocks are shown horizontally or vertically. Use the string 'horizontal' or 'vertical' as a value. When left unspecified, defaults to 'vertical'. While this prop doesn't change any styles for the inner blocks themselves, it does display the Block Movers in the correct orientation, and also ensures drag and drop works correctly. ### `template` -* **Type:** `Array>` + +- **Type:** `Array>` The template is defined as a list of block items. Such blocks can have predefined attributes, placeholder, content, etc. Block templates allow specifying a default initial state for an InnerBlocks area. More information about templates can be found in [template docs](/docs/reference-guides/block-api/block-templates.md). @@ -105,39 +107,43 @@ const TEMPLATE = [ [ 'core/columns', {}, [ The previous example creates an InnerBlocks area containing two columns one with an image and the other with a paragraph. ### `templateInsertUpdatesSelection` -* **Type:** `Boolean` -* **Default:** `false` + +- **Type:** `Boolean` +- **Default:** `false` If true when child blocks in the template are inserted the selection is updated. If false the selection should not be updated when child blocks specified in the template are inserted. ### `templateLock` -* **Type:** `String|Boolean` + +- **Type:** `String|Boolean` Template locking of `InnerBlocks` is similar to [Custom Post Type templates locking](/docs/reference-guides/block-api/block-templates.md#locking). Template locking allows locking the `InnerBlocks` area for the current template. -*Options:* +_Options:_ -- `'all'` — prevents all operations. It is not possible to insert new blocks. Move existing blocks or delete them. -- `'insert'` — prevents inserting or removing blocks, but allows moving existing ones. -- `false` — prevents locking from being applied to an `InnerBlocks` area even if a parent block contains locking. ( Boolean ) +- `'all'` — prevents all operations. It is not possible to insert new blocks. Move existing blocks or delete them. +- `'insert'` — prevents inserting or removing blocks, but allows moving existing ones. +- `false` — prevents locking from being applied to an `InnerBlocks` area even if a parent block contains locking. ( Boolean ) If locking 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 of the Custom Post Type is used. ### `renderAppender` -* **Type:** `Component|false` -* **Default:** - `undefined`. When `renderAppender` is not specified, the default appender is shown. If a `false` value is provided, no appender is rendered. + +- **Type:** `Component|false` +- **Default:** - `undefined`. When `renderAppender` is not specified, the default appender is shown. If a `false` value is provided, no appender is rendered. A component to show as the trailing appender for the inner blocks list. #### Notes -* For convenience two predefined appender components are exposed on `InnerBlocks` which can be used for the prop: - - `InnerBlocks.ButtonBlockAppender` - display a `+` (plus) icon button as the appender. - - `InnerBlocks.DefaultBlockAppender` - display the default block appender, typically the paragraph style appender when the paragraph block is allowed. -* Consumers are also free to pass any valid component. This provides the full flexibility to define a bespoke block appender. + +- For convenience two predefined appender components are exposed on `InnerBlocks` which can be used for the prop: + - `InnerBlocks.ButtonBlockAppender` - display a `+` (plus) icon button as the appender. + - `InnerBlocks.DefaultBlockAppender` - display the default block appender, typically the paragraph style appender when the paragraph block is allowed. +- Consumers are also free to pass any valid component. This provides the full flexibility to define a bespoke block appender. #### Example usage @@ -160,8 +166,8 @@ A component to show as the trailing appender for the inner blocks list. ### `__experimentalCaptureToolbars` -* **Type:** `Boolean` -* **Default:** `false` +- **Type:** `Boolean` +- **Default:** `false` Determines whether the toolbars of _all_ child Blocks (applied deeply, recursive) should have their toolbars "captured" and shown on the Block which is consuming `InnerBlocks`. @@ -169,5 +175,5 @@ For example, a button block, deeply nested in several levels of block `X` that u ### `placeholder` -* **Type:** `Function` -* **Default:** - `undefined`. The placeholder is an optional function that can be passed in to be a rendered component placed in front of the appender. This can be used to represent an example state prior to any blocks being placed. See the Social Links for an implementation example. +- **Type:** `Function` +- **Default:** - `undefined`. The placeholder is an optional function that can be passed in to be a rendered component placed in front of the appender. This can be used to represent an example state prior to any blocks being placed. See the Social Links for an implementation example. diff --git a/packages/block-editor/src/components/inspector-advanced-controls/README.md b/packages/block-editor/src/components/inspector-advanced-controls/README.md index 701ab50d0b0474..b14b0cb6a73e24 100644 --- a/packages/block-editor/src/components/inspector-advanced-controls/README.md +++ b/packages/block-editor/src/components/inspector-advanced-controls/README.md @@ -8,6 +8,7 @@ Inspector Advanced Controls appear under the _Advanced_ panel of a block's [Insp {% codetabs %} {% ESNext %} + ```js const { TextControl, @@ -41,7 +42,9 @@ function MyBlockEdit( { attributes, setAttributes } ) { ); } ``` + {% ES5 %} + ```js var el = wp.element.createElement, Fragment = wp.element.Fragment, @@ -50,7 +53,7 @@ var el = wp.element.createElement, TextControl = wp.components.TextControl, function MyBlockEdit( props ) { - return el( Fragment, null, + return el( Fragment, null, el( 'div', null, /* Block markup goes here */ null ), el( InspectorControls, null, /* Regular control goes here */ null ), el( InspectorAdvancedControls, null, @@ -65,4 +68,5 @@ function MyBlockEdit( props ) { ); } ``` + {% end %} diff --git a/packages/block-editor/src/components/inspector-controls/README.md b/packages/block-editor/src/components/inspector-controls/README.md index 3369cc8002c9f2..2353eff2cc7f52 100644 --- a/packages/block-editor/src/components/inspector-controls/README.md +++ b/packages/block-editor/src/components/inspector-controls/README.md @@ -8,6 +8,7 @@ Inspector Controls appear in the post settings sidebar when a block is being edi {% codetabs %} {% ES5 %} + ```js var el = wp.element.createElement, Fragment = wp.element.Fragment, @@ -55,9 +56,9 @@ registerBlockType( 'my-plugin/inspector-controls-example', { }, }, - edit: function( props ) { + edit: function ( props ) { var blockProps = useBlockProps(); - + var content = props.attributes.content, checkboxField = props.attributes.checkboxField, radioField = props.attributes.radioField, @@ -89,96 +90,79 @@ registerBlockType( 'my-plugin/inspector-controls-example', { props.setAttributes( { selectField: newValue } ); } - return ( + return el( + Fragment, + null, el( - Fragment, + InspectorControls, null, - el( - InspectorControls, - null, - el( - CheckboxControl, + el( CheckboxControl, { + heading: 'Checkbox Field', + label: 'Tick Me', + help: 'Additional help text', + checked: checkboxField, + onChange: onChangeCheckboxField, + } ), + el( RadioControl, { + label: 'Radio Field', + selected: radioField, + options: [ { - heading: 'Checkbox Field', - label: 'Tick Me', - help: 'Additional help text', - checked: checkboxField, - onChange: onChangeCheckboxField - } - ), - el( - RadioControl, + label: 'Yes', + value: 'yes', + }, { - label: 'Radio Field', - selected: radioField, - options: [ - { - label: 'Yes', - value: 'yes' - }, - { - label: 'No', - value: 'no' - } - ], - onChange: onChangeRadioField - } - ), - el( - TextControl, + label: 'No', + value: 'no', + }, + ], + onChange: onChangeRadioField, + } ), + el( TextControl, { + label: 'Text Field', + help: 'Additional help text', + value: textField, + onChange: onChangeTextField, + } ), + el( ToggleControl, { + label: 'Toggle Field', + checked: toggleField, + onChange: onChangeToggleField, + } ), + el( SelectControl, { + label: 'Select Field', + value: selectField, + options: [ { - label: 'Text Field', - help: 'Additional help text', - value: textField, - onChange: onChangeTextField - } - ), - el( - ToggleControl, + value: 'a', + label: 'Option A', + }, { - label: 'Toggle Field', - checked: toggleField, - onChange: onChangeToggleField - } - ), - el( - SelectControl, + value: 'b', + label: 'Option B', + }, { - label: 'Select Field', - value: selectField, - options: [ - { - value: 'a', - label: 'Option A' - }, - { - value: 'b', - label: 'Option B' - }, - { - value: 'c', - label: 'Option C' - } - ], - onChange: onChangeSelectField - } - ) - ), - el( - RichText, - Object.assing( blockProps, { - key: 'editable', - tagName: 'p', - onChange: onChangeContent, - value: content - } ) - ) + value: 'c', + label: 'Option C', + }, + ], + onChange: onChangeSelectField, + } ) + ), + el( + RichText, + Object.assing( blockProps, { + key: 'editable', + tagName: 'p', + onChange: onChangeContent, + value: content, + } ) ) ); }, - save: function( props ) { - var blockProps = useBlockProps.save(); + save: function ( props ) { + var blockProps = useBlockProps.save(); var content = props.attributes.content, checkboxField = props.attributes.checkboxField, radioField = props.attributes.radioField, @@ -189,57 +173,27 @@ registerBlockType( 'my-plugin/inspector-controls-example', { return el( 'div', blockProps, - el( - RichText.Content, - { - value: content, - tagName: 'p' - } - ), - el( - 'h2', - null, - 'Inspector Control Fields' - ), + el( RichText.Content, { + value: content, + tagName: 'p', + } ), + el( 'h2', null, 'Inspector Control Fields' ), el( 'ul', null, - el( - 'li', - null, - 'Checkbox Field: ', - checkboxField - ), - el( - 'li', - null, - 'Radio Field: ', - radioField - ), - el( - 'li', - null, - 'Text Field: ', - textField - ), - el( - 'li', - null, - 'Toggle Field: ', - toggleField - ), - el( - 'li', - null, - 'Select Field: ', - selectField - ) + el( 'li', null, 'Checkbox Field: ', checkboxField ), + el( 'li', null, 'Radio Field: ', radioField ), + el( 'li', null, 'Text Field: ', textField ), + el( 'li', null, 'Toggle Field: ', toggleField ), + el( 'li', null, 'Select Field: ', selectField ) ) ); }, } ); ``` + {% ESNext %} + ```js import { registerBlockType } from '@wordpress/blocks'; import { @@ -247,12 +201,12 @@ import { RadioControl, TextControl, ToggleControl, - SelectControl + SelectControl, } from '@wordpress/components'; import { RichText, InspectorControls, - useBlockProps + useBlockProps, } from '@wordpress/block-editor'; registerBlockType( 'my-plugin/inspector-controls-example', { @@ -291,7 +245,14 @@ registerBlockType( 'my-plugin/inspector-controls-example', { edit( { attributes, setAttributes } ) { const blockProps = useBlockProps(); - const { content, checkboxField, radioField, textField, toggleField, selectField } = attributes; + const { + content, + checkboxField, + radioField, + textField, + toggleField, + selectField, + } = attributes; function onChangeContent( newContent ) { setAttributes( { content: newContent } ); @@ -320,7 +281,6 @@ registerBlockType( 'my-plugin/inspector-controls-example', { return ( <> - @@ -357,16 +315,13 @@ registerBlockType( 'my-plugin/inspector-controls-example', { - - +

Inspector Control Fields

    @@ -404,4 +363,5 @@ registerBlockType( 'my-plugin/inspector-controls-example', { }, } ); ``` + {% end %} diff --git a/packages/block-editor/src/components/justify-content-control/README.md b/packages/block-editor/src/components/justify-content-control/README.md index b98ba0d38693cb..e46542a97b5169 100644 --- a/packages/block-editor/src/components/justify-content-control/README.md +++ b/packages/block-editor/src/components/justify-content-control/README.md @@ -29,46 +29,46 @@ const MyJustifyToolbar = ( { attributes, setAttributes } ) => ( **NOTE:** The justfify toolbar does not add any classes to your component, you must do this using the `setAttributes` function. The toolbar does define the following classnames you should use: - items-justified-left - items-justified-center - items-justified-right - items-justified-space-between - + items-justified-left + items-justified-center + items-justified-right + items-justified-space-between _Note:_ In this example that we render `JustifyContentControl` as a child of the `BlockControls` component. - ### Props #### `allowedControls` -* **Type:** `string[]` -* **Default:** `[ 'left', 'center', 'right', 'space-between' ]` + +- **Type:** `string[]` +- **Default:** `[ 'left', 'center', 'right', 'space-between' ]` An array of strings for what controls to show, by default it shows all. #### `onChange` -* **Type:** `Function` -* **Required:** Yes -A callback function invoked when the toolbar's justification value is changed via an interaction with any of the toolbar's buttons. Called with the new alignment value (ie: `left`, `center`, `right`, `space-between`, `undefined`) as the only argument. +- **Type:** `Function` +- **Required:** Yes +A callback function invoked when the toolbar's justification value is changed via an interaction with any of the toolbar's buttons. Called with the new alignment value (ie: `left`, `center`, `right`, `space-between`, `undefined`) as the only argument. #### `popoverProps` -* **Type:** `Object` -* **Required:** No + +- **Type:** `Object` +- **Required:** No Properties of `popoverProps` object will be passed as props to the nested `Popover` component. Use this object to modify props available for the `Popover` component that are not already exposed in the `DropdownMenu` component, e.g.: the direction in which the popover should open relative to its parent node set with `position` prop. #### `value` -* **Type:** `String` -* **Default:** `undefined` -* **Options:**: `left`, `center`, `right`, `space-between` + +- **Type:** `String` +- **Default:** `undefined` +- **Options:**: `left`, `center`, `right`, `space-between` The current value of the alignment setting. You may only choose from the `Options` listed above. ## Related components Block Editor components are components that can be used to compose the UI of your block editor. Thus, they can only be used under a [`BlockEditorProvider`](https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/provider/README.md) in the components tree. - diff --git a/packages/block-editor/src/components/line-height-control/README.md b/packages/block-editor/src/components/line-height-control/README.md index 8930c4cd1c120d..ca61544e9c541d 100644 --- a/packages/block-editor/src/components/line-height-control/README.md +++ b/packages/block-editor/src/components/line-height-control/README.md @@ -38,7 +38,6 @@ The value of the line height. A callback function that handles the application of the line height value. - ## Related components Block Editor components are components that can be used to compose the UI of your block editor. Thus, they can only be used under a [`BlockEditorProvider`](https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/provider/README.md) in the components tree. diff --git a/packages/block-editor/src/components/link-control/README.md b/packages/block-editor/src/components/link-control/README.md index d762f9893ad3ca..d143b7b5fcb3ed 100644 --- a/packages/block-editor/src/components/link-control/README.md +++ b/packages/block-editor/src/components/link-control/README.md @@ -4,7 +4,6 @@ Renders a link control. A link control is a controlled input which maintains a v It is designed to provide a standardized UI for the creation of a link throughout the Editor. - ## History Much of the context for this component can be found in [the original Issue](https://github.com/WordPress/gutenberg/issues/17557). @@ -15,7 +14,6 @@ These older UIs tended to make use of two existing components: `URLInput` and `U As a result, it was agreed that a new component `LinkControl` would be created to realise the new hyperlink creation interface. This new UI would begin life as an experimental component which would consume `URLInput` internally. The API of `URLInput` would be enhanced as required with "experimental" features to facilitate the implementation of the new UI. - ## Relationship to `` As of Gutenberg 7.4, `` became the default link creation interface within the Block Editor, replacing previous disparate uses of `` and standardizing the UI. @@ -24,9 +22,8 @@ Nonetheless, it should be remembered that `` builds **on top of** ` The distinction between the two components is perhaps best summarized by the following definitions: -* `` - an input for presenting and managing selection behaviors associated with choosing a URL, optionally from a pool of available candidates. -* `` - includes the features of ``, plus additional UI and behaviors to control how this URL applies to the concept of a "link". This includes link "settings" (eg: "opens in new tab", etc) and dynamic, "on the fly" link creation capabilities. - +- `` - an input for presenting and managing selection behaviors associated with choosing a URL, optionally from a pool of available candidates. +- `` - includes the features of ``, plus additional UI and behaviors to control how this URL applies to the concept of a "link". This includes link "settings" (eg: "opens in new tab", etc) and dynamic, "on the fly" link creation capabilities. ## Search Suggestions @@ -43,13 +40,12 @@ When this suggestion is selected it will call the `createSuggestion` prop afford By default `LinkControl` utilizes the `__experimentalFetchLinkSuggestions` API from `core/block-editor` in order to retrieve search suggestions for matching `Page` post-type entities. - ## Props ### value -- Type: `Object` -- Required: No +- Type: `Object` +- Required: No Current link value. @@ -57,15 +53,16 @@ A link `value` is composed of a union between the values of default link propert The resulting default properties of `value` include: -- `url` (`string`): Link URL. -- `title` (`string`, optional): Link title. -- `opensInNewTab` (`boolean`, optional): Whether link should open in a new browser tab. This value is only assigned when not providing a custom `settings` prop. +- `url` (`string`): Link URL. +- `title` (`string`, optional): Link title. +- `opensInNewTab` (`boolean`, optional): Whether link should open in a new browser tab. This value is only assigned when not providing a custom `settings` prop. ### settings -- Type: `Array` -- Required: No -- Default: +- Type: `Array` +- Required: No +- Default: + ``` [ { @@ -79,8 +76,8 @@ An array of settings objects associated with a link (for example: a setting to d ### onChange -- Type: `Function` -- Required: No +- Type: `Function` +- Required: No Value change handler, called with the updated value if the user selects a new link or updates settings. @@ -94,33 +91,33 @@ Value change handler, called with the updated value if the user selects a new li ### showSuggestions -- Type: `boolean` -- Required: No -- Default: `true` +- Type: `boolean` +- Required: No +- Default: `true` Whether to present suggestions when typing the URL. ### showInitialSuggestions -- Type: `boolean` -- Required: No -- Default: `false` +- Type: `boolean` +- Required: No +- Default: `false` Whether to present initial suggestions immediately. ### forceIsEditingLink -- Type: `boolean` -- Required: No +- Type: `boolean` +- Required: No Controls the internal editing state of the component. If passed as either `true` or `false` will respectively show or hide the URL input field. ### createSuggestion -- Type: `function` -- Required: No -- Returns: When called may return either a new `suggestion` directly or a `Promise` which resolves to a -new `suggestion`. +- Type: `function` +- Required: No +- Returns: When called may return either a new `suggestion` directly or a `Promise` which resolves to a + new `suggestion`. Used to handle the dynamic creation of a new `suggestion` (and ultimately new link `value`) within the Link UI. @@ -144,6 +141,7 @@ A `suggestion` should have the following shape: ``` #### Example + ```jsx // Promise example ` that caters it to `LinkControl`'s needs. +The search input used by `LinkControl`. It is a wrapper over `` that caters it to `LinkControl`'s needs. ## Props ### allowDirectEntry -- Type: `boolean` -- Required: No -- Default: `true` +- Type: `boolean` +- Required: No +- Default: `true` The opposite of `noDirectEntry` from LinkControl, refer to an earlier section of this README file for more details. ### children -- Type: `Element` -- Required: No +- Type: `Element` +- Required: No If passed, children are rendered after the input. -```jsx +```jsx -
    -
    +
    +
    ``` ### className -- Type: `string` -- Required: No -- Default: `null` +- Type: `string` +- Required: No +- Default: `null` Passed verbatim to URLInput, refer to it's README.md for more details. ### createSuggestionButtonText -- Type: `string` -- Required: No +- Type: `string` +- Required: No The same as in LinkControl, refer to an earlier section of this README file for more details. ### currentLink -- Type: `Object` -- Required: No -- Default: `{}` +- Type: `Object` +- Required: No +- Default: `{}` The same as `value` in LinkControl, refer to an earlier section of this README file for more details. ### fetchSuggestions -- Type: `Function` -- Required: No +- Type: `Function` +- Required: No Custom search handler for suggestions. If specified, it's passed to `URLInput` as `__experimentalFetchLinkSuggestions`, if not, the default handler is used. @@ -239,18 +237,18 @@ Refer to URLInput's README.md for more details about `__experimentalFetchLinkSug ### onChange -- Type: `Function` -- Required: No +- Type: `Function` +- Required: No -Value change handler passed to the underlying ``. Refer to URLInput's README.md for more details. +Value change handler passed to the underlying ``. Refer to URLInput's README.md for more details. ### onCreateSuggestion -- Type: `Function` -- Required: No +- Type: `Function` +- Required: No By default, when there are no matching results, LinkControlSearchInput proposes creating a new page by rendering a suggestion with -`{ type: __CREATE__, title: <> }` properties. This function is called when that suggestion is selected. +`{ type: __CREATE__, title: <> }` properties. This function is called when that suggestion is selected. See the [createSuggestion](#createSuggestion) section of this file to learn more about suggestions. @@ -264,44 +262,44 @@ See the [createSuggestion](#createSuggestion) section of this file to learn more ### onSelect -- Type: `Function` -- Required: No +- Type: `Function` +- Required: No -Suggestion selection handler, called when the user chooses one of the suggested items with `selectedValues` as the argument. +Suggestion selection handler, called when the user chooses one of the suggested items with `selectedValues` as the argument. ### placeholder -- Type: `string` -- Required: No +- Type: `string` +- Required: No Passed verbatim to URLInput, refer to it's README.md for more details. ### renderSuggestions -- Type: `Function` -- Required: No -- Default: `(props) => ` +- Type: `Function` +- Required: No +- Default: `(props) => ` Function used to render search suggestions. It is decorated with extra properties and passed to `URLInput` as `__experimentalRenderSuggestions`. The following properties are provided by URLInput: -* buildSuggestionItemProps -* handleSuggestionClick -* isInitialSuggestions -* isLoading -* suggestions -* selectedSuggestion -* suggestionsListProps +- buildSuggestionItemProps +- handleSuggestionClick +- isInitialSuggestions +- isLoading +- suggestions +- selectedSuggestion +- suggestionsListProps The following extra properties are provided by LinkControlSearchInput: -* currentInputValue -* createSuggestionButtonText -* handleSuggestionClick -* instanceId -* suggestionsQuery -* withCreateSuggestion +- currentInputValue +- createSuggestionButtonText +- handleSuggestionClick +- instanceId +- suggestionsQuery +- withCreateSuggestion See the [createSuggestion](#createSuggestion) section of this file to learn more about suggestions. @@ -333,67 +331,67 @@ See the [createSuggestion](#createSuggestion) section of this file to learn more ### showInitialSuggestions -- Type: `boolean` -- Required: No -- Default: `false` +- Type: `boolean` +- Required: No +- Default: `false` The same as in LinkControl, refer to an earlier section of this README file for more details. ### showSuggestions -- Type: `boolean` -- Required: No -- Default: `true` +- Type: `boolean` +- Required: No +- Default: `true` The same as in LinkControl, refer to an earlier section of this README file for more details. ### suggestionsQuery -- Type: `Object` -- Required: No -- Default: `{}` +- Type: `Object` +- Required: No +- Default: `{}` The same as in LinkControl, refer to an earlier section of this README file for more details. ### withCreateSuggestion -- Type: `boolean` -- Required: No -- Default: `true` +- Type: `boolean` +- Required: No +- Default: `true` The same as in LinkControl, refer to an earlier section of this README file for more details. ### value -- Type: `string` -- Required: No +- Type: `string` +- Required: No Passed verbatim to URLInput, refer to it's README.md for more details. # LinkControlSearchResults -The list of search results used by `LinkControlSearchInput`. +The list of search results used by `LinkControlSearchInput`. ## Props ### buildSuggestionItemProps -- Type: `Function` -- Required: Yes +- Type: `Function` +- Required: Yes -Function that takes `suggestion` and `index` as arguments, and returns HTML props of the suggestion item. When this component is used with `LinkControlSearchInput`, this property is provided by `URLInput`. +Function that takes `suggestion` and `index` as arguments, and returns HTML props of the suggestion item. When this component is used with `LinkControlSearchInput`, this property is provided by `URLInput`. ### currentInputValue -- Type: `string` -- Required: Yes +- Type: `string` +- Required: Yes Current value of the related search input, used e.g. for highlighting matching part of the page title. When this component is used with `LinkControlSearchInput`, this property is provided by `LinkControlSearchInput`. ### handleSuggestionClick - -- Type: `Function` -- Required: Yes + +- Type: `Function` +- Required: Yes Called with `suggestion` as the argument, when said suggestion is clicked by the user. When this component is used with `LinkControlSearchInput`, this property is provided by `LinkControlSearchInput`. @@ -401,64 +399,64 @@ See the [createSuggestion](#createSuggestion) section of this file to learn more ### instanceId -- Type: `string` -- Required: Yes +- Type: `string` +- Required: Yes Unique ID of parent component, used for the aria-label property. When this component is used with `LinkControlSearchInput`, this property is provided by `LinkControlSearchInput`. ### isLoading -- Type: `boolean` -- Required: Yes +- Type: `boolean` +- Required: Yes Whether the suggestions are being fetched at the moment. When this component is used with `LinkControlSearchInput`, this property is provided by `URLInput`. ### isInitialSuggestions -- Type: `boolean` -- Required: No +- Type: `boolean` +- Required: No -Whether this component was rendered to show initial suggestions (the ones displayed right after mounting, before the user begins interacting with LinkControl). +Whether this component was rendered to show initial suggestions (the ones displayed right after mounting, before the user begins interacting with LinkControl). ### selectedSuggestion -- Type: `Object` -- Required: Yes +- Type: `Object` +- Required: Yes The suggestions that is currently selected. When this component is used with `LinkControlSearchInput`, this property is provided by `LinkControlSearchInput`. ### suggestions -- Type: `Array` -- Required: Yes +- Type: `Array` +- Required: Yes The list of suggestions to render. When this component is used with `LinkControlSearchInput`, this property is provided by `URLInput`. ### suggestionsListProps -- Type: `Object` -- Required: No +- Type: `Object` +- Required: No List of additional HTML properties passed to the element wrapping the list of suggestions. When this component is used with `LinkControlSearchInput`, this property is provided by `URLInput`. ### createSuggestionButtonText -- Type: `string` -- Required: No +- Type: `string` +- Required: No The same as in LinkControl, refer to an earlier section of this README file for more details. ### suggestionsQuery -- Type: `Object` -- Required: No +- Type: `Object` +- Required: No The same as in LinkControl, refer to an earlier section of this README file for more details. ### withCreateSuggestion -- Type: `boolean` -- Required: No +- Type: `boolean` +- Required: No The same as in LinkControl, refer to an earlier section of this README file for more details. @@ -470,53 +468,53 @@ A single suggestion rendered by `LinkControlSearchResults`. ### itemProps -- Type: `Object` -- Required: No +- Type: `Object` +- Required: No -A list of extra HTML properties for the root element rendered by this component. +A list of extra HTML properties for the root element rendered by this component. ### isSelected -- Type: `boolean` -- Required: No -- Default: `false` +- Type: `boolean` +- Required: No +- Default: `false` Whether this item represents a selected suggestion. ### isURL -- Type: `boolean` -- Required: No -- Default: `false` +- Type: `boolean` +- Required: No +- Default: `false` Whether this item represents a suggestion referring to a URL (e.g. post, page). ### onClick -- Type: `Function` -- Required: Yes +- Type: `Function` +- Required: Yes Click handler, called with click event as the only argument. ### searchTerm -- Type: `string` -- Required: Yes +- Type: `string` +- Required: Yes The search term as specified by the user. Used for highlighting the matching part of the suggestion title. ### shouldShowType -- Type: `boolean` -- Required: No -- Default: `false` +- Type: `boolean` +- Required: No +- Default: `false` If true, type of the suggestion is rendered (e.g. post, tag) ### suggestion -- Type: `Object` -- Required: Yes +- Type: `Object` +- Required: Yes The suggestion to render. diff --git a/packages/block-editor/src/components/media-placeholder/README.md b/packages/block-editor/src/components/media-placeholder/README.md index da47806e7b14f3..dc50d50f78a26e 100644 --- a/packages/block-editor/src/components/media-placeholder/README.md +++ b/packages/block-editor/src/components/media-placeholder/README.md @@ -1,5 +1,4 @@ -MediaPlaceholder -=========== +# MediaPlaceholder `MediaPlaceholder` is a React component used to render either the media associated with a block, or an editing interface to replace the media for a block. @@ -37,19 +36,19 @@ A string passed to `FormFileUpload` that tells the browser which file types can More information about this string is available in https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#Unique_file_type_specifiers. This property is similar to the `allowedTypes` property. The difference is the format and the fact that this property affects the behavior of `FormFileUpload` while `allowedTypes` affects the behavior `MediaUpload`. -- Type: `String` -- Required: No -- Platform: Web +- Type: `String` +- Required: No +- Platform: Web ### addToGallery -If true, and if `gallery === true` the gallery media modal opens directly in the media library where the user can add additional images. When uploading/selecting files on the placeholder, the placeholder appends the files to the existing files list. +If true, and if `gallery === true` the gallery media modal opens directly in the media library where the user can add additional images. When uploading/selecting files on the placeholder, the placeholder appends the files to the existing files list. If false the gallery media modal opens in the edit mode where the user can edit existing images, by reordering them, remove them, or change their attributes. When uploading/selecting files on the placeholder the files replace the existing files list. -- Type: `Boolean` -- Required: No -- Default: `false` -- Platform: Web +- Type: `Boolean` +- Required: No +- Default: `false` +- Platform: Web ### allowedTypes @@ -59,125 +58,126 @@ or the complete mime type e.g: `audio/mpeg`, `image/gif`. If allowedTypes is unset all mime types should be allowed. This property is similar to the `accept` property. The difference is the format and the fact that this property affects the behavior of `MediaUpload` while `accept` affects the behavior `FormFileUpload`. -- Type: `Array` -- Required: No -- Platform: Web | Mobile +- Type: `Array` +- Required: No +- Platform: Web | Mobile ### className Class name added to the placeholder. -- Type: `String` -- Required: No -- Platform: Web +- Type: `String` +- Required: No +- Platform: Web ### disableDropZone If true, the Drop Zone will not be rendered. Users won't be able to drag & drop any media into the component or the block. The UI controls to upload the media via file, url or the media library would be intact. -- Type: `Boolean` -- Required: No -- Default: `false` +- Type: `Boolean` +- Required: No +- Default: `false` ### dropZoneUIOnly If true, only the Drop Zone will be rendered. No UI controls to upload the media will be shown. The `disableDropZone` prop still takes precedence over `dropZoneUIOnly` – specifying both as true will result in nothing to be rendered. -- Type: `Boolean` -- Required: No -- Default: `false` +- Type: `Boolean` +- Required: No +- Default: `false` ### icon Icon to display left of the title. When passed as a `String`, the icon will be resolved as a [Dashicon](https://developer.wordpress.org/resource/dashicons/). Alternatively, you can pass in a `WPComponent` such as `BlockIcon`to render instead. -- Type: `String|WPComponent` -- Required: No -- Platform: Web | Mobile +- Type: `String|WPComponent` +- Required: No +- Platform: Web | Mobile ### isAppender If true, the property changes the look of the placeholder to be adequate to scenarios where new files are added to an already existing set of files, e.g., adding files to a gallery. If false the default placeholder style is used. -- Type: `Boolean` -- Required: No -- Default: `false` -- Platform: Web | Mobile +- Type: `Boolean` +- Required: No +- Default: `false` +- Platform: Web | Mobile ### disableMediaButtons If true, only the Drop Zone will be rendered. No UI controls to upload the media will be shown -- Type: `Boolean` -- Required: No -- Default: `false` -- Platform: Web | Mobile +- Type: `Boolean` +- Required: No +- Default: `false` +- Platform: Web | Mobile ### labels An object that can contain a `title` and `instructions` properties. These properties are passed to the placeholder component as `label` and `instructions` respectively. -- Type: `Object` -- Required: No -- Platform: Web | Mobile +- Type: `Object` +- Required: No +- Platform: Web | Mobile ### multiple Whether to allow multiple selection of files or not. -- Type: `Boolean` -- Required: No -- Default: `false` -- Platform: Web +- Type: `Boolean` +- Required: No +- Default: `false` +- Platform: Web ### onError Callback called when an upload error happens. -- Type: `Function` -- Required: No -- Platform: Web +- Type: `Function` +- Required: No +- Platform: Web ### onFilesPreUpload + Callback called before to start to upload the files. -It receives an array with the files to upload before to the final process. It means that it's possible these files couldn't be uploaded. +It receives an array with the files to upload before to the final process. It means that it's possible these files couldn't be uploaded. -- Type: `Function` -- Required: No -- Default: `Function` noop -- Platform: Web +- Type: `Function` +- Required: No +- Default: `Function` noop +- Platform: Web ### onSelect Callback called when the files are selected/uploaded. The call back receives an array with the new files. Each element of the collection is an object containing the media properties of the file e.g.: `url`, `id`,... -- Type: `Function` -- Required: Yes -- Platform: Web | Mobile +- Type: `Function` +- Required: Yes +- Platform: Web | Mobile The argument of the callback is an object containing the following properties: -- Web: `{ url, alt, id, link, caption, sizes, media_details }` -- Mobile: `{ id, url }` + +- Web: `{ url, alt, id, link, caption, sizes, media_details }` +- Mobile: `{ id, url }` ### value An object or an array of objects that contain media ID (`id` property) to be selected by default when opening the media library. -- Type: `Object|Array` -- Required: No -- Platform: Web +- Type: `Object|Array` +- Required: No +- Platform: Web ### onSelectURL Callback called when urls can be configured. No media insertion from url will be available if not set. -- Type: `Function` -- Required: No -- Platform: Web - +- Type: `Function` +- Required: No +- Platform: Web ## Extend @@ -189,13 +189,13 @@ Replace implementation of the placeholder: ```js function replaceMediaPlaceholder() { - return function() { + return function () { return wp.element.createElement( 'div', {}, 'The replacement contents or components.' ); - } + }; } wp.hooks.addFilter( diff --git a/packages/block-editor/src/components/media-replace-flow/README.md b/packages/block-editor/src/components/media-replace-flow/README.md index d9e5d53f77b354..2f462b9414da49 100644 --- a/packages/block-editor/src/components/media-replace-flow/README.md +++ b/packages/block-editor/src/components/media-replace-flow/README.md @@ -2,9 +2,9 @@ A component that implements a replacement flow for various media objects. It is used to allow various blocks that use media to have a toolbar button for replacing it. I offers several options, such as: -- replace from Media Library -- replace using an URL -- replace by uploading new media +- replace from Media Library +- replace using an URL +- replace by uploading new media This component should be used as a child of a `` component. @@ -14,65 +14,65 @@ This component should be used as a child of a `` component. The URL of the media. -- Type: `string` -- Required: Yes +- Type: `string` +- Required: Yes ### mediaId The Id of the attachment post type for the current media. -- Type: `Int` -- Required: No +- Type: `Int` +- Required: No ### allowedTypes A list of media types allowed to replace the current media. -- Type: `Array` -- Required: Yes +- Type: `Array` +- Required: Yes ### accept Comma delimited list of MIME types accepted for upload. -- Type: `string` -- Required: Yes +- Type: `string` +- Required: Yes ### onFilesUpload -Callback called before to start to upload the files. It receives an array with the files to upload before to the final process. +Callback called before to start to upload the files. It receives an array with the files to upload before to the final process. ### onSelect Callback used when media is replaced from the Media Library or when a new media is uploaded. It is called with one argument `media` which is an object with all the media details. -- Type: `func` -- Required: Yes +- Type: `func` +- Required: Yes ### onSelectURL Callback used when media is replaced with an URL. It is called with one argument `newURL` which is a `string` containing the new URL. -- Type: `func` -- Required: Yes +- Type: `func` +- Required: Yes ### name The label of the replace button. -- Type: `string` -- Required: No +- Type: `string` +- Required: No ### createNotice Creates a media replace notice. -- Type: `func` -- Required: No +- Type: `func` +- Required: No ### removeNotice Removes a media replace notice. -- Type: `func` -- Required: No +- Type: `func` +- Required: No diff --git a/packages/block-editor/src/components/media-upload-progress/README.md b/packages/block-editor/src/components/media-upload-progress/README.md index 9447ac4d065c68..3a7ac3e5cfa4a7 100644 --- a/packages/block-editor/src/components/media-upload-progress/README.md +++ b/packages/block-editor/src/components/media-upload-progress/README.md @@ -1,5 +1,4 @@ -MediaUploadProgress -=================== +# MediaUploadProgress `MediaUploadProgress` shows a progress bar while a media file associated with a block is being uploaded. @@ -9,9 +8,7 @@ Usage example ```jsx import { ImageBackground, Text, View } from 'react-native'; -import { - MediaUploadProgress, -} from '@wordpress/block-editor'; +import { MediaUploadProgress } from '@wordpress/block-editor'; function MediaProgress( { url, id } ) { return ( @@ -23,11 +20,11 @@ function MediaProgress( { url, id } ) { resizeMethod="scale" source={ { uri: url } } > - { isUploadFailed && + { isUploadFailed && ( { retryMessage } - } + ) } ); } } @@ -42,17 +39,17 @@ function MediaProgress( { url, id } ) { A media ID that identifies the current upload. -- Type: `Number` -- Required: Yes -- Platform: Mobile +- Type: `Number` +- Required: Yes +- Platform: Mobile ### renderContent Content to be rendered along with the progress bar, usually the thumbnail of the media being uploaded. -- Type: `React components` -- Required: Yes -- Platform: Mobile +- Type: `React components` +- Required: Yes +- Platform: Mobile It passes an object containing the following properties: @@ -62,9 +59,9 @@ It passes an object containing the following properties: Callback called when the progress of the upload is updated. -- Type: `Function` -- Required: No -- Platform: Mobile +- Type: `Function` +- Required: No +- Platform: Mobile The argument of the callback is an object containing the following properties: @@ -74,9 +71,9 @@ The argument of the callback is an object containing the following properties: Callback called when the media file has been uploaded successfully. -- Type: `Function` -- Required: No -- Platform: Mobile +- Type: `Function` +- Required: No +- Platform: Mobile The argument of the callback is an object containing the following properties: @@ -86,20 +83,18 @@ The argument of the callback is an object containing the following properties: Callback called when the media file couldn't be uploaded. -- Type: `Function` -- Required: No -- Platform: Mobile +- Type: `Function` +- Required: No +- Platform: Mobile The argument of the callback is an object containing the following properties: `{ mediaId, progress, state }` - ### onMediaUploadStateReset Callback called when the media upload is reset -- Type: `Function` -- Required: No -- Platform: Mobile - +- Type: `Function` +- Required: No +- Platform: Mobile diff --git a/packages/block-editor/src/components/media-upload/README.md b/packages/block-editor/src/components/media-upload/README.md index 95d612599b51da..9e96d8564e536f 100644 --- a/packages/block-editor/src/components/media-upload/README.md +++ b/packages/block-editor/src/components/media-upload/README.md @@ -1,5 +1,4 @@ -MediaUpload -=========== +# MediaUpload MediaUpload is a React component used to render a button that opens the WordPress media modal. @@ -36,13 +35,13 @@ function MyMediaUploader() { return ( console.log( 'selected ' + media.length ) } + onSelect={ ( media ) => + console.log( 'selected ' + media.length ) + } allowedTypes={ ALLOWED_MEDIA_TYPES } value={ mediaId } render={ ( { open } ) => ( - + ) } /> @@ -61,26 +60,26 @@ Each type is a string that can contain the general mime type e.g: 'image', 'audi or the complete mime type e.g: 'audio/mpeg', 'image/gif'. If allowedTypes is unset all mime types should be allowed. -- Type: `Array` -- Required: No -- Platform: Web | Mobile +- Type: `Array` +- Required: No +- Platform: Web | Mobile ### multiple Whether to allow multiple selections or not. -- Type: `Boolean` -- Required: No -- Default: false -- Platform: Web +- Type: `Boolean` +- Required: No +- Default: false +- Platform: Web ### value Media ID (or media IDs if multiple is true) to be selected by default when opening the media library. -- Type: `Number|Array` -- Required: No -- Platform: Web +- Type: `Number|Array` +- Required: No +- Platform: Web ### onClose @@ -88,35 +87,35 @@ Callback called when the media modal is closed. This is called both when media is selected and when the user closes the modal without making a selection. -- Type: `Function` -- Required: No +- Type: `Function` +- Required: No ### onSelect -Callback called when the media modal is closed after media is selected. +Callback called when the media modal is closed after media is selected. This is called subsequent to `onClose` when media is selected. The selected media are passed as an argument. -- Type: `Function` -- Required: Yes -- Platform: Web | Mobile +- Type: `Function` +- Required: Yes +- Platform: Web | Mobile ### title Title displayed in the media modal. -- Type: `String` -- Required: No -- Default: `Select or Upload Media` -- Platform: Web +- Type: `String` +- Required: No +- Default: `Select or Upload Media` +- Platform: Web ### modalClass CSS class added to the media modal frame. -- Type: `String` -- Required: No -- Platform: Web +- Type: `String` +- Required: No +- Platform: Web ### addToGallery @@ -124,28 +123,28 @@ If true, the gallery media modal opens directly in the media library where the u If false the gallery media modal opens in the edit mode where the user can edit existing images, by reordering them, remove them, or change their attributes. Only applies if `gallery === true`. -- Type: `Boolean` -- Required: No -- Default: `false` -- Platform: Web +- Type: `Boolean` +- Required: No +- Default: `false` +- Platform: Web ### gallery If true, the component will initiate all the states required to represent a gallery. By default, the media modal opens in the gallery edit frame, but that can be changed using the `addToGallery`flag. -- Type: `Boolean` -- Required: No -- Default: `false` -- Platform: Web +- Type: `Boolean` +- Required: No +- Default: `false` +- Platform: Web ## render A callback invoked to render the Button opening the media library. -- Type: `Function` -- Required: Yes -- Platform: Web | Mobile +- Type: `Function` +- Required: Yes +- Platform: Web | Mobile The first argument of the callback is an object containing the following properties: - - `open`: A function opening the media modal when called +- `open`: A function opening the media modal when called diff --git a/packages/block-editor/src/components/multi-selection-inspector/README.md b/packages/block-editor/src/components/multi-selection-inspector/README.md index 285dac0cdca67e..e7edc7ef2f43da 100644 --- a/packages/block-editor/src/components/multi-selection-inspector/README.md +++ b/packages/block-editor/src/components/multi-selection-inspector/README.md @@ -27,8 +27,8 @@ if ( SelectedBlockCount > 1 ) { } ``` - _Note:_ In this example, we detect if more than one block is selected with `getSelectedBlockCount()` before using the `MultiSelectionInspector` component. +_Note:_ In this example, we detect if more than one block is selected with `getSelectedBlockCount()` before using the `MultiSelectionInspector` component. ## Related components -Block Editor components are components that can be used to compose the UI of your block editor. Thus, they can only be used under a [`BlockEditorProvider`](https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/provider/README.md) in the components tree. \ No newline at end of file +Block Editor components are components that can be used to compose the UI of your block editor. Thus, they can only be used under a [`BlockEditorProvider`](https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/provider/README.md) in the components tree. diff --git a/packages/block-editor/src/components/observe-typing/README.md b/packages/block-editor/src/components/observe-typing/README.md index 06f5e85bfdc878..c589c6903416d7 100644 --- a/packages/block-editor/src/components/observe-typing/README.md +++ b/packages/block-editor/src/components/observe-typing/README.md @@ -1,5 +1,4 @@ -Observe Typing -============== +# Observe Typing `` is a component used in managing the editor's internal typing flag. When used to wrap content — typically the top-level block list — it observes keyboard and mouse events to set and unset the typing flag. The typing flag is used in considering whether the block border and controls should be visible. While typing, these elements are hidden for a distraction-free experience. diff --git a/packages/block-editor/src/components/plain-text/README.md b/packages/block-editor/src/components/plain-text/README.md index 74e8832d519c7e..64d1c04b5c09bc 100644 --- a/packages/block-editor/src/components/plain-text/README.md +++ b/packages/block-editor/src/components/plain-text/README.md @@ -6,22 +6,23 @@ Render an auto-growing textarea allow users to fill any textual content. ### `value: string` -*Required.* String value of the textarea +_Required._ String value of the textarea ### `onChange( value: string ): Function` -*Required.* Called when the value changes. +_Required._ Called when the value changes. You can also pass any extra prop to the textarea rendered by this component. ### `ref: Object` -*Optional.* The component forwards the `ref` property to the `TextareaAutosize` component. +_Optional._ The component forwards the `ref` property to the `TextareaAutosize` component. ## Example {% codetabs %} {% ES5 %} + ```js wp.blocks.registerBlockType( /* ... */, { // ... @@ -43,7 +44,9 @@ wp.blocks.registerBlockType( /* ... */, { }, } ); ``` + {% ESNext %} + ```js const { registerBlockType } = wp.blocks; const { PlainText } = wp.editor; @@ -68,4 +71,5 @@ registerBlockType( /* ... */, { }, } ); ``` + {% end %} diff --git a/packages/block-editor/src/components/provider/README.md b/packages/block-editor/src/components/provider/README.md index 647c5854d0e21a..8d78e5b85db0e7 100644 --- a/packages/block-editor/src/components/provider/README.md +++ b/packages/block-editor/src/components/provider/README.md @@ -1,5 +1,4 @@ -BlockEditorProvider -=================== +# BlockEditorProvider BlockEditorProvider is a component which establishes a new block editing context, and serves as the entry point for a new block editor. It is implemented as a [controlled input](https://reactjs.org/docs/forms.html#controlled-components), expected to receive a value of a blocks array, calling `onChange` and/or `onInput` when the user interacts to change blocks in the editor. It is intended to be used as a wrapper component, where its children comprise the user interface through which a user modifies the blocks value, notably via other components made available from this `block-editor` module. @@ -7,34 +6,34 @@ BlockEditorProvider is a component which establishes a new block editing context ### `value` -* **Type:** `Array` -* **Required** `no` +- **Type:** `Array` +- **Required** `no` The current array of blocks. ### `onChange` -* **Type:** `Function` -* **Required** `no` +- **Type:** `Function` +- **Required** `no` A callback invoked when the blocks have been modified in a persistent manner. Contrasted with `onInput`, a "persistent" change is one which is not an extension of a composed input. Any update to a distinct block or block attribute is treated as persistent. The distinction between these two callbacks is akin to the [differences between `input` and `change` events](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/input_event) in the DOM API: ->The input event is fired every time the value of the element changes. **This is unlike the change event, which only fires when the value is committed**, such as by pressing the enter key, selecting a value from a list of options, and the like. +> The input event is fired every time the value of the element changes. **This is unlike the change event, which only fires when the value is committed**, such as by pressing the enter key, selecting a value from a list of options, and the like. In the context of an editor, an example usage of this distinction is for managing a history of blocks values (an "Undo"/"Redo" mechanism). While value updates should always be reflected immediately (`onInput`), you may only want history entries to reflect change milestones (`onChange`). ### `onInput` -* **Type:** `Function` -* **Required** `no` +- **Type:** `Function` +- **Required** `no` A callback invoked when the blocks have been modified in a non-persistent manner. Contrasted with `onChange`, a "non-persistent" change is one which is part of a composed input. Any sequence of updates to the same block attribute are treated as non-persistent, except for the first. ### `children` -* **Type:** `WPElement` -* **Required** `no` +- **Type:** `WPElement` +- **Required** `no` Children elements for which the BlockEditorProvider context should apply. diff --git a/packages/block-editor/src/components/responsive-block-control/README.md b/packages/block-editor/src/components/responsive-block-control/README.md index deabc0bc4af4c7..df14774e1d71fa 100644 --- a/packages/block-editor/src/components/responsive-block-control/README.md +++ b/packages/block-editor/src/components/responsive-block-control/README.md @@ -1,13 +1,12 @@ -ResponsiveBlockControl -============================= +# ResponsiveBlockControl `ResponsiveBlockControl` provides a standardised interface for the creation of Block controls that require **different settings per viewport** (ie: "responsive" settings). -For example, imagine your Block provides a control which affords the ability to change a "padding" value used in the Block display. Consider that whilst this setting may work well on "large" screens, the same value may not work well on smaller screens (it may be too large for example). As a result, you now need to provide a padding control _per viewport/screensize_. +For example, imagine your Block provides a control which affords the ability to change a "padding" value used in the Block display. Consider that whilst this setting may work well on "large" screens, the same value may not work well on smaller screens (it may be too large for example). As a result, you now need to provide a padding control _per viewport/screensize_. -`ResponsiveBlockControl` provides a standardised component for the creation of such interfaces within Gutenberg. +`ResponsiveBlockControl` provides a standardised component for the creation of such interfaces within Gutenberg. -Complete control over rendering the controls is provided and the viewport sizes used are entirely customisable. +Complete control over rendering the controls is provided and the viewport sizes used are entirely customisable. Note that `ResponsiveBlockControl` does not handle any persistence of your control values. The control you provide to `ResponsiveBlockControl` as the `renderDefaultControl` prop should take care of this. @@ -15,11 +14,10 @@ Note that `ResponsiveBlockControl` does not handle any persistence of your contr In a block's `edit` implementation, render a `` component passing the required props plus: -1. a `renderDefaultControl` function which renders an interface control. +1. a `renderDefaultControl` function which renders an interface control. 2. an boolean state for `isResponsive` (see "Props" below). 3. a handler function for `onIsResponsiveChange` (see "Props" below). - By default the default control will be used to render the default (ie: "All") setting _as well as_ the per-viewport responsive settings. ```jsx @@ -41,7 +39,7 @@ registerBlockType( 'my-plugin/my-block', { edit( { attributes, setAttributes } ) { const [ isResponsive, setIsResponsive ] = useState( false ); - + // Used for example purposes only const sizeOptions = [ { @@ -60,7 +58,7 @@ registerBlockType( 'my-plugin/my-block', { const { paddingSize } = attributes; - + // Your custom control can be anything you'd like to use. // You are not restricted to `DimensionControl`s, but this // makes life easier if dealing with standard CSS values. @@ -100,85 +98,88 @@ registerBlockType( 'my-plugin/my-block', { ## Props ### `title` -* **Type:** `String` -* **Default:** `undefined` -* **Required:** `true` -The title of the control group used in the `fieldset`'s `legend` element to label the _entire_ set of controls. +- **Type:** `String` +- **Default:** `undefined` +- **Required:** `true` + +The title of the control group used in the `fieldset`'s `legend` element to label the _entire_ set of controls. ### `property` -* **Type:** `String` -* **Default:** `undefined` -* **Required:** `true` -Used to build accessible labels and ARIA roles for the control group. Should represent the layout property which the component controls (eg: `padding`, `margin`...etc). +- **Type:** `String` +- **Default:** `undefined` +- **Required:** `true` + +Used to build accessible labels and ARIA roles for the control group. Should represent the layout property which the component controls (eg: `padding`, `margin`...etc). ### `isResponsive` -* **Type:** `Boolean` -* **Default:** `false` ) -* **Required:** `false` + +- **Type:** `Boolean` +- **Default:** `false` ) +- **Required:** `false` Determines whether the component displays the default or responsive controls. Updates the state of the toggle control. See also `onIsResponsiveChange` below. ### `onIsResponsiveChange` -* **Type:** `Function` -* **Default:** `undefined` -* **Required:** `true` + +- **Type:** `Function` +- **Default:** `undefined` +- **Required:** `true` A callback function invoked when the component's toggle value is changed between responsive and non-responsive mode. Should be used to update the value of the `isResponsive` prop to reflect the current state of the toggle control. ### `renderDefaultControl` -* **Type:** `Function` -* **Default:** `undefined` -* **Required:** `true` -* **Args:** - - **labelComponent:** (`Function`) - a rendered `ResponsiveBlockControlLabel` component for your control. - - **viewport:** (`Object`) - an object representing viewport attributes for your control. -A render function (prop) used to render the control for which you would like to display per viewport settings. +- **Type:** `Function` +- **Default:** `undefined` +- **Required:** `true` +- **Args:** + - **labelComponent:** (`Function`) - a rendered `ResponsiveBlockControlLabel` component for your control. + - **viewport:** (`Object`) - an object representing viewport attributes for your control. + +A render function (prop) used to render the control for which you would like to display per viewport settings. For example, if you have a `SelectControl` which controls padding size, then pass this component as `renderDefaultControl` and it will be used to render both default and "responsive" controls for "padding". -The component you return from this function will be used to render the control displayed for the (default) "All" state and (if the `renderResponsiveControls` is not provided) the individual responsive controls when in "responsive" mode. +The component you return from this function will be used to render the control displayed for the (default) "All" state and (if the `renderResponsiveControls` is not provided) the individual responsive controls when in "responsive" mode. It is passed a pre-created, accessible `
) }

Type ~ for triggering the autocomplete.

diff --git a/packages/components/src/base-control/README.md b/packages/components/src/base-control/README.md index 854a2420c9497d..6ed5b75b76b333 100644 --- a/packages/components/src/base-control/README.md +++ b/packages/components/src/base-control/README.md @@ -2,22 +2,16 @@ BaseControl component is used to generate labels and help text for components handling user inputs. - ## Usage Render a BaseControl for a textarea input: + ```jsx import { BaseControl } from '@wordpress/components'; const MyBaseControl = () => ( - -