Fix incorrectly rendered HTML tags in docs (#50966)

* Fix incorrectly rendering custom fields docs page

* Fix additional incorrectly rendering html tags in docs
This commit is contained in:
Jacklyn Biggin 2024-09-04 16:25:24 -04:00 committed by GitHub
parent 18ab90badd
commit aaae67f032
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 116 additions and 116 deletions

View File

@ -59,7 +59,7 @@ For our Woo extension, we'll be appending our field right at the end with `wooco
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
&lt;?php
namespace WooProductField\Admin;
@ -68,7 +68,7 @@ defined( 'ABSPATH' ) || exit;
class ProductFields {
public function __construct() {
$this->hooks();
$this-&gt;hooks();
}
private function hooks() {}
@ -93,19 +93,19 @@ With the class set up and being called, we can create a function to add the cust
```php
public function add_field() {
global $product_object;
?>
<div class="inventory_new_stock_information options_group show_if_simple show_if_variable">
<?php woocommerce_wp_text_input(
?&gt;
&lt;div class="inventory_new_stock_information options_group show_if_simple show_if_variable"&gt;
&lt;?php woocommerce_wp_text_input(
array(
'id' => '_new_stock_information',
'label' => __( 'New Stock', 'woo_product_field' ),
'description' => __( 'Information shown in store', 'woo_product_field' ),
'desc_tip' => true,
'value' => $product_object->get_meta( '_new_stock_information' )
'id' =&gt; '_new_stock_information',
'label' =&gt; __( 'New Stock', 'woo_product_field' ),
'description' =&gt; __( 'Information shown in store', 'woo_product_field' ),
'desc_tip' =&gt; true,
'value' =&gt; $product_object-&gt;get_meta( '_new_stock_information' )
)
); ?>
</div>
<?php
); ?&gt;
&lt;/div&gt;
&lt;?php
}
```
@ -119,8 +119,8 @@ Now that we have our field, we need to save it. For this, we can hook into wooco
public function save_field( $post_id, $post ) {
if ( isset( $_POST['_new_stock_information'] ) ) {
$product = wc_get_product( intval( $post_id ) );
$product->update_meta_data( '_new_stock_information', sanitize_text_field( $_POST['_new_stock_information'] ) );
$product->save_meta_data();
$product-&gt;update_meta_data( '_new_stock_information', sanitize_text_field( $_POST['_new_stock_information'] ) );
$product-&gt;save_meta_data();
}
}
```
@ -142,12 +142,12 @@ If we add data and save the product, then the new meta data is inserted into the
At this point you have a working extension that saves a custom field for a product as product meta.
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' )`
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-&gt;get_meta( '\_new_stock_information' )`
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
&lt;?php
namespace WooProductField;
@ -155,7 +155,7 @@ defined( 'ABSPATH' ) || exit;
class Product {
public function __construct() {
$this->hooks();
$this-&gt;hooks();
}
private function hooks() { }
@ -190,9 +190,9 @@ In our function we output the stock information with the [appropriate escape fun
```php
public function add_stock_info() {
global $product;
?>
<p><?php echo esc_html( $product->get_meta( '_new_stock_information' ) ); ?> </p>
<?php
?&gt;
&lt;p&gt;&lt;?php echo esc_html( $product-&gt;get_meta( '_new_stock_information' ) ); ?&gt; &lt;/p&gt;
&lt;?php
}
```
@ -223,14 +223,14 @@ The setup is very similar to simple products, the main difference is that we nee
```php
public function add_variation_field( $loop, $variation_data, $variation ) {
$variation_product = wc_get_product( $variation->ID );
$variation_product = wc_get_product( $variation-&gt;ID );
woocommerce_wp_text_input(
array(
'id' => '\_new_stock_information' . '[' . $loop . ']',
'label' => \_\_( 'New Stock Information', 'woo_product_field' ),
'wrapper_class' => 'form-row form-row-full',
'value' => $variation_product->get_meta( '\_new_stock_information' )
'id' =&gt; '\_new_stock_information' . '[' . $loop . ']',
'label' =&gt; \_\_( 'New Stock Information', 'woo_product_field' ),
'wrapper_class' =&gt; 'form-row form-row-full',
'value' =&gt; $variation_product-&gt;get_meta( '\_new_stock_information' )
)
);
}
@ -242,8 +242,8 @@ For saving we use:
public function save_variation_field( $variation_id, $i ) {
if ( isset( $_POST['_new_stock_information'][$i] ) ) {
$variation_product = wc_get_product( $variation_id );
$variation_product->update_meta_data( '_new_stock_information', sanitize_text_field( $_POST['_new_stock_information'][$i] ) );
$variation_product->save_meta_data();
$variation_product-&gt;update_meta_data( '_new_stock_information', sanitize_text_field( $_POST['_new_stock_information'][$i] ) );
$variation_product-&gt;save_meta_data();
}
}
```

View File

@ -14,17 +14,17 @@ if ( ! function_exists( 'YOUR_PREFIX_login_message' ) ) {
*/
function YOUR_PREFIX_login_message() {
if ( get_option( 'woocommerce_enable_myaccount_registration' ) == 'yes' ) {
?>
<div class="woocommerce-info">
<p><?php _e( 'Returning customers login. New users register for next time so you can:', 'YOUR-TEXTDOMAIN' ); ?></p>
<ul>
<li><?php _e( 'View your order history', 'YOUR-TEXTDOMAIN' ); ?></li>
<li><?php _e( 'Check on your orders', 'YOUR-TEXTDOMAIN' ); ?></li>
<li><?php _e( 'Edit your addresses', 'YOUR-TEXTDOMAIN' ); ?></li>
<li><?php _e( 'Change your password', 'YOUR-TEXTDOMAIN' ); ?></li>
</ul>
</div>
<?php
?&gt;
&lt;div class="woocommerce-info"&gt;
&lt;p&gt;&lt;?php _e( 'Returning customers login. New users register for next time so you can:', 'YOUR-TEXTDOMAIN' ); ?&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;?php _e( 'View your order history', 'YOUR-TEXTDOMAIN' ); ?&gt;&lt;/li&gt;
&lt;li&gt;&lt;?php _e( 'Check on your orders', 'YOUR-TEXTDOMAIN' ); ?&gt;&lt;/li&gt;
&lt;li&gt;&lt;?php _e( 'Edit your addresses', 'YOUR-TEXTDOMAIN' ); ?&gt;&lt;/li&gt;
&lt;li&gt;&lt;?php _e( 'Change your password', 'YOUR-TEXTDOMAIN' ); ?&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;?php
}
}
add_action( 'woocommerce_before_customer_login_form', 'YOUR_PREFIX_login_message' );

View File

@ -83,7 +83,7 @@
"menu_title": "Add Custom Fields to Products",
"tags": "how-to",
"edit_url": "https://github.com/woocommerce/woocommerce/edit/trunk/docs/building-a-woo-store/adding-a-custom-field-to-variable-products.md",
"hash": "59ef97ed2053dedfa5e7c658d5c7fa470d8110afc9b84584cb32b58389bf5687",
"hash": "fe8cf43940f5166bf69f102aa4643cbe32415b1167d6b6d8968d434a4d113879",
"url": "https://raw.githubusercontent.com/woocommerce/woocommerce/trunk/docs/building-a-woo-store/adding-a-custom-field-to-variable-products.md",
"id": "64b686dcd5fdd4842be2fc570108231d5a8bfc1b"
}
@ -439,7 +439,7 @@
"post_title": "Add a message above the login / register form",
"tags": "code-snippet",
"edit_url": "https://github.com/woocommerce/woocommerce/edit/trunk/docs/code-snippets/before-login--register-form.md",
"hash": "49f0d942364ea6815e799972894406cb0963164adfb6c373222dcf7fb0ee6fb9",
"hash": "dd3d61cd1f99d459956167041718e6a25693901a810d4bde47613d5ea2595ca3",
"url": "https://raw.githubusercontent.com/woocommerce/woocommerce/trunk/docs/code-snippets/before-login--register-form.md",
"id": "26ea2036f16952c8c965f2ab38ab214e421aa615"
},
@ -727,7 +727,7 @@
"menu_title": "Implement merchant onboarding",
"tags": "how-to",
"edit_url": "https://github.com/woocommerce/woocommerce/edit/trunk/docs/extension-development/handling-merchant-onboarding.md",
"hash": "a34e2c637ac47adb1dd2e7b2510fb3eb7ff517b8f31e9cfa6fe4d3920f2567e7",
"hash": "c73e3c5015e6cda3be9ebd2d5fbda590ac9fa599e5fb02163c971c01060970ad",
"url": "https://raw.githubusercontent.com/woocommerce/woocommerce/trunk/docs/extension-development/handling-merchant-onboarding.md",
"id": "89fe15dc232379f546852822230c334d3d940b93"
},
@ -1050,7 +1050,7 @@
"menu_title": "Registering custom collections",
"tags": "how-to",
"edit_url": "https://github.com/woocommerce/woocommerce/edit/trunk/docs/product-collection-block/register-product-collection.md",
"hash": "e3df65c5eec52e4bb797e34c040dbb8f820ea6571e9ce50b1d518e95ca6cb169",
"hash": "27c321bed35524d74019e015f5eed6cdca7e6c2efe0bc89ffdd2b9b5d43c47e8",
"url": "https://raw.githubusercontent.com/woocommerce/woocommerce/trunk/docs/product-collection-block/register-product-collection.md",
"id": "3bf26fc7c56ae6e6a56e1171f750f5204fcfcece"
},
@ -1451,7 +1451,7 @@
{
"post_title": "Template structure & Overriding templates via a theme",
"edit_url": "https://github.com/woocommerce/woocommerce/edit/trunk/docs/theme-development/template-structure.md",
"hash": "0d026ed5e9706b97dd03d6f7dc86aeb580b11549fa99c9d6f906bbca6f136a01",
"hash": "a82d885c8395385dc51c976b2b51eec88cdcce72bf905fda78f97d77533ce079",
"url": "https://raw.githubusercontent.com/woocommerce/woocommerce/trunk/docs/theme-development/template-structure.md",
"id": "34bfebec9fc45e680976814928a7b8a1778af14e"
},
@ -1804,5 +1804,5 @@
"categories": []
}
],
"hash": "cbe507d24f0d6ae827c01a98fd2d7c6e8db74053a7b3db869c6941dd7442d250"
"hash": "212688b70a2dd0e70819746e6ffc033bc2279cb5b7b6350f377bbc3bc28c080f"
}

View File

@ -26,7 +26,7 @@ Setup tasks appear on the WooCommerce Admin home screen and prompt a merchant to
To register your task as an extended task list item, you'll need to start by creating a new PHP class that extends the Task class. This class will define the properties and behavior of your custom task.
```php
<?php
&lt;?php
/**
* Custom task example.
*
@ -113,37 +113,37 @@ import {
} from '@woocommerce/onboarding';
import { registerPlugin } from '@wordpress/plugins';
const Task = ( { onComplete, task, query } ) => {
const Task = ( { onComplete, task, query } ) =&gt; {
// Implement your task UI/feature here.
return <div></div>;
return &lt;div&gt;&lt;/div&gt;;
};
registerPlugin( 'add-task-content', {
render: () => (
<WooOnboardingTask id="my-task">
{ ( { onComplete, query, task } ) => (
<Task onComplete={ onComplete } task={ task } query={ query } />
render: () =&gt; (
&lt;WooOnboardingTask id="my-task"&gt;
{ ( { onComplete, query, task } ) =&gt; (
&lt;Task onComplete={ onComplete } task={ task } query={ query } /&gt;
) }
</WooOnboardingTask>
&lt;/WooOnboardingTask&gt;
),
} );
registerPlugin( 'add-task-list-item', {
scope: 'woocommerce-tasks',
render: () => (
<WooOnboardingTaskListItem id="my-task">
{ ( { defaultTaskItem: DefaultTaskItem } ) => (
render: () =&gt; (
&lt;WooOnboardingTaskListItem id="my-task"&gt;
{ ( { defaultTaskItem: DefaultTaskItem } ) =&gt; (
// Add a custom wrapper around the default task item.
<div
&lt;div
className="woocommerce-custom-tasklist-item"
style={ {
border: '1px solid red',
} }
>
<DefaultTaskItem />
</div>
&gt;
&lt;DefaultTaskItem /&gt;
&lt;/div&gt;
) }
</WooOnboardingTaskListItem>
&lt;/WooOnboardingTaskListItem&gt;
),
} );
```
@ -168,37 +168,37 @@ import { registerPlugin } from '@wordpress/plugins';
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 = ( { onComplete, task } ) => {
const Task = ( { onComplete, task } ) =&gt; {
const { actionTask } = useDispatch( ONBOARDING_STORE_NAME );
const { isActioned } = task;
return (
<Card className="woocommerce-task-card">
<CardBody>
&lt;Card className="woocommerce-task-card"&gt;
&lt;CardBody&gt;
{ __(
"This task's completion status is dependent on being actioned. The action button below will action this task, while the complete button will optimistically complete the task in the task list and redirect back to the task list. Note that in this example, the task must be actioned for completion to persist.",
'plugin-domain'
) }{ ' ' }
<br />
<br />
&lt;br /&gt;
&lt;br /&gt;
{ __( 'Task actioned status: ', 'plugin-domain' ) }{ ' ' }
{ isActioned ? 'actioned' : 'not actioned' }
<br />
<br />
<div>
<button
onClick={ () => {
&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;button
onClick={ () =&gt; {
actionTask( 'my-task' );
} }
>
&gt;
{ __( 'Action task', 'plugin-domain' ) }
</button>
<button onClick={ onComplete }>
&lt;/button&gt;
&lt;button onClick={ onComplete }&gt;
{ __( 'Complete', 'plugin-domain' ) }
</button>
</div>
</CardBody>
</Card>
&lt;/button&gt;
&lt;/div&gt;
&lt;/CardBody&gt;
&lt;/Card&gt;
);
};
```
@ -211,14 +211,14 @@ Next, we register the Task component as a plugin named "add-task-content" using
```js
registerPlugin( 'add-task-content', {
render: () => (
render: () =&gt; (
{ ( {
onComplete,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
query,
task,
} ) => }
} ) =&gt; }
),
scope: 'woocommerce-tasks',
@ -232,20 +232,20 @@ Finally, we register another plugin named "my-task-list-item-plugin." This plugi
```js
registerPlugin( 'my-task-list-item-plugin', {
scope: 'woocommerce-tasks',
render: () => (
<WooOnboardingTaskListItem id="my-task">
{ ( { defaultTaskItem: DefaultTaskItem } ) => (
render: () =&gt; (
&lt;WooOnboardingTaskListItem id="my-task"&gt;
{ ( { defaultTaskItem: DefaultTaskItem } ) =&gt; (
// Add a custom wrapper around the default task item.
<div
&lt;div
className="woocommerce-custom-tasklist-item"
style={ {
border: '1px solid red',
} }
>
<DefaultTaskItem />
</div>
&gt;
&lt;DefaultTaskItem /&gt;
&lt;/div&gt;
) }
</WooOnboardingTaskListItem>
&lt;/WooOnboardingTaskListItem&gt;
),
} );
```
@ -344,7 +344,7 @@ import { addFilter } from '@wordpress/hooks';
addFilter(
'woocommerce_admin_homescreen_quicklinks',
'my-extension',
( quickLinks ) => {
( quickLinks ) =&gt; {
return [
...quickLinks,
{
@ -374,7 +374,7 @@ Despite being a part of the new React-powered admin experience in WooCommerce, A
The recommended approach for using Admin Notes is to encapsulate your note within its own class that uses the [NoteTraits](https://github.com/woocommerce/woocommerce-admin/blob/831c9ff13a862f22cf53d3ae676daeabbefe90ad/src/Notes/NoteTraits.php) trait included with WooCommerce Admin. Below is a simple example of what this might look like:
```php
<?php
&lt;?php
/**
* Simple note provider
*
@ -423,10 +423,10 @@ class ExampleNote {
$note = new Automattic\WooCommerce\Admin\Notes\Note();
// Set our note's title.
$note->set_title( 'Getting Started' );
$note-&gt;set_title( 'Getting Started' );
// Set our note's content.
$note->set_content(
$note-&gt;set_content(
sprintf(
'Extension activated on %s.', $activated_time_formatted
)
@ -436,41 +436,41 @@ class ExampleNote {
// You can use this property to re-localize notes on the fly, but
// that is just one use. You can store other data here too. This
// is backed by a longtext column in the database.
$note->set_content_data( (object) array(
'getting_started' => true,
'activated' => $activated_time,
'activated_formatted' => $activated_time_formatted
$note-&gt;set_content_data( (object) array(
'getting_started' =&gt; true,
'activated' =&gt; $activated_time,
'activated_formatted' =&gt; $activated_time_formatted
) );
// Set the type of the note. Note types are defined as enum-style
// constants in the Note class. Available note types are:
// error, warning, update, info, marketing.
$note->set_type( Note::E_WC_ADMIN_NOTE_INFORMATIONAL );
$note-&gt;set_type( Note::E_WC_ADMIN_NOTE_INFORMATIONAL );
// Set the type of layout the note uses. Supported layout types are:
// 'banner', 'plain', 'thumbnail'
$note->set_layout( 'plain' );
$note-&gt;set_layout( 'plain' );
// Set the image for the note. This property renders as the src
// attribute for an img tag, so use a string here.
$note->set_image( '' );
$note-&gt;set_image( '' );
// Set the note name and source. You should store your extension's
// name (slug) in the source property of the note. You can use
// the name property of the note to support multiple sub-types of
// notes. This also gives you a handy way of namespacing your notes.
$note->set_source( 'inbox-note-example');
$note->set_name( self::NOTE_NAME );
$note-&gt;set_source( 'inbox-note-example');
$note-&gt;set_name( self::NOTE_NAME );
// Add action buttons to the note. A note can support 0, 1, or 2 actions.
// The first parameter is the action name, which can be used for event handling.
// The second parameter renders as the label for the button.
// The third parameter is an optional URL for actions that require navigation.
$note->add_action(
$note-&gt;add_action(
'settings', 'Open Settings', '?page=wc-settings&tab=general'
);
$note->add_action(
$note-&gt;add_action(
'learn_more', 'Learn More', 'https://example.com'
);
@ -559,12 +559,12 @@ Next, we'll instantiate a new `Note` object.
Once we have an instance of the Note class, we can work with its API to set its properties, starting with its title.
`$note->set_title( 'Getting Started' );`
`$note-&gt;set_title( 'Getting Started' );`
Then we'll use some of the timestamp data we collected above to set the note's content.
```php
$note->set_content(
$note-&gt;set_content(
sprintf(
'Extension activated on %s.', $activated_time_formatted
)
@ -574,41 +574,41 @@ $note->set_content(
In addition to regular content, notes also support structured content using the `content_data` property. You can use this property to re-localize notes on the fly, but that is just one use case. You can store other data here too. This is backed by a `longtext` column in the database.
```php
$note->set_content_data( (object) array(
'getting_started' => true,
'activated' => $activated_time,
'activated_formatted' => $activated_time_formatted
$note-&gt;set_content_data( (object) array(
'getting_started' =&gt; true,
'activated' =&gt; $activated_time,
'activated_formatted' =&gt; $activated_time_formatted
) );
```
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 );`
`$note-&gt;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 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.
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' );`
`$note-&gt;set_layout( 'plain' );`
If you have an image that you want to add to your Admin Note, you can specify it using the `set_image` function. This property ultimately renders as the `src` attribute on an `img` tag, so use a string here.
`$note->set_image( '' );`
`$note-&gt;set_image( '' );`
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 );
$note-&gt;set_source( 'inbox-note-example');
$note-&gt;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 action's button, and the third is an optional URL for actions that require navigation.
```php
$note->add_action(
$note-&gt;add_action(
'settings', 'Open Settings', '?page=wc-settings&tab=general'
);
$note->add_action(
$note-&gt;add_action(
'learn_more', 'Learn More', 'https://example.com'
);
```