Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Bring mappings adjacent to each other. Improve documenting inconsiste…
…ncies.
  • Loading branch information
getdave committed May 19, 2021
commit 164314c26e6bdd03a9d37b6bde1b4d606132054f
62 changes: 41 additions & 21 deletions packages/edit-navigation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,31 +70,51 @@ The Navigation Editor needs to be able to map navigation items in two directions
1. `nav_menu_item`s to Blocks - when displaying an existing navigation.
2. Blocks to `nav_menu_item`s - when _saving_ an navigation being editing in the Navigation screen.

To understand this fully, one must first appreciate that WordPress maps raw `nav_menu_item` posts to Menu item _objects_. These have various properties which map to block attributes as follows:

| Property | Description | Equivalent Block Attribute |
| :----------------- | :-------------------------------------------------------------------------------------------------------: | :----------------------------------------------------: |
| `ID` | The term_id if the menu item represents a taxonomy term. | Not mapped. |
| `attr_title` | The title attribute of the link element for this menu item. | `title` |
| `classes` | The array of class attribute values for the link element of this menu item. | `classNames` |
| `db_id` | The DB ID of this item as a nav_menu_item object, if it exists (0 if it doesn't exist). | Not mapped. |
| `description` | The description of this menu item. | `description` |
| `menu_item_parent` | The DB ID of the nav_menu_item that is this item's menu parent, if any. 0 otherwise. | Not mapped.<sup>[1](#menu_item_menu_item_parent)</sup> |
| `object` | The type of object originally represented, such as 'category', 'post', or 'attachment'. | `type` |
| `object_id` | The DB ID of the original object this menu item represents, e.g. ID for posts and term_id for categories. | `id` |
| `post_parent` | The DB ID of the original object's parent object, if any (0 otherwise). | Not mapped. |
| `post_title` | A "no title" label if menu item represents a post that lacks a title. | Not mapped. |
| `target` | The target attribute of the link element for this menu item. | `opensInNewTab`<sup>[2](#menu_item_target)</sup> |
| `title` | The title of this menu item. | `label` |
| `type` | The family of objects originally represented, such as 'post_type' or 'taxonomy'. | `kind` |
| `type_label` | The singular label used to describe this type of menu item. | Not mapped. |
| `url` | The URL to which this menu item points. | `url` |
| `xfn` | The XFN relationship expressed in the link of this menu item. | `rel` |
| `\_invalid` | Whether the menu item represents an object that no longer exists. | Not mapped. |
The Navigation Editor has two dedicated methods for handling mapping between these two expressions of the data:

- [`menuItemToBlockAttributes()`](https://github.com/WordPress/gutenberg/blob/7fcd57c9a62c232899e287f6d96416477d810d5e/packages/edit-navigation/src/store/utils.js#L261-L313).
- [`blockAttributestoMenuItem()`](https://github.com/WordPress/gutenberg/blob/7fcd57c9a62c232899e287f6d96416477d810d5e/packages/edit-navigation/src/store/utils.js#L184-L253)

To understand these fully, one must appreciate that WordPress maps raw `nav_menu_item` posts to [Menu item _objects_](https://core.trac.wordpress.org/browser/tags/5.7.1/src/wp-includes/nav-menu.php#L786). These have various properties which map as follows:

| Menu Item object property | Equivalent Block Attribute | Description |
| :------------------------ | :----------------------------------------------------: | :-------------------------------------------------------------------------------------------------------: |
| `ID` | Not mapped. | The term_id if the menu item represents a taxonomy term. |
| `attr_title` | `title` | The title attribute of the link element for this menu item. |
| `classes` | `classNames` | The array of class attribute values for the link element of this menu item. |
| `db_id` | Not mapped. | The DB ID of this item as a nav_menu_item object, if it exists (0 if it doesn't exist). |
| `description` | `description` | The description of this menu item. |
| `menu_item_parent` | Not mapped.<sup>[1](#menu_item_menu_item_parent)</sup> | The DB ID of the nav_menu_item that is this item's menu parent, if any. 0 otherwise. |
| `object` | `type` | The type of object originally represented, such as 'category', 'post', or 'attachment'. |
| `object_id` | `id` | The DB ID of the original object this menu item represents, e.g. ID for posts and term_id for categories. |
| `post_parent` | Not mapped. | The DB ID of the original object's parent object, if any (0 otherwise). |
| `post_title` | Not mapped. | A "no title" label if menu item represents a post that lacks a title. |
| `target` | `opensInNewTab`<sup>[2](#menu_item_target)</sup> | The target attribute of the link element for this menu item. |
| `title` | `label` | The title of this menu item. |
| `type` | `kind` | The family of objects originally represented, such as 'post_type' or 'taxonomy'. |
| `type_label` | Not mapped. | The singular label used to describe this type of menu item. |
| `url` | `url` | The URL to which this menu item points. |
| `xfn` | `rel` | The XFN relationship expressed in the link of this menu item. |
| `\_invalid` | Not mapped. | Whether the menu item represents an object that no longer exists. |

- [<a name="menu_item_menu_item_parent">1</a>] - the parent -> child relationship is expressed in block via the `innerBlocks` attribute and is therefore not required as a explicit block attribute.
- [<a name="menu_item_target">2</a>] - applies only if the value of the `target` field is `_blank`.

### Inconsistencies

#### Mapping

For historical reasons, the following properties display some inconsistency in their mapping from Menu Item Object to Block attribute:

- `type` -> `kind` - the family of objects is stored as `kind` on the block and so must be mapped accordingly.
- `object` -> `type` - the type of object is stored as `type` on the block and so must be mapped accordingly.
- `object_id` -> `id` - the block stores a reference to the original object's ID as the `id` _attribute_. This should not be confused with the block's `clientId` which is unrelated.
- `attr_title` -> `title` - the HTML `title` attribute is stored as `title` on the block and so must be mapped accordingly.

#### Object Types

- Menu Item objects which represent "Tags" are stored in WordPress as `post_tag` but the block expects their `type` attribute to be `tag` (omiting the `post_` suffix). This inconsistency is accounted for in [the mapping utilities methods](https://github.com/WordPress/gutenberg/blob/7fcd57c9a62c232899e287f6d96416477d810d5e/packages/edit-navigation/src/store/utils.js#L279-L281).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As an aside, I think we can still change this to prefer post_tag before the navigation block is finalized. (We'd still need to account for older data that has tag though).


## Hooks

`useMenuItems` and `useNavigationBlock` hooks are the central part of this package. They bridge the gap between the API and the block editor interface:
Expand Down