Global Search and Command Palette
Add your resources to the Evolve global search, and your screens and actions to the Cmd-K palette.
Implement the Searchable interface
Your models should implement the Searchable interface and define the following functions:
public function scopeSearch(Builder $query, string $keyword)
{
// Eloquent query to search for a given `$keyword`
}
public function getSearchableTitle(): string
{
// Define the title for a search result
}
public function getSearchableDescription(): ?string
{
// Define the description for a search result
}
public function getSearchableAdminUrl(): string
{
// Define the backend route for when a user
// clicks on a search result in the control panel
}Link blocks to your editor 2.21
Search results, the activity log and the media usage list also show single blocks. A click on one opens the editor of the record the block sits on. If your model carries blocks (use HasBlocks), implement BlockContainer and return the URL of its block editor. Add ?blockId= so the editor opens the block directly:
use Racerfish\Evolve\Contracts\BlockContainer;
use Racerfish\Evolve\Models\Block;
class Order extends Model implements BlockContainer
{
use HasBlocks;
public function blockEditUrl(Block $block): string
{
return route('shop.order.edit', $this->getKey()) . '?blockId=' . $block->getKey();
}
}The route must render the block editor (@livewire('evolve::block.editor', ['blockable' => $item])). Nested blocks ask their parent block, so a card inside a cards block opens in the same editor. A model without the contract links to the page editor, which only fits pages. Pages, sections and all models of the bundled modules implement it.
Register searchable models
Register your searchable models in config/evolve.php or in the module registration searchable option:
Evolve::registerModule('blog', [
// ...
'searchable' => [
Post::class,
]
]);Optionally name the heading of your results in the Cmd-K palette. Without it the plural class name is used:
public static function getSearchableGroupLabel(): string
{
return __('shop::views.orders');
}Content search is limited to the roles in evolve.roles.search (default developer, admin, content_manager).
Command palette
Cmd+K lists panel screens (views) and things to start (actions) next to the content results. Each entry is a PanelCommand pointing at a named route. It only shows when the route exists and the user passes every role: middleware on it, so you rarely need to repeat roles.
Modules pass their commands with the registration. The module label (or name) is shown next to each entry:
use Racerfish\Evolve\Support\PanelCommand;
Evolve::registerModule('blog', [
// ...
'label' => 'blog::views.blog', // optional, defaults to 'name'
'commands' => [
PanelCommand::view('blog::views.posts', 'blog.post.index')->icon('newspaper'),
PanelCommand::view('blog::views.categories', 'blog.category.index')->icon('newspaper'),
PanelCommand::action('blog::views.new-post', 'blog.post.create')->keywords(['article', 'artikel']),
],
]);A host app registers its own in a service provider. A closure runs per request and can build commands from data:
use Racerfish\Evolve\Facades\Evolve;
use Racerfish\Evolve\Support\PanelCommand;
Evolve::registerCommands([
PanelCommand::view('Orders', 'app.order.index')->icon('bag')->keywords('bestellungen'),
PanelCommand::action('New order', 'app.order.index', ['create' => 'true']),
fn () => Shop::pluck('name', 'id')->map(
fn (string $name, int $id) => PanelCommand::view($name, 'app.shop.show', ['shop' => $id])->icon('bag')
),
]);view()andaction()take a label (translation key or plain text), a route name and route parameters. Actions get theplusicon.->icon()takes a panel icon name (or a Font Awesome alias).->keywords()adds search terms in any language. The English label is searchable anyway.->context()sets the muted text next to the label.->roles('admin|developer')narrows an entry further than its route does.- For a list with a drawer, point the action at the list with
['create' => 'true']. For a resource with its own create page, point it at the.createroute.