Query Scopes & Filters

Query scopes and filters allow you to narrow down query results using custom conditions.

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;
Docs feedback

Submit improvements, related content, or suggestions through Github.

Betterify this page →