Yeah, I see. Thanks for sharing.
Regarding how to fetch a menu:
- The
name is the more use friendly one and easy to find in the WP Dashboard. But if the name of the menu is changed, you have to change your frontity.settings.js file.
- The
slug is more user friendly, but it’s also hard to obtain from the WP Dashboard. Actually, I don’t know how. Also, if you change the name, the slug changes as well. It is more URL friendly than the name because it doesn’t have special character, spaces and so on.
- The
id doesn’t ever change, which is great. But it doesn’t give you information about which menu is when you copy and paste it in frontity.settings.js. You can get it in the WP Dashboard looking at the URL, but only after you click “Select”, which is probably not intuitive enough.
If we want to use the official plugin and respect the structure we’ve been following for the rest of the WP content, my initial thought is that it should be something like this:
state.source.data["menus/1"] = {
isMenu: true,
type: "menu",
id: 1,
items: [
{ type: "menu-item", id: 2 },
{ type: "menu-item", id: 3 },
{ type: "menu-item", id: 4, children: [
{ type: "menu-item", id: 5 },
{ type: "menu-item", id: 6 },
{ type: "menu-item", id: 7, children: [
{ type: "menu-item", id: 8 },
{ type: "menu-item", id: 9 },
] },
] },
{ type: "menu-item", id: 10 },
{ type: "menu-item", id: 11 },
]
};
state.source.menu["1"] = {
id: 1,
description: "My menu description",
name: "My First menu",
slug: "my-fist-menu",
meta: []
};
state.source["menu-item"]["2"] = {
id: 2,
title: {
rendered: "Home"
},
status: "publish",
link: "/", // <- remove the domain
attr_title: "",
description: "",
type: "custom",
type_label: "Custom Link",
object: "custom",
object_id: 2,
parent: 0,
menu_item_parent: 0,
menu_order: 1,
target: "",
classes: [""],
xfn: [""],
meta: []
};
We can remove the domain from the URL as we do for the link field of posts and taxonomies.
The React component for the menu could be something like this:
const Menu = ({ state }) => {
const data = state.source.get("menus/1");
return (
<ul>
{data.items.map(item =>
<MenuItem id={item.id} children={item.children} />
)}
</ul>
);
}
const MenuItem = ({ state, id, children }) => {
const item = state.source["menu-item"][id];
return (
<li>
<Link href={item.link}>{item.title.rendered}</Link>
{children && (
<ul>
{children.map(child => {
<MenuItem id={child.id} children={child.children} />
}
</ul>
)}
</li>
);
);
Feedback is welcomed!