This page refers to the Control Panel’s side-bar navigation. Not to be confused with “Navs“, where you can create trees to be used for the front-end of your site.
Overview
Customization vs Extension
Statamic offers the ability for end users to customize their CP nav via a user-friendly preferences GUI, but this page is focused on Statamic’s PHP API for extending the CP nav within an addon.
Registering Your Extension
Every nav item is represented by a NavItem
object, which has a full API for adding, removing, and modifying items. You may register your nav extensions in the boot()
method of a service provider.
Adding Items
Let’s assume we’re creating a Store addon, and want to add a Store
nav item to the Content
section of the navigation. To add this item, we’ll add the following code to our service provider’s boot()
method:
use Statamic\Facades\CP\Nav; public function bootAddon(){ Nav::extend(function ($nav) { $nav->content('Store') ->route('store.index') ->icon('shopping-cart'); });}
The content()
method there is a magic method, and the name of method defines the section name that will be used. If we need to display special characters in our section name, we can create()
the nav item and explicitly define the section name:
Nav::extend(function ($nav) { $nav->create('Store') ->section('Jack & Sons Inc.') ->route('store.index') ->icon('shopping-cart');});
If you wish to use a custom SVG or one from the Streamline Icon Pack that’s not included in Statamic, you may pass the SVG icon to the icon()
method, in place of an icon name.
You can access the complete set of default icons for the icon()
method in the vendor files located at vendor/statamic/cms/resources/svg/icons
. Alternatively, you can also view them directly on GitHub
Nav::extend(function ($nav) { $nav->create('Store') ->section('Jack & Sons Inc.') ->route('store.index') ->icon('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M6.547 9.674l7.778 7.778a4.363 4.363 0 0 0 .9-4.435l5.965-5.964.177.176a1.25 1.25 0 0 0 1.768-1.767l-4.6-4.6a1.25 1.25 0 0 0-1.765 1.771l.177.177-5.965 5.965a4.366 4.366 0 0 0-4.435.899zM10.436 13.563L.5 23.499" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"/></svg>');});
Note that the Nav
facade is Statamic\Facades\CP\Nav
.
There’s another Nav facade without the CP namespace, and it’s for the front-end “Navs“ feature.
Adding Children
Maybe we have Products
and Orders
, which we want to display as children under the Store
item. To do this, we’ll add a children()
call to the parent nav item:
Nav::extend(function ($nav) { $nav->content('Store') ->route('store.index') ->icon('shopping-cart') ->children([ 'Products' => cp_route('store.products.index'), 'Orders' => cp_route('store.orders.index') ]);});
If we need to customize our child items further, we can use object notation. For example, maybe we would like to authorize whether the user can()
see these nav items:
Nav::extend(function ($nav) { $nav->content('Store') ->route('store.index') ->icon('shopping-cart') ->can('view store') ->children([ $nav->item('Products')->route('store.products.index')->can('view products'), $nav->item('Orders')->route('store.orders.index')->can('view orders') ]);});
We can also defer the creation of children until render time by passing a closure. For example, if we’re dynamically hitting a data store to generate our children, we can use a closure to avoid the performance hit unless the navigation actually needs to render the children:
Nav::extend(function ($nav) { $nav->content('Store') ->url('store') ->icon('shopping-cart') ->children(function () { return ProductType::hasPublished()->get()->map(function ($type) { return Nav::item($type->name)->url($type->url); }); });});
Removing Items
To remove an item, we may specify the section and item name:
Nav::extend(function ($nav) { $nav->remove('Content', 'Store');});
To remove a child of an item, we can pass a third param to specify the child’s name:
Nav::extend(function ($nav) { $nav->remove('Content', 'Collections', 'Products');});
To remove an entire section, we only need to specify the section name:
Nav::extend(function ($nav) { $nav->remove('Content');});
Modifying Items
We can access any existing item using the same syntax as described above when adding items. We can even modify native Statamic nav items. For example, maybe we wish to change the icon for the Collections
item in the Content
section of the nav:
Nav::extend(function ($nav) { $nav->content('Collections') ->icon('coins');});
The content()
method there is a magic method, which performs a findOrCreate()
under the hood. If the nav item is found, we can then chain on any modifications to be applied to the item. If our section name contains any special characters, we can perform an explicit findOrCreate()
:
Nav::extend(function ($nav) { $nav->findOrCreate('Jack & Sons Inc.', 'Store') ->icon('coins');});
The NavItem Class
Each item you see in the navigation is an instance of the Statamic\CP\Navigation\NavItem
class. Each top level instance within a section may contain its own collection of NavItem
children.
Basic API
The code examples above demonstrate how to add, modify, and remove NavItem
objects. Once you have a NavItem
object, the following chainable methods are available to you:
Method | Parameters | Description |
---|---|---|
name() |
$name (string) |
Define item name. |
section() |
$section (string) |
Define section name. |
route() |
$name (string), $params (mixed, optional) |
Define a route automatically prefixing with statamic.cp. |
url() |
$url (string) |
Define a URL instead of a route. A string without a leading slash will be relative from the CP. A leading slash will be relative from the root. You may provide an absolute URL. |
icon() |
$icon (string) |
Define icon. |
children() |
$children (array|collection|closure) |
Define child items. |
can() |
$ability (string), $params (mixed, optional) |
Define authorization. |
view() |
$view (string) |
Define custom view. |