Create Dynamic Menus in Storyblok and Laravel
Storyblok is the first headless CMS that works for developers & marketers alike.
In this part of the tutorial series, we will make the menu in our header component dynamic, so that you can manage it directly from Storyblok.
If you’re in a hurry, have a look at our source code demo in GitHub!
Requirements
This tutorial is the third part of the Ultimate Tutorial Series for Laravel. We recommend that you follow the previous tutorials before starting this one.
Setup in Storyblok
First, we will have to create a new content type component wherein our menu entries can be stored. In order to do that, go to the Block Library {1} and create a New block {2}.
Enter the name config
{1} and choose Content type block {2}.
Now you can create a new field with the name header_menu
{1} and choose the field type Blocks {2}.
In this field, we would like to provide the possibility to add menu links as nested blocks. To accomplish that, let’s create another new block. This time it should be a Nested block {1} with the name menu_link
{2}.
Now we can add a new field called link
{1} in this newly created block and choose Link as the field type {2}.
Alright, our component schemas are almost done! Just one more step: to avoid that just any block could be nested in our header_menu
, we want to make sure that only specific components can be inserted {1}. Now you can choose the menu_link
block in the whitelist {2}.
With that out of the way we can now go to the Content of our Storyblok space. In here, we want to create a new story with the name Config {2}, using our recently created content type Config {3}.
If you open this newly created Config story, you can now nest as many menu_link
blocks in the header_menu
field as you would like. For now, let’s add our Blog and About page.
Rendering the Menu in Laravel
Having taken care of our setup in Storyblok, we can now turn to the code and implement our dynamic menu in the blade template. To accomplish that, we have to refactor a bit of the code we already implemented for the static header, and add the dynamic Header component. In detail we will:
- add a new component class
- add the logic for retrieving the new config Story (via the Storyblok PHP SDK) in a new component class
- refactor the component blade template and make it dynamic
The Header component class
We are going to create a component class for implementing the logic for retrieving the config Story from Storyblok. Create a new file app/View/Components/Header.php
. We will implement the two methods: __construct()
and render()
:
In the constructor method we are going to create an instance of Storyblok Client, using the API key from the configuration, setting the editMode (for retrieving the draft version), and setting the resolve links for the URL. For resolving the links we are using: $storyblok->resolveLinks('url');
.
If your space was created in the United States, don't forget to set the apiRegion
parameter in Storyblok\Client
initialization. If you need more examples, you can see the PHP SDK readme documentation for "Initialization for US spaces"
In the constructor we are retrieving the information from a specific Story ('config'
): $response = $storyblok->getStoryBySlug('config');
.
In the render()
method we are going to load the blade in resources/views/components/common/header.blade.php
via the view()
helper: return view('components.common.header');
The Header blade template
In the file resources/views/components/common/header.blade.php
already created in the Part 2 of the Laravel Ultimate Tutorial series, we can load dynamically the menu items thanks to the work made in the component class that filled the $headerMenu
variable. The $headerMenu
variable is an array, where we can find the menu items, and for each menu item, we can access the full_slug
property for composing the destination URL and the name
for the label of the link.
Now, we can refactor the way we are calling the Header component from the blade templates. Let's remove the header in the layout file:
Afterwards, we can include the new header here:
And finally create the resources/views/components/config.blade.php
file, for allowing the correct rendering when the editor user will select the config Story in the visual editor:
When opening the visual editor, you can now see the expected result:
Please remember to start your Laravel application locally via php artisan server
. Since HTTPS is a requirement for the Visual Editor, you also have to use the following command (as explained in Part 1):
If you missed something, you can start reading and learn Add a headless CMS to Laravel in 5 minutes.
Resource | Link |
---|---|
Storyblok Laravel Ultimate Tutorial | https://www.storyblok.com/tp/storyblok-laravel-ultimate-tutorial |
Storyblok PHP SDK client | https://github.com/storyblok/php-client |
Storyblok APIs | https://www.storyblok.com/docs/api |
Laravel | https://laravel.com/ |
PHP 8 | https://www.php.net/ |