원클릭으로
add-grid
Create an admin grid class (fields, filters, actions) for an existing Sylius Resource
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Create an admin grid class (fields, filters, actions) for an existing Sylius Resource
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Implement the fix described in a GitHub issue and open a Pull Request that closes it
Apply the latest review feedback to a Pull Request and push it to the PR branch
Add an admin autocomplete form type for a Sylius Resource (translatable or not), optionally injected into another form via an extension
Add an admin FormType for an existing Sylius Resource
Add a Sylius admin grid for an existing Sylius Resource
Add a multiple images collection (OneToMany) to an existing Sylius Resource
| name | add-grid |
| description | Create an admin grid class (fields, filters, actions) for an existing Sylius Resource |
| argument-hint | [ModelName] |
| allowed-tools | AskUserQuestion, Bash, Read, Edit, Write, Glob, Grep |
Ask the user for the ModelName if not provided.
This skill creates a standalone Grid class. It does not attach the grid to the resource — run /sylius-stack:add-operation Index afterwards to expose it as the index page.
Read src/Entity/{ModelName}.php to retrieve the fields with their names and Doctrine types.
Based on the entity fields, ask the user:
Show action on itemsCreate src/Grid/Admin{ModelName}Grid.php.
Grid name convention: app_admin_{model_snake} (e.g. Book → app_admin_book)
| Doctrine type | Grid field | Notes |
|---|---|---|
string, text | StringField | add ->setSortable(true) when useful |
datetime, date | DateTimeField | default format Y-m-d H:i:s |
integer, float | StringField | plain display |
boolean | TwigField | use @SyliusBootstrapAdminUi/shared/grid/field/boolean.html.twig |
| complex / multi-property | TwigField with ->setPath('.') | gives access to full object in template via {{ data.xxx }} |
StringField:
StringField::create('title')
->setLabel('app.ui.{model_snake}.title')
->setSortable(true),
DateTimeField:
DateTimeField::create('createdAt', 'Y-m-d', null)
->setLabel('app.ui.{model_snake}.created_at'),
TwigField — boolean:
TwigField::create('enabled', '@SyliusBootstrapAdminUi/shared/grid/field/boolean.html.twig')
->setLabel('app.ui.{model_snake}.enabled'),
TwigField — full object (access multiple properties in template):
TwigField::create('summary', 'grid/{model_snake}/field/summary.html.twig')
->setLabel('app.ui.{model_snake}.summary')
->setPath('.'),
{# templates/grid/{model_snake}/field/summary.html.twig #}
<strong>{{ data.title }}</strong>
<p>{{ data.description }}</p>
| Use case | Filter |
|---|---|
| Single string field | StringFilter::create('title') |
| Multiple string fields | StringFilter::create('search')->setOptions(['fields' => ['title', 'description']]) |
| Boolean flag | BooleanFilter::create('enabled') |
| Date range | DateFilter::create('createdAt') |
| Related entity | EntityFilter::create('category', Category::class) |
For an AJAX autocomplete filter on a related entity (useful when the related table is large), use /sylius-stack:add-autocomplete instead — it creates the dedicated filter class and wires it into the grid.
Always include by default:
->addActionGroup(
MainActionGroup::create(
CreateAction::create(),
)
)
->addActionGroup(
ItemActionGroup::create(
UpdateAction::create(),
DeleteAction::create(),
// ShowAction::create(), // uncomment if a show page exists
)
)
->addActionGroup(
BulkActionGroup::create(
DeleteAction::create(),
)
)
->setLimits([10, 25, 50]) // items per page options
// ->orderBy('fieldName', 'asc') // only use a field declared in withFields()
<?php
declare(strict_types=1);
namespace App\Grid;
use App\Entity\{ModelName};
use Sylius\Bundle\GridBundle\Builder\Action\CreateAction;
use Sylius\Bundle\GridBundle\Builder\Action\DeleteAction;
use Sylius\Bundle\GridBundle\Builder\Action\UpdateAction;
use Sylius\Bundle\GridBundle\Builder\ActionGroup\BulkActionGroup;
use Sylius\Bundle\GridBundle\Builder\ActionGroup\ItemActionGroup;
use Sylius\Bundle\GridBundle\Builder\ActionGroup\MainActionGroup;
use Sylius\Bundle\GridBundle\Builder\Field\DateTimeField;
use Sylius\Bundle\GridBundle\Builder\Field\StringField;
use Sylius\Bundle\GridBundle\Builder\Field\TwigField;
use Sylius\Bundle\GridBundle\Builder\Filter\BooleanFilter;
use Sylius\Bundle\GridBundle\Builder\Filter\DateFilter;
use Sylius\Bundle\GridBundle\Builder\Filter\EntityFilter;
use Sylius\Bundle\GridBundle\Builder\Filter\StringFilter;
// Remove unused imports depending on what fields/filters are used
use Sylius\Bundle\GridBundle\Builder\GridBuilderInterface;
use Sylius\Bundle\GridBundle\Grid\AbstractGrid;
use Sylius\Component\Grid\Attribute\AsGrid;
#[AsGrid(
name: 'app_admin_{model_snake}',
resourceClass: {ModelName}::class,
)]
final class Admin{ModelName}Grid extends AbstractGrid
{
public function __invoke(GridBuilderInterface $gridBuilder): void
{
$gridBuilder
->withFields(
// add fields here
)
->withFilters(
// add filters here
)
->setLimits([10, 25, 50])
// ->orderBy('fieldName', 'asc') // only use a field declared in withFields()
->addActionGroup(
MainActionGroup::create(
CreateAction::create(),
)
)
->addActionGroup(
ItemActionGroup::create(
UpdateAction::create(),
DeleteAction::create(),
)
)
->addActionGroup(
BulkActionGroup::create(
DeleteAction::create(),
)
)
;
}
}
Create or update translations/messages.en.yaml. Use the pattern app.ui.{model_snake}.{field} — one key per field declared in the grid:
app:
ui:
{model_snake}:
{field_1}: '{Field 1 label}'
{field_2}: '{Field 2 label}'
Example for Book with fields title, description, price:
app:
ui:
book:
title: 'Title'
description: 'Description'
price: 'Price'
bin/console cache:clear
bin/console sylius:debug:grid 'App\Grid\Admin{ModelName}Grid'
The grid's fields, filters and actions should be printed.
/sylius-stack:add-operation Index to expose the grid as the admin index page/sylius-stack:add-menu once the index operation exists, to add it to the admin sidebar