replace forward tick with ' in docs folder (#42799)

* replace forward tick with ' in docs folder

* replace encoded bcktick with single quote in docs folder

---------

Co-authored-by: Ron Rennick <ronald.rennick@automattic.com>
This commit is contained in:
Ron Rennick 2024-01-02 16:59:26 -04:00 committed by GitHub
parent 44e4a75419
commit 64a51caa06
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
50 changed files with 296 additions and 291 deletions

View File

@ -3,7 +3,7 @@ post_title: Add a country
---
Add this code to your child themes `functions.php` file or via a plugin that allows custom functions to be added, such as the [Code Snippets](https://wordpress.org/plugins/code-snippets/) plugin. Avoid adding custom code directly to your parent themes functions.php file, as this will be wiped entirely when you update the theme.
Add this code to your child theme's `functions.php` file or via a plugin that allows custom functions to be added, such as the [Code Snippets](https://wordpress.org/plugins/code-snippets/) plugin. Avoid adding custom code directly to your parent theme's functions.php file, as this will be wiped entirely when you update the theme.
```php
if ( ! function_exists( 'YOUR_PREFIX_add_country_to_countries_list' ) ) {

View File

@ -2,7 +2,7 @@
post_title: Add a currency and symbol
---
Add this code to your child themes `functions.php` file or via a plugin that allows custom functions to be added, such as the [Code Snippets](https://wordpress.org/plugins/code-snippets/) plugin. Avoid adding custom code directly to your parent themes functions.php file, as this will be wiped entirely when you update the theme.
Add this code to your child theme's `functions.php` file or via a plugin that allows custom functions to be added, such as the [Code Snippets](https://wordpress.org/plugins/code-snippets/) plugin. Avoid adding custom code directly to your parent theme's functions.php file, as this will be wiped entirely when you update the theme.
```php
if ( ! function_exists( 'YOUR_PREFIX_add_currency_name' ) ) {

View File

@ -2,7 +2,7 @@
post_title: Add or modify states
---
Add this code to your child themes `functions.php` file or via a plugin that allows custom functions to be added, such as the [Code Snippets](https://wordpress.org/plugins/code-snippets/) plugin. Avoid adding custom code directly to your parent themes functions.php file, as this will be wiped entirely when you update the theme.
Add this code to your child theme's `functions.php` file or via a plugin that allows custom functions to be added, such as the [Code Snippets](https://wordpress.org/plugins/code-snippets/) plugin. Avoid adding custom code directly to your parent theme's functions.php file, as this will be wiped entirely when you update the theme.
Add your own or modify shipping states in WooCommerce.

View File

@ -4,7 +4,7 @@ post_title: Adjust the quantity input values
Set the starting value, maximum value, minimum value, and increment amount for quantity input fields on product pages.
Add this code to your child themes `functions.php` file or via a plugin that allows custom functions to be added, such as the [Code snippets](https://wordpress.org/plugins/code-snippets/) plugin. Avoid adding custom code directly to your parent themes `functions.php` file, as this will be wiped entirely when you update the theme.
Add this code to your child theme's `functions.php` file or via a plugin that allows custom functions to be added, such as the [Code snippets](https://wordpress.org/plugins/code-snippets/) plugin. Avoid adding custom code directly to your parent theme's `functions.php` file, as this will be wiped entirely when you update the theme.
```php
if ( ! function_exists( 'YOUR_PREFIX_woocommerce_quantity_input_args' ) ) {

View File

@ -2,9 +2,9 @@
post_title: Add a message above the login / register form
---
This code will add a custom message above the login/register form on the users my-account page.
This code will add a custom message above the login/register form on the user's my-account page.
Add this code to your child themes `functions.php` file or via a plugin that allows custom functions to be added, such as the [Code snippets](https://wordpress.org/plugins/code-snippets/) plugin. Avoid adding custom code directly to your parent themes `functions.php` file, as this will be wiped entirely when you update the theme.
Add this code to your child theme's `functions.php` file or via a plugin that allows custom functions to be added, such as the [Code snippets](https://wordpress.org/plugins/code-snippets/) plugin. Avoid adding custom code directly to your parent theme's `functions.php` file, as this will be wiped entirely when you update the theme.
```php
if ( ! function_exists( 'YOUR_PREFIX_login_message' ) ) {

View File

@ -4,7 +4,7 @@ post_title: Change a currency symbol
See the [currency list](https://woocommerce.github.io/code-reference/files/woocommerce-includes-wc-core-functions.html#source-view.475) for reference on currency codes.
Add this code to your child themes `functions.php` file or via a plugin that allows custom functions to be added, such as the [Code Snippets](https://wordpress.org/plugins/code-snippets/) plugin. Avoid adding custom code directly to your parent themes functions.php file, as this will be wiped entirely when you update the theme.
Add this code to your child theme's `functions.php` file or via a plugin that allows custom functions to be added, such as the [Code Snippets](https://wordpress.org/plugins/code-snippets/) plugin. Avoid adding custom code directly to your parent theme's functions.php file, as this will be wiped entirely when you update the theme.
```php
if ( ! function_exists( 'YOUR_PREFIX_change_currency_symbol' ) ) {

View File

@ -4,11 +4,11 @@ post_title: Customizing checkout fields using actions and filters
If you are unfamiliar with code and resolving potential conflicts, we have an extension that can help: [WooCommerce Checkout Field Editor](https://woo.com/products/woocommerce-checkout-field-editor/). Installing and activating this extension overrides any code below that you try to implement; and you cannot have custom checkout field code in your functions.php file when the extension is activated.
Custom code should be copied into your child themes **functions.php** file.
Custom code should be copied into your child theme's **functions.php** file.
## How Are Checkout Fields Loaded to WooCommerce?
The billing and shipping fields for checkout pull from the countries class `class-wc-countries.php` and the **`get_address_fields`** function. This allows WooCommerce to enable/disable fields based on the users location.
The billing and shipping fields for checkout pull from the countries class `class-wc-countries.php` and the **`get_address_fields`** function. This allows WooCommerce to enable/disable fields based on the user's location.
Before returning these fields, WooCommerce puts the fields through a *filter*. This allows them to be edited by third-party plugins, themes and your own custom code.
@ -69,7 +69,7 @@ That means you have **full control** over checkout fields you only need to
## Overriding Core Fields
Hooking into the  **`woocommerce_checkout_fields`** filter lets you override any field. As an example, lets change the placeholder on the order_comments fields. Currently, its set to:
Hooking into the  **`woocommerce_checkout_fields`** filter lets you override any field. As an example, let's change the placeholder on the order_comments fields. Currently, it's set to:
```php
_x( 'Notes about your order, e.g. special notes for delivery.', 'placeholder', 'woocommerce' );
@ -116,7 +116,7 @@ function custom_override_checkout_fields( $fields ) {
}
```
Heres a full list of fields in the array passed to `woocommerce_checkout_fields`:
Here's a full list of fields in the array passed to `woocommerce_checkout_fields`:
- Billing
- `billing_first_name`
@ -186,7 +186,7 @@ function custom_override_default_address_fields( $address_fields ) {
### Defining select options
If you are adding a field with type select, as stated above you would define key/value pairs. For example:
If you are adding a field with type 'select', as stated above you would define key/value pairs. For example:
```php
$fields['billing']['your_field']['options'] = array(
@ -201,9 +201,9 @@ Priority in regards to PHP code helps establish when a bit of code - called a fu
Code with a higher number set as the priority will run after code with a lower number, meaning code with a priority of 20 will run after code with 10 priority.
The priority argument is set during the [add_action](https://developer.wordpress.org/reference/functions/add_action/) function, after you establish which hook youre connecting to and what the name of your custom function will be.
The priority argument is set during the [add_action](https://developer.wordpress.org/reference/functions/add_action/) function, after you establish which hook you're connecting to and what the name of your custom function will be.
In the example below, blue text is the name of the hook were modifying, green text is the name of our custom function, and red is the priority we set.
In the example below, blue text is the name of the hook we're modifying, green text is the name of our custom function, and red is the priority we set.
![Setting priority for the hooked function](https://woo.com/wp-content/uploads/2012/04/priority-markup.png)
@ -224,7 +224,7 @@ function wc_empty_cart_redirect_url() {
add_filter( 'woocommerce_return_to_shop_redirect', 'wc_empty_cart_redirect_url', 10 );
```
There, we can see the priority is set to 10. This is the typical default for WooCommerce functions and scripts, so that may not be sufficient to override that buttons functionality.
There, we can see the priority is set to 10. This is the typical default for WooCommerce functions and scripts, so that may not be sufficient to override that button's functionality.
Instead, we can change the priority to any number greater than 10. While 11 would work, best practice dictates we use increments of ten, so 20, 30, and so on.
@ -239,7 +239,7 @@ function wc_empty_cart_redirect_url() {
add_filter( 'woocommerce_return_to_shop_redirect', 'wc_empty_cart_redirect_url', 20 );
```
With priority, we can have two functions that are acting on the same hook. Normally this would cause a variety of problems, but since weve established one has a higher priority than the other, our site will only load the appropriate function, and we will be taken to the Specials page as intended with the code below.
With priority, we can have two functions that are acting on the same hook. Normally this would cause a variety of problems, but since we've established one has a higher priority than the other, our site will only load the appropriate function, and we will be taken to the Specials page as intended with the code below.
```php
/**
@ -265,7 +265,7 @@ add_filter( 'woocommerce_return_to_shop_redirect', 'wc_empty_cart_redirect_url',
### Adding Custom Shipping And Billing Fields
Adding fields is done in a similar way to overriding fields. For example, lets add a new field to shipping fields `shipping_phone`:
Adding fields is done in a similar way to overriding fields. For example, let's add a new field to shipping fields `shipping_phone`:
```php
// Hook in
@ -296,13 +296,13 @@ function my_custom_checkout_field_display_admin_order_meta($order){
![It's alive!](https://woo.com/wp-content/uploads/2012/04/WooCommerce-Codex-Shipping-Field-Hook.png)
Its alive!
It's alive!
What do we do with the new field? Nothing. Because we defined the field in the `checkout_fields` array, the field is automatically processed and saved to the order post meta (in this case, \_shipping_phone). If you want to add validation rules, see the checkout class where there are additional hooks you can use.
### Adding a Custom Special Field
To add a custom field is similar. Lets add a new field to checkout, after the order notes, by hooking into the following:
To add a custom field is similar. Let's add a new field to checkout, after the order notes, by hooking into the following:
```php
/**
@ -354,7 +354,7 @@ A checkout error is displayed if the field is blank:
![WooCommerce Codex - Checkout Field Notice](https://woo.com/wp-content/uploads/2012/04/WooCommerce-Codex-Checkout-Field-Notice.png)
Finally, lets save the new field to order custom fields using the following code:
Finally, let's save the new field to order custom fields using the following code:
```php
/**

View File

@ -2,9 +2,9 @@
post_title: Change number of related products output
---
Add code to your child themes functions.php file or via a plugin that allows custom functions to be added, such as the [Code snippets](https://wordpress.org/plugins/code-snippets/) plugin. Avoid adding custom code directly to your parent themes `functions.php` file as this will be wiped entirely when you update the theme.
Add code to your child theme's functions.php file or via a plugin that allows custom functions to be added, such as the [Code snippets](https://wordpress.org/plugins/code-snippets/) plugin. Avoid adding custom code directly to your parent theme's `functions.php` file as this will be wiped entirely when you update the theme.
Please note that it does not work for all themes because of the way theyre coded.
Please note that it does not work for all themes because of the way they're coded.
```php
if ( ! function_exists( 'YOUR_PREFIX_related_products_args' ) ) {

View File

@ -3,7 +3,7 @@ post_title: Rename a country
---
Add this code to your child themes `functions.php` file or via a plugin that allows custom functions to be added, such as the [Code Snippets](https://wordpress.org/plugins/code-snippets/) plugin. Avoid adding custom code directly to your parent themes functions.php file, as this will be wiped entirely when you update the theme.
Add this code to your child theme's `functions.php` file or via a plugin that allows custom functions to be added, such as the [Code Snippets](https://wordpress.org/plugins/code-snippets/) plugin. Avoid adding custom code directly to your parent theme's functions.php file, as this will be wiped entirely when you update the theme.
```php
if ( ! function_exists( 'YOUR_PREFIX_rename_country' ) ) {

View File

@ -4,7 +4,7 @@ post_title: Unhook and remove WooCommerce emails
This code allows you to unhook and remove the default WooCommerce emails.
Add this code to your child themes `functions.php` file or via a plugin that allows custom functions to be added, such as the [Code snippets](https://wordpress.org/plugins/code-snippets/) plugin. Avoid adding custom code directly to your parent themes `functions.php` file, as this will be wiped entirely when you update the theme.
Add this code to your child theme's `functions.php` file or via a plugin that allows custom functions to be added, such as the [Code snippets](https://wordpress.org/plugins/code-snippets/) plugin. Avoid adding custom code directly to your parent theme's `functions.php` file, as this will be wiped entirely when you update the theme.
```php
if ( ! function_exists( 'YOUR_PREFIX_unhook_woocommerce_emails' ) ) {

View File

@ -26,7 +26,7 @@ On this page, we will share some guidelines to help you assess the impact degree
- It only updates automated tests, things related to infrastructure not included in the WooCommerce release package, or other projects in the monorepo not included in the release package.
- It only contains readme or changelog changes.
- Fixes a low-priority bug such as a typo etc.
- Doesnt need to be verified in multiple environment types.
- Doesn't need to be verified in multiple environment types.
- Regular scheduled (not a fix release) core version bumps for the Blocks package (as testing will already be scheduled).
- It's part of a feature that hasn't been released as a whole yet (i.e. it's behind a feature flag currently in progress).

View File

@ -12,14 +12,14 @@ Each of these objects contains a schema for the data it controls (properties), a
* Structure Each object has a pre-defined structure and keeps its own data valid.
* Control We control the flow of data, and any validation needed, so we know when changes occur.
* Ease of development As a developer, you dont need to know the internals of the data youre working with, just the names.
* Ease of development As a developer, you don't need to know the internals of the data you're working with, just the names.
* Abstraction The data can be moved elsewhere, e.g. custom tables, without affecting existing code.
* Unification We can use the same code for updating things in admin as we do in the REST API and CLIs. Everything is unified.
* Simplified code Less procedural code to update objects which reduces likelihood of malfunction and adds more unit test coverage.
## CRUD object structure
The [`WC_Data`](https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/includes/abstracts/abstract-wc-data.php) class is the basic implementation for CRUD objects, and all CRUD objects extend it. The most important properties to note are `$data`, which is an array of props supported in each object, and `$id`, which is the objects ID.
The [`WC_Data`](https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/includes/abstracts/abstract-wc-data.php) class is the basic implementation for CRUD objects, and all CRUD objects extend it. The most important properties to note are `$data`, which is an array of props supported in each object, and `$id`, which is the object's ID.
The [coupon object class](https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/includes/class-wc-coupon.php) is a good example of extending `WC_Data` and adding CRUD functions to all properties.
@ -127,7 +127,7 @@ public function __construct( $data = '' ) {
}
```
Note how it sets the ID based on the data passed to the object, then calls the data store to retrieve the data from the database. Once the data is read via the data store, or if no ID is set, `$this->set_object_read( true );` is set so the data store and CRUD object knows its read. Once this is set, changes are tracked.
Note how it sets the ID based on the data passed to the object, then calls the data store to retrieve the data from the database. Once the data is read via the data store, or if no ID is set, `$this->set_object_read( true );` is set so the data store and CRUD object knows it's read. Once this is set, changes are tracked.
### Saving and deleting

View File

@ -2,22 +2,22 @@
post_title: Adding a section to a settings tab
---
When youre adding building an extension for WooCommerce that requires settings of some kind, its important to ask yourself: **Where do they belong?** If your extension just has a couple of simple settings, do you really need to create a new tab specifically for it? Most likely the answer is no.
When you're adding building an extension for WooCommerce that requires settings of some kind, it's important to ask yourself: **Where do they belong?** If your extension just has a couple of simple settings, do you really need to create a new tab specifically for it? Most likely the answer is no.
## [When to Create a Section](https://github.com/woocommerce/woocommerce/blob/trunk/docs/extesion-developlment/adding-a-section-to-a-settings-tab.md#section-1)
Lets say we had an extension that adds a slider to a single product page. This extension doesnt have many options, just a couple:
Let's say we had an extension that adds a slider to a single product page. This extension doesn't have many options, just a couple:
- Auto-insert into single product page (checkbox)
- Slider Title (text field)
Thats only two options, specifically related to **Products**. We could quite easily just append them onto the core WooCommerce Products Settings (**WooCommerce > Settings > Products**), but that wouldnt be very user friendly. Users wouldnt know where to look initially so theyd have to scan all of the Products options and it would be difficult / impossible to link the options directly. Fortunately, as of WooCommerce 2.2.2, there is a new filter in place that allows you add a new **section**, beneath one of the core settings tabs.
That's only two options, specifically related to **Products**. We could quite easily just append them onto the core WooCommerce Products Settings (**WooCommerce > Settings > Products**), but that wouldn't be very user friendly. Users wouldn't know where to look initially so they'd have to scan all of the Products options and it would be difficult / impossible to link the options directly. Fortunately, as of WooCommerce 2.2.2, there is a new filter in place that allows you add a new **section**, beneath one of the core settings' tabs.
> **Note:** This is a **Developer level** doc. If you are unfamiliar with code/templates and resolving potential conflicts, select a [WooExpert or Developer](https://woo.com/customizations/) for assistance. We are unable to provide support for customizations under our [Support Policy](https://woo.com/support-policy/).
## [How to Create a Section](https://github.com/woocommerce/woocommerce/blob/trunk/docs/extesion-developlment/adding-a-section-to-a-settings-tab.md#section-2)
Well go over doing this through individual functions, but you should probably create a Class that stores all of your settings methods.
We'll go over doing this through individual functions, but you should probably create a Class that stores all of your settings methods.
The first thing you need to is add the section, which can be done like this by hooking into the `woocommerce_get_sections_products` filter:
@ -41,11 +41,11 @@ function wcslider_add_section( $sections ) {
_[wc-create-section-beneath-products.php](https://gist.github.com/woogists/2964ec01c8bea50fcce62adf2f5c1232/raw/da5348343cf3664c0bc8b6b132d8105bfcf9ca51/wc-create-section-beneath-products.php)_
Make sure you change the **wcslider** parts to suit your extensions name / text-domain. The important thing about the `woocommerce_get_sections_products` filter, is that the last part **products**, is the tab youd like to add a section to. So if you want to add a new tab to accounts section, you would hook into the `woocommerce_get_sections_accounts` filter.
Make sure you change the **wcslider** parts to suit your extension's name / text-domain. The important thing about the `woocommerce_get_sections_products` filter, is that the last part **products**, is the tab you'd like to add a section to. So if you want to add a new tab to accounts section, you would hook into the `woocommerce_get_sections_accounts` filter.
## [How to Add Settings to a Section](https://github.com/woocommerce/woocommerce/blob/trunk/docs/extesion-developlment/adding-a-section-to-a-settings-tab.md#section-3)
Now that youve got the tab, you need to filter the output of `woocommerce_get_sections_products` (or similar). You would add the settings like usual using the [**WooCommerce Settings API**](https://github.com/woocommerce/woocommerce/blob/trunk/docs/settings-api/), but check for the current section before adding the settings to the tabs settings array. For example, lets add the sample settings we discussed above to the new **wcslider** section we just created:
Now that you've got the tab, you need to filter the output of `woocommerce_get_sections_products` (or similar). You would add the settings like usual using the [**WooCommerce Settings API**](https://github.com/woocommerce/woocommerce/blob/trunk/docs/settings-api/), but check for the current section before adding the settings to the tab's settings array. For example, let's add the sample settings we discussed above to the new **wcslider** section we just created:
```php
/**
@ -128,7 +128,7 @@ function wcslider_all_settings( $settings, $current_section ) {
_[wc-add-settings-section.php](https://gist.github.com/woogists/4038b83900508806c57a193a2534b845#file-wc-add-settings-section-php)_
Were hooking into the same `woocommerce_get_sections_products` filter, but this time doing a check that the `$current_section` matches our earlier defined custom section (wcslider), before adding in our new settings.
We're hooking into the same `woocommerce_get_sections_products` filter, but this time doing a check that the `$current_section` matches our earlier defined custom section (wcslider), before adding in our new settings.
## [Using the New Settings](https://github.com/woocommerce/woocommerce/blob/trunk/docs/extesion-developlment/adding-a-section-to-a-settings-tab.md#section-4)

View File

@ -47,16 +47,16 @@ When you run the built-in extension generator, it will output something that loo
└── webpack.config.js
```
Heres a breakdown of what these files are and what purpose they serve:
Here's a breakdown of what these files are and what purpose they serve:
`README.md`
This file is meant to have a high-level overview of your extension to make it easier for people to use and extend your project. The generator outputs a basic file with some minimal instructions in it to get you started, but you should replace the contents of the file with information specific to your project. Its important to keep in mind that this file is not the same as the readme.txt file required by WordPress.org plugin directory, which must adhere to specific file standads.
This file is meant to have a high-level overview of your extension to make it easier for people to use and extend your project. The generator outputs a basic file with some minimal instructions in it to get you started, but you should replace the contents of the file with information specific to your project. It's important to keep in mind that this file is not the same as the readme.txt file required by WordPress.org plugin directory, which must adhere to specific file standads.
`[your-extension-name].php`
This is your extensions main PHP file. It functions as the entry point for your extension and is where youll likely include code that hooks your extension into WordPress and WooCommerce. You can read more about the purpose of this file in the Getting Started section of the WordPress Plugin Developer Handbook.
This is your extension's main PHP file. It functions as the entry point for your extension and is where you'll likely include code that hooks your extension into WordPress and WooCommerce. You can read more about the purpose of this file in the Getting Started section of the WordPress Plugin Developer Handbook.
`package.json`
This is a manifest file that Node uses for a number of different purposes. It can store configuration settings for tools, lists of dependencies, aliases for common scripts, and even metadata about your extension. The WooCommerce extension generator outputs a package.json file that will bundle many helpful dependencies with your extension, as well as a variety of scripts you can use in conjunction with these dependencies to streamline your workflow and make sure your extension conforms to the same standards as other WordPress plugins and WooCommerce extensions. Heres an example of what your package.json file might look like initially:
This is a manifest file that Node uses for a number of different purposes. It can store configuration settings for tools, lists of dependencies, aliases for common scripts, and even metadata about your extension. The WooCommerce extension generator outputs a package.json file that will bundle many helpful dependencies with your extension, as well as a variety of scripts you can use in conjunction with these dependencies to streamline your workflow and make sure your extension conforms to the same standards as other WordPress plugins and WooCommerce extensions. Here's an example of what your package.json file might look like initially:
```json
{
@ -92,15 +92,15 @@ The settings in this autogenerated file tell Webpack to use the default configur
## Try out your extension
If you used the extension generator to create your extension, youll need to complete a few final steps to see it in action.
If you used the extension generator to create your extension, you'll need to complete a few final steps to see it in action.
First, navigate to your extensions root directory on your development server:
First, navigate to your extension's root directory on your development server:
```sh
cd /your/server/wc-content/plugins/your-extension/
```
Then install the projects dependencies.
Then install the project's dependencies.
```sh
npm install
@ -112,7 +112,7 @@ Finally, run the start script to generate an initial build of your extension. Th
npm start
```
Once your initial build is complete, you can browse to the administrative area of your local WordPress environment and activate your extension. If everything worked as it should, you should see a message in your browsers JavaScript console:
Once your initial build is complete, you can browse to the administrative area of your local WordPress environment and activate your extension. If everything worked as it should, you should see a message in your browser's JavaScript console:
```sh
hello world

View File

@ -11,7 +11,7 @@ For a list of Classes in WooCommerce, please see the [WooCommerce Code Reference
### [WooCommerce](https://github.com/woocommerce/woocommerce/blob/trunk/docs/extension-development/class-reference#section-3)
The main class is `woocommerce` which is available globally via the `$woocommerce` variable. This handles the main functions of WooCommerce and inits other classes, stores site-wide variables, and handles error/success messages. The woocommerce class initializes the following classes when constructed:
The main class is `woocommerce` which is available globally via the `$woocommerce` variable. This handles the main functions of WooCommerce and init's other classes, stores site-wide variables, and handles error/success messages. The woocommerce class initializes the following classes when constructed:
- `WC_Query` stored in `$woocommerce->query`
- `WC_Customer` stored in `$woocommerce->customer`

View File

@ -4,7 +4,7 @@ post_title: Setting up your development environment
## Introduction
Building an extension for WooCommerce is a straightforward process, but there are a several moving parts and a few supporting software tools youll want to familiarize yourself with. This guide will walk you through the steps of getting a basic development environment set up for building WooCommerce extensions.
Building an extension for WooCommerce is a straightforward process, but there are a several moving parts and a few supporting software tools you'll want to familiarize yourself with. This guide will walk you through the steps of getting a basic development environment set up for building WooCommerce extensions.
If you would like to contribute to the WooCommerce core platform; please read our [contributor documentation and guidelines](https://github.com/woocommerce/woocommerce/wiki/How-to-set-up-WooCommerce-development-environment).
@ -22,11 +22,11 @@ WooCommerce extensions are a specialized type of WordPress plugin. If you are ne
[PNpm](https://pnpm.io/)
[Composer](https://getcomposer.org/download/)
Note: If youre working on a Windows machine, you may want to take a look at the Building Extensions in Windows Environments section of this guide before proceeding.
Note: If you're working on a Windows machine, you may want to take a look at the Building Extensions in Windows Environments section of this guide before proceeding.
### Setting up your reusable WordPress development environment
In addition to the software listed above, youll also want to have some way of setting up a local development server stack. There are a number of different tools available for this, each with a certain set of functionality and limitations. We recommend choosing an option below that fits your preferred workflow best.
In addition to the software listed above, you'll also want to have some way of setting up a local development server stack. There are a number of different tools available for this, each with a certain set of functionality and limitations. We recommend choosing an option below that fits your preferred workflow best.
### WordPress-specific tools
@ -42,7 +42,7 @@ In addition to the software listed above, youll also want to have some way of
[WAMP](https://www.wampserver.com/en/) A Windows web development environment that lets you create applications with Apache2, PHP, and MySQL.
[XAMPP](https://www.apachefriends.org/index.html) An easy-to-install Apache distribution containing MariaDB, PHP, and Perl. Its available for Windows, Linux, and OS X.
[XAMPP](https://www.apachefriends.org/index.html) An easy-to-install Apache distribution containing MariaDB, PHP, and Perl. It's available for Windows, Linux, and OS X.
### Minimum server requirements
@ -52,7 +52,7 @@ Regardless of the tool you choose for managing your development environment, you
While development environments can vary, the basic file structure for a WordPress environment should be consistent.
When developing a WooCommerce extension, youll usually be doing most of your work within the public_html directory of your local server. For now, take some time to familiarize yourself with a few key paths:
When developing a WooCommerce extension, you'll usually be doing most of your work within the public_html directory of your local server. For now, take some time to familiarize yourself with a few key paths:
`wp-content/debug.log` This is the file where WordPress writes the important output such as errors and other messages useful for debugging.
@ -62,7 +62,7 @@ When developing a WooCommerce extension, youll usually be doing most of your
## Adding WooCommerce Core to your environment
When developing an extension for WooCommerce, its helpful to install a development version of WooCommerce core.
When developing an extension for WooCommerce, it's helpful to install a development version of WooCommerce core.
### Clone the WC Core repo into `wp-content/plugins/`
@ -81,7 +81,7 @@ Found '/path/to/woocommerce/.nvmrc' with version <v12>
Now using node v12.21.0 (npm v6.14.11)
```
Note: if you dont have the required version of Node installed, NVM will alert you so you can install it:
Note: if you don't have the required version of Node installed, NVM will alert you so you can install it:
```sh
Found '/path/to/woocommerce/.nvmrc' with version <v12>
@ -104,7 +104,7 @@ pnpm build
Running this script will compile the JavaScript and CSS that WooCommerce needs to operate. If you try to run WooCommerce on your server without generating the compiled assets, you may experience errors and other unwanted side-effects.
Note: In some environments, you may see an out-of-memory error when you try to build WooCommerce. If this happens, you simply need to adjust the memory_limit setting in your environments php.ini configuration to a higher value. The process for changing this value varies depending on the environment management tooling you use, so its best to consult your tools documentation before making any changes.
Note: In some environments, you may see an out-of-memory error when you try to build WooCommerce. If this happens, you simply need to adjust the memory_limit setting in your environment's php.ini configuration to a higher value. The process for changing this value varies depending on the environment management tooling you use, so it's best to consult your tool's documentation before making any changes.
## Adding WooCommerce Admin to your environment
@ -126,7 +126,7 @@ Found '/path/to/woocommerce-admin/.nvmrc' with version <lts/*>
Now using node v14.16.0 (npm v6.14.11)
```
Note: if you dont have the required version of Node installed, NVM will alert you so you can install it.
Note: if you don't have the required version of Node installed, NVM will alert you so you can install it.
```sh
Found '/path/to/woocommerce-admin/.nvmrc' with version <v12>
@ -174,7 +174,7 @@ Found '/path/to/woocommerce-gutenberg-products-block/.nvmrc' with version <lts/*
Now using node v14.16.0 (npm v6.14.11)
```
Note: if you dont have the required version of Node installed, NVM will alert you so you can install it.
Note: if you don't have the required version of Node installed, NVM will alert you so you can install it.
```sh
Found '/path/to/woocommerce-gutenberg-products-block/.nvmrc' with version <v12>
@ -197,7 +197,7 @@ This will compile and minify the JavaScript and CSS from the /assets directory t
## Finishing up
Once you have WooCommerce and its sibling extensions installed in your WordPress environment, start up your server, browse to your site and handle any initial setup steps or importing youd like to do. This is a good time to load sample data and activate themes and plugins.
Once you have WooCommerce and its sibling extensions installed in your WordPress environment, start up your server, browse to your site and handle any initial setup steps or importing you'd like to do. This is a good time to load sample data and activate themes and plugins.
Depending on which extensions you installed in your environment you should have one or more of the following directories in your `public_html` directory:

View File

@ -65,7 +65,7 @@ Code conventions also prevent basic mistakes, as [Apple made with iOS 7.0.6](htt
Avoid creating custom database tables. Whenever possible, use WordPress [post types](http://codex.wordpress.org/Post_Types#Custom_Post_Types), [taxonomies](http://codex.wordpress.org/Taxonomies), and [options](http://codex.wordpress.org/Creating_Options_Pages).
Consider the permanence of your data. Heres a quick primer:
Consider the permanence of your data. Here's a quick primer:
- If the data may not always be present (i.e., it expires), use a transient.
- If the data is persistent but not always present, consider using the WP Cache.
@ -143,15 +143,15 @@ Use the follow headers to declare “required” and “tested up to” versions
## [Plugin URI](https://woo.com/document/create-a-plugin/#section-11)
Ensure that the Plugin URI line of the above plugin header is provided. This line should contain the URL of the plugins product/sale page or to a dedicated page for the plugin on your website.
Ensure that the Plugin URI line of the above plugin header is provided. This line should contain the URL of the plugin's product/sale page or to a dedicated page for the plugin on your website.
## [Make it Extensible](https://woo.com/document/create-a-plugin/#section-13)
Developers should use WordPress actions and filters to allow for modification/customization without requiring users to touch the plugins core code base.
Developers should use WordPress actions and filters to allow for modification/customization without requiring users to touch the plugin's core code base.
If your plugin creates a front-end output, we recommend to having a templating engine in place so users can create custom template files in their themes WooCommerce folder to overwrite the plugins template files.
If your plugin creates a front-end output, we recommend to having a templating engine in place so users can create custom template files in their theme's WooCommerce folder to overwrite the plugin's template files.
For more information, check out Pippins post on [Writing Extensible Plugins with Actions and Filters](http://code.tutsplus.com/tutorials/writing-extensible-plugins-with-actions-and-filters--wp-26759).
For more information, check out Pippin's post on [Writing Extensible Plugins with Actions and Filters](http://code.tutsplus.com/tutorials/writing-extensible-plugins-with-actions-and-filters--wp-26759).
## [Use of External Libraries](https://woo.com/document/create-a-plugin/#section-14)
@ -159,7 +159,7 @@ The use of entire external libraries is typically not suggested as this can open
## [Remove Unused Code](https://woo.com/document/create-a-plugin/#section-15)
With version control, theres no reason to leave commented-out code; its annoying to scroll through and read. Remove it and add it back later if needed.
With version control, there's no reason to leave commented-out code; it's annoying to scroll through and read. Remove it and add it back later if needed.
## [Comment](https://woo.com/document/create-a-plugin/#section-16)
@ -167,7 +167,7 @@ If you have a function, what does the function do? There should be comments for
## [Avoid God Objects](https://woo.com/document/create-a-plugin/#section-17)
[God Objects](http://en.wikipedia.org/wiki/God_object) are objects that know or do too much. The point of object-oriented programming is to take a large problem and break it into smaller parts. When functions do too much, its hard to follow their logic, making bugs harder to fix. Instead of having massive functions, break them down into smaller pieces.
[God Objects](http://en.wikipedia.org/wiki/God_object) are objects that know or do too much. The point of object-oriented programming is to take a large problem and break it into smaller parts. When functions do too much, it's hard to follow their logic, making bugs harder to fix. Instead of having massive functions, break them down into smaller pieces.
## [Test Extension Quality & Security with Quality Insights Tool](https://woo.com/document/create-a-plugin/#section-18)
@ -189,16 +189,16 @@ Its a good practice to separate business logic (i.e., how the plugin works) f
## [Use Transients to Store Offsite Information](https://woo.com/document/create-a-plugin/#section-21)
If you provide a service via an API, its best to store that information so future queries can be done faster and the load on your service is lessened. [WordPress transients](http://codex.wordpress.org/Transients_API) can be used to store data for a certain amount of time.
If you provide a service via an API, it's best to store that information so future queries can be done faster and the load on your service is lessened. [WordPress transients](http://codex.wordpress.org/Transients_API) can be used to store data for a certain amount of time.
## [Logging Data](https://woo.com/document/create-a-plugin/#section-22)
You may want to log data that can be useful for debugging purposes. This is great with two conditions:
- Allow any logging as an opt in.
- Allow any logging as an 'opt in'.
- Use the [WC_Logger](https://woo.com/wc-apidocs/class-WC_Logger.html) class. A user can then view logs on their system status page.
If adding logging to your extension, heres a snippet for presenting a link to the logs, in a way the extension user can easily make use of.
If adding logging to your extension, here's a snippet for presenting a link to the logs, in a way the extension user can easily make use of.
```php
$label = \_\_( 'Enable Logging', 'your-textdomain-here' );

View File

@ -62,7 +62,7 @@ The General Data Protection Regulation (GDPR) is in effect, granting EU resident
### Privacy Policy Documentation
- Maintain an up-to-date privacy policy detailing your plugins data handling.
- Maintain an up-to-date privacy policy detailing your plugin's data handling.
- Include browser storage methods and third-party data sharing in your documentation.
### Data Cleanup

View File

@ -4,11 +4,11 @@ post_title: Handling deactivation and uninstallation
## Introduction
There are a number of cleanup tasks youll need to handle when a merchant deactivates or uninstalls your extension. This guide provides a brief overview of WooCommerce-specific items youll want to make sure you account for when defining your extensions deactivation and uninstallation logic.
There are a number of cleanup tasks you'll need to handle when a merchant deactivates or uninstalls your extension. This guide provides a brief overview of WooCommerce-specific items you'll want to make sure you account for when defining your extension's deactivation and uninstallation logic.
## Removing Scheduled Actions
If your extension uses Action Scheduler to queue any background jobs, its important to unschedule those actions when your extension is uninstalled or deactivated.
If your extension uses Action Scheduler to queue any background jobs, it's important to unschedule those actions when your extension is uninstalled or deactivated.
`as_unschedule_all_actions( $hook, $args, $group );`
@ -41,11 +41,11 @@ function my_extension_deactivate_task() {
register_deactivation_hook( __FILE__, 'my_extension_deactivate_task' );
```
Keep in mind that merchant tasks are managed via a hybrid approach that involves both PHP and JavaScript, so the client-side registration only happens when your extensions JavaScript runs.
Keep in mind that merchant tasks are managed via a hybrid approach that involves both PHP and JavaScript, so the client-side registration only happens when your extension's JavaScript runs.
## Unregistering navigation
When your extension deactivates and uninstalls, any registration youve done with the WooCommerce Navigation will be handled automatically.
When your extension deactivates and uninstalls, any registration you've done with the WooCommerce Navigation will be handled automatically.
## WordPress cleanup tasks

View File

@ -4,7 +4,7 @@ post_title: Handling merchant onboarding
## Introduction
Onboarding is a critical part of the merchants user experience. It helps set them up for success and ensures theyre not only using your extension correctly but also getting the most out of it. There are a few especially useful features that you can take advantage of as a developer to help onboard merchants who are using your extension:
Onboarding is a critical part of the merchant's user experience. It helps set them up for success and ensures they're not only using your extension correctly but also getting the most out of it. There are a few especially useful features that you can take advantage of as a developer to help onboard merchants who are using your extension:
- Setup tasks
- Store management links
@ -21,7 +21,7 @@ Setup tasks appear on the WooCommerce Admin home screen and prompt a merchant to
### Registering the task with PHP
To register your task as an extended task list item, youll need to hook in to the `woocommerce_get_registered_extended_tasks` filter with a function that appends your task to the array the filter provides.
To register your task as an extended task list item, you'll need to hook in to the `woocommerce_get_registered_extended_tasks` filter with a function that appends your task to the array the filter provides.
```php
// Task registration
@ -35,9 +35,9 @@ function my_extension_register_the_task( $registered_tasks_list_items ) {
add_filter( 'woocommerce_get_registered_extended_tasks', 'my_extension_register_the_task', 10, 1 );
```
### Registering the tasks JavaScript
### Registering the task's JavaScript
In addition to registering the task name, youll also need to register and enqueue the transpiled JavaScript file containing your task component, its configuration, and its event-handlers. A common way to do this is to create a dedicated registration function that hooks into the `admin_enqueue_scripts` action in WordPress. If you do things this way, you can nest the `add_filter` call for `woocommerce_get_registered_extended_tasks` in this function as well. Below is an annotated example of how this registration might look:
In addition to registering the task name, you'll also need to register and enqueue the transpiled JavaScript file containing your task component, its configuration, and its event-handlers. A common way to do this is to create a dedicated registration function that hooks into the `admin_enqueue_scripts` action in WordPress. If you do things this way, you can nest the `add_filter` call for `woocommerce_get_registered_extended_tasks` in this function as well. Below is an annotated example of how this registration might look:
```php
// Register the task list item and the JS.
@ -191,11 +191,11 @@ addFilter(
);
```
In the example above, the extension does a few different things. Lets break it down:
In the example above, the extension does a few different things. Let's break it down:
#### Handle imports
First, import any functions, components, or other utilities from external dependencies. Weve kept WooCommerce-related dependencies separate from others for the sake of keeping things tidy. In a real-world extension, you may be importing other local modules. In those cases, we recommend creating a visually separate section for those imports as well.
First, import any functions, components, or other utilities from external dependencies. We've kept WooCommerce-related dependencies separate from others for the sake of keeping things tidy. In a real-world extension, you may be importing other local modules. In those cases, we recommend creating a visually separate section for those imports as well.
```js
// External dependencies
@ -207,7 +207,7 @@ import { Card, CardBody } from '@wordpress/components'``;
import { getHistory, getNewPath } from '@woocommerce/navigation'``;
```
The `addFilter` function allows us to hook in to JavaScript filters the same way that the traditional PHP call to `add_filter()` does. The `apiFetch` utility allows our extension to query the WordPress REST API without needing to deal with keys or authentication. Finally, the `Card` and `CardBody` are predefined React components that well use as building blocks for our extensions Task component.
The `addFilter` function allows us to hook in to JavaScript filters the same way that the traditional PHP call to `add_filter()` does. The `apiFetch` utility allows our extension to query the WordPress REST API without needing to deal with keys or authentication. Finally, the `Card` and `CardBody` are predefined React components that we'll use as building blocks for our extension's Task component.
#### Create Event Handlers
@ -230,13 +230,13 @@ const markTaskComplete = () => {
};
```
In the example above, the event handler uses `apiFetch` to set the `woocommerce_admin_add_task_example_complete` options value to `true` and then updates the components state data and redirects the browser to the Admin root. In the case of an error, were simply logging it to the console, but you may want to implement your own solution here.
In the example above, the event handler uses `apiFetch` to set the `woocommerce_admin_add_task_example_complete` option's value to `true` and then updates the component's state data and redirects the browser to the Admin root. In the case of an error, we're simply logging it to the console, but you may want to implement your own solution here.
The `markTaskIncomplete` function is more or less an inverse of `markTaskComplete` that toggles the tasks completion status in the opposite direction.
The `markTaskIncomplete` function is more or less an inverse of `markTaskComplete` that toggles the task's completion status in the opposite direction.
#### Construct the component
Next, we create a [functional component](https://reactjs.org/docs/components-and-props.html) that returns our task card. The intermixed JavaScript/HTML syntax were using here is called JSX. If youre unfamiliar with it, you can [read more about it in the React docs](https://reactjs.org/docs/introducing-jsx.html).
Next, we create a [functional component](https://reactjs.org/docs/components-and-props.html) that returns our task card. The intermixed JavaScript/HTML syntax we're using here is called JSX. If you're unfamiliar with it, you can [read more about it in the React docs](https://reactjs.org/docs/introducing-jsx.html).
```js
const Task = () => {
@ -263,11 +263,11 @@ const Task = () => {
};
```
In the example above, were using the `Card` and `CardBody` components to construct our tasks component. The `div` inside the `CardBody` uses a [JavaScript expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Expressions) (`{}`) to embed a ternary operator that uses the components state to determine whether to display the task as complete or incomplete.
In the example above, we're using the `Card` and `CardBody` components to construct our task's component. The `div` inside the `CardBody` uses a [JavaScript expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Expressions) (`{}`) to embed a ternary operator that uses the component's state to determine whether to display the task as complete or incomplete.
#### Configure task and add it to the WooCommerce task list
Finally, well set some configuration values for our task and then use the `addFilter` function to append our task to the WooCommerce Admin Onboarding Task List.
Finally, we'll set some configuration values for our task and then use the `addFilter` function to append our task to the WooCommerce Admin Onboarding Task List.
```js
addFilter(
@ -293,7 +293,7 @@ addFilter(
);
```
In the example above, were setting our tasks configuration as we pass it into the filter for simplicity, but in a real-world extension, you might encapsulate this somewhere else for better separation of concerns. Below is a list of properties that the task-list component supports for tasks.
In the example above, we're setting our task's configuration as we pass it into the filter for simplicity, but in a real-world extension, you might encapsulate this somewhere else for better separation of concerns. Below is a list of properties that the task-list component supports for tasks.
| Name | Type | Required | Description |
|----------------|------------|----------|-------------|
@ -305,8 +305,8 @@ In the example above, were setting our tasks configuration as we pass it i
| visible | Boolean | Yes | Whether the task is visible or not |
| additionalInfo | String | No | Additional information |
| time | String | Yes | Time it takes to finish up the task |
| isDismissable | Boolean | No | Whether the task is dismissable or not. If false the Dismiss button wont be visible |
| onDismiss | Function | No | Callback method that its triggered on dismission |
| isDismissable | Boolean | No | Whether the task is dismissable or not. If false the Dismiss button won't be visible |
| onDismiss | Function | No | Callback method that it's triggered on dismission |
| type | String | Yes | Type of task list item, setup items will be in the store setup and extension in the extensions setup |
@ -326,13 +326,13 @@ Adding your own store management links is a simple process that involves:
### Installing the Icons package
Store management links use the `@wordpress/icons` package. If your extension isnt already using it, youll need to add it to your extensions list of dependencies.
Store management links use the `@wordpress/icons` package. If your extension isn't already using it, you'll need to add it to your extension's list of dependencies.
`npm` `install` ` @wordpress``/icons ` `--save`
### Enqueuing the JavaScript
The logic that adds your custom link to the store management section will live in a JavaScript file. Well register and enqueue that file with WordPress in our PHP file:
The logic that adds your custom link to the store management section will live in a JavaScript file. We'll register and enqueue that file with WordPress in our PHP file:
```js
function custom_store_management_link() {
@ -347,11 +347,11 @@ add_action( 'admin_enqueue_scripts', 'custom_store_management_link' );
```
The first argument of this call is a handle, the name by which WordPress will refer to the script were enqueuing. The second argument is the URL where the script is located.
The first argument of this call is a handle, the name by which WordPress will refer to the script we're enqueuing. The second argument is the URL where the script is located.
The third argument is an array of script dependencies. By supplying the `wp-hooks` handle in that array, were ensuring that our script will have access to the `addFilter` function well be using to add our link to WooCommerces list.
The third argument is an array of script dependencies. By supplying the `wp-hooks` handle in that array, we're ensuring that our script will have access to the `addFilter` function we'll be using to add our link to WooCommerce's list.
The fourth argument is a priority, which determines the order in which JavaScripts are loaded in WordPress. Were setting a priority of 10 in our example. Its important that your script runs before the store management section is rendered. With that in mind, make sure your priority value is lower than 15 to ensure your link is rendered properly.
The fourth argument is a priority, which determines the order in which JavaScripts are loaded in WordPress. We're setting a priority of 10 in our example. It's important that your script runs before the store management section is rendered. With that in mind, make sure your priority value is lower than 15 to ensure your link is rendered properly.
### Supply your link via JavaScript
@ -381,13 +381,13 @@ addFilter(
## Using Admin Notes
Admin Notes are meant for displaying insightful information about your WooCommerce store, extensions, activity, and achievements. Theyre also useful for displaying information that can help with the day-to-day tasks of managing and optimizing a store. A good general rule is to use Admin Notes for information that is:
Admin Notes are meant for displaying insightful information about your WooCommerce store, extensions, activity, and achievements. They're also useful for displaying information that can help with the day-to-day tasks of managing and optimizing a store. A good general rule is to use Admin Notes for information that is:
1. Timely
2. Relevant
3. Useful
With that in mind, you might consider using Admin Notes to celebrate a particular milestone that a merchant has passed, or to provide additional guidance about using a specific feature or flow. Conversely, you shouldnt use Admin Notes to send repeated messages about the same topic or target all users with a note that is only relevant to a subset of merchants. Its okay to use Admin Notes for specific promotions, but you shouldnt abuse the system. Use your best judgement and remember the home screen is meant to highlight a stores most important actionable tasks.
With that in mind, you might consider using Admin Notes to celebrate a particular milestone that a merchant has passed, or to provide additional guidance about using a specific feature or flow. Conversely, you shouldn't use Admin Notes to send repeated messages about the same topic or target all users with a note that is only relevant to a subset of merchants. It's okay to use Admin Notes for specific promotions, but you shouldn't abuse the system. Use your best judgement and remember the home screen is meant to highlight a store's most important actionable tasks.
Despite being a part of the new React-powered admin experience in WooCommerce, Admin Notes are available to developers via a standard PHP interface.
@ -514,11 +514,11 @@ register_deactivation_hook( __FILE__, 'my_great_extension_deactivate' );
### Breaking it down
Lets break down the example above to examine what each section does.
Let's break down the example above to examine what each section does.
#### Namespacing and feature availability checks
First, were doing some basic namespacing and feature availability checks, along with a safeguard to make sure this file only executes within the WordPress application space.
First, we're doing some basic namespacing and feature availability checks, along with a safeguard to make sure this file only executes within the WordPress application space.
```php
namespace My\Wonderfully\Namespaced\Extension\Area;
@ -537,7 +537,7 @@ if ( ! class_exists( 'WC_Data_Store' ) ) {
#### Using Note and NoteTraits objects
Next, we define a simple class that will serve as a note provider for our note. To create and manage note objects, well import the `Note` and `NotesTraits` classes from WooCommerce Admin.
Next, we define a simple class that will serve as a note provider for our note. To create and manage note objects, we'll import the `Note` and `NotesTraits` classes from WooCommerce Admin.
```php
class ExampleNote {
@ -554,9 +554,9 @@ Before proceeding, create a constant called `NOTE_NAME` and assign a unique note
`const NOTE_NAME = 'my-prefix-example-note';`
#### Configure the notes details
#### Configure the note's details
Once youve set your notes name, you can define and configure your note. The `NoteTraits` class will call `self::get_note()` when performing operations, so you should encapsulate your notes instantiation and configuration in a static function called `get_note()` that returns a `Note` object.
Once you've set your note's name, you can define and configure your note. The `NoteTraits` class will call `self::get_note()` when performing operations, so you should encapsulate your note's instantiation and configuration in a static function called `get_note()` that returns a `Note` object.
```php
public static function get_note() {
@ -565,7 +565,7 @@ public static function get_note() {
}
```
Inside our `get_note()` function, well handle any logic for collecting data our Note may need to display. Our example note will include information about when the extension was activated, so this bit of code is just for demonstration. You might include other logic here depending on what data your note should contain.
Inside our `get_note()` function, we'll handle any logic for collecting data our Note may need to display. Our example note will include information about when the extension was activated, so this bit of code is just for demonstration. You might include other logic here depending on what data your note should contain.
```php
$activated_time = current_time( 'timestamp', 0);
@ -573,7 +573,7 @@ $activated_time_formatted = date( 'F jS', $activated_time );
```
Next, well instantiate a new `Note` object.
Next, we'll instantiate a new `Note` object.
`$note = new Note();`
@ -581,7 +581,7 @@ Once we have an instance of the Note class, we can work with its API to set its
`$note->set_title( 'Getting Started' );`
Then well use some of the timestamp data we collected above to set the notes content.
Then we'll use some of the timestamp data we collected above to set the note's content.
```php
$note->set_content(
@ -601,13 +601,13 @@ $note->set_content_data( (object) array(
) );
```
Next, well set the notes `type` property. Note types are defined as enum-style class constants in the `Note` class. Available note types are _error_, _warning_, _update_, _info_, and _marketing_. When selecting a note type, be aware that the _error_ and _update_ result in the note being shown as a Store Alert, not in the Inbox. Its best to avoid using these types of notes unless you absolutely need to.
Next, we'll set the note's `type` property. Note types are defined as enum-style class constants in the `Note` class. Available note types are _error_, _warning_, _update_, _info_, and _marketing_. When selecting a note type, be aware that the _error_ and _update_ result in the note being shown as a Store Alert, not in the Inbox. It's best to avoid using these types of notes unless you absolutely need to.
`$note->set_type( Note::E_WC_ADMIN_NOTE_INFORMATIONAL );`
Admin Notes also support a few different layouts. You can specify `banner`, `plain`, or `thumbnail` as the layout. If youre interested in seeing the different layouts in action, take a look at [this simple plugin](https://gist.github.com/octaedro/864315edaf9c6a2a6de71d297be1ed88) that you can install to experiment with them.
Admin Notes also support a few different layouts. You can specify `banner`, `plain`, or `thumbnail` as the layout. If you're interested in seeing the different layouts in action, take a look at [this simple plugin](https://gist.github.com/octaedro/864315edaf9c6a2a6de71d297be1ed88) that you can install to experiment with them.
Well choose `plain` as our layout, but its also the default, so we could leave this property alone and the effect would be the same.
We'll choose `plain` as our layout, but it's also the default, so we could leave this property alone and the effect would be the same.
`$note->set_layout( 'plain' );`
@ -615,14 +615,14 @@ If you have an image that you want to add to your Admin Note, you can specify it
`$note->set_image( '' );`
Next, well set the values for our Admin Notes `name` and `source` properties. As a best practice, you should store your extensions name (i.e. its slug) in the `source` property of the note. You can use the `name` property to support multiple sub-types of notes. This gives you a handy way of namespacing your notes and managing them at both a high and low level.
Next, we'll set the values for our Admin Note's `name` and `source` properties. As a best practice, you should store your extension's name (i.e. its slug) in the `source` property of the note. You can use the `name` property to support multiple sub-types of notes. This gives you a handy way of namespacing your notes and managing them at both a high and low level.
```php
$note->set_source( 'inbox-note-example');
$note->set_name( self::NOTE_NAME );
```
Admin Notes can support 0, 1, or 2 actions (buttons). You can use these actions to capture events that trigger asynchronous processes or help the merchant navigate to a particular view to complete a step, or even simply to provide an external link for further information. The `add_action()` function takes up to three arguments. The first is the action name, which can be used for event handling, the second renders as a label for the actions button, and the third is an optional URL for actions that require navigation.
Admin Notes can support 0, 1, or 2 actions (buttons). You can use these actions to capture events that trigger asynchronous processes or help the merchant navigate to a particular view to complete a step, or even simply to provide an external link for further information. The `add_action()` function takes up to three arguments. The first is the action name, which can be used for event handling, the second renders as a label for the action's button, and the third is an optional URL for actions that require navigation.
```php
$note->add_action(
@ -641,7 +641,7 @@ Finally, remember to have the `get_note()` function return the configured Note o
To add and delete notes, you can use the helper functions that are part of the `NoteTraits` class: `possibly_add_note()` and its counterpart `possibly_delete_note()`. These functions will handle some of the repetitive logic related to note management and will also run checks to help you avoid creating duplicate notes.
Our example extension ties these calls to activation and deactivation hooks for the sake of simplicity. While there are many events for which you may want to add Notes to a merchants inbox, deleting notes upon deactivation and uninstallation is an important part of managing your extensions lifecycle.
Our example extension ties these calls to activation and deactivation hooks for the sake of simplicity. While there are many events for which you may want to add Notes to a merchant's inbox, deleting notes upon deactivation and uninstallation is an important part of managing your extension's lifecycle.
```php
function my_great_extension_activate() {

View File

@ -8,18 +8,18 @@ Building a WooCommerce extension that provides a first-class experience for merc
## The main plugin file
Your extensions main PHP file is a bootstrapping file. It contains important metadata about your extension that WordPress and WooCommerce use for a number of ecosystem integration processes, and it serves as the primary entry point for your extensions functionality. While there is not a particular rule enforced around naming this file, using a hyphenated version of the plugin name is a common best practice. (i.e. my-extension.php)
Your extension's main PHP file is a bootstrapping file. It contains important metadata about your extension that WordPress and WooCommerce use for a number of ecosystem integration processes, and it serves as the primary entry point for your extension's functionality. While there is not a particular rule enforced around naming this file, using a hyphenated version of the plugin name is a common best practice. (i.e. my-extension.php)
## Declaring extension metadata
Your extensions main plugin file should have a header comment that includes a number of important pieces of metadata about your extension. WordPress has a list of header requirements to which all plugins must adhere, but there are additional considerations for WooCommerce extensions:
Your extension's main plugin file should have a header comment that includes a number of important pieces of metadata about your extension. WordPress has a list of header requirements to which all plugins must adhere, but there are additional considerations for WooCommerce extensions:
- The `Author` and `Developer` fields are required and should be set to
either your name or your company name.
- The `Developer URI` field should be your official webpage URL.
- The `Plugin URI` field should contain the URL of the extensions product page in the WooCommerce Marketplace or the extensions official landing page on your website.
- The `Plugin URI` field should contain the URL of the extension's product page in the WooCommerce Marketplace or the extension's official landing page on your website.
- For extensions listed in the WooCommerce Marketplace, to help facilitate the update process, add a `Woo` field and an appropriate value. WooCommerce Marketplace vendors can find this snippet by logging in to the Vendors Dashboard and navigating to `Extensions > All Extensions`. Then, select the product and click Edit product page. This snippet will be in the upper-right-hand corner of the screen.
@ -47,7 +47,7 @@ Below is an example of what the header content might look like for an extension
## Preventing data leaks
As a best practice, your extensions PHP files should contain a conditional statement at the top that checks for WordPress ABSPATH constant. If this constant is not defined, the script should exit.
As a best practice, your extension's PHP files should contain a conditional statement at the top that checks for WordPress' ABSPATH constant. If this constant is not defined, the script should exit.
`defined( 'ABSPATH' ) || exit;`
@ -55,13 +55,13 @@ This check prevents your PHP files from being executed via direct browser access
## Managing extension lifecycle
Because your main PHP file is the primary point of coupling between your extension and WordPress, you should use it as a hub for managing your extensions lifecycle. At a very basic level, this means handling:
Because your main PHP file is the primary point of coupling between your extension and WordPress, you should use it as a hub for managing your extension's lifecycle. At a very basic level, this means handling:
- Activation
- Execution
- Deactivation
Starting with these three broad lifecycle areas, you can begin to break your extensions functionality down further to help maintain a good separation of concerns.
Starting with these three broad lifecycle areas, you can begin to break your extension's functionality down further to help maintain a good separation of concerns.
## Handling activation and deactivation
@ -83,15 +83,15 @@ register_deactivation_hook( __FILE__, 'my_extension_deactivate' );
## Maintaining a separation of concerns
There are numerous ways to organize the code in your extension. You can find a good overview of best practices in the WordPress Plugin Developer Handbook. Regardless of the approach you use for organizing your code, the nature of WordPress shared application space makes it imperative that you build with an eye toward interoperability. There are a few common principles that will help you optimize your extension and ensure it is a good neighbor to others:
There are numerous ways to organize the code in your extension. You can find a good overview of best practices in the WordPress Plugin Developer Handbook. Regardless of the approach you use for organizing your code, the nature of WordPress' shared application space makes it imperative that you build with an eye toward interoperability. There are a few common principles that will help you optimize your extension and ensure it is a good neighbor to others:
- Use namespacing and prefixing to avoid conflicts with other extensions.
- Use classes to encapsulate your extensions functionality.
- Use classes to encapsulate your extension's functionality.
- Check for existing declarations, assignments, and implementations.
## The core extension class
As mentioned above, encapsulating different parts of your extensions functionality using classes is an important measure that not only helps with interoperability, but which also makes your code easier to maintain and debug. Your extension may have many different classes, each shouldering some piece of functionality. At a minimum, your extension should define a central class which can handle the setup, initialization and management of a single instance of itself.
As mentioned above, encapsulating different parts of your extension's functionality using classes is an important measure that not only helps with interoperability, but which also makes your code easier to maintain and debug. Your extension may have many different classes, each shouldering some piece of functionality. At a minimum, your extension should define a central class which can handle the setup, initialization and management of a single instance of itself.
## Implementing a singleton pattern
@ -146,7 +146,7 @@ if ( ! class_exists( 'My_Extension' ) ) :
endif;
```
Notice that the example class above is designed to be instantiated by calling the static class method `instance()`, which will either return an existing instance of the class or create one and return it. In order to fully protect against unwanted instantiation, its also necessary to override the built-in magic methods `__clone()` and `__wakeup()`. You can implement your own error logging here or use something like `_doing_it_wrong()` which handles error logging for you. You can also use WooCommerces wrapper function `wc_doing_it_wrong()` here. Just be sure your code checks that the function exists first.
Notice that the example class above is designed to be instantiated by calling the static class method `instance()`, which will either return an existing instance of the class or create one and return it. In order to fully protect against unwanted instantiation, it's also necessary to override the built-in magic methods `__clone()` and `__wakeup()`. You can implement your own error logging here or use something like `_doing_it_wrong()` which handles error logging for you. You can also use WooCommerce's wrapper function `wc_doing_it_wrong()` here. Just be sure your code checks that the function exists first.
## Constructor
@ -169,7 +169,7 @@ protected function __construct() {
## Loading dependencies
The includes() function above is where youll load other class dependencies, typically via an include or require constructs. A common way of managing and loading external dependencies is to use Composers autoload feature, but you can also load specific files individually. You can read more about how to autoload external dependencies in the Composer documentation. A basic example of a setup method that uses both Composer and internal inclusion is below.
The includes() function above is where you'll load other class dependencies, typically via an include or require constructs. A common way of managing and loading external dependencies is to use Composer's autoload feature, but you can also load specific files individually. You can read more about how to autoload external dependencies in the Composer documentation. A basic example of a setup method that uses both Composer and internal inclusion is below.
```php
public function includes() {
@ -185,9 +185,9 @@ public function includes() {
## Initialization
The `init()` function above is where you should handle any setup for the classes you loaded in the includes() method. This step is where youll often perform any initial registration with relevant actions or filters. Its also where you can register and enqueue your extensions JavaScripts and stylesheets.
The `init()` function above is where you should handle any setup for the classes you loaded in the includes() method. This step is where you'll often perform any initial registration with relevant actions or filters. It's also where you can register and enqueue your extension's JavaScripts and stylesheets.
Heres an example of what your initialization method might look like:
Here's an example of what your initialization method might look like:
```php
private function init() {
@ -205,13 +205,13 @@ private function init() {
}
```
There are many different ways that your core class initialization method might look, depending on the way that you choose to architect your extension. The important concept here is that this function serves as a central point for handling any initial registration and setup that your extension requires in order to respond to web requests going forward.
There are many different ways that your core class' initialization method might look, depending on the way that you choose to architect your extension. The important concept here is that this function serves as a central point for handling any initial registration and setup that your extension requires in order to respond to web requests going forward.
## Delaying initialization
The WordPress activation hook we set up above with register_activation_hook() may seem like a great place to instantiate our extensions main class, and in some cases it will work. By virtue of being a plugin for a plugin, however, WooCommerce extensions typically require WooCommerce to be loaded in order to function properly, so its often best to delay instantiation and initialization until after WordPress has loaded other plugins.
The WordPress activation hook we set up above with register_activation_hook() may seem like a great place to instantiate our extension's main class, and in some cases it will work. By virtue of being a plugin for a plugin, however, WooCommerce extensions typically require WooCommerce to be loaded in order to function properly, so it's often best to delay instantiation and initialization until after WordPress has loaded other plugins.
To do that, instead of hooking your instantiation to your extensions activation hook, use the plugins_loaded action in WordPress to instantiate your extensions core class and add its singleton to the $GLOBALS array.
To do that, instead of hooking your instantiation to your extension's activation hook, use the plugins_loaded action in WordPress to instantiate your extension's core class and add its singleton to the $GLOBALS array.
```php
function my_extension_initialize() {
@ -231,7 +231,7 @@ In the example above, WordPress will wait until after all plugins have been load
## Handling execution
Once your extension is active and initialized, the possibilities are wide open. This is where the proverbial magic happens in an extension, and its largely up to you to define. While implementing specific functionality is outside the scope of this guide, there are some best practices to keep in mind as you think about how to build out your extensions functionality.
Once your extension is active and initialized, the possibilities are wide open. This is where the proverbial magic happens in an extension, and it's largely up to you to define. While implementing specific functionality is outside the scope of this guide, there are some best practices to keep in mind as you think about how to build out your extension's functionality.
- Keep an event-driven mindset. Merchants and shoppers who use your extension will be interacting with WooCommerce using web requests, so it can be helpful to anchor your extension to some of the critical flows that users follow in WooCommerce.
@ -251,9 +251,9 @@ The WordPress deactivation hook we set up earlier in our main PHP file with regi
## Uninstallation
While its certainly possible to completely reverse everything your extension has created when a merchant deactivates it, its not advisable nor practical in most cases. Instead, its best to reserve that behavior for uninstallation.
While it's certainly possible to completely reverse everything your extension has created when a merchant deactivates it, it's not advisable nor practical in most cases. Instead, it's best to reserve that behavior for uninstallation.
For handling uninstallation, its best to follow the guidelines in the WordPress Plugin Handbook.
For handling uninstallation, it's best to follow the guidelines in the WordPress Plugin Handbook.
## Putting it all together

View File

@ -2,19 +2,19 @@
post_title: Implementing settings for extensions
---
If youre customizing WooCommerce or adding your own functionality to it youll probably need a settings page of some sort. One of the easiest ways to create a settings page is by taking advantage of the [`WC_Integration` class](https://woocommerce.github.io/code-reference/classes/WC-Integration.html 'WC_Integration Class'). Using the Integration class will automatically create a new settings page under **WooCommerce > Settings > Integrations** and it will automatically save, and sanitize your data for you. Weve created this tutorial so you can see how to create a new integration.
If you're customizing WooCommerce or adding your own functionality to it you'll probably need a settings page of some sort. One of the easiest ways to create a settings page is by taking advantage of the [`WC_Integration` class](https://woocommerce.github.io/code-reference/classes/WC-Integration.html 'WC_Integration Class'). Using the Integration class will automatically create a new settings page under **WooCommerce > Settings > Integrations** and it will automatically save, and sanitize your data for you. We've created this tutorial so you can see how to create a new integration.
## Setting up the Integration
Youll need at least two files to create an integration so youll need to create a directory.
You'll need at least two files to create an integration so you'll need to create a directory.
### Creating the Main Plugin File
Create your main plugin file to [hook](https://developer.wordpress.org/reference/functions/add_action/ 'WordPress add_action()') into the `plugins_loaded` hook and check if the `WC_Integration` [class exists](https://www.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends 'PHP Class Exists'). If it doesnt then the user most likely doesnt have WooCommerce activated. After you do that you need to register the integration. Load the integration file (well get to this file in a minute). Use the `woocommerce_integrations` filter to add a new integration to the [array](http://php.net/manual/en/language.types.array.php 'PHP Array').
Create your main plugin file to [hook](https://developer.wordpress.org/reference/functions/add_action/ 'WordPress add_action()') into the `plugins_loaded` hook and check if the `WC_Integration` [class exists](https://www.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends 'PHP Class Exists'). If it doesn't then the user most likely doesn't have WooCommerce activated. After you do that you need to register the integration. Load the integration file (we'll get to this file in a minute). Use the `woocommerce_integrations` filter to add a new integration to the [array](http://php.net/manual/en/language.types.array.php 'PHP Array').
### Creating the Integration Class
Now that we have the framework setup lets actually implement this Integration class. There already is a `WC_Integration` class so we want to make a [child class](http://php.net/manual/en/keyword.extends.php 'PHP Child Class'). This way it inherits all of the existing methods and data. Youll need to set an id, a description, and a title for your integration. These will show up on the integration page. Youll also need to load the settings by calling: `$this->init_form_fields();` & `$this->init_settings();` Youll also need to save your options by calling the `woocommerce_update_options_integration_{your method id}` hook. Lastly you have to input some settings to save! Weve included two dummy fields below but well go more into fields in the next section.
Now that we have the framework setup let's actually implement this Integration class. There already is a `WC_Integration` class so we want to make a [child class](http://php.net/manual/en/keyword.extends.php 'PHP Child Class'). This way it inherits all of the existing methods and data. You'll need to set an id, a description, and a title for your integration. These will show up on the integration page. You'll also need to load the settings by calling: `$this->init_form_fields();` & `$this->init_settings();` You'll also need to save your options by calling the `woocommerce_update_options_integration_{your method id}` hook. Lastly you have to input some settings to save! We've included two dummy fields below but we'll go more into fields in the next section.
> Added to a file named `class-wc-integration-demo-integration.php`
@ -150,7 +150,7 @@ $WC_Integration_Demo = new WC_Integration_Demo( __FILE__ );
## Creating Settings
If you took a look through the last section youll see that we added two dummy settings using the `init_form_fields()` method.
If you took a look through the last section you'll see that we added two dummy settings using the `init_form_fields()` method.
### Types of Settings
@ -165,7 +165,7 @@ WooCommerce includes support for 8 types of settings.
- select
- multiselect
And these settings have attributes which you can use. These affect the way the setting looks and behaves on the settings page. It doesnt affect the setting itself. The attributes will manifest slightly differently depending on the setting type. A placeholder for example doesnt work with checkboxes. To see exactly how they work you should look through the [source code](https://github.com/woocommerce/woocommerce/blob/master/includes/abstracts/abstract-wc-settings-api.php#L180 'WC Settings API on GitHub'). Ex.
And these settings have attributes which you can use. These affect the way the setting looks and behaves on the settings page. It doesn't affect the setting itself. The attributes will manifest slightly differently depending on the setting type. A placeholder for example doesn't work with checkboxes. To see exactly how they work you should look through the [source code](https://github.com/woocommerce/woocommerce/blob/master/includes/abstracts/abstract-wc-settings-api.php#L180 'WC Settings API on GitHub'). Ex.
- title
- class
@ -177,7 +177,7 @@ And these settings have attributes which you can use. These affect the way the s
### Creating Your Own Settings
The built-in settings are great but you may need extra controls to create your settings page. Thats why we included some methods to do this for you. First, define a setting by adding it to the `$this->form_fields` array, entering the kind of form control you want under `type`. You can override the default HTML for your form inputs by creating a method with a name of the format `generate_{ type }_html` which outputs HTML markup. To specify how buttons are rendered, youd add a method called `generate_button_html`. For textareas, youd add a `generate_textarea_html` method, and so on. (Check out the `generate_settings_html` method of the `WC_Settings_API` class in the WooCommerce source code to see how WooCommerce uses this.) The below example creates a button that goes to Woo.com.
The built-in settings are great but you may need extra controls to create your settings page. That's why we included some methods to do this for you. First, define a setting by adding it to the `$this->form_fields` array, entering the kind of form control you want under `type`. You can override the default HTML for your form inputs by creating a method with a name of the format `generate_{ type }_html` which outputs HTML markup. To specify how buttons are rendered, you'd add a method called `generate_button_html`. For textareas, you'd add a `generate_textarea_html` method, and so on. (Check out the `generate_settings_html` method of the `WC_Settings_API` class in the WooCommerce source code to see how WooCommerce uses this.) The below example creates a button that goes to Woo.com.
```php
/**
@ -245,11 +245,11 @@ public function generate_button_html( $key, $data ) {
## Validating & Sanitizing Data
To create the best user experience youll most likely want to validate and sanitize your data. The integration class already performs basic sanitization so that theres no malicious code present but you could further sanitize by removing unused data. An example of sanitizing data would be integrating with a 3rd party service where all API keys are upper case. You could convert the API key to upper case which will make it a bit more clear for the user.
To create the best user experience you'll most likely want to validate and sanitize your data. The integration class already performs basic sanitization so that there's no malicious code present but you could further sanitize by removing unused data. An example of sanitizing data would be integrating with a 3rd party service where all API keys are upper case. You could convert the API key to upper case which will make it a bit more clear for the user.
### Sanitize
We'll demonstrate how to sanitize data first because its a bit easier to understand. But the one thing you should keep in mind is that sanitizing happens _after_ validation. So if something isnt validated it wont get to the sanitization step.
We'll demonstrate how to sanitize data first because it's a bit easier to understand. But the one thing you should keep in mind is that sanitizing happens _after_ validation. So if something isn't validated it won't get to the sanitization step.
```php
/**
@ -279,7 +279,7 @@ public function sanitize_settings( $settings ) {
### Validation
Validation isnt always necessary but its nice to do. If your API keys are always 10 characters long and someone enters one thats not 10 then you can print out an error message and prevent the user a lot of headache when they assumed they put it in correctly. First set up a `validate_{setting key}_field` method for each field you want to validate. For example, with the `api_key` field you need a `validate_api_key_field()` method.
Validation isn't always necessary but it's nice to do. If your API keys are always 10 characters long and someone enters one that's not 10 then you can print out an error message and prevent the user a lot of headache when they assumed they put it in correctly. First set up a `validate_{setting key}_field` method for each field you want to validate. For example, with the `api_key` field you need a `validate_api_key_field()` method.
```php
public function validate_api_key_field( $key, $value ) {
@ -293,4 +293,4 @@ public function validate_api_key_field( $key, $value ) {
## A complete example
If youve been following along you should have a complete integration example. If you have any problems see our [full integration demo](https://github.com/woogists/woocommerce-integration-demo 'Integration Demo').
If you've been following along you should have a complete integration example. If you have any problems see our [full integration demo](https://github.com/woogists/woocommerce-integration-demo 'Integration Demo').

View File

@ -34,6 +34,6 @@ Now use your attribute in **Appearance > Menus**. You will notice, however, tha
You need to theme your attribute to make it display products as you want. To do this:
1. Copy `woocommerce/templates/taxonomy-product_cat.php` into your theme folder
2. Rename the template to reflect your attribute in our example wed use `taxonomy-pa_size.php`
2. Rename the template to reflect your attribute in our example we'd use `taxonomy-pa_size.php`
You should now see this template when viewing taxonomy terms for your custom attribute.

View File

@ -10,7 +10,7 @@ There are a few different ways you might want to get started utilizing WooCommer
### [Installing and setting up WooCommerce](https://woo.com/document/build-online-store/)
If youre brand new to Woo, this guide will show you How to build an online store on WooCommerce. This is where you can learn the ins and outs of how WooCommerce works before you start developing.
If you're brand new to Woo, this guide will show you How to build an online store on WooCommerce. This is where you can learn the ins and outs of how WooCommerce works before you start developing.
### [Extension Development Quick Start](https://github.com/woocommerce/woocommerce/tree/trunk/packages/js/create-woo-extension)
@ -73,7 +73,7 @@ While WooCommerce Blocks are now the easiest and most flexible way to display yo
### [WooCommerce on GitHub](https://github.com/woocommerce)
This is the official WooCommerce organization on GitHub. Here youll find the majority of development work that happens on open source projects that the WooCommerce team maintains.
This is the official WooCommerce organization on GitHub. Here you'll find the majority of development work that happens on open source projects that the WooCommerce team maintains.
### [Automattic on GitHub](https://github.com/automattic)
@ -89,7 +89,7 @@ This is the official WordPress organization on GitHub a go-to source for
### [WordPress Developer Resources](https://developer.wordpress.org/)
All the resources you need for developing with WordPress. If youre not familiar with the WordPress development ecosystem, this is a great place to start.
All the resources you need for developing with WordPress. If you're not familiar with the WordPress development ecosystem, this is a great place to start.
### [WooCommerce Community Slack](https://woo.com/community-slack)

View File

@ -20,7 +20,7 @@ This is the command-line interface for [WordPress](https://wordpress.org/). You
#### [wp-env](https://www.npmjs.com/package/@wordpress/env)
This command-line tool lets you easily set up a local WordPress environment for building and testing plugins and themes. Its simple to install and requires no configuration.
This command-line tool lets you easily set up a local WordPress environment for building and testing plugins and themes. It's simple to install and requires no configuration.
#### [eslint-plugin](https://www.npmjs.com/package/@woocommerce/eslint-plugin)

View File

@ -9,7 +9,7 @@ Sometimes, you might need to customize your theme or WooCommerce beyond what is
## What is a child theme?
Before we start its important that you understand what a child theme is. In short, a child theme is a layer that you put on top of the parent theme to make alterations without having to develop a new theme from scratch. There are two major reasons to use child themes:
Before we start it's important that you understand what a child theme is. In short, a child theme is a layer that you put on top of the parent theme to make alterations without having to develop a new theme from scratch. There are two major reasons to use child themes:
- Theme developers can use child themes as a way to offer variations on a theme, similar to what we do with the [Storefront child themes](https://woo.com/products/storefront/)
- Developers can use child themes to host customizations of the parent theme or any plugin on the site since the child theme will get priority over the plugins and parent theme
@ -39,7 +39,7 @@ Template: themedir
*/
```
Next, we need to change the **Template** field to point to our installed WooTheme. In this example, well use the Storefront theme, which is installed under `wp-content/themes/storefront/`. The result will look like this:
Next, we need to change the **Template** field to point to our installed WooTheme. In this example, we'll use the Storefront theme, which is installed under `wp-content/themes/storefront/`. The result will look like this:
```css
/*
@ -54,7 +54,7 @@ Template: storefront
/* --------------- Theme customization starts here ----------------- */
```
**Note:** With Storefront, you do not need to enqueue any of the parent theme style files with PHP from the themes `functions.php` file or `@import` these into the child themes `style.css` file as the main parent Storefront theme does this for you.
**Note:** With Storefront, you do not need to enqueue any of the parent theme style files with PHP from the theme's `functions.php` file or `@import` these into the child themes `style.css` file as the main parent Storefront theme does this for you.
With Storefront, a child theme only requires a blank `functions.php` file and a `style.css` file to get up and running.
@ -62,18 +62,18 @@ With Storefront, a child theme only requires a blank `functions.php` file and a
You can upload the child theme either through your FTP client, or using the Add New theme option in WordPress.
- **Through FTP.** If youre using FTP, it means that you go directly to the folders of your website. That means youll need **FTP access** to your host, so you can upload the new child theme. If you dont have this, you should talk to your host and they can give you your FTP login details, and then download an FTP program to upload your files.
- **Through FTP.** If you're using FTP, it means that you go directly to the folders of your website. That means you'll need **FTP access** to your host, so you can upload the new child theme. If you don't have this, you should talk to your host and they can give you your FTP login details, and then download an FTP program to upload your files.
- **Through the WP Dashboard.** If you create a .zip file of your child theme folder you can then simply upload that to your site from the **WordPress > Appearance > Themes > Add New** section.
Once youve done that, your child theme will be uploaded to a new folder in `wp-content/themes/`, for example, `wp-content/themes/storefront-child/`. Once uploaded, we can go to our **WP Dashboard > Appearance > Themes** and activate the child theme.
Once you've done that, your child theme will be uploaded to a new folder in `wp-content/themes/`, for example, `wp-content/themes/storefront-child/`. Once uploaded, we can go to our **WP Dashboard > Appearance > Themes** and activate the child theme.
## Customizing design and functionality
Your child theme is now ready to be modified. Currently, it doesnt hold any customization, so lets look at a couple of examples of how we can customize the child theme without touching the parent theme.
Your child theme is now ready to be modified. Currently, it doesn't hold any customization, so let's look at a couple of examples of how we can customize the child theme without touching the parent theme.
### Design customization
Lets do an example together where we change the color of the site title. Add this to your `/storefront-child/style.css`:
Let's do an example together where we change the color of the site title. Add this to your `/storefront-child/style.css`:
```css
.site-branding h1 a {
@ -85,17 +85,17 @@ After saving the file and refreshing our browser, you will now see that the colo
### Template changes
**Note:** This doesnt apply to Storefront child themes. Any customizations to a Storefront child themes files will be lost when updating. Instead of customizing the Storefront child themes files directly, we recommended that you add code snippets to a customization plugin. Weve created one to do just this. Download [Theme Customizations](https://github.com/woocommerce/theme-customisations) for free.
**Note:** This doesn't apply to Storefront child themes. Any customizations to a Storefront child theme's files will be lost when updating. Instead of customizing the Storefront child theme's files directly, we recommended that you add code snippets to a customization plugin. We've created one to do just this. Download [Theme Customizations](https://github.com/woocommerce/theme-customisations) for free.
But wait, theres more! You can do the same with the template files (`*.php`) in the theme folder. For example if w, wanted to modify some code in the header, we need to copy header.php from our parent theme folder `wp-content/themes/storefront/header.php` to our child theme folder `wp-content/themes/storefront-child/header.php`. Once we have copied it to our child theme, we edit `header.php` and customize any code we want. The `header.php` in the child theme will be used instead of the parent themes `header.php`.
But wait, there's more! You can do the same with the template files (`*.php`) in the theme folder. For example if w, wanted to modify some code in the header, we need to copy header.php from our parent theme folder `wp-content/themes/storefront/header.php` to our child theme folder `wp-content/themes/storefront-child/header.php`. Once we have copied it to our child theme, we edit `header.php` and customize any code we want. The `header.php` in the child theme will be used instead of the parent theme's `header.php`.
The same goes for WooCommerce templates. If you create a new folder in your child theme called “WooCommerce”, you can make changes to the WooCommerce templates there to make it more in line with the overall design of your website. More on WooCommerces template structure [can be found here](https://woo.com/document/template-structure/).
The same goes for WooCommerce templates. If you create a new folder in your child theme called “WooCommerce”, you can make changes to the WooCommerce templates there to make it more in line with the overall design of your website. More on WooCommerce's template structure [can be found here](https://woo.com/document/template-structure/).
### Functionality changes
**NOTE**: The functions.php in your child theme should be **empty** and not include anything from the parent themes functions.php.
**NOTE**: The functions.php in your child theme should be **empty** and not include anything from the parent theme's functions.php.
The `functions.php` in your child theme is loaded **before** the parent themes `functions.php`. If a function in the parent theme is **pluggable**, it allows you to copy a function from the parent theme into the child themes `functions.php` and have it replace the one in your parent theme. The only requirement is that the parent themes function is **pluggable**, which basically means it is wrapped in a conditional if statement e.g:
The `functions.php` in your child theme is loaded **before** the parent theme's `functions.php`. If a function in the parent theme is **pluggable**, it allows you to copy a function from the parent theme into the child theme's `functions.php` and have it replace the one in your parent theme. The only requirement is that the parent theme's function is **pluggable**, which basically means it is wrapped in a conditional if statement e.g:
```php
if ( ! function_exists( "parent_function_name" ) ) {

View File

@ -6,7 +6,7 @@ post_title: WooCommerce Endpoints
Endpoints are an extra part in the website URL that is detected to show different content when present.
For example: You may have a my account page shown at URL **yoursite.com/my-account**. When the endpoint edit-account is appended to this URL, making it **yoursite.com/my-account/edit-account** then the **Edit account page** is shown instead of the **My account page**.
For example: You may have a 'my account' page shown at URL **yoursite.com/my-account**. When the endpoint 'edit-account' is appended to this URL, making it '**yoursite.com/my-account/edit-account**' then the **Edit account page** is shown instead of the **My account page**.
This allows us to show different content without the need for multiple pages and shortcodes, and reduces the amount of content that needs to be installed.
@ -51,7 +51,7 @@ If you want to include an endpoint in your menus, you need to use the Links sect
Enter the full URL to the endpoint and then insert that into your menu.
Remember that some endpoints, such as view-order, require an order ID to work. In general, we dont recommend adding these endpoints to your menus. These pages can instead be accessed via the my-account page.
Remember that some endpoints, such as view-order, require an order ID to work. In general, we don't recommend adding these endpoints to your menus. These pages can instead be accessed via the my-account page.
## Using endpoints in Payment Gateway Plugins
@ -74,7 +74,7 @@ Gateways need to use these methods for full 2.1+ compatibility.
### Endpoints are not working
On Windows servers, the **web.config** file may not be set correctly to allow for the endpoints to work correctly. In this case, clicking on endpoint links (e.g. /edit-account/ or /customer-logout/) may appear to do nothing except refresh the page. In order to resolve this, try simplifying the **web.config** file on your Windows server. Heres a sample file configuration:
On Windows servers, the **web.config** file may not be set correctly to allow for the endpoints to work correctly. In this case, clicking on endpoint links (e.g. /edit-account/ or /customer-logout/) may appear to do nothing except refresh the page. In order to resolve this, try simplifying the **web.config** file on your Windows server. Here's a sample file configuration:
```xml
<?xml version="1.0" encoding="UTF-8"?>
@ -99,7 +99,7 @@ On Windows servers, the **web.config** file may not be set correctly to allow fo
### Pages direct to wrong place
Landing on the wrong page when clicking an endpoint URL is typically caused by incorrect settings. For example, clicking Edit address on your account page takes you to the Shop page instead of the edit address form means you selected the wrong page in settings. Confirm that your pages are correctly configured and that a different page is used for each section.
Landing on the wrong page when clicking an endpoint URL is typically caused by incorrect settings. For example, clicking 'Edit address' on your account page takes you to the Shop page instead of the edit address form means you selected the wrong page in settings. Confirm that your pages are correctly configured and that a different page is used for each section.
### How to Remove “Downloads” from My Account

View File

@ -4,25 +4,25 @@ post_title: High Performance Order Storage (HPOS)
WooCommerce has traditionally stored store orders and related order information (like refunds) as custom WordPress post types or post meta records. This comes with performance issues.
[High-Performance Order Storage (HPOS)](https://developer.woo.com/2022/09/14/high-performance-order-storage-progress-report/) also previously known as “Custom Order Tables” is a solution that provides an easy-to-understand and solid database structure specifically designed for eCommerce needs. It uses the WooCommerce CRUD design to store order data in custom tables optimized for WooCommerce queries with minimal impact on the stores performance.
[High-Performance Order Storage (HPOS)](https://developer.woo.com/2022/09/14/high-performance-order-storage-progress-report/) also previously known as “Custom Order Tables” is a solution that provides an easy-to-understand and solid database structure specifically designed for eCommerce needs. It uses the WooCommerce CRUD design to store order data in custom tables optimized for WooCommerce queries with minimal impact on the store's performance.
In January 2022, we published the [initial plan for the Custom Order Tables feature](https://developer.woo.com/2022/01/17/the-plan-for-the-woocommerce-custom-order-table/) and since then, weve been working hard to bring the High-Performance Order Storage (HPOS) to WooCommerce Core. In May 2022, we invited you to [test the order migration process](https://developer.woo.com/2022/05/16/call-for-early-testing-custom-order-table-migrations/) and provide feedback on how our initial work performs on real stores of varied configurations.
In January 2022, we published the [initial plan for the Custom Order Tables feature](https://developer.woo.com/2022/01/17/the-plan-for-the-woocommerce-custom-order-table/) and since then, we've been working hard to bring the High-Performance Order Storage (HPOS) to WooCommerce Core. In May 2022, we invited you to [test the order migration process](https://developer.woo.com/2022/05/16/call-for-early-testing-custom-order-table-migrations/) and provide feedback on how our initial work performs on real stores of varied configurations.
From WooCommerce 8.2, released on October 2023, [High-Performance Order Storage (HPOS)](https://developer.woo.com/2022/09/14/high-performance-order-storage-progress-report/) is officially released under the stable flag and will be enabled by default for new installations.
## [Whats New with High-Performance Order Storage?](https://github.com/woocommerce/woocommerce/blob/trunk/docs/high-performance-order-storage/#section-1)
## [What's New with High-Performance Order Storage?](https://github.com/woocommerce/woocommerce/blob/trunk/docs/high-performance-order-storage/#section-1)
Bringing High-Performance Order Storage (HPOS) to WooCommerce improves these three essential properties for eCommerce stores.
1/ **Scalability**
The rise in the number of customers and customer orders increases the load on your stores database making it difficult to handle customer order requests and deliver a seamless user experience.
The rise in the number of customers and customer orders increases the load on your store's database making it difficult to handle customer order requests and deliver a seamless user experience.
With High-Performance Order Storage, you get dedicated tables for data like orders and order addresses and thus dedicated indexes which results in fewer read/write operations and fewer busy tables. This feature enables eCommerce stores of all shapes and sizes to scale their business to their maximum potential without expert intervention.
2/ **Reliability**
High-Performance Order Storage makes implementing and restoring targeted data backup easier. Youll no longer need to worry about losing orders, inventory numbers, or client information with reliable backup in these custom order tables. Itll also facilitate implementing read/write locks and prevent race conditions.
High-Performance Order Storage makes implementing and restoring targeted data backup easier. You'll no longer need to worry about losing orders, inventory numbers, or client information with reliable backup in these custom order tables. It'll also facilitate implementing read/write locks and prevent race conditions.
3/ **Simplicity**
@ -148,7 +148,7 @@ If you are using a plugin that is not compatible with High-Performance Order Sto
![Plugins page](https://woo.com/wp-content/uploads/2023/10/image-22.png?w=650)
> **Note:** If you are using a third-party extension that isnt working properly with High-Performance Order Storage then please notify the developers of the extension and ask them to update their extension to add support for HPOS. Its up to the extension developers to add support for HPOS. We have [developer resources and documentation](https://developer.woo.com/2022/09/14/high-performance-order-storage-progress-report/) available to help with their integration efforts.
> **Note:** If you are using a third-party extension that isn't working properly with High-Performance Order Storage then please notify the developers of the extension and ask them to update their extension to add support for HPOS. It's up to the extension developers to add support for HPOS. We have [developer resources and documentation](https://developer.woo.com/2022/09/14/high-performance-order-storage-progress-report/) available to help with their integration efforts.
## [Disabling HPOS](https://github.com/woocommerce/woocommerce/blob/trunk/docs/high-performance-order-storage/#section-10)

View File

@ -21,7 +21,7 @@ To activate High-Performance Order Storage, existing stores will first need to g
![wc_schedule_pending_batch_process Screen](https://woo.com/wp-content/uploads/2023/10/2.jpg?w=650)
![wc_run_batch_process Screen](https://woo.com/wp-content/uploads/2023/10/New-Project-5.jpg?w=650)
4/ After both tables are successfully synchronized, youll be able to select the option to switch to High-Performance Order Storage (HPOS).
4/ After both tables are successfully synchronized, you'll be able to select the option to switch to High-Performance Order Storage (HPOS).
- It is advisable to maintain compatibility mode for some time to ensure a seamless transition. In case of any issues, reverting to the post table can be done instantly.

View File

@ -2,7 +2,7 @@
post_title: Translating WooCommerce
---
WooCommerce is already translated into several languages and is translation-ready right out of the box. All thats needed is a translation file for your language.
WooCommerce is already translated into several languages and is translation-ready right out of the box. All that's needed is a translation file for your language.
There are several methods to create a translation, most of which are outlined in the WordPress Codex. In most cases you can contribute to the project on [https://translate.wordpress.org/projects/wp-plugins/woocommerce/](https://translate.wordpress.org/projects/wp-plugins/woocommerce/).
@ -25,7 +25,7 @@ We encourage contributions to our translations. If you want to add translated st
Both stable and development versions of WooCommerce are available for translation. When you install or update WooCommerce, WordPress will automatically fetch a 100% complete translation for your language. If such a translation isn't available, you can either download it manually or contribute to complete the translation, benefiting all users.
If youre new to translating, check out the [translators handbook](https://make.wordpress.org/polyglots/handbook/tools/glotpress-translate-wordpress-org/) to get started.
If you're new to translating, check out the [translators handbook](https://make.wordpress.org/polyglots/handbook/tools/glotpress-translate-wordpress-org/) to get started.
### Downloading translations from translate.wordpress.org manually
@ -149,9 +149,9 @@ In order to fix it, navigate to WooCommerce settings corresponding to the string
Navigate back to the Checkout page translations should be reflected there.
### I have translated the strings I needed, but some of them dont show up translated on the front end. Why?
### I have translated the strings I needed, but some of them don't show up translated on the front end. Why?
If some of your translated strings dont show up as expected on your WooCommerce site, the first thing to check is if these strings have both a Single and Plural form in the Source text section. To do so, open the corresponding translation on [https://translate.wordpress.org/projects/wp-plugins/woocommerce/](https://translate.wordpress.org/projects/wp-plugins/woocommerce/), e.g. [the translation for Product and Products](https://translate.wordpress.org/projects/wp-plugins/woocommerce/stable/de/default/?filters%5Bstatus%5D=either&filters%5Boriginal_id%5D=577764&filters%5Btranslation_id%5D=24210880).
If some of your translated strings don't show up as expected on your WooCommerce site, the first thing to check is if these strings have both a Single and Plural form in the Source text section. To do so, open the corresponding translation on [https://translate.wordpress.org/projects/wp-plugins/woocommerce/](https://translate.wordpress.org/projects/wp-plugins/woocommerce/), e.g. [the translation for Product and Products](https://translate.wordpress.org/projects/wp-plugins/woocommerce/stable/de/default/?filters%5Bstatus%5D=either&filters%5Boriginal_id%5D=577764&filters%5Btranslation_id%5D=24210880).
This screenshot shows that the Singular translation is available:

View File

@ -10,9 +10,9 @@ Payment gateways in WooCommerce are class based and can be added through tradit
Payment gateways come in several varieties:
1. **Form based** This is where the user must click a button on a form that then redirects them to the payment processor on the gateways own website. _Example_: PayPal standard, Authorize.net DPM
1. **Form based** This is where the user must click a button on a form that then redirects them to the payment processor on the gateway's own website. _Example_: PayPal standard, Authorize.net DPM
2. **iFrame based** This is when the gateway payment system is loaded inside an iframe on your store. _Example_: SagePay Form, PayPal Advanced
3. **Direct** This is when the payment fields are shown directly on the checkout page and the payment is made when place order is pressed. _Example_: PayPal Pro, Authorize.net AIM
3. **Direct** This is when the payment fields are shown directly on the checkout page and the payment is made when 'place order' is pressed. _Example_: PayPal Pro, Authorize.net AIM
4. **Offline** No online payment is made. _Example_: Cheque, Bank Transfer
Form and iFrame based gateways post data offsite, meaning there are less security issues for you to think about. Direct gateways, however, require server security to be implemented ([SSL certificates](https://woo.com/document/ssl-and-https/), etc.) and may also require a level of [PCI compliance](https://woo.com/document/pci-dss-compliance-and-woocommerce/).
@ -23,7 +23,7 @@ Form and iFrame based gateways post data offsite, meaning there are less securit
**Note:** We are unable to provide support for customizations under our [Support Policy](https://woo.com/support-policy/). If you are unfamiliar with code/templates and resolving potential conflicts, select a [WooExpert or Developer](https://woo.com/customizations/)  for assistance.
**Note:** The instructions below are for the default Checkout page. If youre looking to add a custom payment method for the new Checkout block, check out [this documentation.](https://github.com/woocommerce/woocommerce-blocks/blob/trunk/docs/third-party-developers/extensibility/checkout-payment-methods/payment-method-integration.md)
**Note:** The instructions below are for the default Checkout page. If you're looking to add a custom payment method for the new Checkout block, check out [this documentation.](https://github.com/woocommerce/woocommerce-blocks/blob/trunk/docs/third-party-developers/extensibility/checkout-payment-methods/payment-method-integration.md)
Payment gateways should be created as additional plugins that hook into WooCommerce. Inside the plugin, you need to create a class after plugins are loaded. Example:
@ -62,8 +62,8 @@ Most methods are inherited from the WC_Payment_Gateway class, but some are requ
Within your constructor, you should define the following variables:
- `$this->id` Unique ID for your gateway, e.g., your_gateway
- `$this->icon` If you want to show an image next to the gateways name on the frontend, enter a URL to an image.
- `$this->id` Unique ID for your gateway, e.g., 'your_gateway'
- `$this->icon` If you want to show an image next to the gateway's name on the frontend, enter a URL to an image.
- `$this->has_fields` Bool. Can be set to true if you want payment fields to show on the checkout (if doing a direct integration).
- `$this->method_title` Title of the payment method shown on the admin page.
- `$this->method_description` Description for the payment method shown on the admin page.
@ -75,7 +75,7 @@ $this->init\_form\_fields();
$this->init_settings();
```
Well cover `init_form_fields()` later, but this basically defines your settings that are then loaded with `init_settings()`.
We'll cover `init_form_fields()` later, but this basically defines your settings that are then loaded with `init_settings()`.
After `init_settings()` is called, you can get the settings and load them into variables, meaning:
@ -91,7 +91,7 @@ add_action( 'woocommerce_update_options_payment_gateways\_' . $this->id, array(
#### init_form_fields()
Use this method to set `$this->form_fields` these are options youll show in admin on your gateway settings page and make use of the [WC Settings API](https://woo.com/document/settings-api/ "https://woo.com/document/settings-api/").
Use this method to set `$this->form_fields` these are options you'll show in admin on your gateway settings page and make use of the [WC Settings API](https://woo.com/document/settings-api/ "https://woo.com/document/settings-api/").
A basic set of settings for your gateway would consist of _enabled_, _title_ and _description_:
@ -166,7 +166,7 @@ return;
WooCommerce will catch this error and show it on the checkout page.
Stock levels are updated via actions (`woocommerce_payment_complete` and in transitions between order statuses), so its no longer needed to manually call the methods reducing stock levels while processing the payment.
Stock levels are updated via actions (`woocommerce_payment_complete` and in transitions between order statuses), so it's no longer needed to manually call the methods reducing stock levels while processing the payment.
### Updating Order Status and Adding Notes
@ -197,7 +197,7 @@ If you are creating an advanced, direct gateway (i.e., one that takes payment o
$this->has_fields = true;
```
This tells the checkout to output a payment_box containing your direct payment form that you define next.
This tells the checkout to output a 'payment_box' containing your direct payment form that you define next.
Create a method called `payment_fields()` this contains your form, most likely to have credit card details.
@ -249,6 +249,6 @@ For more information, see [WC_API - The WooCommerce API Callback](https://woo.c
## Hooks in Gateways
Its important to note that adding hooks inside gateway classes may not trigger. Gateways are only loaded when needed, such as during checkout and on the settings page in admin.
It's important to note that adding hooks inside gateway classes may not trigger. Gateways are only loaded when needed, such as during checkout and on the settings page in admin.
You should keep hooks outside of the class or use WC-API if you need to hook into WordPress events from your class.

View File

@ -2,7 +2,7 @@
post_title: WooCommerce payment gateway plugin base
---
This code can be used as a base to create your own simple custom payment gateway for WooCommerce. If not used in a custom plugin, you need to add this code to your child themes functions.php file or via a plugin that allows custom functions to be added, such as the [Code snippets](https://wordpress.org/plugins/code-snippets/) plugin. Please dont add custom code directly to your parent themes functions.php file as this will be wiped entirely when you update the theme.
This code can be used as a base to create your own simple custom payment gateway for WooCommerce. If not used in a custom plugin, you need to add this code to your child theme's functions.php file or via a plugin that allows custom functions to be added, such as the [Code snippets](https://wordpress.org/plugins/code-snippets/) plugin. Please don't add custom code directly to your parent theme's functions.php file as this will be wiped entirely when you update the theme.
``` php

View File

@ -46,11 +46,11 @@ Like everything in the new product form, each extension point is a separate bloc
### Product form groups (tabs)
The new product form consists of groups currently displayed as tabs. Each is a separate view and may contain any number of sections and subsections. All areas serve a specific purpose, allowing merchants to quickly find the information theyre looking for (both in default Woo features and extensions).
The new product form consists of groups currently displayed as tabs. Each is a separate view and may contain any number of sections and subsections. All areas serve a specific purpose, allowing merchants to quickly find the information they're looking for (both in default Woo features and extensions).
![Product form groups](https://woocommerce.files.wordpress.com/2023/11/product-editor-ext-guidelines-form-groups.gif)
If a tab doesnt contain any sections, it wont be shown to merchants.
If a tab doesn't contain any sections, it won't be shown to merchants.
- **General:** Essential product information, including the name, image, and description. This tab is also where key features live for non-standard product types: downloads, groups, links, etc.
- **Organization:** This tab contains all the data used to organize and categorize product information: from categories to attributes. Best for extensions that provide new ways to describe products, e.g., product identifiers, statuses, special tags, etc.
@ -59,7 +59,7 @@ If a tab doesnt contain any sections, it wont be shown to merchants.
- **Shipping:** All the information merchants need to enter to present customers with accurate shipping rates at checkout. Best for physical product details that may impact shipping (e.g. capacity or volume), additional shipping carrier settings, or custom shipping options.
- **Variations:** Contains variation options and product variations.
Custom product types manage the visibility of the default groups and add new ones. This is particularly useful if a custom product has a unique structure and requires extra information that isnt included in the default groups.
Custom product types manage the visibility of the default groups and add new ones. This is particularly useful if a custom product has a unique structure and requires extra information that isn't included in the default groups.
[Learn more about custom product types](#custom-product-types)
@ -67,7 +67,7 @@ Custom product types manage the visibility of the default groups and add new one
Depending on the type of your extension (and your use case), you can pick the interface location that best suits how users will interact with it.
To choose, put yourself in the merchants shoes: where would you go to find this feature? What is it related to? Adding your extension to a group of similar features will help make it easier for merchants to find your extension.
To choose, put yourself in the merchant's shoes: where would you go to find this feature? What is it related to? Adding your extension to a group of similar features will help make it easier for merchants to find your extension.
See the guide below for some practical examples.
@ -79,7 +79,7 @@ The extension allows merchants to enter a product identifier, such as ISBN, EAN,
##### Our recommendations
The identifier is a single piece of information that helps merchants describe and categorize the product across their store and other sales channels. Its best suited to be added as a field in the Product catalog section in the Organization group.
The identifier is a single piece of information that helps merchants describe and categorize the product across their store and other sales channels. It's best suited to be added as a field in the Product catalog section in the Organization group.
[Learn more about fields](#fields)
@ -106,13 +106,13 @@ Fields are the simplest type of extension. They let users add extra product info
- Single-field, supplementary features
- Showing or hiding form elements depending on specific conditions
❌ **What they *arent* for:**
❌ **What they *aren't* for:**
- Multi-field or multi-step forms
- Complex tables, e.g., permissions, restrictions, shipping volumes, etc
- Embedded third-party experiences and websites
Field extensions should always be logically related to the form area they are in. For example, if youre building a dropshipping extension, your warehouse selection field should live in the first section of the Inventory group. To ensure an excellent experience for our merchants, we do not recommend placing it in a separate group, section, or subsection.
Field extensions should always be logically related to the form area they are in. For example, if you're building a dropshipping extension, your warehouse selection field should live in the first section of the Inventory group. To ensure an excellent experience for our merchants, we do not recommend placing it in a separate group, section, or subsection.
**Other use cases include:**
@ -128,11 +128,11 @@ Subsections add extra fields to existing form groups. They are small forms with
✅ **What they *are* for:**
- Relevant features that can be crucial to merchants product creation flow
- Relevant features that can be crucial to merchants' product creation flow
- 2-5 field forms with simple functionality, e.g., dimensions or tax settings
- Lists of items, e.g., attachments, channels, or accounts
❌ **What they *arent* for:**
❌ **What they *aren't* for:**
- Simple extensions with 1-2 fields
- Multi-step forms and complex tables
@ -140,7 +140,7 @@ Subsections add extra fields to existing form groups. They are small forms with
💡 **Example:**
If youre developing an extension that allows merchants to upload 360 images or videos, you could add it as a field or a button in the Images section in the General tab. This way, merchants can create the perfect product gallery without jumping between multiple tabs.
If you're developing an extension that allows merchants to upload 360 images or videos, you could add it as a field or a button in the Images section in the General tab. This way, merchants can create the perfect product gallery without jumping between multiple tabs.
**Other use cases include:**
@ -157,10 +157,10 @@ Sections are significant parts of the form that may consist of multiple subsecti
✅ **What they *are* for:**
- Complex forms with multiple fields, tables, and list items
- Standalone features that dont build off of anything else
- Standalone features that don't build off of anything else
- Extensions that rely on user-created items, such as tags or attributes
❌ **What they *arent* for:**
❌ **What they *aren't* for:**
- Simple extensions with 1-2 fields
- Read-only descriptions, setup guides, and advertisements
@ -168,7 +168,7 @@ Sections are significant parts of the form that may consist of multiple subsecti
💡 **Example:**
If youre working on an extension that allows merchants to offer discounts based on the number of purchased items, you may consider adding a new section in the Pricing tab. This will give you enough space to present the information in a legible, easy-to-navigate manner.
If you're working on an extension that allows merchants to offer discounts based on the number of purchased items, you may consider adding a new section in the Pricing tab. This will give you enough space to present the information in a legible, easy-to-navigate manner.
**Other use cases include:**
@ -180,9 +180,9 @@ If youre working on an extension that allows merchants to offer discounts bas
![Top bar example](https://woocommerce.files.wordpress.com/2023/11/product-editor-ext-guidelines-top-bar.png)
Top bar extensions offer supplementary experiences **not vital** to the critical product creation flows. Theyre secondary, meaning that they shouldnt contain information that may impact the products overall quality or completeness.
Top bar extensions offer supplementary experiences **not vital** to the critical product creation flows. They're secondary, meaning that they shouldn't contain information that may impact the product's overall quality or completeness.
Each top bar extension has its unique icon in the top navigation bar. Note that when the number of extensions exceeds 4, theyre truncated in a dropdown menu.
Each top bar extension has its unique icon in the top navigation bar. Note that when the number of extensions exceeds 4, they're truncated in a dropdown menu.
For example, top bar extensions can be used to:
@ -198,7 +198,7 @@ Depending on their roles, top bar extensions can be displayed in either a **popo
Dialog extensions differ from other extensions as they are unrelated to any section or functionality within the product form. They can connect to third-party systems or come with complex interfaces that require a separate, focused experience.
Dialogs can have different sizes (small, medium, large, or custom) and trigger locations (text or icon button anywhere in the form or in the forms top bar).
Dialogs can have different sizes (small, medium, large, or custom) and trigger locations (text or icon button anywhere in the form or in the form's top bar).
✅ **What they *are* for:**
@ -206,7 +206,7 @@ Dialogs can have different sizes (small, medium, large, or custom) and trigger l
- Advanced configuration and setup flows
- Dedicated content embedded from a third-party service
❌ **What they *arent* for:**
❌ **What they *aren't* for:**
- Single-field features or simple settings screens
- Small functionalities that could fit within the form
@ -228,9 +228,9 @@ With custom product types, you can:
- Add and hide sections within a group
- Add and hide subsections and fields
- Includes core fields
- Can be set up conditionally based on a custom fields value
- Can be set up conditionally based on a custom field's value
Custom product types include niche and specific use cases, such as bookings, tickets, gift cards, rentals, etc. Heres when we suggest you should consider creating a custom product type:
Custom product types include niche and specific use cases, such as bookings, tickets, gift cards, rentals, etc. Here's when we suggest you should consider creating a custom product type:
- Your extension consists of several different form sections scattered across several different tabs
- Using just your extension, merchants can completely a product

View File

@ -52,7 +52,7 @@ Cases when we use lower case:
### Contractions
Use with discretion. Contractions, such as Im and theres, give writing an informal and conversational feel, but may be inappropriate if content is being translated. For example, sometimes the not in dont is ignored by online translators.
Use with discretion. Contractions, such as I'm and there's, give writing an informal and conversational feel, but may be inappropriate if content is being translated. For example, sometimes the not in don't is ignored by online translators.
### Emoji
@ -99,7 +99,7 @@ Spell out fractions: one-fourth
#### Percent
Spell out the word percent. Dont use % symbol unless space is limited, e.g., for use on social media.
Spell out the word 'percent.' Don't use % symbol unless space is limited, e.g., for use on social media.
#### Phone numbers
@ -126,7 +126,7 @@ Use numbers and am or pm with a space and without periods.
- 7:00 am
- 7:30 pm
Use a hyphen between times to indicate a time period in am or pm. Use to if the time period spans am and pm.
Use a hyphen between times to indicate a time period in am or pm. Use 'to' if the time period spans am and pm.
- 7:00-9:00 am and 7:00 am to 10:30 pm
@ -150,20 +150,20 @@ Abbreviate decades
#### Ampersands
Ampersands need only be used when part of an official company/brand name. Should not be substituted for and.
Ampersands need only be used when part of an official company/brand name. Should not be substituted for 'and.'
- Ben & Jerrys
- Ben & Jerry's
- Andre, Timo, and Donny went to a football game at Camp Nou.
#### Apostrophes
An apostrophe makes a word possessive. If a word already ends in s and is singular, add an s. If a word ends in s and is plural, add an apostrophe.
An apostrophe makes a word possessive. If a word already ends in s and is singular, add an 's. If a word ends in s and is plural, add an apostrophe.
- A teammate borrowed Sams bike.
- A teammate borrowed Chriss bike.
- Employees hid the office managers pens.
- A teammate borrowed Sam's bike.
- A teammate borrowed Chris's bike.
- Employees hid the office managers' pens.
These are possessives: FAQs questions, HEs weekly rotation. These are plural: FAQs and HEs.
These are possessives: FAQ's questions, HE's weekly rotation. These are plural: FAQs and HEs.
#### Colons
@ -223,12 +223,12 @@ Question marks follow the same placement convention explained in Periods.
#### Quotation marks
Periods and commas go within quotation marks. Question marks within quotes follow logic-if the question mark is part of the quotation, it goes within. If youre asking a question that ends with a quote, it goes outside the quote.
Periods and commas go within quotation marks. Question marks within quotes follow logic—if the question mark is part of the quotation, it goes within. If you're asking a question that ends with a quote, it goes outside the quote.
Use single quotation marks for quotes within quotes.
- Who sings, “All These Things That Ive Done”?
- Brandon Flowers of The Killers said, “I was inspired and on a roll when I wrote, I got soul, but Im not a soldier.
- Who sings, “All These Things That I've Done”?
- Brandon Flowers of The Killers said, “I was inspired and on a roll when I wrote, 'I got soul, but I'm not a soldier.'
#### Semicolons
@ -246,7 +246,7 @@ Use brand identity names and products as written on official websites.
- Pull&Bear
- UE Boom
Refer to a company or product as it (not they).
Refer to a company or product as 'it' (not 'they').
- WooCommerce is, and not WooCommerce are.
@ -276,7 +276,7 @@ Capitalize job titles, the names of teams, and departments.
#### Pronouns
Use he/him/his and she/her/her as appropriate. Dont use “one” as a pronoun. Use they/them/their if gender is unknown or when referring to a group.
Use he/him/his and she/her/her as appropriate. Don't use “one” as a pronoun. Use they/them/their if gender is unknown or when referring to a group.
#### Quotations
@ -293,15 +293,15 @@ The first time you mention a school, college, or university in a piece of writin
#### States, cities, and countries
Spell out all city and state names. Dont abbreviate city names.
Spell out all city and state names. Don't abbreviate city names.
On first mention, write out United States. For further mentions, use U.S. The same applies to other countries or federations with a common abbreviation, such as European Union (EU) and United Kingdom (UK).
#### URLs and websites
Capitalize the names of websites and web publications. Dont italicize.
Capitalize the names of websites and web publications. Don't italicize.
Avoid writing out URLs; omit `http://www` when its necessary.
Avoid writing out URLs; omit `http://www` when it's necessary.
### Slang and jargon

View File

@ -16,7 +16,7 @@ You will make it harder for WordPress to detect what page you are trying to reac
- `http://yoursite.com/about-page/` (this is the URL of a standard page)
- `http://yoursite.com/product-category/category-x/` (this is the URL leading to a product category)
What would happen if we remove that product-category part?
What would happen if we remove that 'product-category' part?
- `http://yoursite.com/about-page/`
- `http://yoursite.com/category-x/`

View File

@ -6,7 +6,7 @@ WooCommerce has a shipping method API which plugins can use to add their own rat
## Create a plugin
First off, create a regular WordPress/WooCommerce plugin see our [Extension Developer Handbook](/docs/extension-development/extension-developer-handbook.md) to get started. Youll define your shipping method class in this plugin file and maintain it outside of WooCommerce.
First off, create a regular WordPress/WooCommerce plugin see our [Extension Developer Handbook](/docs/extension-development/extension-developer-handbook.md) to get started. You'll define your shipping method class in this plugin file and maintain it outside of WooCommerce.
## Create a function to house your class
@ -24,7 +24,7 @@ add_action( 'woocommerce_shipping_init', 'your_shipping_method_init' );
## Create your class
Create your class and place it inside the function you just created. Make sure it extends the shipping method class so that you have access to the API. Youll see below we also init our shipping method options.
Create your class and place it inside the function you just created. Make sure it extends the shipping method class so that you have access to the API. You'll see below we also init our shipping method options.
``` php
if ( ! class_exists( 'WC_Your_Shipping_Method' ) ) {
@ -74,7 +74,7 @@ if ( ! class_exists( 'WC_Your_Shipping_Method' ) ) {
## Defining settings/options
You can then define your options using the settings API. In the snippets above youll notice we init_form_fields and init_settings. These load up the settings API. To see how to add settings, see [WooCommerce settings API](https://woo.com/document/settings-api/).
You can then define your options using the settings API. In the snippets above you'll notice we init_form_fields and init_settings. These load up the settings API. To see how to add settings, see [WooCommerce settings API](https://woo.com/document/settings-api/).
## The calculate_shipping() method

View File

@ -8,12 +8,12 @@ This style guide is intended to provide guidelines for creating effective and us
### Language style
- Its important to use clear and concise language that is easy to understand. Use active voice and avoid using jargon or technical terms that may be unfamiliar to the user. The tone should be friendly and approachable, and should encourage the user to take action.
- It's important to use clear and concise language that is easy to understand. Use active voice and avoid using jargon or technical terms that may be unfamiliar to the user. The tone should be friendly and approachable, and should encourage the user to take action.
- Articles are written in the 3rd-person voice.
Example: “Add an embed block to your page.”
- Use American English for spelling and punctuation styles, or consider using a different word that doesnt have a different spelling in other English variants.
- Use American English for spelling and punctuation styles, or consider using a different word that doesn't have a different spelling in other English variants.
- Use sentence case (not title case) for docs titles and subheadings.
Example: “Introduction to the launch experience” rather than “Introduction to the Launch Experience.”
@ -23,7 +23,7 @@ This style guide is intended to provide guidelines for creating effective and us
### Writing tips
- Our target audience has a range of roles and abilities. When creating a tutorial or how-to guide, its important to consider the intended audience. Are they beginners or advanced users? What is their technical background? Understanding the audience can help guide the level of detail and the choice of language used in the guide.
- Our target audience has a range of roles and abilities. When creating a tutorial or how-to guide, it's important to consider the intended audience. Are they beginners or advanced users? What is their technical background? Understanding the audience can help guide the level of detail and the choice of language used in the guide.
- Use language understable even by readers with little technical knowledge and readers whose first language might not be English.
@ -130,7 +130,7 @@ Visual aids such as screenshots, diagrams, code snippets and videos can be very
Phrases that are more familiarly known in their acronym form can be used. The first time an acronym appears on any page, the full phrase must be included, followed by its acronym in parentheticals.
Example: Weve enhanced the querying functionality in WooCommerce with the introduction of High Performance Order Storage (HPOS).
Example: We've enhanced the querying functionality in WooCommerce with the introduction of High Performance Order Storage (HPOS).
After that, the acronym can be used for the remainder of the page.
@ -140,7 +140,7 @@ When deciding if a term is common, consider the impact on translation and future
### Article content
When creating a how-to guide, its important to use a consistent and easy-to-follow format. Here is a suggested template for a software how-to guide:
When creating a how-to guide, it's important to use a consistent and easy-to-follow format. Here is a suggested template for a software how-to guide:
**Introduction**: Provide an overview of the task or feature that the guide covers.
@ -161,7 +161,7 @@ When creating a how-to guide, its important to use a consistent and easy-to-f
## Testing
Before publishing a tutorial or guide, its important to test it thoroughly to ensure that the instructions are accurate and easy to follow.
Before publishing a tutorial or guide, it's important to test it thoroughly to ensure that the instructions are accurate and easy to follow.
## Structure

View File

@ -20,7 +20,7 @@ If you want more control over the layout of WooCommerce elements or full reviews
## Theme Integration
There are three possible ways to integrate WooCommerce with a theme. If you are using WooCommerce 3.2 or below (**strongly discouraged**) you will need to use one of these methods to ensure WooCommerce shop and product pages are rendered correctly in your theme. If you are using a version of WooCommerce 3.3 or above you only need to do a theme integration if the automatic one doesnt meet your needs.
There are three possible ways to integrate WooCommerce with a theme. If you are using WooCommerce 3.2 or below (**strongly discouraged**) you will need to use one of these methods to ensure WooCommerce shop and product pages are rendered correctly in your theme. If you are using a version of WooCommerce 3.3 or above you only need to do a theme integration if the automatic one doesn't meet your needs.
### Using `woocommerce_content()`
@ -28,7 +28,7 @@ This solution allows you to create a new template page within your theme that is
To set up this template page:
1. **Duplicate page.php:** Duplicate your themes `page.php` file, and name it `woocommerce.php`. This path to the file should follow this pattern: `wp-content/themes/YOURTHEME/woocommerce.php`.
1. **Duplicate page.php:** Duplicate your theme's `page.php` file, and name it `woocommerce.php`. This path to the file should follow this pattern: `wp-content/themes/YOURTHEME/woocommerce.php`.
2. **Edit your page (woocommerce.php)**: Open up your newly created `woocommerce.php` in a text editor.
3. **Replace the loop:** Next you need to find the loop (see [The_Loop](https://codex.wordpress.org/The_Loop)). The loop usually starts with code like this:
@ -48,15 +48,15 @@ This varies between themes. Once you have found it, **delete it**. In its place,
<?php woocommerce_content(); ?>
```
This will make it use **WooCommerces loop instead**. Save the file. Youre done.
This will make it use **WooCommerce's loop instead**. Save the file. You're done.
**Note:** When creating `woocommerce.php` in your themes folder, you will not be able to override the `woocommerce/archive-product.php` custom template as `woocommerce.php` has priority over `archive-product.php`. This is intended to prevent display issues.
**Note:** When creating `woocommerce.php` in your theme's folder, you will not be able to override the `woocommerce/archive-product.php` custom template as `woocommerce.php` has priority over `archive-product.php`. This is intended to prevent display issues.
### Using hooks
The hook method is more involved, but it is also more flexible. This is similar to the method we use when creating themes. Its also the method we use to integrate nicely with WordPress default themes.
The hook method is more involved, but it is also more flexible. This is similar to the method we use when creating themes. It's also the method we use to integrate nicely with WordPress default themes.
Insert a few lines in your themes `functions.php` file.
Insert a few lines in your theme's `functions.php` file.
First unhook the WooCommerce wrappers:
@ -80,7 +80,7 @@ function my_theme_wrapper_end() {
}
```
Make sure that the markup matches that of your theme. If youre unsure of which classes or IDs to use, take a look at your themes `page.php` for guidance.
Make sure that the markup matches that of your theme. If you're unsure of which classes or IDs to use, take a look at your theme's `page.php` for guidance.
**Whenever possible use the hooks to add or remove content. This method is more robust than overriding the templates.** If you have overridden a template, you have to update the template any time the file changes. If you are using the hooks, you will only have to update if the hooks change, which happens much less frequently.
@ -92,7 +92,7 @@ For information about overriding the WooCommerce templates with your own custom
If you are using custom WooCommerce template overrides in your theme you need to declare WooCommerce support using the `add_theme_support` function. WooCommerce template overrides are only enabled on themes that declare WooCommerce support. If you do not declare WooCommerce support in your theme, WooCommerce will assume the theme is not designed for WooCommerce compatibility and will use shortcode-based unsupported theme rendering to display the shop.
Declaring WooCommerce support is straightforward and involves adding one function in your themes `functions.php` file.
Declaring WooCommerce support is straightforward and involves adding one function in your theme's `functions.php` file.
### Basic Usage
@ -138,7 +138,7 @@ The `product_grid` settings let theme developers set default, minimum, and maxim
The product gallery introduced in 3.0.0 ([read here for more information](https://developer.woo.com/2016/10/19/new-product-gallery-merged-in-to-core-for-2-7/)) uses Flexslider, Photoswipe, and the jQuery Zoom plugin to offer swiping, lightboxes, and other neat features.
In versions `3.0`, `3.1`, and `3.2`, the new gallery is off by default and needs to be enabled using a snippet (below) or by using a compatible theme. This is because its common for themes to disable the WooCommerce gallery and replace it with their own scripts.
In versions `3.0`, `3.1`, and `3.2`, the new gallery is off by default and needs to be enabled using a snippet (below) or by using a compatible theme. This is because it's common for themes to disable the WooCommerce gallery and replace it with their own scripts.
In versions `3.3+`, the gallery is off by default for WooCommerce compatible themes unless they declare support for it (below). 3rd party themes with no WooCommerce support will have the gallery enabled by default.
@ -188,10 +188,10 @@ Inside the `assets/css/` directory, you will find the stylesheets responsible fo
Files to look for are `woocommerce.scss` and `woocommerce.css`.
- `woocommerce.css` is the minified stylesheet its the CSS without any of the spaces, indents, etc. This makes the file very fast to load. This file is referenced by the plugin and declares all WooCommerce styles.
- `woocommerce.css` is the minified stylesheet it's the CSS without any of the spaces, indents, etc. This makes the file very fast to load. This file is referenced by the plugin and declares all WooCommerce styles.
- `woocommerce.scss` is not directly used by the plugin, but by the team developing WooCommerce. We use [SASS](http://sass-lang.com/) in this file to generate the CSS in the first file.
The CSS is written to make the default layout compatible with as many themes as possible by using percentage-based widths for all layout styles. It is, however, likely that youll want to make your own adjustments.
The CSS is written to make the default layout compatible with as many themes as possible by using percentage-based widths for all layout styles. It is, however, likely that you'll want to make your own adjustments.
### Modifications
@ -212,7 +212,7 @@ WooCommerce also outputs the theme name (plus other useful information, such as
### Disabling WooCommerce styles
If you plan to make major changes, or create a theme from scratch, then you may prefer your theme not reference the WooCommerce stylesheet at all. You can tell WooCommerce to not use the default `woocommerce.css` by adding the following code to your themes `functions.php` file:
If you plan to make major changes, or create a theme from scratch, then you may prefer your theme not reference the WooCommerce stylesheet at all. You can tell WooCommerce to not use the default `woocommerce.css` by adding the following code to your theme's `functions.php` file:
```php
add_filter( 'woocommerce_enqueue_styles', '__return_false' );
@ -220,4 +220,4 @@ add_filter( 'woocommerce_enqueue_styles', '__return_false' );
With this definition in place, your theme will no longer use the WooCommerce stylesheet and give you a blank canvas upon which you can build your own desired layout and styles.
Styling a WooCommerce theme from scratch for the first time is no easy task. There are many different pages and elements that need to be styled, and if youre new to WooCommerce, you are probably not familiar with many of them. A non-exhaustive list of WooCommerce elements to style can be found [here](https://developer.files.wordpress.com/2017/12/woocommerce-theme-testing-checklist.pdf).
Styling a WooCommerce theme from scratch for the first time is no easy task. There are many different pages and elements that need to be styled, and if you're new to WooCommerce, you are probably not familiar with many of them. A non-exhaustive list of WooCommerce elements to style can be found [here](https://developer.files.wordpress.com/2017/12/woocommerce-theme-testing-checklist.pdf).

View File

@ -8,7 +8,7 @@ post_title: Conditional tags
The conditional tags of WooCommerce and WordPress can be used in your template files to change what content is displayed based on what *conditions* the page matches. For example, you may want to display a snippet of text above the shop page. With the `is_shop()` conditional tag, you can.
Because WooCommerce uses custom post types, you can also use many of WordPress conditional tags. See [codex.wordpress.org/Conditional_Tags](https://codex.wordpress.org/Conditional_Tags) for a list of the tags included with WordPress.
Because WooCommerce uses custom post types, you can also use many of WordPress' conditional tags. See [codex.wordpress.org/Conditional_Tags](https://codex.wordpress.org/Conditional_Tags) for a list of the tags included with WordPress.
**Note**: You can only use conditional query tags after the `posts_selection` [action hook](https://codex.wordpress.org/Plugin_API/Action_Reference#Actions_Run_During_a_Typical_Request) in WordPress (the `wp` action hook is the first one through which you can use these conditionals). For themes, this means the conditional tag will never work properly if you are using it in the body of functions.php.
@ -33,18 +33,18 @@ The list below holds the main conditional tags. To see all conditional tags, vis
- `is_product_category()`
Returns true when viewing a product category archive.
- `is_product_category( 'shirts' )`
When the product category page for the shirts category is being displayed.
When the product category page for the 'shirts' category is being displayed.
- `is_product_category( array( 'shirts', 'games' ) )`
When the product category page for the shirts or games category is being displayed.
When the product category page for the 'shirts' or 'games' category is being displayed.
### Product tag page
- `is_product_tag()`
Returns true when viewing a product tag archive
- `is_product_tag( 'shirts' )`
When the product tag page for the shirts tag is being displayed.
When the product tag page for the 'shirts' tag is being displayed.
- `is_product_tag( array( 'shirts', 'games' ) )`
When the product tag page for the shirts or games tags is being displayed.
When the product tag page for the 'shirts' or 'games' tags is being displayed.
### Single product page
@ -64,7 +64,7 @@ The list below holds the main conditional tags. To see all conditional tags, vis
### Customer account pages
- `is_account_page()`
Returns true on the customers account pages.
Returns true on the customer's account pages.
### Endpoint

View File

@ -42,6 +42,6 @@ If you are looking for the default templates to use for updating, you want to us
- Download the latest version from [the WordPress.org plugin page](https://wordpress.org/plugins/woocommerce/).
- Download the latest release from [the GitHub repository](https://github.com/woocommerce/woocommerce/releases).
### Why dont you make a button to click and update everything?
### Why don't you make a button to click and update everything?
It is impossible to make a video or a one-click update. Why? Because there are thousands of themes, and every theme is coded differently. One size does not fit all.

View File

@ -6,7 +6,7 @@ This guide covers general guidelines and best practices to follow in order to en
We recommend you review the [UI best practices for WordPress](https://developer.wordpress.org/themes/advanced-topics/ui-best-practices/) to ensure your theme is aligned with the WordPress theme requirements.
Make sure your theme fits one or more industries currently available in the [WooCommerce themes store](https://woo.com/product-category/themes). Its important that the theme offers enough originality and distinctiveness in its design, while keeping it familiar, in order to be distinguished from other themes on the WooCommerce theme store. Your theme should avoid copying existing themes on the WooCommerce theme store or other WordPress theme marketplaces.
Make sure your theme fits one or more industries currently available in the [WooCommerce themes store](https://woo.com/product-category/themes). It's important that the theme offers enough originality and distinctiveness in its design, while keeping it familiar, in order to be distinguished from other themes on the WooCommerce theme store. Your theme should avoid copying existing themes on the WooCommerce theme store or other WordPress theme marketplaces.
## Design
@ -70,7 +70,7 @@ Any customization supported by the theme, such as layout options, additional fea
Themes should not bundle or require the installation of additional plugins/extensions (or frameworks) that provide additional options or functionality. For more information on customisation, check out the [WordPress theme customization API](https://codex.wordpress.org/Theme_Customization_API)**.**
On activation, themes shouldnt override the WordPress theme activation flow by taking the user into other pages.
On activation, themes shouldn't override the WordPress theme activation flow by taking the user into other pages.
## Branding
@ -82,6 +82,6 @@ The interface should solely focus on the experience, the usage of notices, banne
Upon submission theme authors must provide a way for the theme to be showcased and tested. The sample content/demo should refrain from using custom graphics/assets that will not be present in the deliverables to avoid merchant confusion and broken expectations (examples: using logos, illustrations). When creating a theme for a specific vertical theme authors should consider using sample content that aligns with the vertical.
All imagery and text should be appropriate for all ages/family-friendly. The theme author should consider using imagery that is inclusive of ages, nationalities, etc. The theme should refrain from using imagery that looks like stock photography.
All imagery and text should be appropriate for all ages/family-friendly. The theme author should consider using imagery that is inclusive of ages, nationalities, etc. The theme should refrain from using imagery that looks like 'stock photography'.
The theme must be distributed and cleared of all the necessary licenses for assets such as images, fonts, icons, etc.

View File

@ -12,7 +12,7 @@ To do this tutorial you will need to have a WordPress install with the WooCommer
## Setting up the plugin
To get started, lets do the steps to [create a skeleton plugin](https://github.com/woocommerce/woocommerce/tree/trunk/packages/js/create-woo-extension).
To get started, let's do the steps to [create a skeleton plugin](https://github.com/woocommerce/woocommerce/tree/trunk/packages/js/create-woo-extension).
First, navigate to your wp-content/plugins folder, then run:
@ -28,7 +28,7 @@ npm install # Install dependencies
npm run build # Build the javascript
```
WordPress has its own class file naming convention which doesnt work with PSR-4 out of the box. To learn more about Naming Conventions see the [WP Handbook](https://developer.wordpress.org/coding-standards/wordpress-coding-standards/php/#naming-conventions). We will use the standard format of “class-my-classname.php” format, so lets go to the composer.json file and change the autoload to:
WordPress has its own class file naming convention which doesn't work with PSR-4 out of the box. To learn more about Naming Conventions see the [WP Handbook](https://developer.wordpress.org/coding-standards/wordpress-coding-standards/php/#naming-conventions). We will use the standard format of “class-my-classname.php” format, so let's go to the composer.json file and change the autoload to:
```json
"autoload": {
@ -50,11 +50,11 @@ Our aim is to create a new custom text field for WooCommerce products to save ne
WooCommerce allows us to add our code to these sections through [hooks](https://developer.wordpress.org/plugins/hooks/), which are a standard WordPress method to extend code. In the “Inventory” section we have the following action hooks available to us:
For our Woo extension, well be appending our field right at the end with `woocommerce_product_options_inventory_product_data`.
For our Woo extension, we'll be appending our field right at the end with `woocommerce_product_options_inventory_product_data`.
## Creating our class
Lets get started with creating a new class which will hold the code for the field. Add a new file with the name `class-product-fields.php` to the `/includes/admin/` folder. Within the class, we add our namespace, an abort if anyone tries to call the file directly and a \_\_construct method which calls the `hooks()` method:
Let's get started with creating a new class which will hold the code for the field. Add a new file with the name `class-product-fields.php` to the `/includes/admin/` folder. Within the class, we add our namespace, an abort if anyone tries to call the file directly and a \_\_construct method which calls the `hooks()` method:
```php
<?php
@ -73,7 +73,7 @@ class ProductFields {
}
```
Then in Terminal we run `composer dump-autoload -o` to regenerate the class map. Once thats done, we add the class to our `setup.php` \_\_construct() function like so:
Then in Terminal we run `composer dump-autoload -o` to regenerate the class map. Once that's done, we add the class to our `setup.php` \_\_construct() function like so:
```php
class Setup {
@ -107,7 +107,7 @@ public function add_field() {
}
```
Lets take a look at the arguments in the array. The ID will be used as meta_key in the database. The Label and Description are shown in the data section, and by setting desc_tip to true, it will be shown as a hover over the info icon. The last argument value ensures that if a value is already stored, then it will be shown.
Let's take a look at the arguments in the array. The ID will be used as meta_key in the database. The Label and Description are shown in the data section, and by setting desc_tip to true, it will be shown as a hover over the info icon. The last argument value ensures that if a value is already stored, then it will be shown.
For the div class, the class names `show_if_simple` and `show_if_variable` will control when our section is shown. This is linked to JS code which dynamically hides/reveals sections. If for example, we wanted to hide the section from variable products, then we can simply delete `show_if_variable`.
@ -123,7 +123,7 @@ public function save_field( $post_id, $post ) {
}
```
This function checks if our new field is in the POST array. If yes, we create the product object, update our metadata and save the metadata. The `update_meta_data` function will either update an existing meta field or add a new one. And as were inserting into the database, we must [sanitize our field value](https://developer.wordpress.org/apis/security/sanitizing/).
This function checks if our new field is in the POST array. If yes, we create the product object, update our metadata and save the metadata. The `update_meta_data` function will either update an existing meta field or add a new one. And as we're inserting into the database, we must [sanitize our field value](https://developer.wordpress.org/apis/security/sanitizing/).
And to make it all work, we add the hooks:
@ -142,7 +142,7 @@ At this point you have a working extension that saves a custom field for a produ
Showing the field in the store
If we want to display the new field in our store, then we can do this with the `get_meta()` method of the Woo product class: `$product->get_meta( '\_new_stock_information' )`
Lets get started by creating a new file /includes/class-product.php. You may have noticed that this is outside the `/admin/` folder as this code will run in the front. So when we set up the class, we also adjust the namespace accordingly:
Let's get started by creating a new file /includes/class-product.php. You may have noticed that this is outside the `/admin/` folder as this code will run in the front. So when we set up the class, we also adjust the namespace accordingly:
```php
<?php
@ -162,7 +162,7 @@ class Product {
Again we run `composer dump-autoload -o` to update our class map.
If you took a look at the extension setup you may have noticed that `/admin/setup.php` is only called if were within WP Admin. So to call our new class well add it directly in `/woo-product-field.php`:
If you took a look at the extension setup you may have noticed that `/admin/setup.php` is only called if we're within WP Admin. So to call our new class we'll add it directly in `/woo-product-field.php`:
```php
public function __construct() {
@ -173,7 +173,7 @@ public function __construct() {
}
```
For adding the field to the front we have several options. We could create a theme template, but if we are working with a WooCommerce-compatible theme and dont need to make any other changes then a quick way is to use hooks. If we look into `/woocommerce/includes/wc-template-hooks.php` we can see all the existing actions for `woocommerce_single_product_summary` which controls the section at the top of the product page:
For adding the field to the front we have several options. We could create a theme template, but if we are working with a WooCommerce-compatible theme and don't need to make any other changes then a quick way is to use hooks. If we look into `/woocommerce/includes/wc-template-hooks.php` we can see all the existing actions for `woocommerce_single_product_summary` which controls the section at the top of the product page:
For our extension, let's add the new stock information after the excerpt by using 21 as the priority:
@ -183,7 +183,7 @@ private function hooks() {
}
```
In our function we output the stock information with the [appropriate escape function](https://developer.wordpress.org/apis/security/escaping/), in this case, Im suggesting to use `esc_html()` to force plain text.
In our function we output the stock information with the [appropriate escape function](https://developer.wordpress.org/apis/security/escaping/), in this case, I'm suggesting to use `esc_html()` to force plain text.
```php
public function add_stock_info() {
@ -197,7 +197,7 @@ public function add_stock_info() {
Now if we refresh the product page our stock information will be shown just below the excerpt:
Fantastic! You have completed this tutorial and have a working WooCommerce extension that adds a new custom field and shows it in the store! 🎉I hope its shown you how easily you can extend WooCommerce through hooks and tailor it to your or your clients shop requirements!
Fantastic! You have completed this tutorial and have a working WooCommerce extension that adds a new custom field and shows it in the store! 🎉I hope it's shown you how easily you can extend WooCommerce through hooks and tailor it to your or your client's shop requirements!
Below is a bonus task if you are interested in variable products. Feel free to come back to this later.
@ -205,7 +205,7 @@ Below is a bonus task if you are interested in variable products. Feel free to c
The above example was done with a simple product. But what if we have variations, for example, a T-Shirt in multiple sizes and we wanted to store different stock information for each variant? WooCommerce lets us do that with the [variable product type](https://woo.com/document/variable-product/).
A variable product type has variations as its children. To add a custom field to a variation, we can use the `woocommerce_variation_options_inventory` hook, and to save `woocommerce_save_product_variation` so lets update our `hooks()` method with the new action hooks like so:
A variable product type has variations as its children. To add a custom field to a variation, we can use the `woocommerce_variation_options_inventory` hook, and to save `woocommerce_save_product_variation` so let's update our `hooks()` method with the new action hooks like so:
```php
private function hooks() {

View File

@ -45,10 +45,10 @@ Lifecycle hooks can be used to communicate that a lifecycle event is about to st
In general, lifecycle hooks:
* Come in pairs (before and after)
* Come in pairs ('before' and 'after')
* Are always actions, never filters
* The before hook will generally always provide callbacks with the arguments array, if there is one
* The after hook will generally also provide callbacks with the functions return value, if there is one
* The 'before' hook will generally always provide callbacks with the arguments array, if there is one
* The 'after' hook will generally also provide callbacks with the function's return value, if there is one
Note that lifecycle hooks primarily exist to let other systems observe, rather than to modify the result. Of course, this does not stop the function author from additionally providing a filter hook that serves this function.
@ -92,7 +92,7 @@ function get_product_metrics( $args ): array {
### Modifying function input and output (global rendering functions)
In the case of global rendering or formatting functions (so-called “template tags”), where it is not readily possible to implement better alternatives, it is permissible to add filters for both the function arguments and the functions return value.
In the case of global rendering or formatting functions (so-called “template tags”), where it is not readily possible to implement better alternatives, it is permissible to add filters for both the function arguments and the function's return value.
This should be done sparingly, and only where necessary. Remember that while providing opportunities for other components to perform extensive customization, it can potentially derail other components which expect unmodified output.

View File

@ -4,22 +4,22 @@ post_title: User experience guidelines - best practices
## Best practices
**Plugin name should simply state the feature of the plugin and not use an existing core feature or extension in its title**. The plugin name should appear at all times in the UI as a functional and original name. e.g “Appointments” instead of “VendorXYZ Bookings Plugin for WooCommerce.”
**Plugin name should simply state the feature of the plugin and not use an existing core feature or extension in its' title**. The plugin name should appear at all times in the UI as a functional and original name. e.g “Appointments” instead of “VendorXYZ Bookings Plugin for WooCommerce.”
**Avoid creating new UI**. Before considering a new UI, review the WordPress interface to see if a component can be repurposed. Follow existing UI navigation patterns so merchants have context on where they are when navigating to a new experience.
**Be considerate of mobile for the merchant (and shopper-facing if applicable) experience**. Stores operate 24/7. Merchants shouldnt be limited to checking their store on a desktop. Extensions need to be built responsively so they work on all device sizes.
**Be considerate of mobile for the merchant (and shopper-facing if applicable) experience**. Stores operate 24/7. Merchants shouldn't be limited to checking their store on a desktop. Extensions need to be built responsively so they work on all device sizes.
**Its all about the merchant**. Dont distract with unrelated content. Keep the product experience front and center to help the user achieve the tasks they purchased your product for.
**It's all about the merchant**. Don't distract with unrelated content. Keep the product experience front and center to help the user achieve the tasks they purchased your product for.
**Present a review request at the right time**. Presenting users with a request for review is a great way to get feedback on your extension. Think about best placement and timing to show these prompts.
Here are some best practices:
- Avoid showing the user a review request upon first launching the extension. Once the user has had a chance to set up, connect, and use the plugin theyll have a better idea of how to rate it.
- Try to present the review request at a time thats least disruptive, such as after successful completion of a task or event.
- Avoid showing the user a review request upon first launching the extension. Once the user has had a chance to set up, connect, and use the plugin they'll have a better idea of how to rate it.
- Try to present the review request at a time that's least disruptive, such as after successful completion of a task or event.
**Dont alter the core interface**. Dont express your brand by changing the shape of containers in the Woo admin.
**Don't alter the core interface**. Don't express your brand by changing the shape of containers in the Woo admin.
**Focus on the experience**. After the customer installs your product, the experience should be the primary focus. Keep things simple and guide the user to successful setup. Do not convolute the experience or distract the user with branding, self promotion, large banners, or anything obtrusive.

View File

@ -4,7 +4,7 @@ post_title: User experience guidelines - colors
## Colors
When creating extensions for the WordPress wp-admin, use the core colors, respect the users WordPress admin color scheme selection, and ensure your designs pass AA level guidelines.
When creating extensions for the WordPress wp-admin, use the core colors, respect the user's WordPress admin color scheme selection, and ensure your designs pass AA level guidelines.
When using components with text, such as buttons, cards, or navigation, the background-to-text contrast ratio should be at least 4.5:1 to be [WCAG AA compliant](https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html). Be sure to [test your color contrast ratios](https://webaim.org/resources/contrastchecker/) to abide by WCAG standards.

View File

@ -4,7 +4,7 @@ post_title: User experience guidelines - notices
## Notices
Use notices primarily to provide user feedback in response to an action. Avoid using notices to communicate offers or announcements. Dont apply brand colors, fonts, or illustrations to your notices.
Use notices primarily to provide user feedback in response to an action. Avoid using notices to communicate offers or announcements. Don't apply brand colors, fonts, or illustrations to your notices.
If a post-activation notice is required, keep it within the WordPress plugin area-do not display it on the dashboard, or any other parts of the platform.
@ -18,7 +18,7 @@ Use short but meaningful messages that communicate what is happening. Ensure tha
### Design
The placement of feedback is vital so the user notices it. For example, when validation messages are needed to prompt the user to enter data, get the users attention by displaying a message close to the inputs where data needs to be revised.
The placement of feedback is vital so the user notices it. For example, when validation messages are needed to prompt the user to enter data, get the user's attention by displaying a message close to the inputs where data needs to be revised.
![visualization of four different notice designs next to one another](https://woocommerce.files.wordpress.com/2023/10/notices1.png)
@ -28,7 +28,7 @@ The placement of feedback is vital so the user notices it. For example, when val
**Warning Message**: When the user performs an action that may have completed successfully, but the user should review it and proceed with caution.
**Informational Message**: When its necessary to provide information before the user executes any action on the screen. Examples can be limitations within a time period or when a global setting limits actions on the current screen.
**Informational Message**: When it's necessary to provide information before the user executes any action on the screen. Examples can be limitations within a time period or when a global setting limits actions on the current screen.
### Examples

View File

@ -6,23 +6,28 @@ post_title: User experience guidelines - onboarding
The first experience your users have with your extension is crucial. A user activating your extension for the first time provides an opportunity to onboard new and reorient returning users the right way. Is it clear to the user how to get started? Keep in mind that the more difficult the setup, the more likely a user will abandon the product altogether so keep it simple and direct.
**Use primary buttons as calls to action and keep secondary information deprioritized for clarity**. Guide merchants towards successful setup with a clear next step and/or step-by-step process with progress indicator if the extension isnt configured or if setup is not complete.
**Use primary buttons as calls to action and keep secondary information deprioritized for clarity**. Guide merchants towards successful setup with a clear next step and/or step-by-step process with progress indicator if the extension isn't configured or if setup is not complete.
**If necessary, provide a dismissible notification in the plugin area**. Add a notification to communicate next steps if setup or connection is required to successfully enable the plugin.
- Use the standard WordPress notice format and WooCommerce admin notices API.
- Notices should be dismissible. Users should always have a clear way to close the notice.
<<<<<<< HEAD
- Keep the post-activation notice with the WordPress plugin area in context of the plugin listing—do not display it on the dashboard, or any other parts of the platform.
- Don't display more than one notice.
=======
- Keep the post-activation notice with the WordPress plugin area in context of the plugin listing-do not display it on the dashboard, or any other parts of the platform.
- Dont display more than one notice.
>>>>>>> trunk
- Try to keep the notice copy between 125 to 200 characters.
If no action is required for setup its best to rely on other onboarding aids such as the Task List (link to component) and Inbox (link to component) to help users discover features and use your plugin.
If no action is required for setup it's best to rely on other onboarding aids such as the Task List (link to component) and Inbox (link to component) to help users discover features and use your plugin.
**Get to the point and keep it instructional**. This is not a time to promote your brand or pitch the product. The user has bought your product and is ready to use it. Keep the information instructional and precise and avoid the use of branded colors, fonts, and illustrations in empty states and other onboarding aids. Help users with context on next steps.
**Show helpful empty states**. Rely on the existing plugin UI, if any, to guide users towards successful setup and use of the plugin. Avoid onboarding emails, push notifications, and welcome tours.
**Plugins should not redirect on activation from WordPress plugins area**. This can break bulk activation of plugins. Following the [dotorg plugin guideline 11](https://developer.wordpress.org/plugins/wordpress-org/detailed-plugin-guidelines/#11-plugins-should-not-hijack-the-admin-dashboard), the extension shouldnt hijack the dashboard or hide functionality of core or other extensions.
**Plugins should not redirect on activation from WordPress plugins area**. This can break bulk activation of plugins. Following the [dotorg plugin guideline 11](https://developer.wordpress.org/plugins/wordpress-org/detailed-plugin-guidelines/#11-plugins-should-not-hijack-the-admin-dashboard), the extension shouldn't hijack the dashboard or hide functionality of core or other extensions.
**Avoid dead end links and pages**. There should always be a way forward or back.

View File

@ -19,7 +19,7 @@ Anything that **requires** action should go in the task list.
- Tasks that will enable, connect, or configure an extension.
- Tasks that are critical to the business, such as capturing payment or responding to disputes.
- *What doesnt appear in the Things to do Task List:*
- *What doesn't appear in the Things to do Task List:*
- Any critical update that would impact or prevent the functioning of the store should appear as a top level notice using the standard WordPress component.
- Informational notices such as feature announcements or tips for using the plugin should appear in the Inbox as they are not critical and do not require action.
@ -41,7 +41,7 @@ The Inbox provides informational, useful, and supplemental content to the user,
- Tips for using the plugin and introducing features.
- Insights such as inspirational messages or milestones.
- *What doesnt appear in the Inbox*:
- *What doesn't appear in the Inbox*:
- Notices that require action, extension setup tasks, or regular feedback notices.

View File

@ -6,13 +6,13 @@ This guide covers general guidelines, and best practices to follow in order to e
We strongly recommend you review the current [WooCommerce setup experience](https://woo.com/documentation/plugins/woocommerce/getting-started/) to get familiar with the user experience and taxonomy.
We also recommend you review the [WordPress core guidelines](https://developer.wordpress.org/plugins/wordpress-org/detailed-plugin-guidelines/) to ensure your product isnt breaking any rules, and review [this helpful resource](https://woo.com/document/grammar-punctuation-style-guide/) on content style.
We also recommend you review the [WordPress core guidelines](https://developer.wordpress.org/plugins/wordpress-org/detailed-plugin-guidelines/) to ensure your product isn't breaking any rules, and review [this helpful resource](https://woo.com/document/grammar-punctuation-style-guide/) on content style.
## General
Use existing WordPress/WooCommerce UI, built in components (text fields, checkboxes, etc) and existing menu structures.
Plugins which draw on WordPress core design aesthetic will benefit from future updates to this design as WordPress continues to evolve. If you need to make an exception for your product, be prepared to provide a valid use case.
Plugins which draw on WordPress' core design aesthetic will benefit from future updates to this design as WordPress continues to evolve. If you need to make an exception for your product, be prepared to provide a valid use case.
- [WordPress Components library](https://wordpress.github.io/gutenberg/?path=/story/docs-introduction--page)
- [Figma for WordPress](https://make.wordpress.org/design/2018/11/19/figma-for-wordpress/) | ([WordPress Design Library Figma](https://www.figma.com/file/e4tLacmlPuZV47l7901FEs/WordPress-Design-Library))

View File

@ -4,7 +4,7 @@ post_title: Configuring caching plugins for WooCommerce
## Excluding Pages from the Cache
Oftentimes if using caching plugins theyll already exclude these pages. Otherwise make sure you exclude the following pages from the cache through your caching systems respective settings.
Oftentimes if using caching plugins they'll already exclude these pages. Otherwise make sure you exclude the following pages from the cache through your caching systems respective settings.
- Cart
- My Account
@ -14,7 +14,7 @@ These pages need to stay dynamic since they display information specific to the
## Excluding WooCommerce Session from the Cache
If the caching system youre using offers database caching, it might be helpful to exclude `_wc_session_` from being cached. This will be dependent on the plugin or host caching so refer to the specific instructions or docs for that system.
If the caching system you're using offers database caching, it might be helpful to exclude `_wc_session_` from being cached. This will be dependent on the plugin or host caching so refer to the specific instructions or docs for that system.
## Excluding WooCommerce Cookies from the Cache
@ -28,21 +28,21 @@ Cookies in WooCommerce help track the products in your customers cart, can keep
| woocommerce_recently_viewed | session | Powers the Recent Viewed Products widget. |
| store_notice[notice id] | session | Allows customers to dismiss the Store Notice. |
Were unable to cover all options, but we have added some tips for the popular caching plugins. For more specific support, please reach out to the support team responsible for your caching integration.
We're unable to cover all options, but we have added some tips for the popular caching plugins. For more specific support, please reach out to the support team responsible for your caching integration.
### W3 Total Cache Minify Settings
Ensure you add mfunc to the Ignored comment stems option in the Minify settings.
Ensure you add 'mfunc' to the 'Ignored comment stems' option in the Minify settings.
### WP-Rocket
WooCommerce is fully compatible with WP-Rocket. Please ensure that the following pages (Cart, Checkout, My Account) are not to be cached in the plugins settings.
WooCommerce is fully compatible with WP-Rocket. Please ensure that the following pages (Cart, Checkout, My Account) are not to be cached in the plugin's settings.
We recommend avoiding JavaScript file minification.
### WP Super Cache
WooCommerce is natively compatible with WP Super Cache. WooCommerce sends information to WP Super Cache so that it doesnt cache the Cart, Checkout, or My Account pages by default.
WooCommerce is natively compatible with WP Super Cache. WooCommerce sends information to WP Super Cache so that it doesn't cache the Cart, Checkout, or My Account pages by default.
### Varnish
@ -95,6 +95,6 @@ unset beresp.http.set-cookie;
### Why is my Password Reset stuck in a loop?
This is due to the My Account page being cached, Some hosts with server-side caching dont prevent my-account.php from being cached.
This is due to the My Account page being cached, Some hosts with server-side caching don't prevent my-account.php from being cached.
If youre unable to reset your password and keep being returned to the login screen, please speak to your host to make sure this page is being excluded from their caching.
If you're unable to reset your password and keep being returned to the login screen, please speak to your host to make sure this page is being excluded from their caching.