Use the acf/load_value filter to load values to a Select field.
I recently saw the code for a custom ACF Pro block that rendered a menu. The field group used a text field for the menu name. I felt that asking the user to enter the menu name was error prone so I experimented with changing the text field to a select field, populated with a list of available menus.
Populate a select field
With the acf/load_field filter I can add to or completely replace the drop down values set in the Field Group definition. I use
acf/load_field/type=select so that the filter function only runs on select fields. If you have multiple field groups or multiple select fields you can add additional checks to confirm you are modifying the right field e.g. check the field key or name.
Get menus and their IDs
Getting the menus was easier than I expected: wp_get_nav_menus() returns an array of menu objects. I loop through these to get the menu name and ID and set the select field’s choices to this list. Using the menu ID allows for the menu name to be changed without impacting any chosen menu.
Output the menu
The code that inspired this post used a ACF block. To keep the code here short and simple I chose to simply render the chosen menu at the end of the content of the post (via
the_content filter). Using it in a block would be very similar (get_field() and wp_nav_menu()).
If the chosen menu does not exist WordPress will return the first non-empty menu. I want it to return nothing and a comment in the documention from 2014 said that passing a bogus
theme_location is the only way to achieve this. This is why I added
fallback_cb arguments to the wp_nav_menu() call.