Search code examples
wordpress-rest-apigatsby

Get WordPress Submenus in Gatsby JS


I am fiddling around with Gatsby JS using WP as the backend and so far so good. Now I was trying to pull in the menu which for main menu items works just as expected. What I can't really wrap my head around is how to get the submenus pulled in.

The only related thing I found was https://github.com/gatsbyjs/gatsby/issues/2426 which does give me the submenus if I log the data. Just can't get them to be pulled into the menu.

Here is my query in layouts/index.js:

export const query = graphql`
  query LayoutQuery {
    allWordpressWpApiMenusMenusItems {
      edges {
        node {
          name
          count
          items {
            order
            title
            url
            wordpress_children {
              wordpress_id
              title
              url
            }
          }
        }
      }
    }
}
`

This is my menu component:

class MainMenu extends Component {
  render(){

    const data = this.props.menu.allWordpressWpApiMenusMenusItems.edges["0"].node.items
    console.log(data)

    return(
      <div>
      <h1>Menu</h1>
      <ul>
        {data.map((item) =>
          <li key={item.object_slug}>
            <Link to={item.url}>
              {item.title}
            </Link>
          </li>
        )}
      </ul>
      </div>
    )
  }
}

export default MainMenu

I tried fiddling around with variations of

{item.children["0"].wordpress_children.title}

but just can't get it to work:/ Any ideas or pointers would be much appreciated!


Solution

  • I just tested this, and your logic is sound all you need is another loop to display subitems. So in your MainMenu.js you can do something like this:

    class MainMenu extends Component {
    render() {
    
        const data = this.props.menu.allWordpressWpApiMenusMenusItems.edges[0].node.items
        console.log(data)
        return (
            <div>
                <h1>Main Menu</h1>
                <ul>
                    {data.map((item) =>
                        <li key={item.object_slug}>
                            <Link to={item.url}>
                                {item.title}
                            </Link>
                            <ul>
                                {item.wordpress_children && item.wordpress_children.map((subitem) =>
                                    <li key={item.wordpress_id}>
                                        <Link to={subitem.url}>
                                            {subitem.title}
                                        </Link>
                                    </li>
                                )}
                            </ul>
                        </li>
                    )}
                </ul>
            </div>
        )
    }
    }
    

    This line is very important {item.wordpress_children && item.wordpress_children.map((subitem)

    This will check if your menu item has subitems, and if it does it will map them and iterate through them.

    I hope this works for you, I tested it and it works.