Building the Ibexa website: Query Field Type
Websites and applications are full of lists of different types. The Ibexa DXP storage engine allows querying your custom data models using the search API. Historically queries have been done in the backend code, decoupling listings from the rest of the content model. With 3.0 we announced an altenative method: The Query Field Type
The Query Field Type is a new field type for our content engine. It allows defining content listings from within the database instead of the code. This links the content model closer to content listings, which are closely listed. For administrators working with the Query Field Type is identical to any field type like image or rich text fields.
Let's take the blog you're reading as a practical example. Blogs are built using two content types: blog and blog post. The parent blog is a container for child elements (like this post you're reading). Defining the post content type took a lion's share of the time needed to define and construct: it needs to have the necessary fields like headings, intro and images as well as metadata like tags and author relationships:
The container is really just a shell for all the posts and has very little content in it. This is reflected in the content structure which is simple and essentially just metadata:
The interesting part here is the labelled "Blog posts". This is a Query Field Type that executes a listing based on parameters. It allows defining relationships beyond the standard parent-child relationship we get as a side product of the tree structure. In the back end the field type has some configuration options unique to this field type:
The query type allows selecting a query type either from the built-in query types or alternatively custom ones you've created. Here we're using our our own query type to enable custom sorting (more on this later). The returned type defines what type of items are returned by the query type. This information is used to generate GraphQL API schemas automatically so you can use the query type for headless use cases.
The enable pagination and items per page fields are used to automatically provide pagination when the view is rendered on the server side. Finally, the parameters field allows you to pass parameters to the query type. These could be static per page, but also dynamic, based on the viewed location and content object. In our case, we are using the current location to enable multiple blogs, i.e. our main blog and the tech blog.
On the server side we are using a single shared query type for different use cases, this blog post listing being one and the latest blog posts at the end of the page being another. If you're curious, the main method of our BlogPostsQueryType is as follows:
public function getQuery(array $parameters = []): LocationQuery { $criteria = [ new Query\Criterion\Visibility(Query\Criterion\Visibility::VISIBLE), new Query\Criterion\ContentTypeIdentifier('blog_post'), ]; if (!empty($parameters['path_string'])) { $criteria[] = new Query\Criterion\Subtree($parameters['path_string']); } if (!empty($parameters['parent_location_id'])) { $criteria[] = new Query\Criterion\ParentLocationId($parameters['parent_location_id']); } if (!empty($parameters['excluded_post_ids'])) { $criteria[] = new Query\Criterion\LogicalNot( new Query\Criterion\ContentId($parameters['excluded_post_ids']) ); } $options = [ 'filter' => new Query\Criterion\LogicalAnd($criteria), 'sortClauses' => [ new SortClause\Field('blog_post', 'publish_date',Query::SORT_DESC) ] ]; return new LocationQuery($options); }
In addition to just simplifying our codebase and allowing tying listing definition to our content engine, using the query type also enables improved experience in the backend. Your query types might have different sorting than that of the standard content tree. This could lead to some confusion when working with data.
In our case we've hidden all the blog posts from tree structure and users use the query type listing view instead. This makes sure the administration sorting interface is always reflecting the public view. Because the sorting logic is shared between them.
The content query field type is a new approach for implementing listings of content and data in Ibexa DXP. We use this method all over the site where we need to list content and so far it has served us very well. For your next project I recommend you take a look at the documentation of the Content Query Field Type and view the Ibexa DXP v3.2 launch webinar for some details on the latest improvements.
Considerations for Creating Rich Customer Experiences
DXP eBook
If you are struggling with your B2B digital transformation efforts, why not reach out to us to discuss your project. Feel free to download and read Ibexa's eBook on Digital Experience Platforms and the four considerations for creating exceptional customer experiences.