---
url: /en/docs/collections/entries/views.md
description: >-
  Configure sorting, grouping and filtering options for the entry listing view
  of a Sveltia CMS entry collection.
---

# Entry Views

Sveltia CMS provides several options to customize how entries are displayed in the listing view. Users can sort, group, and filter entries based on specific fields to improve navigation and organization.

## Sorting

By default, Sveltia CMS supports sorting by `title`, `date`, `author` and `description` fields if they exist in the collection. If the `date` and `author` fields are not present, Sveltia CMS will look for commit date and author information from Git history (if available) to enable sorting by those fields.

When the [`summary` option](/en/docs/collections/entries/listings#summaries) is defined for a collection, Sveltia CMS also enables sorting by entry summaries. This allows you to sort entries based on the customized summary content, which can include multiple fields and string transformations.

When the [`reorder` option](/en/docs/collections/entries/operations#reordering-entries) is enabled for a collection, Sveltia CMS enables manual sorting of entries in the listing view. This allows users to drag and drop entries to reorder them as needed.

You can customize the sortable fields using the `sortable_fields` option. It accepts an array of field names that you want to enable for sorting in the entry listing view. It also accepts a special `slug` field to sort entries by their slugs.

The example below shows how to enable sorting by custom fields such as `category` and nested fields like `author.name`:

::: code-group

```yaml [YAML]{16}
collections:
  - name: posts
    label: Blog posts
    folder: /content/posts
    fields:
      - { name: title, label: Title }
      - { name: published_date, label: Published Date, widget: datetime }
      - {
          name: author,
          label: Author,
          widget: object,
          fields: [{ name: name, label: Name }, { name: email, label: Email }],
        }
      - { name: category, label: Category }
      - { name: body, label: Body, widget: richtext }
    sortable_fields: [title, published_date, author.name, category]
```

```toml [TOML]{5}
[[collections]]
name = "posts"
label = "Blog posts"
folder = "/content/posts"
sortable_fields = ["title", "published_date", "author.name", "category"]

[[collections.fields]]
name = "title"
label = "Title"

[[collections.fields]]
name = "published_date"
label = "Published Date"
widget = "datetime"

[[collections.fields]]
name = "author"
label = "Author"
widget = "object"

[[collections.fields.fields]]
name = "name"
label = "Name"

[[collections.fields.fields]]
name = "email"
label = "Email"

[[collections.fields]]
name = "category"
label = "Category"

[[collections.fields]]
name = "body"
label = "Body"
widget = "richtext"
```

```json [JSON]{22}
{
  "collections": [
    {
      "name": "posts",
      "label": "Blog posts",
      "folder": "/content/posts",
      "fields": [
        { "name": "title", "label": "Title" },
        { "name": "published_date", "label": "Published Date", "widget": "datetime" },
        {
          "name": "author",
          "label": "Author",
          "widget": "object",
          "fields": [
            { "name": "name", "label": "Name" },
            { "name": "email", "label": "Email" }
          ]
        },
        { "name": "category", "label": "Category" },
        { "name": "body", "label": "Body", "widget": "richtext" }
      ],
      "sortable_fields": ["title", "published_date", "author.name", "category"]
    }
  ]
}
```

```js [JavaScript]{17}
{
  collections: [
    {
      name: "posts",
      label: "Blog posts",
      folder: "/content/posts",
      fields: [
        { name: "title", label: "Title" },
        { name: "published_date", label: "Published Date", widget: "datetime" },
        { name: "author", label: "Author", widget: "object", fields: [
          { name: "name", label: "Name" },
          { name: "email", label: "Email" },
        ] },
        { name: "category", label: "Category" },
        { name: "body", label: "Body", widget: "richtext" },
      ],
      sortable_fields: ["title", "published_date", "author.name", "category"],
    },
  ],
}
```

:::

::: info Extended syntax

Sveltia CMS supports an extended syntax used in [Static CMS](https://staticjscms.netlify.app/docs/collection-overview#sortable-fields) to define a default sort field and direction. This is useful if you want entries to be sorted by a date field in descending order by default. Here is the same configuration using the extended syntax:

```yaml
sortable_fields:
  fields: [title, published_date, author.name, category]
  default:
    field: published_date
    direction: descending
```

The default direction is `ascending` if not specified.

For backward compatibility with Static CMS, the `direction` option accepts title case values: `Ascending` and `Descending`. However, `None` is not supported and has the same effect as `ascending`.

:::

::: info Known issue

Git commit information is not available with the GitLab backend due to API limitations.

:::

## Grouping

The `view_groups` option allows you to group entries in the listing view based on specific field values. This is useful for organizing entries into categories or sections for easier navigation.

The example below demonstrates how to group blog posts by their `draft` status and by the year extracted from the `date` field:

::: code-group

```yaml [YAML]{10-15}
collections:
  - name: posts
    label: Blog posts
    folder: /content/posts
    fields:
      - { name: title, label: Title }
      - { name: date, label: Published Date, widget: datetime }
      - { name: draft, label: Draft, widget: boolean }
      - { name: body, label: Body, widget: richtext }
    view_groups:
      - field: draft
      - label: Drafts
        field: date
        label: Year
        pattern: '\d{4}'
```

```toml [TOML]{25-32}
[[collections]]
name = "posts"
label = "Blog posts"
folder = "/content/posts"

[[collections.fields]]
name = "title"
label = "Title"

[[collections.fields]]
name = "date"
label = "Published Date"
widget = "datetime"

[[collections.fields]]
name = "draft"
label = "Draft"
widget = "boolean"

[[collections.fields]]
name = "body"
label = "Body"
widget = "richtext"

[[collections.view_groups]]
label = "Drafts"
field = "draft"

[[collections.view_groups]]
label = "Year"
field = "date"
pattern = "\\d{4}"
```

```json [JSON]{13-23}
{
  "collections": [
    {
      "name": "posts",
      "label": "Blog posts",
      "folder": "/content/posts",
      "fields": [
        { "name": "title", "label": "Title" },
        { "name": "date", "label": "Published Date", "widget": "datetime" },
        { "name": "draft", "label": "Draft", "widget": "boolean" },
        { "name": "body", "label": "Body", "widget": "richtext" }
      ],
      "view_groups": [
        {
          "label": "Drafts",
          "field": "draft"
        },
        {
          "label": "Year",
          "field": "date",
          "pattern": "\\d{4}"
        }
      ]
    }
  ]
}
```

```js [JavaScript]{13-23}
{
  collections: [
    {
      name: "posts",
      label: "Blog posts",
      folder: "/content/posts",
      fields: [
        { name: "title", label: "Title" },
        { name: "date", label: "Published Date", widget: "datetime" },
        { name: "draft", label: "Draft", widget: "boolean" },
        { name: "body", label: "Body", widget: "richtext" },
      ],
      view_groups: [
        {
          label: "Drafts",
          field: "draft",
        },
        {
          label: "Year",
          field: "date",
          pattern: "\\d{4}",
        },
      ],
    },
  ],
}
```

:::

::: info Extended syntax

Sveltia CMS supports an extended syntax used in [Static CMS](https://staticjscms.netlify.app/docs/collection-overview#view-groups) to define a default group. Here is the same configuration using the extended syntax:

```yaml
view_groups:
  groups:
    - name: drafts
      label: Drafts
      field: draft
    - name: year
      label: Year
      field: date
      pattern: '\d{4}'
  default: year
```

The `default` option has to be the `name` of one of the `groups`; any other name is reported as a config validation error on the login screen, as the collection would otherwise open ungrouped.

To sort the Year group in descending order by date, you can add the `sortable_fields` property as described in the [Sorting](#sorting) section above:

```yaml
sortable_fields:
  fields: [date, title]
  default:
    field: date
    direction: descending
```

:::

A named view group can also be used with the [`reorder` option](/en/docs/collections/entries/operations#reordering-within-groups) to let editors reorder entries within their own group.

### Grouping by a Comparison

A view group can also split the entries by a comparison, using the same options as a [view filter](#comparing-values). The entries satisfying the condition are grouped under the group’s `label`, and the other entries under “Other”. For example, the following group lists the upcoming events first, followed by the past and undated ones:

```yaml
view_groups:
  - label: Upcoming
    field: date
    gte: '{{today}}'
```

## Filtering

The `view_filters` option allows you to define preset filters that editors can quickly apply to the entry listing view. This is useful for quickly accessing specific subsets of entries based on common criteria.

::: code-group

```yaml [YAML]{11-20}
collections:
  - name: posts
    label: Blog posts
    folder: /content/posts
    fields:
      - { name: title, label: Title }
      - { name: date, label: Published Date, widget: datetime }
      - { name: draft, label: Draft, widget: boolean }
      - { name: category, label: Category }
      - { name: body, label: Body, widget: richtext }
    view_filters:
      - label: Drafts
        field: draft
        pattern: true
      - label: Posts from 2024
        field: date
        pattern: '^2024'
      - label: Travel or Food
        field: category
        pattern: travel|food
```

```toml [TOML]{29-42}
[[collections]]
name = "posts"
label = "Blog posts"
folder = "/content/posts"

[[collections.fields]]
name = "title"
label = "Title"

[[collections.fields]]
name = "date"
label = "Published Date"
widget = "datetime"

[[collections.fields]]
name = "draft"
label = "Draft"
widget = "boolean"

[[collections.fields]]
name = "category"
label = "Category"

[[collections.fields]]
name = "body"
label = "Body"
widget = "richtext"

[[collections.view_filters]]
label = "Drafts"
field = "draft"
pattern = "true"

[[collections.view_filters]]
label = "Posts from 2024"
field = "date"
pattern = "^2024"

[[collections.view_filters]]
label = "Travel or Food"
field = "category"
pattern = "travel|food"
```

```json [JSON]{14-30}
{
  "collections": [
    {
      "name": "posts",
      "label": "Blog posts",
      "folder": "/content/posts",
      "fields": [
        { "name": "title", "label": "Title" },
        { "name": "date", "label": "Published Date", "widget": "datetime" },
        { "name": "draft", "label": "Draft", "widget": "boolean" },
        { "name": "category", "label": "Category" },
        { "name": "body", "label": "Body", "widget": "richtext" }
      ],
      "view_filters": [
        {
          "label": "Drafts",
          "field": "draft",
          "pattern": "true"
        },
        {
          "label": "Posts from 2024",
          "field": "date",
          "pattern": "^2024"
        },
        {
          "label": "Travel or Food",
          "field": "category",
          "pattern": "travel|food"
        }
      ]
    }
  ]
}
```

```js [JavaScript]{14-30}
{
  collections: [
    {
      name: "posts",
      label: "Blog posts",
      folder: "/content/posts",
      fields: [
        { name: "title", label: "Title" },
        { name: "date", label: "Published Date", widget: "datetime" },
        { name: "draft", label: "Draft", widget: "boolean" },
        { name: "category", label: "Category" },
        { name: "body", label: "Body", widget: "richtext" },
      ],
      view_filters: [
        {
          label: "Drafts",
          field: "draft",
          pattern: "true",
        },
        {
          label: "Posts from 2024",
          field: "date",
          pattern: "^2024",
        },
        {
          label: "Travel or Food",
          field: "category",
          pattern: "travel|food",
        },
      ],
    },
  ],
}
```

:::

::: info Extended syntax

Sveltia CMS supports an extended syntax used in [Static CMS](https://staticjscms.netlify.app/docs/collection-overview#view-filters) to define a default filter. Here is the same configuration using the extended syntax:

```yaml
view_filters:
  filters:
    - name: drafts
      label: Drafts
      field: draft
      pattern: true
    - name: posts_2024
      label: Posts from 2024
      field: date
      pattern: '^2024'
    - name: travel_or_food
      label: Travel or Food
      field: category
      pattern: travel|food
  default: drafts
```

The `default` option has to be the `name` of one of the `filters`; any other name is reported as a config validation error on the login screen, as the collection would otherwise open unfiltered.

:::

### Comparing Values

A view filter can compare the field value with a given value instead of, or in addition to, matching a `pattern`. This makes it possible to filter entries by a date, such as upcoming and past events, or by a number, such as products above a certain price. The following options are available:

| Option   | Description                                                                         |
| -------- | ----------------------------------------------------------------------------------- |
| `eq`     | The field value has to be equal to the given value.                                 |
| `ne`     | The field value has to be different from the given value.                           |
| `lt`     | The field value has to be less than the given value.                                |
| `lte`    | The field value has to be less than or equal to the given value.                    |
| `gt`     | The field value has to be greater than the given value.                             |
| `gte`    | The field value has to be greater than or equal to the given value.                 |
| `in`     | The field value has to be equal to one of the given values, defined as an array.    |
| `not_in` | The field value has to be different from all the given values, defined as an array. |

The value of a DateTime field is compared as a date, so the given value has to be in the same format as the field value, or one of the following template tags:

| Tag                                                                        | Description                                                                                                                                                         |
| -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `{{now}}`                                                                  | The current date and time.                                                                                                                                          |
| `{{today}}`                                                                | The current date in the `YYYY-MM-DD` format. Use this rather than `{{now}}` with a date-only field, so that an entry dated today is included in a `gte` comparison. |
| `{{year}}`, `{{month}}`, `{{day}}`, `{{hour}}`, `{{minute}}`, `{{second}}` | The parts of the current date and time, which can also be used in a `pattern`, e.g. `^{{year}}` for the entries of this year.                                       |

The tags are resolved in the user’s local time zone whenever the entry list is updated, and every minute while such a filter or group is applied, so a filter like “Upcoming events” keeps working without any change to the configuration.

A number field value and a numeric given value are compared as numbers; any other value is compared as a string. An entry without a value for the field only matches `ne` and `not_in`. When several options are defined for one filter, all of them have to be satisfied.

The comparison options can also be used with the [extended syntax](#filtering) described above, for example to apply the “Upcoming” filter by default:

```yaml
view_filters:
  filters:
    - name: upcoming
      label: Upcoming
      field: date
      gte: '{{today}}'
    - name: past
      label: Past
      field: date
      lt: '{{today}}'
  default: upcoming
```

The example below defines the filters for a list of events:

::: code-group

```yaml [YAML]{10-24}
collections:
  - name: events
    label: Events
    folder: /content/events
    fields:
      - { name: title, label: Title }
      - { name: date, label: Date, widget: datetime, time_format: false }
      - { name: capacity, label: Capacity, widget: number }
      - { name: status, label: Status, widget: select, options: [scheduled, cancelled] }
    view_filters:
      - label: Upcoming
        field: date
        gte: '{{today}}'
      - label: Past
        field: date
        lt: '{{today}}'
      - label: This year
        field: date
        pattern: '^{{year}}'
      - label: Large venues
        field: capacity
        gte: 100
      - label: Not cancelled
        field: status
        ne: cancelled
```

```toml [TOML]{28-51}
[[collections]]
name = "events"
label = "Events"
folder = "/content/events"

[[collections.fields]]
name = "title"
label = "Title"

[[collections.fields]]
name = "date"
label = "Date"
widget = "datetime"
time_format = false

[[collections.fields]]
name = "capacity"
label = "Capacity"
widget = "number"

[[collections.fields]]
name = "status"
label = "Status"
widget = "select"
options = ["scheduled", "cancelled"]

[[collections.view_filters]]
label = "Upcoming"
field = "date"
gte = "{{today}}"

[[collections.view_filters]]
label = "Past"
field = "date"
lt = "{{today}}"

[[collections.view_filters]]
label = "This year"
field = "date"
pattern = "^{{year}}"

[[collections.view_filters]]
label = "Large venues"
field = "capacity"
gte = 100

[[collections.view_filters]]
label = "Not cancelled"
field = "status"
ne = "cancelled"
```

```json [JSON]{13-39}
{
  "collections": [
    {
      "name": "events",
      "label": "Events",
      "folder": "/content/events",
      "fields": [
        { "name": "title", "label": "Title" },
        { "name": "date", "label": "Date", "widget": "datetime", "time_format": false },
        { "name": "capacity", "label": "Capacity", "widget": "number" },
        { "name": "status", "label": "Status", "widget": "select", "options": ["scheduled", "cancelled"] }
      ],
      "view_filters": [
        {
          "label": "Upcoming",
          "field": "date",
          "gte": "{{today}}"
        },
        {
          "label": "Past",
          "field": "date",
          "lt": "{{today}}"
        },
        {
          "label": "This year",
          "field": "date",
          "pattern": "^{{year}}"
        },
        {
          "label": "Large venues",
          "field": "capacity",
          "gte": 100
        },
        {
          "label": "Not cancelled",
          "field": "status",
          "ne": "cancelled"
        }
      ]
    }
  ]
}
```

```js [JavaScript]{13-39}
{
  collections: [
    {
      name: "events",
      label: "Events",
      folder: "/content/events",
      fields: [
        { name: "title", label: "Title" },
        { name: "date", label: "Date", widget: "datetime", time_format: false },
        { name: "capacity", label: "Capacity", widget: "number" },
        { name: "status", label: "Status", widget: "select", options: ["scheduled", "cancelled"] },
      ],
      view_filters: [
        {
          label: "Upcoming",
          field: "date",
          gte: "{{today}}",
        },
        {
          label: "Past",
          field: "date",
          lt: "{{today}}",
        },
        {
          label: "This year",
          field: "date",
          pattern: "^{{year}}",
        },
        {
          label: "Large venues",
          field: "capacity",
          gte: 100,
        },
        {
          label: "Not cancelled",
          field: "status",
          ne: "cancelled",
        },
      ],
    },
  ],
}
```

:::
