Skip to content

add advanced sort_by support#105

Open
rommelfreddy wants to merge 1 commit into
storyblok:masterfrom
webidea24:task/sort-by
Open

add advanced sort_by support#105
rommelfreddy wants to merge 1 commit into
storyblok:masterfrom
webidea24:task/sort-by

Conversation

@rommelfreddy
Copy link
Copy Markdown

@rommelfreddy rommelfreddy commented May 27, 2026

Summary

This PR extends sort_by support in the Content API client so the SDK can represent the full Storyblok sorting syntax
used by the Content Delivery API.

It adds support for:

  • single sort definitions via SortBy
  • chained comma-separated sorts via SortByCollection
  • numeric sort modifiers via :float and :int`
  • null handling via :nulls_first and :nulls_last

Storyblok supports richer sort_by expressions than the SDK could previously express. In particular, the actual
implementation could not model:

  • chained sorts like name:desc,slug:asc
  • numeric modifiers like content.price:asc:float
  • null ordering like path:desc:nulls_first

This PR brings the SDK in line with the documented API behavior.

StoriesRequest now accepts:

public SortBy|SortByCollection|null $sortBy = null

This keeps the API compact and breaking-change-free while allowing both simple and advanced sorting scenarios.

What Changed

  • SortBy was extended to support:

    • field
    • direction
    • optional dataType
    • optional nulls
  • Added new enums:

    • SortByDataType
    • SortByNulls
  • Added SortByCollection to represent multiple sort definitions

  • Updated StoriesRequest::toArray() so sort_by is generated from either:

    • a single SortBy
    • or a SortByCollection

Examples

Simple default property sorting

new StoriesRequest(
    sortBy: new SortBy('created_at', Direction::Desc),
);

Results into

created_at:desc

Numeric sorting

new StoriesRequest(
    sortBy: new SortBy('content.price', Direction::Asc, SortByDataType::Float),
);
new StoriesRequest(
    sortBy: new SortBy('content.price', Direction::Asc, SortByDataType::Int),
);

Results into

content.price:asc:float
content.price:asc:int

Null handling:

new StoriesRequest(
    sortBy: new SortBy('path', Direction::Desc, null, SortByNulls::First),
);

new StoriesRequest(
    sortBy: new SortBy('path', Direction::Desc, null, SortByNulls::Last),
);

Results into

path:desc:nulls_first
path:desc:nulls_last

Multiple sorts:

new StoriesRequest(
    sortBy: new SortByCollection([
        new SortBy('name', Direction::Desc),
        new SortBy('slug', Direction::Asc),
    ]),
);

Results into

name:desc,slug:asc

Combined advanced sorts

$request = new StoriesRequest(
    sortBy: new SortByCollection([
        new SortBy('first_published_at', Direction::Desc, null, SortByNulls::Last),
        new SortBy('published_at', Direction::Desc, null, SortByNulls::Last),
        new SortBy('created_at', Direction::Desc),
    ]),
);

Results into

first_published_at:desc:nulls_last,published_at:desc:nulls_last,created_at:desc

Tests

Added/updated unit tests for:

  • SortBy
  • SortByCollection
  • StoriesRequest

Verified cases include:

  • simple sorting
  • advanced sorting with data type modifiers
  • null ordering
  • chained sorting serialization through StoriesRequest::toArray()

I didn't adjust the existing tests, because the changes are no breaking changes, so all other test still passes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant