Element index page¶
The biggest win for a plugin that manages its own element type: don’t rebuild the listing UI — extend Craft’s. A one-line template gives you sources, search, filters, view modes, pagination, and bulk actions. This is exactly how the Shopify plugin lists products.
All productsActiveDraftArchived
| Title | Status | Options | Variants |
|---|---|---|---|
| Field Notes Notebook | Active | Color Size | 4 |
| Enamel Pin | Draft | Style | 2 |
templates/products/_index.twig
{% extends "_layouts/elementindex" %}
{% set title = "Products"|t("my-plugin") %}
{% set elementType = "myplugin\\elements\\Product" %}
{# Add your own toolbar button without losing Craft's #}
{% block toolbar %}
{{ parent() }}
<a class="btn submit" data-icon="external" href="{{ newProductUrl }}">
{{ "New Product"|t("my-plugin") }}
</a>
{% endblock %}
Note
Custom columns. Define the columns in your element class with defineTableAttributes(), then render each cell by overriding attributeHtml($attribute) — return a status label, an external-link icon (Html::a('', $url, ['data' => ['icon' => 'external']])), or plain text. That’s the entire recipe behind the Shopify products table above.