Skip to content

Commit

Permalink
Update docs to avoid recommending anti-pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
getdave committed Jan 30, 2024
1 parent 4853ce5 commit 1127a5d
Showing 1 changed file with 23 additions and 5 deletions.
28 changes: 23 additions & 5 deletions lib/README.md
Expand Up @@ -12,9 +12,9 @@ The following documentation is intended to act as a guide only. If you're unsure

To make it easier for contributors to identify features that should be merged into Core and those that can be deleted, Gutenberg uses the following file structure for its PHP code:

- `lib/experimental` - Experimental features that exist only in the plugin. They should not be merged into Core.
- `lib/compat/wordpress-X.Y` - Stable features that are intended to be merged into Core in a future `X.Y` release, or that were previously merged to Core in the `X.Y` release and remain in the plugin for backwards compatibility when running the plugin on older versions of WordPress.
- `lib/compat/plugin` - Features for backwards compatibility for the plugin consumers. These files don't need to be merged into Core and should have a timeline for when they should be removed from the plugin.
- `lib/experimental` - Experimental features that exist only in the plugin. They should not be merged into Core.
- `lib/compat/wordpress-X.Y` - Stable features that are intended to be merged into Core in a future `X.Y` release, or that were previously merged to Core in the `X.Y` release and remain in the plugin for backwards compatibility when running the plugin on older versions of WordPress.
- `lib/compat/plugin` - Features for backwards compatibility for the plugin consumers. These files don't need to be merged into Core and should have a timeline for when they should be removed from the plugin.

Files at the root of `/lib` are generally considered to contain "evergreen" code. Such code is both fundamental to the proper functioning of the plugin, and also so often updated that versioning it between WordPress releases is not practical. Changes to these files are merged into Core as required.

Expand Down Expand Up @@ -60,6 +60,8 @@ function wp_get_something_useful() {

Plugin code that is stable and expected to be merged "as-is" into Core in the near future can use the `wp_` prefix for functions or a `WP_` prefix for classes.

#### Avoiding duplicate declarations

When doing so, care must be taken to ensure that no duplicate declarations to create functions or classes exist between Gutenberg and WordPress core code. A quick codebase search will also help you know if your new names are unique.

Wrapping such code in `class_exists()` and `function_exists()` checks should be used to ensure it executes in the plugin up until it is merged to Core, or when running the plugin on older versions of WordPress.
Expand All @@ -86,8 +88,10 @@ Or for classes:
* @package WordPress
* @since 6.3.0
*/
if ( class_exists( 'WP_A_Stable_Class' ) ) {
return;
if ( ! class_exists( 'WP_A_Stable_Class' ) ) {
// your code for WP_A_Stable_Class here.
// Do not invert this pattern with an early `return`.
// See below for details...
}

/**
Expand All @@ -100,6 +104,19 @@ class WP_A_Stable_Class { ... }

Wrapping code in `class_exists()` and `function_exists()` is usually inappropriate for evergreen code, or any plugin code that we expect to undergo constant change between WordPress releases, because it would prevent the latest versions of the code from being used. For example, the statement `class_exists( 'WP_Theme_JSON' )` would return `true` because the class already exists in Core.

The early return pattern shown below is considered an **anti-pattern** because it is not supported by older versions of PHP and can cause [unexpected side effects](https://github.com/WordPress/gutenberg/pull/58429#issuecomment-1916670097):

```php
/**
* ANTI-PATTERN
* DO NOT COPY!
*
*/
if ( class_exists( 'WP_A_Stable_Class' ) ) {
return; // do not do this.
}
```

When to use which prefix is a judgement call, but the general rule is that if you're unsure, use the `gutenberg` prefix because it will less likely give rise to naming conflicts.

#### When not to use plugin-specific prefixes/suffixes
Expand Down Expand Up @@ -176,6 +193,7 @@ add_action( 'init', 'wp_register_navigation_cpt' );
```

### Requiring files in lib/load.php

Should the load order allow it, try to group imports according to WordPress release, then feature. It'll help everyone to quickly recognise the files that belong to specific WordPress releases.

Existing comments in `lib/load.php` should act as a guide.
Expand Down

0 comments on commit 1127a5d

Please sign in to comment.