You may create scopes that can be used in various places, such as inside the collection tag or inside control panel listings.
Scopes
Any scope classes located within app/Scopes
will be automatically registered.
You may create a scope class by running php please make:scope YourScope
, which will give you a class with a few methods for you to implement, for example:
<?php namespace App\Scopes; use Statamic\Query\Scopes\Scope; class Featured extends Scope{ public function apply($query, $values) { $query->where('featured', true); }}
The apply
method will give you a query builder instance, allowing you to modify it how you see fit.
It will also give you $values
, which will be an array of contextual values. For example, when using the scope on a collection tag, you will get all the parameter values. When used as a filter inside the control panel, you will get all of your filter’s field values.
Example: Suppose a collection named “portfolio” and a dynamically obtained “slug” variable. The scope is called PorfolioScope. In your Antlers template:
{{ collection:portfolio query_scope="portfolio_scope" slug="{portfolio}" }} {{ content }}{{ /collection:portfolio }}
In PortfolioScope
:
public function apply($query, $values){ $slug = $values['slug']; $query->where('slug', $slug);}
This will gives you the content of that page.
Using scopes programmatically
In order to use a scope as a query builder method, like “local scopes” in Eloquent, you have to register it on the respective query builder:
use Statamic\Facades\Entry; public function boot(){ Entry::allowQueryScope(Featured::class);}
Entry::query()->where('this', 'that')->featured()->get();
However, unlike Eloquent’s local scopes, Statamic’s scopes accept an array of context. Make sure to pass an associative array rather than individual arguments:
$query->featured([ 'field' => 'value', 'foo' => 'bar',]);
Filters
Filters are UI based scopes that will be displayed in listings inside the Control Panel.
You’re able to configure any number of fields to a filter to allow your users to refine their listings.
You may create a filter class by running php please make:filter YourScope
, which will give you a class with a few methods for you to implement, for example:
<?php namespace App\Scopes; use Statamic\Query\Scopes\Filter; class Featured extends Filter{ public function fieldItems() { return [ 'featured' => [ 'type' => 'radio', 'options' => [ 'featured' => __('Featured'), 'not_featured' => __('Not Featured'), ] ] ]; } public function autoApply() { return [ 'featured' => 'not_featured', ]; } public function apply($query, $values) { $query->where('featured', $values['featured'] === 'featured'); } public function badge($values) { return $values['featured'] === 'featured' ? __('is featured') : __('not featured'); } public function visibleTo($key) { return $key === 'entries' && $this->context['collection'] == 'blog'; }}
The fieldItems
method lets you define which filter fields will be displayed, just like a field inside a Blueprint.
The apply
method works exactly as it would in a standard scope.
The badge
method lets you define the badge text to be used when the filter is active on a listing.
The visibleTo
method allows you to control in which listings this filter will be displayed. You will be given a key that represents the type of listing. For example, an author filter might be appropriate for the entries
listing but not users
. You may also be given an array of contextual data which will vary depending on the listing. For instance, for entries
, the current collection name can be accessed with $this->context['collection']
.
The autoApply
method lets you define a default value to apply.
You may also pin your filters to the filters bar by setting the $pinned
class property:
public $pinned = true;