Resource tools are very similar to custom tools; however, instead of being listed in the Nova sidebar, resource tools are displayed on a particular resource's detail page. Like Nova tools, resource tools are incredibly customizable, and primarily consist of a single-file Vue component that is totally under your control.
Resource tools may be generated using the nova:resource-tool
Artisan command. By default, all new tools will be placed in the nova-components
directory of your application. When generating a tool using the nova:resource-tool
command, the tool name you pass to the command should follow the Composer vendor/package
format. So, if we were building a Stripe inspector tool, we might run the following command:
php artisan nova:resource-tool acme/stripe-inspector
When generating a tool, Nova will prompt you to install the tool's NPM dependencies, compile its assets, and update your application's composer.json
file. All custom tools are registered with your application as a Composer "path" repository.
Nova resource tools include all of the scaffolding necessary to build your tool. Each tool even contains its own composer.json
file and is ready to be shared with the world on GitHub or the source control provider of your choice.
Nova resource tools may be registered in your resource's fields
method. This method returns an array of fields and tools available to the resource. To register your resource tool, add your tool to the array of fields returned by this method:
use Acme\StripeInspector\StripeInspector;
/**
* Get the fields displayed by the resource.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function fields(NovaRequest $request)
{
return [
ID::make()->sortable(),
StripeInspector::make(),
];
}
If you would like to only expose a given tool to certain users, you may invoke the canSee
method when registering your tool. The canSee
method accepts a closure which should return true
or false
. The closure will receive the incoming HTTP request:
use Acme\StripeInspector\StripeInspector;
/**
* Get the fields displayed by the resource.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function fields(NovaRequest $request)
{
return [
ID::make('ID', 'id')->sortable(),
StripeInspector::make()->canSee(function ($request) {
return $request->user()->managesBilling();
}),
];
}
Often, you will need to allow the consumer's of your tool to customize run-time configuration options on the tool. You may do this by exposing methods on your tool class. These methods may call the tool's underlying withMeta
method to add information to the tool's metadata, which will be available within your Tool.vue
component. The withMeta
method accepts an array of key / value options:
<?php
namespace Acme\StripeInspector;
use Laravel\Nova\ResourceTool;
class StripeInspector extends ResourceTool
{
/**
* Get the displayable name of the resource tool.
*
* @return string
*/
public function name()
{
return 'Stripe Inspector';
}
/**
* Indicates that the Stripe inspector should allow refunds.
*
* @return $this
*/
public function issuesRefunds()
{
return $this->withMeta(['issuesRefunds' => true]);
}
/**
* Get the component name for the resource tool.
*
* @return string
*/
public function component()
{
return 'stripe-inspector';
}
}
Your resource tool's Tool.vue
component receives several Vue props
: resourceName
, resourceId
, and panel
. The resourceId
property contains the primary key of the resource the tool is currently attached to. You may use the resourceId
when making requests to your controllers. The panel
prop provides access to any tool options that may be available via the fields
:
const issuesRefunds = this.panel.fields[0].issuesRefunds;
Resource tools also offer the ability to dynamically set options on the tool without a setter method by simple calling the desired option as a method when registering the tool. If called with an argument, it will be set as the option's value:
use Acme\StripeInspector\StripeInspector;
/**
* Get the fields displayed by the resource.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function fields(NovaRequest $request)
{
return [
ID::make('ID', 'id')->sortable(),
StripeInspector::make()->issuesRefunds(),
];
}
Each tool generated by Nova includes its own service provider and "tool" class. Using the stripe-inspector
tool as an example, the tool class will be located at src/StripeInspector.php
.
The tool's service provider is also located within the src
directory of the tool, and is registered within the extra
section of your tool's composer.json
file so that it will be auto-loaded by Laravel.
Often, you will need to define Laravel routes that are called by your tool. When Nova generates your tool, it creates a routes/api.php
routes file. If needed, you may use this file to define any routes your tool requires.
All routes within this file are automatically defined inside a route group by your tool's ToolServiceProvider
. The route group specifies that all routes within the group should receive a /nova-vendor/tool-name
prefix, where tool-name
is the "kebab-case" name of your tool. So, for example, /nova-vendor/stripe-inspector
. You are free to modify this route group definition, but take care to make sure your Nova tool will co-exist with other Nova packages.
Routing Authorization
When building routes for your tool, you should always add authorization to these routes using Laravel gates or policies.
When Nova generates your tool, resources/js
and resources/css
directories are generated for you. These directories contain your tool's JavaScript and CSS. The primary files of interest in these directories are: resources/js/components/Tool.vue
and resources/css/tool.css
.
The Tool.vue
file is a single-file Vue component that contains your tool's front-end. From this file, you are free to build your tool however you want. Your tool can make HTTP requests using Axios via Nova.request.
Your Nova tool's service provider registers your tool's compiled assets so that they will be available to the Nova front-end:
use Laravel\Nova\Nova;
use Laravel\Nova\Events\ServingNova;
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
$this->app->booted(function () {
$this->routes();
});
Nova::serving(function (ServingNova $event) {
Nova::script('stripe-inspector', __DIR__.'/../dist/js/tool.js');
Nova::style('stripe-inspector', __DIR__.'/../dist/css/tool.css');
});
}
JavaScript Bootstrap & Routing
Your component is bootstrapped and registered in the resources/js/tool.js
file. You are free to modify this file or register additional components here as needed.
Your Nova resource tool contains a webpack.mix.js
file, which is generated when Nova creates your tool. You may build your tool using the NPM dev
and prod
commands:
# Compile your assets for local development...
npm run dev
# Compile and minify your assets...
npm run prod
In addition, you may run the NPM watch
command to auto-compile your assets when they are changed:
npm run watch