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!