From backpex
Creates Backpex resource actions for bulk operations (invitations, exports, imports, etc.) on the resource as a whole via index toolbar buttons with a slide-over form.
How this skill is triggered — by the user, by Claude, or both
Slash command
/backpex:create-resource-actionThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are an expert at creating resource actions for Backpex. Resource actions operate on the resource as a whole (not individual items) and appear as buttons in the index toolbar. They open a slide-over with a form.
You are an expert at creating resource actions for Backpex. Resource actions operate on the resource as a whole (not individual items) and appear as buttons in the index toolbar. They open a slide-over with a form.
| Callback | Signature | Description |
|---|---|---|
title/0 | -> string | Slide-over title |
label/0 | -> string | Button text in index toolbar |
fields/0 | -> keyword list | Form field definitions |
changeset/3 | (change, attrs, metadata) -> changeset | Validate form data. metadata has :assigns and :target keys |
handle/2 | (socket, data) -> {:ok, socket} | {:error, changeset} | Execute the action with validated data |
| Callback | Default | Description |
|---|---|---|
base_schema/1 | schemaless changeset | Override to use a real Ecto schema |
defmodule MyAppWeb.ResourceActions.InviteUser do
use Backpex.ResourceAction
import Ecto.Changeset
@impl Backpex.ResourceAction
def title, do: "Invite User"
@impl Backpex.ResourceAction
def label, do: "Invite"
@impl Backpex.ResourceAction
def fields do
[
email: %{
module: Backpex.Fields.Text,
label: "Email",
type: :string
},
role: %{
module: Backpex.Fields.Select,
label: "Role",
options: [Admin: "admin", User: "user"],
prompt: "Select role...",
type: :string
}
]
end
@impl Backpex.ResourceAction
def changeset(change, attrs, _metadata) do
change
|> cast(attrs, [:email, :role])
|> validate_required([:email, :role])
|> validate_format(:email, ~r/@/)
end
@impl Backpex.ResourceAction
def handle(socket, data) do
case MyApp.Accounts.send_invitation(data.email, data.role) do
:ok ->
{:ok, Phoenix.LiveView.put_flash(socket, :info, "Invitation sent to #{data.email}.")}
{:error, reason} ->
{:ok, Phoenix.LiveView.put_flash(socket, :error, "Failed: #{reason}")}
end
end
end
defmodule MyAppWeb.ResourceActions.ExportPosts do
use Backpex.ResourceAction
import Ecto.Changeset
@impl Backpex.ResourceAction
def title, do: "Export Posts"
@impl Backpex.ResourceAction
def label, do: "Export"
@impl Backpex.ResourceAction
def fields do
[
format: %{
module: Backpex.Fields.Select,
label: "Format",
options: [CSV: "csv", JSON: "json"],
prompt: "Select format...",
type: :string
}
]
end
@impl Backpex.ResourceAction
def changeset(change, attrs, _metadata) do
change
|> cast(attrs, [:format])
|> validate_required([:format])
|> validate_inclusion(:format, ["csv", "json"])
end
@impl Backpex.ResourceAction
def handle(socket, data) do
# Trigger export...
{:ok, Phoenix.LiveView.put_flash(socket, :info, "Export started in #{data.format} format.")}
end
end
@impl Backpex.LiveResource
def resource_actions do
[
invite: %{module: MyAppWeb.ResourceActions.InviteUser},
export: %{module: MyAppWeb.ResourceActions.ExportPosts}
]
end
The keyword key (e.g. :invite) is used as the action identifier for routing and authorization via can?/3.
| Aspect | Resource Action | Item Action |
|---|---|---|
| Scope | Whole resource | Selected items |
| UI | Slide-over form | Modal dialog |
| Callbacks | title/0, label/0, handle/2 | icon/2, label/2, handle/3 |
| Form | Always has fields | Optional |
| Location | Index toolbar only | Row, index toolbar, show page |
lib/my_app_web/resource_actions/<snake_case_name>.exMyAppWeb.ResourceActions.<ActionName>type: key in each field map (e.g. type: :string). This is required for the schemaless changeset to work.can?(assigns, :action_key, nil) in the LiveResource (item is always nil){:error, changeset} from handle/2 to keep the form open and show validation errorsnpx claudepluginhub naymspace/backpexGuides creation of custom Backpex item actions for table rows, show pages, and index toolbars, with support for server-side handle/3, client-side link/2, optional form modals, and confirm dialogs.
Generates FilamentPHP v4 actions for resources, pages, and tables including modals, confirmations, forms, and bulk operations.
Implements Umbraco backoffice collection actions as toolbar buttons for bulk operations like Create New or exports, via code execution or URL navigation using manifests and TypeScript classes from official docs.