Netgen’s Site API for eZ Platform

Introduction

The intention of this page is to give you a short overview of what Site API is. For that purpose we can break the whole package into three main parts:

  1. Dedicated API layer
  2. Integration with eZ Platform
  3. Query Types

Dedicated API layer

As Repository API was designed to be usable for general purpose, it can come as awkward and too verbose when used for building websites. Site API fixes this by implementing a dedicated API layer on top of eZ Platform Repository API which is designed for developing websites.

Having a dedicated layer enables us to take an extra step and do things you would not typically want to do in Repository API. With Site API we can we can implement lazy loaded properties and methods that enable content model traversal directly from the entities because:

  1. it’s a dedicated layer for building websites

  2. it’s not intended to be layered (meaning no different API implementations
    like Cache, Permission etc)

Handling multiple languages

The way Site API handles multiple languages was the initial motive for implementing it and deserves to be mentioned separately.

Language configuration for a siteaccess consists of a prioritized list of languages. For example, you could have a siteaccess with two languages, Croatian language as the most prioritized one and English language as a fallback when Croatian translation does not exist:

ezpublish:
    system:
        cro:
            languages:
                - 'cro-HR'
                - 'eng-GB'

The intention here is that the siteaccess should first show content in Croatian language if it’s available, fallback to English translation when Croatian is not available and ignore any other language. However, this is quite hard to implement correctly with vanilla Repository API, even with the newest addition of siteaccess-aware Repository layer introduced in eZ Platform 7.2.

With Site API this comes out of the box and you don’t have to pay special attention to it. All possible ways to get a Content or a Location, whether through loading by ID, as a related Content, accessing the field on the parent Location’s Content, searching or using methods and properties on the Site API objects – it already respects this configuration. You can depend that you will always get back only what can and should be rendered on the current siteaccess and then simply stop caring about it, because it just works.

That feature alone significantly reduces cognitive load for developers, frees them from writing tedious boilerplate code just to respect the language configuration, avoids ridiculous sanity checks and mistakes and improves the overall developer experience.

Objects

Site API entities and values are similar to their counterparts in eZ Platform’s Repository API:

  • Content

    The first difference from Repository Content is that it exist in a single translation, meaning it contains the fields for only one translation. That translation will always be the correct one to be rendered, resolved from the language configuration of the siteaccess. You won’t need to choose the field in the correct translation, manually or through some kind of helper service. The Content’s single translation is always the correct one.

    Content fields are lazy-loaded, which means they are loaded only if accessed. This voids the need to have a separate, light version of Content (ContentInfo in Repository API). Content object also provides properties and methods to enable access to Content’s Locations and relations. Example usage from Twig:

    <h1>{{ content.name }}</h1>
    <h2>Parent name: {{ content.mainLocation.parent.content.name }}</h2>
    <h3>Number of Locations: {{ content.locations|length }}</h3>
    
    {{ ng_render_field(content.fields.title) }}
    
    <ul>
        {% for relation in content.fieldRelations('articles') %}
            <li>{{ relation.title }}</li>
        {% endfor %}
    </ul>
    
  • ContentInfo

    The purpose of ContentInfo object in Repository API is to provide a lightweight version of Content object, containing only metadata (and omitting the fields). Since in Site API Content’s fields are lazy-loaded, there is no real need for ContentInfo. Still, Site API provides it to keep the usage in templates similar to standard eZ Platform templates and through that make the migration and comparison easier.

    Site ContentInfo also provides access to data that is in Repository API available only through loading other objects, like ContentType identifier. Example usage from Twig:

    <h2>Section ID: {{ content.contentInfo.sectionId }}</h2>
    <h2>ContentType identifier: {{ content.contentInfo.contentTypeIdentifier }}</h2>
    

    Note

    In Site API it is not possible to load ContentInfo directly.
    It is only available through properties on Content and Location objects.
  • Location

    Site Location is similar to Repository Location. It provides properties and methods to enable simple Location tree traversal (siblings, children, parents, ancestors etc). Example usage from Twig:

    <h1>{{ location.content.name }} - Articles</h1>
    <h2>Parent: {{ location.parent.content.name }}</h2>
    <h3>Grandparent: {{ location.parent.parent.content.name }}</h3>
    
    {% set children = location.filterChildren(['article']) %}
    
    <ul>
    {% for child in children %}
        <li>{{ child.content.name }}</li>
    {% endfor %}
    </ul>
    
    {{ pagerfanta( children, 'twitter_bootstrap' ) }}
    
  • Field

    Field object aggregates some properties from its FieldDefinition, like FieldType identifier, name and description. It also implements isEmpty() method, which makes simple to check if the field value is empty, without requiring external helpers. Example usage from Twig:

    <h1>{{ content.fields.title.name }}</h1>
    <p>You can access the value directly: {{ content.fields.title.value.text }}</p>
    
    {% if not content.fields.title.empty %}
        <p>{{ ng_render_field( content.fields.title ) }}</p>
    {% endif %}
    
    {% set image = content.fields.image %}
    {% if not image.empty %}
        <img src="{{ ng_image_alias( image, 'i1140' ).uri }}"
             alt="{{ image.value.alternativeText }}" />
    {% endif %}
    

For your convenience all objects contain their corresponding Repository objects in properties prefixed with inner. Example usage from Twig:

<h1>Content ID: {{ content.innerContent.id }}</h1>
<h2>Location ID: {{ location.innerLocation.id }}</h2>
<h3>Field ID: {{ field.innerField.id }}</h3>

For more details see Templating and Objects reference pages.

Services

The API provides you with a set of read-only services:

  1. LoadService
Provides methods to load Content and Locations by ID (and remote ID):
  1. FindService
Provides methods to find Content and Locations using eZ Platform Repository Search API.
  1. FilterService

This is quite similar to the FindService, but only works with Legacy search engine, even if that is not the configured engine for the repository.

Why? While Solr search engine provides more features and more performance than Legacy search engine, it’s a separate system needs to be synchronized with changes in the database. This synchronization comes with a delay, which can be a problem in some cases.

FilterService gives you access to search that is always up to date, because it uses Legacy search engine that works directly with database. At the same time, search on top of Solr, with all the advanced features (like fulltext search or facets) is still available through FindService.

  1. RelationService
Provides methods for loading relations.

All services return only published Content and handle translations in a completely transparent way. Language fallback configuration for the current siteaccess is automatically taken into account and you will always get back only what should be rendered on the siteaccess. If the available translation is not configured for a siteaccess, you won’t be able to find or load Content or Location. The services will behave as if it does not exist.

Note

All of the Site API services are read-only. If you need to write to the eZ Platform’s content repository, use its existing Repository API.

For more details see Services reference page.

Integration with eZ Platform

You can use the Site API services described above as you would normally do it a Symfony application. But these are also integrated into eZ Platform’s view layer. There is a Site API version of the view configuration, available under ngcontent_view key:

ezpublish:
    system:
        frontend_group:
            ngcontent_view:
                line:
                    article:
                        template: "@NetgenSite/content/line/article.html.twig"
                        match:
                            Identifier\ContentType: article

Aside from Query Type configuration described below, the format is exactly the same as eZ Platform’s view configuration under content_view key. Separate view configuration is also needed because we need to handle it with code that will inject Site API objects to the template, instead of standard eZ Platform objects. Together with this we provide Site API version of the Content View object, which is used by the default Content view controller and custom controllers.

With the configuration from above you you will be able to render a line view for an article by executing a request to ng_content:viewAction. However, that does not mean URL aliases will be handled by the Site API view configuration as well. This needs to be explicitly enabled, per siteaccess:

netgen_ez_platform_site_api:
    system:
        frontend_group:
            override_url_alias_view_action: true

Note

You can use the Site API’s view configuration and eZ Platform’s view configuration at the same time. However, URL aliases can be handled exclusively by the one or the other.

For more details see Configuration reference page.

Query Types

Query Types provide a set of predefined queries that can be configured for a specific view, as part of the view configuration under ngcontent_view key. It also provides a system for developing new queries inheriting common functionality.

While they can be used from PHP, main intention is to use them from the view configuration. This is best explained with an example:

ezpublish:
    system:
        frontend_group:
            ngcontent_view:
                full:
                    folder:
                        template: '@ezdesign/content/full/folder.html.twig'
                        match:
                            Identifier\ContentType: folder
                        queries:
                            children_documents:
                                query_type: SiteAPI:Location/Children
                                max_per_page: 10
                                page: '@=queryParam("page", 1)'
                                parameters:
                                    content_type: document
                                    section: restricted
                                    sort: priority desc

Other side of the configuration from the example above is full view folder template:

{% set documents = ng_query( 'children_documents' ) %}

<h3>Documents in this folder</h3>

<ul>
{% for document in documents %}
    <li>{{ document.name }}</li>
{% endfor %}
</ul>

{{ pagerfanta( documents, 'twitter_bootstrap' ) }}

If you used Legacy eZ Publish, this is similar to template fetch function. Important difference is that in Legacy you used template fetch functions to pull the data into the template. Instead, with Site API Query Types you push the data to the template. This keeps the logic out of the templates and gives you better control and overview.

For more details see Query Types reference page.

Site API is a lightweight layer built on top of eZ Platform’s Repository API. Its purpose is to solve common use cases, remove boilerplate code and provide better developer experience for building websites. While it will make PHP developers more productive, it will also lower the entry barrier for newcomers and open most of the development process to roles other than PHP developer.

With it, frontend developers, content builders and others will be able to do most of the work related to eZ Platform content modelling, independently of PHP developers and without the need to work with PHP. They will require only knowledge of eZ Platform’s content model, Twig templates and view configuration in YAML.

If you are new to Site API, read the Introduction first.

Reference

Reference

Installation

To install Site API first add it as a dependency to your project:

$ composer require netgen/ezplatform-site-api

Once Site API is installed, activate the bundle in app/AppKernel.php file by adding it to the $bundles array in registerBundles() method, together with other required bundles:

public function registerBundles()
{
    //...

    $bundles[] = new Netgen\Bundle\EzPlatformSiteApiBundle\NetgenEzPlatformSiteApiBundle();
    $bundles[] = new Netgen\Bundle\EzPlatformSearchExtraBundle\NetgenEzPlatformSearchExtraBundle();

    return $bundles;
}

And that’s it. Once you finish the installation you will be able to use Site API services as you would normally do in a Symfony application. However, at this point Site API is not yet fully enabled. That is done per siteaccess, see Configuration page to learn more.

Configuration

Site API has its own view configuration, available under ngcontent_view key. Aside from Query Type configuration that is documented separately, this is exactly the same as eZ Platform’s default view configuration under content_view key. You can use this configuration right after the installation, but note that it won’t be used for full views rendered for eZ Platform URL aliases right away. Until you configure that, it will be used only when calling its controller explicitly with ng_content:viewAction.

Content on this page:

Configure handling of URL aliases

To use Site API view rules for pages rendered from eZ Platform URL aliases, you have to enable it for a specific siteaccess with the following semantic configuration:

netgen_ez_platform_site_api:
    system:
        frontend_group:
            override_url_alias_view_action: true

Here frontend_group is the siteaccess group (or a siteaccess) for which you want to activate the Site API. This switch is useful if you have a siteaccess that can’t use the it, for example a custom admin or intranet interface.

Note

To use Site API view configuration automatically on pages rendered from eZ Platform URL aliases, you need to enable it manually per siteaccess.

Site API Content views

Once you enable override_url_alias_view_action for a siteaccess, all your full view templates and controllers will need to use Site API to keep working. They will be resolved from Site API view configuration, available under ngcontent_view key. That means Content and Location variables inside Twig templates will be instances of Site API Content and Location value objects, $view variable passed to your custom controllers will be an instance of Site API ContentView variable, and so on.

If needed you can still use content_view rules. This will allow you to have both Site API template override rules as well as original eZ Platform template override rules, so you can rewrite your templates bit by bit. You can decide which one to use by calling either ng_content:viewAction or ez_content:viewAction controller.

Tip

View configuration is the only eZ Platform configuration regularly edited
by frontend developers.

For example, if using the following configuration:

ezpublish:
    system:
        frontend_group:
            ngcontent_view:
                line:
                    article:
                        template: '@App/content/line/article.html.twig'
                        match:
                            Identifier\ContentType: article
            content_view:
                line:
                    article:
                        template: '@App/content/line/ez_article.html.twig'
                        match:
                            Identifier\ContentType: article

Rendering a line view for an article with ng_content:viewAction would use @App/content/line/article.html.twig template, while rendering a line view for an article with ez_content:viewAction would use @App/content/line/ez_article.html.twig template.

It is also possible to use custom controllers, this is documented on Custom controllers reference documentation page.

Redirections

With Site API, it’s also possible to configure redirects directly from the view configuration. You can set up temporary or permanent redirect to either Content, Location, Tag, Symfony route or any full url.

For the target configuration you can use expression language, meaning it is easily possible to redirect, for example, to the parent of the current location, or to the named object.

Example configuration:

ezpublish:
    system:
        frontend_group:
            ngcontent_view:
                container:
                    redirect:
                        target: "@=location.parent"
                        target_parameters:
                            foo: bar
                        permanent: false
                    match:
                        Identifier\ContentType: container
                article:
                    redirect:
                        target: "@=namedObject.getLocation('homepage')"
                        target_parameters:
                            foo: bar
                            siteaccess: cro
                        permanent: true
                        absolute: true
                    match:
                        Identifier\ContentType: article
                category:
                    redirect:
                        target: '@=location.getChildren(1)[0]'
                        permanent: true
                    match:
                        Identifier\ContentType: category
                news:
                    redirect:
                        target: 'login'
                        target_parameters:
                            foo: bar
                        permanent: false
                    match:
                        Identifier\ContentType: news
                blog:
                    redirect:
                        target: 'https://netgen.io'
                    match:
                        Identifier\ContentType: blog

There also shortcuts available for simplified configuration:

ezpublish:
    system:
        frontend_group:
            ngcontent_view:
                container:
                    temporary_redirect: "@=namedObject.getTag('running')"
                    match:
                        Identifier\ContentType: container
                category:
                    permanent_redirect: "@=content.getFieldRelation('internal_redirect')"
                    match:
                        Identifier\ContentType: container

Note

Configuration of named objects is documented in more detail below.

Shortcut functions are available for accessing each type of named object directly:

  • namedContent(name)

    Provides access to named Content.

  • namedLocation(name)

    Provides access to named Location.

  • namedTag(name)

    Provides access to named Tag.

Named objects

Named objects feature provides a way to configure specific objects (Content, Location and Tag) by name and ID, and a way to access them by name from PHP, Twig and Query Type configuration.

Example configuration:

netgen_ez_platform_site_api:
    system:
        frontend_group:
            named_objects:
                content:
                    certificate: 42
                    site_info: 'abc123'
                location:
                    homepage: 2
                    articles: 'zxc456'
                tag:
                    categories: 24
                    colors: 'bnm789'

From the example, certificate and site_info are names of Content objects, homepage and articles are names of Location objects and categories and colors are names of Tag objects. The example also shows it’s possible to use both a normal ID (integer) or remote ID (string). In fact, it shows a short syntax, where the type of ID is inferred from the type, while full syntax equivalent to the above would be:

netgen_ez_platform_site_api:
    system:
        frontend_group:
            named_objects:
                content:
                    certificate:
                        id: 42
                    site_info:
                        remote_id: 'abc123'
                location:
                    homepage:
                        id: 2
                    articles:
                        remote_id: 'zxc456'
                tag:
                    categories:
                        id: 24
                    colors:
                        remote_id: 'bnm789'
Accessing named objects
Content Field inconsistencies

Sometimes when the content model is changed or for any reason the data is not consistent, it can happen that some Content Fields are missing. In case of content model change that is a temporary situation lasting while the data is being updated in the background. But even in the case of inconsistent database, typically you do not want that to result in site crash.

To account for this Site API provides the following semantic configuration:

netgen_ez_platform_site_api:
    system:
        frontend_group:
            fail_on_missing_fields: true
            render_missing_field_info: false

By default fail_on_missing_fields is set to %kernel.debug% container parameter, which means accessing a nonexistent field in dev environment will fail and result in a RuntimeException.

On the other hand, when not in debug mode (in prod environment), the system will not crash, but will instead return a special Surrogate type field, which always evaluates as empty and renders to an empty string. In this case, a critical level message will be logged, so you can find and fix the problem.

Second configuration option render_missing_field_info controls whether Surrogate field will render as an empty string or it will render useful debug information. By default its value is false, meaning it will render as an empty string. That behavior is also what you should use in the production environment. Setting this option to true can be useful in debug mode, together with setting fail_on_missing_fields to false, as that will provide a visual cue about the missing field without the page crashing and without the need to go into the web debug toolbar to find the logged message.

Note

You can configure both render_missing_field_info and fail_on_missing_fields per siteaccess or siteaccess group.

Templating

Site API objects are used directly in the templates. Below you will find examples for the most common use cases. Objects are documented in more detail on Objects reference documentation page.

Content on this page:

Content rendering

Site API provides three Twig functions for content rendering:

  • ng_view_content

    Warning

    Twig function ng_view_content is considered to be experimental. Once the correct behavior is confirmed in practice, this warning will be removed.

    This function provides a way to render Content view without executing a subrequest. The idea is to avoid bad performance of subrequests in debug mode. Because of profiling that is active in debug mode, having a lots of subrequests on a page can significantly affect performance and memory consumption. Since for a large part of use cases it’s not necessary to render Content views through a subrequest, having an alternative way to render them can improve performance and hence developer’s experience.

    The function can be used for views defined in Site API view configuration and it supports custom controllers.

    Note

    This function is not a complete replacement for rendering Content views, since it does not dispatch MVC events from eZ Publish Kernel, like MVCEvents::PRE_CONTENT_VIEW. For that reason it’s safe to use only for those views that don’t depend on them. This should be the case for most of them.

    Depending on the use case, you might be able to replace usage of MVC events with ViewEvents from eZ Publish Kernel, which are dispatched by ng_view_content.

    The function accepts four parameters, similar as parameters available for ez_content:viewAction controller:

    1. required Content or Location object
    2. required string view identifier (e.g. line, block)
    3. optional array of parameters, with keys as parameter names and corresponding values as parameter values

    Parameters defined through this array will be available as Request attributes and can be passed as arguments to the controller action if defined there. Also, parameter with name params is recognized as an array of custom view parameters and will be available in the view object and in the rendered template.

    1. optional boolean value indicating whether to render the template in the configured layout, by default false

    Example usage:

    {{ ng_view_content(
        content,
        'line',
        {
            'foo': 'bar',
            'params': {
                'custom': 'view param'
            }
        },
        false
    ) }}
    

    The example above is intended to replace the following Content view render through the subrequest:

    {{ render(
        controller(
            'ng_content:viewAction', {
                'contentId': content.id,
                'viewType': 'line',
                'layout': false,
                'foo': 'bar',
                'params': {
                    'custom': 'view param'
                }
            }
        )
    ) }}
    
  • ng_render_field

    Similar to ez_render_field from eZ Platform, this function is used to render the Content’s field using the configured template:

    <p>{{ ng_render_field( content.field.body ) }}</p>
    
  • ng_image_alias

    Similar to ez_image_alias from eZ Platform, this function provides access to the image variation of a ezimage type field:

    <img src="{{ ng_image_alias( content.fields.image, 'large' ).uri }}" />
    

ng_render_field and ng_image_alias are shown in more detail in the examples below. There are two other Twig functions, ng_query and ng_raw_query. These are used with Query Types and are documented separately on Query Types reference documentation page.

Basic usage
  • Accessing Location’s Content object

    Content is available in the Location’s property content:

    {{ set content = location.content }}
    
  • Displaying the name of a Content

    Content’s name is available in the name property:

    <h1>Content's name: {{ content.name }}</h1>
    
  • Linking to a Location

    Linking is done using the path() Twig function, same as before.

    <a href="{{ path(location) }}">{{ location.content.name }}</a>
    
  • Linking to a Content

    Linking to Content will create a link to Content’s main Location.

    <a href="{{ path(content) }}">{{ content.name }}</a>
    
Working with Content fields
  • Accessing a Content Field

    Note

    Content’s fields are lazy-loaded, which means they will be transparently loaded only at the point you access them.

    The most convenient way to access a Content field in Twig is using the dot notation:

    {% set title_field = content.fields.title %}
    

    Alternatively, you can do the same using the array notation:

    {% set title_field = content.fields['title'] %}
    

    Or by calling getField() method on the Content object, also available as field() in Twig, which requires Field identifier as argument:

    {% set title_field = content.field('title') %}
    
  • Checking if the Field exists

    Checking if the field exists can be done with hasField() method on the Content object:

    {% if content.hasField('title') %}
        <p>Content has a 'title' field</p>
    {% endif %}
    
  • Displaying Field’s metadata

    Field object aggregates some data from the FieldDefinition:

    {% set title_field = content.fields.title %}
    
    <p>Field name: {{ title_field.name }}</p>
    <p>Field description: {{ title_field.description }}</p>
    <p>FieldType identifier: {{ title_field.fieldTypeIdentifier }}</p>
    
  • Rendering the field using the configured template

    To render a field in vanilla eZ Platform you would use ez_render_field function, which does that using the configured template block. For the same purpose and using the same templates, Site API provides its own function ng_render_field. It has two parameters:

    1. required Field object

    2. optional hash of parameters, by default an empty array []

      This parameter is exactly the same as you would use with ez_render_field. The only exception is the lang parameter, used to override the language of the rendered field, which is not used by the ng_render_field.

    Basic usage:

    {{ ng_render_field( content.fields.title ) }}
    

    Using the second parameter to override the default template block:

    {{
        ng_render_field(
            content.fields.title,
            { 'template': '@AcmeTest/field/my_field_template.html.twig' }
        )
    }}
    
  • Checking if the Field’s value is empty

    This is done by calling isEmpty() method on the Field object, also available as empty() or just empty in Twig:

    {% if content.fields.title.empty %}
        <p>Title is empty</p>
    {% else %}
        {{ ng_render_field( content.fields.title ) }}
    {% endif %}
    
  • Accessing the Field’s value

    Typically you would render the field using ng_render_field Twig function, but if needed you can also access field’s value directly. Value format varies by the FieldType, so you’ll need to know about the type of the Field whose value you’re accessing. You can find out more about that on the official FieldType reference page or even looking at the value’s code.

    Here we’ll assume title field is of the FieldType ezstring. Latest code for that FieldType’s value can be found here.

    <h1>Value of the title field is: '{{ content.field.title.value.text }}'</h1>
    
  • Rendering the image field

    Typically for this you would use the built-in template through ng_render_field function, but you can also do it manually if needed:

    {% set image = content.fields.image %}
    
    {% if not image.empty %}
        <img src="{{ ng_image_alias( image, 'i1140' ).uri }}"
             alt="{{ image.value.alternativeText }}" />
    {% endif %}
    
Traversing the Content model
Content Locations
  • Accessing the main Location of a Content

    {% set main_location = content.mainLocation %}
    
  • Listing Content’s Locations

    This is done by calling the method getLocations(), also available as locations() in Twig. It returns an array of Locations sorted by the path string (e.g. /1/2/191/300/) and optionally accepts maximum number of items returned (by default 25).

    {% set locations = content.locations(10) %}
    
    <p>First 10 Content's Locations:</p>
    
    <ul>
    {% for location in locations %}
        <li>
            <a href="{{ path(location) }}">Location #{{ location.id }}</a>
        </li>
    {% endif %}
    </ul>
    
  • Paginating through Content’s Locations

    This is done by calling the method filterLocations(), which returns a Pagerfanta instance with Locations sorted by the path string (e.g. /1/2/191/300/) and accepts two optional parameters:

    1. optional maximum number of items per page, by default 25
    2. optional current page, by default 1
    {% set locations = content.filterLocations(10, 2) %}
    
    <h3>Content's Location, page {{ locations.currentPage }}</h3>
    <p>Total: {{ locations.nbResults }} items</p>
    
    <ul>
    {% for location in locations %}
        <li>
            <a href="{{ path(location) }}">Location #{{ location.id }}</a>
        </li>
    {% endfor %}
    </ul>
    
    {{ pagerfanta( locations, 'twitter_bootstrap' ) }}
    
Content Field relations
  • Accessing a single field relation

    This is done by calling the method getFieldRelation(), also available as fieldRelation() in Twig. It has one required parameter, which is the identifier of the relation field. In our example, the relation field’s identifier is related_article.

    {% set related_content = content.fieldRelation('related_article') %}
    
    {% if related_content is defined %}
        <a href="{{ path(related_content) }}">{{ related_content.name }}</a>
    {% else %}
        <p>There are two possibilities:</p>
        <ol>
            <li>Relation field 'related_article' is empty</p>
            <li>You don't have a permission to read the related Content</li>
        </ol>
        <p>In any case, you can't render the related Content!</p>
    {% endif %}
    

    Note

    If relation field contains multiple relations, the first one will be returned. If it doesn’t contain relations or you don’t have the access to read the related Content, the method will return null. Make sure to check if that’s the case.

  • Accessing all field relations

    This is done by calling the method getFieldRelations(), also available as fieldRelations() in Twig. It returns an array of Content items and has two parameters:

    1. required identifier of the relation field
    2. optional maximum number of items returned, by default 25
    {% set related_articles = content.fieldRelations('related_articles', 10) %}
    
    <ul>
    {% for article in related_articles %}
        <li>
            <a href="{{ path(article) }}">{{ article.name }}</a>
        </li>
    {% endfor %}
    </ul>
    
  • Filtering through field relations

    This is done by calling the method filterFieldRelations(), which returns a Pagerfanta instance and has four parameters:

    1. required identifier of the relation field
    2. optional array of ContentType identifiers that will be used to filter the result, by default an empty array []
    3. optional maximum number of items per page, by default 25
    4. optional current page, by default 1
    {% set articles = content.filterFieldRelations('related_items', ['article'], 10, 1) %}
    
    <ul>
    {% for article in articles %}
        <li>
            <a href="{{ path(article) }}">{{ article.name }}</a>
        </li>
    {% endfor %}
    </ul>
    
    {{ pagerfanta( events, 'twitter_bootstrap' ) }}
    
Location children
  • Listing Location’s children

    This is done by calling the method getChildren(), also available as children() in Twig. It returns an array of children Locations and optionally accepts maximum number of items returned (by default 25).

    {% set children = location.children(10) %}
    
    <h3>List of 10 Location's children, sorted as is defined on the Location</h3>
    
    <ul>
    {% for child in children %}
        <li>
            <a href="{{ path(child) }}">{{ child.name }}</a>
        </li>
    {% endfor %}
    </ul>
    
  • Filtering through Location’s children

    This is done by calling the method filterChildren(), which returns a Pagerfanta instance and has three parameters:

    1. optional array of ContentType identifiers that will be used to filter the result, by default an empty array []
    2. optional maximum number of items per page, by default 25
    3. optional current page, by default 1
    {% set documents = location.filterChildren(['document'], 10, 1) %}
    
    <h3>Children documents, page {{ documents.currentPage }}</h3>
    <p>Total: {{ documents.nbResults }} items</p>
    
    <ul>
    {% for document in documents %}
        <li>
            <a href="{{ path(document) }}">{{ document.name }}</a>
        </li>
    {% endfor %}
    </ul>
    
    {{ pagerfanta( documents, 'twitter_bootstrap' ) }}
    
Location siblings
  • Listing Location’s siblings

    This is done by calling the method getSiblings(), also available as siblings() in Twig. It returns an array of children Locations and optionally accepts maximum number of items returned (by default 25).

    {% set children = location.siblings(10) %}
    
    <h3>List of 10 Location's siblings, sorted as is defined on the parent Location</h3>
    
    <ul>
    {% for sibling in siblings %}
        <li>
            <a href="{{ path(sibling) }}">{{ sibling.name }}</a>
        </li>
    {% endfor %}
    </ul>
    
  • Filtering through Location’s siblings

    This is done by calling the method filterSiblings(), which returns a Pagerfanta instance and has three parameters:

    1. optional array of ContentType identifiers that will be used to filter the result, by default an empty array []
    2. optional maximum number of items per page, by default 25
    3. optional current page, by default 1
    {% set articles = location.filterSiblings(['article'], 10, 1) %}
    
    <h3>Sibling articles, page {{ articles.currentPage }}</h3>
    <p>Total: {{ articles.nbResults }} items</p>
    
    <ul>
    {% for article in articles %}
        <li>
            <a href="{{ path(articles) }}">{{ articles.name }}</a>
        </li>
    {% endfor %}
    </ul>
    
    {{ pagerfanta( articles, 'twitter_bootstrap' ) }}
    
Working with Named Objects

Named objects feature provides a way to configure specific objects (Content, Location and Tag) by name and ID, and a way to access them by name from PHP, Twig and Query Type configuration. Site API NamedObjectProvider service is available as namedObject. Its purpose is providing access to configured named objects.

Note

Configuration of named objects is documented in more detail on the Configuration page. Usage of named objects from PHP is documented on the Services page.

A following named object configuration is given:

ezpublish:
    system:
        frontend_group:
            named_objects:
                content:
                    certificate: 3
                location:
                    homepage: 2
                tag:
                    colors: 4

Three functions for accessing named objects are available, one for each object type:

  • ng_named_content

    Provides access to named Content object. Example usage:

    {% set certificate = ng_named_content('certificate') %}
    
  • ng_named_location

    Provides access to named Location object. Example usage:

    {% set homepage = ng_named_location('homepage') %}
    
  • ng_named_tag

    Provides access to named Tag object. Example usage:

    {% set colors = ng_named_tag('colors') %}
    

Query Types

Site API Query Types expand upon Query Type feature from eZ Publish Kernel, using the same basic interfaces. That will enable using your existing Query Types, but how Site API integrates them with the rest of the system differs from eZ Publish Kernel.

Content on this page:

Built-in Site API Query Types

A number of generic Query Types is provided out of the box. We can separate these into three groups:

General purpose
General purpose Content fetch

This Query Type is used to build general purpose Location queries.

Identifier SiteAPI:Location/Fetch
Common Content conditions
Common query parameters
Examples
Common Content conditions
content_type

Defines ContentType of the Content by the identifier.

  • value type: string
  • value format: single, array
  • operators: eq, in
  • target: string ContentType identifier
  • required: false
  • default: not defined

Examples:

# identical to the example below
content_type: article
content_type:
    eq: article
# identical to the example below
content_type: [image, video]
content_type:
    in: [image, video]
field

Defines conditions on Content fields.

  • value type: integer, string, boolean
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between, like, contains
  • target: string Field identifier
  • required: false
  • default: not defined

Examples:

field:
    date_field:
        not:
            gt: 'today +5 days'
    price:
        between: [100, 200]
        not: 155
is_field_empty

Defines conditions on whether the Content fields are empty or not.

Note

IsEmptyField criterion is supported only by Solr search engine, so this condition can be used only with the FindService. In order to use it configure the query with parameter use_filter set to false.

  • value type: boolean, null
  • value format: single
  • operators: eq
  • target: string Field identifier
  • required: false
  • default: not defined

Examples:

is_field_empty:
    image: false
    video: true
# allow both empty and non-empty fields, which is also the default behaviour
is_field_empty:
    audio: ~
creation_date

Defines the creation (first publication) date of the Content as a timestamp or time string as accepted by PHP function strtotime.

  • value type: integer, string
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
creation_date: 1535117737
creation_date:
    eq: 1535117737
# identical to the example below
creation_date: [1435117737, 1535117737]
creation_date:
    in: [1435117737, 1535117737]
# multiple operators are combined with logical AND
creation_date:
    gt: '29 June 1991'
    lte: '5 August 1995'
creation_date:
    gt: 'today'
creation_date:
    between: ['-1 week 2 days 4 hours 2 seconds', 'today']
modification_date

Defines the modification (last publication) date of the Content as a timestamp or time string as accepted by PHP function strtotime.

  • value type: integer, string
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
modification_date: 1535117737
modification_date:
    eq: 1535117737
# identical to the example below
modification_date: [1435117737, 1535117737]
modification_date:
    in: [1435117737, 1535117737]
# multiple operators are combined with logical AND
modification_date:
    gt: '29 June 1991'
    lte: '5 August 1995'
modification_date:
    gt: 'today'
modification_date:
    between: ['-1 week 2 days 4 hours 2 seconds', 'today']
section

Defines Section of the Content by the identifier.

  • value type: string
  • value format: single, array
  • operators: eq, in
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
section: standard
section:
    eq: standard
# identical to the example below
section: [standard, restricted]
section:
    in: [standard, restricted]
state

Defines ObjectState of the Content by the ObjectStateGroup and ObjectState identifiers.

Note

Content can only exist in single ObjectState from the same ObjectStateGroup.

  • value type: string ObjectState identifier
  • value format: single
  • operators: eq
  • target: string ObjectStateGroup identifier
  • required: false
  • default: not defined

Examples:

# identical to the example below
state:
    ez_lock: not_locked
state:
    ez_lock:
        eq: not_locked
# multiple states are combined with logical AND
# identical to the example below
state:
    ez_lock: locked
    approval: rejected
state:
    ez_lock:
        eq: locked
    approval:
        eq: rejected
Common query parameters
limit

Defines the maximum number of items to return.

Note

This parameter will not be used if you execute the query from Twig using ng_query function. In that case Pargerfanta pager is used with semantic parameters page and max_per_page. To execute the query directly use ng_raw_query Twig function instead.

  • value type: integer
  • value format: single
  • required: false
  • default: 25

Examples:

limit: 10
offset

Defines the offset for search hits, used for paging the results.

Note

This parameter will not be used if you execute the query from Twig using ng_query function. In that case Pargerfanta pager is used with semantic parameters page and max_per_page. To execute the query directly use ng_raw_query Twig function instead.

  • value type: integer
  • value format: single
  • required: false
  • default: 0

Examples:

offset: 20
sort
  • value type: string, SortClause
  • value format: single, array
  • required: false
  • default: not defined

Here you can use any SortClause implementation. However, if you define the query in the view configuration, you won’t be able to instantiate the SortClause there. For that reason we provide a way to define the sort clause as a string instead. We this format a subset of commonly used SortClauses is supported. Sort direction is defined as asc for ascending and desc for descending. In can be omitted, in which case it will default to asc.

Strings can be used to define multiple sort clauses through an array of definitions:

sort:
    - depth asc
    - modified desc

Following sort clauses are available through string definition:

Location depth

String depth enables sorting by Location’s depth:

sort: depth
sort: depth asc
sort: depth desc
Content Field

String in form of of field/[content_type]/[field] enables sorting by any Content Field. For example by Field with identifier title in ContentType with identifier article:

sort: field/article/title
sort: field/article/title asc
sort: field/article/title desc
Content modification date

String modified enables sorting by the Content modification date:

sort: modified
sort: modified asc
sort: modified desc
Content name

String name enables sorting by the Content name:

sort: name
sort: name asc
sort: name desc
Location priority

String priority enables sorting by the Location priority:

sort: priority
sort: priority asc
sort: priority desc
Content publication date

String published enables sorting by the Content publication/creation date:

sort: published
sort: published asc
sort: published desc
General purpose Location fetch

This Query Type is used to build general purpose Location queries.

Identifier SiteAPI:Location/Fetch
Inherited Location conditions
Common Content conditions
Common query parameters
Examples
Inherited Location conditions
depth

Defines absolute depth of the Location in the tree.

  • value type: integer
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
depth: 3
depth:
    eq: 3
# identical to the example below
depth: [3, 4, 8]
depth:
    in: [3, 4, 8]
# multiple operators are combined with logical AND
depth:
    in: [3, 4, 5]
    gt: 4
    lte: 8
depth:
    between: [4, 7]
main

Defines whether returned Locations are main Locations or not. Use true to get main Locations, false to get non-main Locations and null to get both (which is also the default behaviour).

  • value type: boolean, null
  • value format: single
  • operators: eq
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
main: true
main:
    eq: true
# get both main and non-main Locations, which is also the default behaviour
main: ~
parent_location_id

Defines Location’s parent Location ID.

  • value type: integer, string
  • value format: single, array
  • operators: eq, in
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
parent_location_id: 42
parent_location_id:
    eq: 42
# identical to the example below
parent_location_id: [11, 24, 42]
parent_location_id:
    in: [11, 24, 42]
priority

Defines the priority of the Location.

  • value type: integer
  • value format: single
  • operators: gt, gte, lt, lte, between
  • target: none
  • required: false
  • default: not defined

Examples:

# multiple operators are combined with logical AND
depth:
    gt: 4
    lte: 8
depth:
    between: [4, 7]
subtree
  • value type: string
  • value format: single, array
  • operators: eq, in
  • target: none
  • required: false
  • default: not defined

bla bla

visible

Defines whether returned Locations are visible or not. Use true to get visible Locations, false to get hidden Locations and null to get both (which is also the default behaviour).

  • value type: boolean, null
  • value format: single
  • operators: eq
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
visible: false
visible:
    eq: false
# get both visible and hidden Locations, which also the default behaviour
visible: ~
Common Content conditions
content_type

Defines ContentType of the Content by the identifier.

  • value type: string
  • value format: single, array
  • operators: eq, in
  • target: string ContentType identifier
  • required: false
  • default: not defined

Examples:

# identical to the example below
content_type: article
content_type:
    eq: article
# identical to the example below
content_type: [image, video]
content_type:
    in: [image, video]
field

Defines conditions on Content fields.

  • value type: integer, string, boolean
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between, like, contains
  • target: string Field identifier
  • required: false
  • default: not defined

Examples:

field:
    date_field:
        not:
            gt: 'today +5 days'
    price:
        between: [100, 200]
        not: 155
is_field_empty

Defines conditions on whether the Content fields are empty or not.

Note

IsEmptyField criterion is supported only by Solr search engine, so this condition can be used only with the FindService. In order to use it configure the query with parameter use_filter set to false.

  • value type: boolean, null
  • value format: single
  • operators: eq
  • target: string Field identifier
  • required: false
  • default: not defined

Examples:

is_field_empty:
    image: false
    video: true
# allow both empty and non-empty fields, which is also the default behaviour
is_field_empty:
    audio: ~
creation_date

Defines the creation (first publication) date of the Content as a timestamp or time string as accepted by PHP function strtotime.

  • value type: integer, string
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
creation_date: 1535117737
creation_date:
    eq: 1535117737
# identical to the example below
creation_date: [1435117737, 1535117737]
creation_date:
    in: [1435117737, 1535117737]
# multiple operators are combined with logical AND
creation_date:
    gt: '29 June 1991'
    lte: '5 August 1995'
creation_date:
    gt: 'today'
creation_date:
    between: ['-1 week 2 days 4 hours 2 seconds', 'today']
modification_date

Defines the modification (last publication) date of the Content as a timestamp or time string as accepted by PHP function strtotime.

  • value type: integer, string
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
modification_date: 1535117737
modification_date:
    eq: 1535117737
# identical to the example below
modification_date: [1435117737, 1535117737]
modification_date:
    in: [1435117737, 1535117737]
# multiple operators are combined with logical AND
modification_date:
    gt: '29 June 1991'
    lte: '5 August 1995'
modification_date:
    gt: 'today'
modification_date:
    between: ['-1 week 2 days 4 hours 2 seconds', 'today']
section

Defines Section of the Content by the identifier.

  • value type: string
  • value format: single, array
  • operators: eq, in
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
section: standard
section:
    eq: standard
# identical to the example below
section: [standard, restricted]
section:
    in: [standard, restricted]
state

Defines ObjectState of the Content by the ObjectStateGroup and ObjectState identifiers.

Note

Content can only exist in single ObjectState from the same ObjectStateGroup.

  • value type: string ObjectState identifier
  • value format: single
  • operators: eq
  • target: string ObjectStateGroup identifier
  • required: false
  • default: not defined

Examples:

# identical to the example below
state:
    ez_lock: not_locked
state:
    ez_lock:
        eq: not_locked
# multiple states are combined with logical AND
# identical to the example below
state:
    ez_lock: locked
    approval: rejected
state:
    ez_lock:
        eq: locked
    approval:
        eq: rejected
Common query parameters
limit

Defines the maximum number of items to return.

Note

This parameter will not be used if you execute the query from Twig using ng_query function. In that case Pargerfanta pager is used with semantic parameters page and max_per_page. To execute the query directly use ng_raw_query Twig function instead.

  • value type: integer
  • value format: single
  • required: false
  • default: 25

Examples:

limit: 10
offset

Defines the offset for search hits, used for paging the results.

Note

This parameter will not be used if you execute the query from Twig using ng_query function. In that case Pargerfanta pager is used with semantic parameters page and max_per_page. To execute the query directly use ng_raw_query Twig function instead.

  • value type: integer
  • value format: single
  • required: false
  • default: 0

Examples:

offset: 20
sort
  • value type: string, SortClause
  • value format: single, array
  • required: false
  • default: not defined

Here you can use any SortClause implementation. However, if you define the query in the view configuration, you won’t be able to instantiate the SortClause there. For that reason we provide a way to define the sort clause as a string instead. We this format a subset of commonly used SortClauses is supported. Sort direction is defined as asc for ascending and desc for descending. In can be omitted, in which case it will default to asc.

Strings can be used to define multiple sort clauses through an array of definitions:

sort:
    - depth asc
    - modified desc

Following sort clauses are available through string definition:

Location depth

String depth enables sorting by Location’s depth:

sort: depth
sort: depth asc
sort: depth desc
Content Field

String in form of of field/[content_type]/[field] enables sorting by any Content Field. For example by Field with identifier title in ContentType with identifier article:

sort: field/article/title
sort: field/article/title asc
sort: field/article/title desc
Content modification date

String modified enables sorting by the Content modification date:

sort: modified
sort: modified asc
sort: modified desc
Content name

String name enables sorting by the Content name:

sort: name
sort: name asc
sort: name desc
Location priority

String priority enables sorting by the Location priority:

sort: priority
sort: priority asc
sort: priority desc
Content publication date

String published enables sorting by the Content publication/creation date:

sort: published
sort: published asc
sort: published desc
Content relations
All tag fields Content relations Query Type

This Query Type is used to build queries that fetch Content tag field relations from all tag fields of a given Content.

Hint

Tag field Content relations are Content items tagged with a tag contained in the tag fields of a given Content.

Hint

This query type assumes Netgen’s TagsBundle is used for tagging functionality.

Identifier SiteAPI:Content/Relations/AllTagFields
Own conditions
Common Content conditions
Common query parameters
Examples

On full view for product type Content fetch all Content of type article that is tagged with any of the tags from the given product. Sort them by name and paginate them by 10 per page using URL query parameter page:

ezpublish:
    system:
        frontend_group:
            ngcontent_view:
                full:
                    product:
                        template: '@ezdesign/content/full/product.html.twig'
                        match:
                            Identifier\ContentType: product
                        queries:
                            related_articles:
                                query_type: SiteAPI:Content/Relations/AllTagFields
                                max_per_page: 10
                                page: '@=queryParam("page", 1)'
                                parameters:
                                    content_type: article
                                    sort: name
{% set articles = ng_query( 'related_articles' ) %}

<h3>Related articles</h3>

<ul>
{% for article in articles %}
    <li>{{ article.name }}</li>
{% endfor %}
</ul>

{{ pagerfanta( articles, 'twitter_bootstrap' ) }}
Own conditions
content

Defines the source (from) relation Content, which is the one containing tag fields.

Note

This condition is required. It’s also automatically set to the Content instance resolved by the view builder if the query is defined in the view builder configuration.

  • value type: Content
  • value format: single
  • operators: none
  • target: none
  • required: true
  • default: not defined

Examples:

# this is also automatically set when using from view builder configuration
content: '@=content'
# fetch relations from Content's main Location parent Location's Content
content: '@=content.mainLocation.parent.content'
# fetch relations from Content's main Location parent Location's parent Location's Content
content: '@=content.mainLocation.parent.parent.content'
exclude_self

Defines whether to include Content defined by the content condition in the result set.

  • value type: boolean
  • value format: single
  • operators: none
  • target: none
  • required: false
  • default: true

Examples:

# do not include the source relation Content, this is also the default behaviour
exclude_self: true
# include the source relation Content
exclude_self: false
Common Content conditions
content_type

Defines ContentType of the Content by the identifier.

  • value type: string
  • value format: single, array
  • operators: eq, in
  • target: string ContentType identifier
  • required: false
  • default: not defined

Examples:

# identical to the example below
content_type: article
content_type:
    eq: article
# identical to the example below
content_type: [image, video]
content_type:
    in: [image, video]
field

Defines conditions on Content fields.

  • value type: integer, string, boolean
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between, like, contains
  • target: string Field identifier
  • required: false
  • default: not defined

Examples:

field:
    date_field:
        not:
            gt: 'today +5 days'
    price:
        between: [100, 200]
        not: 155
is_field_empty

Defines conditions on whether the Content fields are empty or not.

Note

IsEmptyField criterion is supported only by Solr search engine, so this condition can be used only with the FindService. In order to use it configure the query with parameter use_filter set to false.

  • value type: boolean, null
  • value format: single
  • operators: eq
  • target: string Field identifier
  • required: false
  • default: not defined

Examples:

is_field_empty:
    image: false
    video: true
# allow both empty and non-empty fields, which is also the default behaviour
is_field_empty:
    audio: ~
creation_date

Defines the creation (first publication) date of the Content as a timestamp or time string as accepted by PHP function strtotime.

  • value type: integer, string
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
creation_date: 1535117737
creation_date:
    eq: 1535117737
# identical to the example below
creation_date: [1435117737, 1535117737]
creation_date:
    in: [1435117737, 1535117737]
# multiple operators are combined with logical AND
creation_date:
    gt: '29 June 1991'
    lte: '5 August 1995'
creation_date:
    gt: 'today'
creation_date:
    between: ['-1 week 2 days 4 hours 2 seconds', 'today']
modification_date

Defines the modification (last publication) date of the Content as a timestamp or time string as accepted by PHP function strtotime.

  • value type: integer, string
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
modification_date: 1535117737
modification_date:
    eq: 1535117737
# identical to the example below
modification_date: [1435117737, 1535117737]
modification_date:
    in: [1435117737, 1535117737]
# multiple operators are combined with logical AND
modification_date:
    gt: '29 June 1991'
    lte: '5 August 1995'
modification_date:
    gt: 'today'
modification_date:
    between: ['-1 week 2 days 4 hours 2 seconds', 'today']
section

Defines Section of the Content by the identifier.

  • value type: string
  • value format: single, array
  • operators: eq, in
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
section: standard
section:
    eq: standard
# identical to the example below
section: [standard, restricted]
section:
    in: [standard, restricted]
state

Defines ObjectState of the Content by the ObjectStateGroup and ObjectState identifiers.

Note

Content can only exist in single ObjectState from the same ObjectStateGroup.

  • value type: string ObjectState identifier
  • value format: single
  • operators: eq
  • target: string ObjectStateGroup identifier
  • required: false
  • default: not defined

Examples:

# identical to the example below
state:
    ez_lock: not_locked
state:
    ez_lock:
        eq: not_locked
# multiple states are combined with logical AND
# identical to the example below
state:
    ez_lock: locked
    approval: rejected
state:
    ez_lock:
        eq: locked
    approval:
        eq: rejected
Common query parameters
limit

Defines the maximum number of items to return.

Note

This parameter will not be used if you execute the query from Twig using ng_query function. In that case Pargerfanta pager is used with semantic parameters page and max_per_page. To execute the query directly use ng_raw_query Twig function instead.

  • value type: integer
  • value format: single
  • required: false
  • default: 25

Examples:

limit: 10
offset

Defines the offset for search hits, used for paging the results.

Note

This parameter will not be used if you execute the query from Twig using ng_query function. In that case Pargerfanta pager is used with semantic parameters page and max_per_page. To execute the query directly use ng_raw_query Twig function instead.

  • value type: integer
  • value format: single
  • required: false
  • default: 0

Examples:

offset: 20
sort
  • value type: string, SortClause
  • value format: single, array
  • required: false
  • default: not defined

Here you can use any SortClause implementation. However, if you define the query in the view configuration, you won’t be able to instantiate the SortClause there. For that reason we provide a way to define the sort clause as a string instead. We this format a subset of commonly used SortClauses is supported. Sort direction is defined as asc for ascending and desc for descending. In can be omitted, in which case it will default to asc.

Strings can be used to define multiple sort clauses through an array of definitions:

sort:
    - depth asc
    - modified desc

Following sort clauses are available through string definition:

Location depth

String depth enables sorting by Location’s depth:

sort: depth
sort: depth asc
sort: depth desc
Content Field

String in form of of field/[content_type]/[field] enables sorting by any Content Field. For example by Field with identifier title in ContentType with identifier article:

sort: field/article/title
sort: field/article/title asc
sort: field/article/title desc
Content modification date

String modified enables sorting by the Content modification date:

sort: modified
sort: modified asc
sort: modified desc
Content name

String name enables sorting by the Content name:

sort: name
sort: name asc
sort: name desc
Location priority

String priority enables sorting by the Location priority:

sort: priority
sort: priority asc
sort: priority desc
Content publication date

String published enables sorting by the Content publication/creation date:

sort: published
sort: published asc
sort: published desc
Forward field Content relations Query Type

This Query Type is used to build fetch Content that is related to from relation type fields of the given Content.

Identifier SiteAPI:Content/Relations/ForwardFields
Own conditions
Common Content conditions
Common query parameters
Examples

Content of type blog_post has relation field images which is used to define relations to image type Content. On full view for blog_post fetch 10 related images sorted by name and paginate them by 10 per page using URL query parameter page.

ezpublish:
    system:
        frontend_group:
            ngcontent_view:
                full:
                    blog_post:
                        template: '@ezdesign/content/full/blog_post.html.twig'
                        match:
                            Identifier\ContentType: blog_post
                        queries:
                            related_images:
                                query_type: SiteAPI:Content/Relations/ForwardFields
                                max_per_page: 10
                                page: 1
                                parameters:
                                    relation_field: images
                                    content_type: image
                                    sort: name
<h3>Related images</h3>

<ul>
{% for image in ng_query( 'related_images' ) %}
    <li>
        {{ ng_image_alias( image.fields.image, 'gallery' ) }}
    </li>
{% endfor %}
</ul>

{{ pagerfanta( documents, 'twitter_bootstrap' ) }}
Own conditions
content

Defines the source (from) relation Content, which is the one containing relation type fields.

Note

This condition is required. It’s also automatically set to the Content instance resolved by the view builder if the query is defined in the view builder configuration.

  • value type: Content
  • value format: single
  • operators: none
  • target: none
  • required: true
  • default: not defined

Examples:

# this is also automatically set when using from view builder configuration
content: '@=content'
# fetch relations from Content's main Location parent Location's Content
content: '@=content.mainLocation.parent.content'
# fetch relations from Content's main Location parent Location's parent Location's Content
content: '@=content.mainLocation.parent.parent.content'
relation_field

Defines Content fields to take into account for determining relations.

  • value type: string
  • value format: single, array
  • operators: none
  • target: none
  • required: true
  • default: not defined

Examples:

relation_field: appellation
relation_field: [head, heart, base]
Common Content conditions
content_type

Defines ContentType of the Content by the identifier.

  • value type: string
  • value format: single, array
  • operators: eq, in
  • target: string ContentType identifier
  • required: false
  • default: not defined

Examples:

# identical to the example below
content_type: article
content_type:
    eq: article
# identical to the example below
content_type: [image, video]
content_type:
    in: [image, video]
field

Defines conditions on Content fields.

  • value type: integer, string, boolean
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between, like, contains
  • target: string Field identifier
  • required: false
  • default: not defined

Examples:

field:
    date_field:
        not:
            gt: 'today +5 days'
    price:
        between: [100, 200]
        not: 155
is_field_empty

Defines conditions on whether the Content fields are empty or not.

Note

IsEmptyField criterion is supported only by Solr search engine, so this condition can be used only with the FindService. In order to use it configure the query with parameter use_filter set to false.

  • value type: boolean, null
  • value format: single
  • operators: eq
  • target: string Field identifier
  • required: false
  • default: not defined

Examples:

is_field_empty:
    image: false
    video: true
# allow both empty and non-empty fields, which is also the default behaviour
is_field_empty:
    audio: ~
creation_date

Defines the creation (first publication) date of the Content as a timestamp or time string as accepted by PHP function strtotime.

  • value type: integer, string
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
creation_date: 1535117737
creation_date:
    eq: 1535117737
# identical to the example below
creation_date: [1435117737, 1535117737]
creation_date:
    in: [1435117737, 1535117737]
# multiple operators are combined with logical AND
creation_date:
    gt: '29 June 1991'
    lte: '5 August 1995'
creation_date:
    gt: 'today'
creation_date:
    between: ['-1 week 2 days 4 hours 2 seconds', 'today']
modification_date

Defines the modification (last publication) date of the Content as a timestamp or time string as accepted by PHP function strtotime.

  • value type: integer, string
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
modification_date: 1535117737
modification_date:
    eq: 1535117737
# identical to the example below
modification_date: [1435117737, 1535117737]
modification_date:
    in: [1435117737, 1535117737]
# multiple operators are combined with logical AND
modification_date:
    gt: '29 June 1991'
    lte: '5 August 1995'
modification_date:
    gt: 'today'
modification_date:
    between: ['-1 week 2 days 4 hours 2 seconds', 'today']
section

Defines Section of the Content by the identifier.

  • value type: string
  • value format: single, array
  • operators: eq, in
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
section: standard
section:
    eq: standard
# identical to the example below
section: [standard, restricted]
section:
    in: [standard, restricted]
state

Defines ObjectState of the Content by the ObjectStateGroup and ObjectState identifiers.

Note

Content can only exist in single ObjectState from the same ObjectStateGroup.

  • value type: string ObjectState identifier
  • value format: single
  • operators: eq
  • target: string ObjectStateGroup identifier
  • required: false
  • default: not defined

Examples:

# identical to the example below
state:
    ez_lock: not_locked
state:
    ez_lock:
        eq: not_locked
# multiple states are combined with logical AND
# identical to the example below
state:
    ez_lock: locked
    approval: rejected
state:
    ez_lock:
        eq: locked
    approval:
        eq: rejected
Common query parameters
limit

Defines the maximum number of items to return.

Note

This parameter will not be used if you execute the query from Twig using ng_query function. In that case Pargerfanta pager is used with semantic parameters page and max_per_page. To execute the query directly use ng_raw_query Twig function instead.

  • value type: integer
  • value format: single
  • required: false
  • default: 25

Examples:

limit: 10
offset

Defines the offset for search hits, used for paging the results.

Note

This parameter will not be used if you execute the query from Twig using ng_query function. In that case Pargerfanta pager is used with semantic parameters page and max_per_page. To execute the query directly use ng_raw_query Twig function instead.

  • value type: integer
  • value format: single
  • required: false
  • default: 0

Examples:

offset: 20
sort
  • value type: string, SortClause
  • value format: single, array
  • required: false
  • default: not defined

Here you can use any SortClause implementation. However, if you define the query in the view configuration, you won’t be able to instantiate the SortClause there. For that reason we provide a way to define the sort clause as a string instead. We this format a subset of commonly used SortClauses is supported. Sort direction is defined as asc for ascending and desc for descending. In can be omitted, in which case it will default to asc.

Strings can be used to define multiple sort clauses through an array of definitions:

sort:
    - depth asc
    - modified desc

Following sort clauses are available through string definition:

Location depth

String depth enables sorting by Location’s depth:

sort: depth
sort: depth asc
sort: depth desc
Content Field

String in form of of field/[content_type]/[field] enables sorting by any Content Field. For example by Field with identifier title in ContentType with identifier article:

sort: field/article/title
sort: field/article/title asc
sort: field/article/title desc
Content modification date

String modified enables sorting by the Content modification date:

sort: modified
sort: modified asc
sort: modified desc
Content name

String name enables sorting by the Content name:

sort: name
sort: name asc
sort: name desc
Location priority

String priority enables sorting by the Location priority:

sort: priority
sort: priority asc
sort: priority desc
Content publication date

String published enables sorting by the Content publication/creation date:

sort: published
sort: published asc
sort: published desc
Reverse field Content relations Query Type

This Query Type is used to build fetch Content that relates to the given Content from its relation type fields.

Identifier SiteAPI:Content/Relations/ReverseFields
Own conditions
Common Content conditions
Common query parameters
Examples

Content of type article has relation field authors which is used to define relations to author type Content. On full view for author fetch all articles authored by that author, sort them by title and paginate them by 10 per page using URL query parameter page:

ezpublish:
    system:
        frontend_group:
            ngcontent_view:
                full:
                    author:
                        template: '@ezdesign/content/full/author.html.twig'
                        match:
                            Identifier\ContentType: author
                        queries:
                            authored_articles:
                                query_type: SiteAPI:Content/Relations/ReverseFields
                                max_per_page: 10
                                page: '@=queryParam("page", 1)'
                                parameters:
                                    relation_field: authors
                                    content_type: article
                                    sort: field/article/title asc
<h3>Author's articles</h3>

<ul>
{% for article in ng_query( 'authored_articles' ) %}
    <li>{{ article.name }}</li>
{% endfor %}
</ul>

{{ pagerfanta( children, 'twitter_bootstrap' ) }}
Own parameters
content

Defines the destination (to) relation Content.

Note

This condition is required. It’s also automatically set to the Content instance resolved by the view builder if the query is defined in the view builder configuration.

Note

Since this is about reverse relations, Content defined by this condition is not the one containing relation type fields referenced by relation_field. It’s the one receiving relations from Content containing those fields.

  • value type: Content
  • value format: single
  • operators: none
  • target: none
  • required: true
  • default: not defined

Examples:

# this is also automatically set when using from view builder configuration
content: '@=content'
# fetch relations to Content's main Location parent Location's Content
content: '@=content.mainLocation.parent.content'
# fetch relations to Content's main Location parent Location's parent Location's Content
content: '@=content.mainLocation.parent.parent.content'
relation_field

Defines Content fields to take into account for determining relations.

  • value type: string
  • value format: single, array
  • operators: none
  • target: none
  • required: true
  • default: not defined

Examples:

relation_field: authors
relation_field: [color, size]
Common Content conditions
content_type

Defines ContentType of the Content by the identifier.

  • value type: string
  • value format: single, array
  • operators: eq, in
  • target: string ContentType identifier
  • required: false
  • default: not defined

Examples:

# identical to the example below
content_type: article
content_type:
    eq: article
# identical to the example below
content_type: [image, video]
content_type:
    in: [image, video]
field

Defines conditions on Content fields.

  • value type: integer, string, boolean
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between, like, contains
  • target: string Field identifier
  • required: false
  • default: not defined

Examples:

field:
    date_field:
        not:
            gt: 'today +5 days'
    price:
        between: [100, 200]
        not: 155
is_field_empty

Defines conditions on whether the Content fields are empty or not.

Note

IsEmptyField criterion is supported only by Solr search engine, so this condition can be used only with the FindService. In order to use it configure the query with parameter use_filter set to false.

  • value type: boolean, null
  • value format: single
  • operators: eq
  • target: string Field identifier
  • required: false
  • default: not defined

Examples:

is_field_empty:
    image: false
    video: true
# allow both empty and non-empty fields, which is also the default behaviour
is_field_empty:
    audio: ~
creation_date

Defines the creation (first publication) date of the Content as a timestamp or time string as accepted by PHP function strtotime.

  • value type: integer, string
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
creation_date: 1535117737
creation_date:
    eq: 1535117737
# identical to the example below
creation_date: [1435117737, 1535117737]
creation_date:
    in: [1435117737, 1535117737]
# multiple operators are combined with logical AND
creation_date:
    gt: '29 June 1991'
    lte: '5 August 1995'
creation_date:
    gt: 'today'
creation_date:
    between: ['-1 week 2 days 4 hours 2 seconds', 'today']
modification_date

Defines the modification (last publication) date of the Content as a timestamp or time string as accepted by PHP function strtotime.

  • value type: integer, string
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
modification_date: 1535117737
modification_date:
    eq: 1535117737
# identical to the example below
modification_date: [1435117737, 1535117737]
modification_date:
    in: [1435117737, 1535117737]
# multiple operators are combined with logical AND
modification_date:
    gt: '29 June 1991'
    lte: '5 August 1995'
modification_date:
    gt: 'today'
modification_date:
    between: ['-1 week 2 days 4 hours 2 seconds', 'today']
section

Defines Section of the Content by the identifier.

  • value type: string
  • value format: single, array
  • operators: eq, in
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
section: standard
section:
    eq: standard
# identical to the example below
section: [standard, restricted]
section:
    in: [standard, restricted]
state

Defines ObjectState of the Content by the ObjectStateGroup and ObjectState identifiers.

Note

Content can only exist in single ObjectState from the same ObjectStateGroup.

  • value type: string ObjectState identifier
  • value format: single
  • operators: eq
  • target: string ObjectStateGroup identifier
  • required: false
  • default: not defined

Examples:

# identical to the example below
state:
    ez_lock: not_locked
state:
    ez_lock:
        eq: not_locked
# multiple states are combined with logical AND
# identical to the example below
state:
    ez_lock: locked
    approval: rejected
state:
    ez_lock:
        eq: locked
    approval:
        eq: rejected
Common query parameters
limit

Defines the maximum number of items to return.

Note

This parameter will not be used if you execute the query from Twig using ng_query function. In that case Pargerfanta pager is used with semantic parameters page and max_per_page. To execute the query directly use ng_raw_query Twig function instead.

  • value type: integer
  • value format: single
  • required: false
  • default: 25

Examples:

limit: 10
offset

Defines the offset for search hits, used for paging the results.

Note

This parameter will not be used if you execute the query from Twig using ng_query function. In that case Pargerfanta pager is used with semantic parameters page and max_per_page. To execute the query directly use ng_raw_query Twig function instead.

  • value type: integer
  • value format: single
  • required: false
  • default: 0

Examples:

offset: 20
sort
  • value type: string, SortClause
  • value format: single, array
  • required: false
  • default: not defined

Here you can use any SortClause implementation. However, if you define the query in the view configuration, you won’t be able to instantiate the SortClause there. For that reason we provide a way to define the sort clause as a string instead. We this format a subset of commonly used SortClauses is supported. Sort direction is defined as asc for ascending and desc for descending. In can be omitted, in which case it will default to asc.

Strings can be used to define multiple sort clauses through an array of definitions:

sort:
    - depth asc
    - modified desc

Following sort clauses are available through string definition:

Location depth

String depth enables sorting by Location’s depth:

sort: depth
sort: depth asc
sort: depth desc
Content Field

String in form of of field/[content_type]/[field] enables sorting by any Content Field. For example by Field with identifier title in ContentType with identifier article:

sort: field/article/title
sort: field/article/title asc
sort: field/article/title desc
Content modification date

String modified enables sorting by the Content modification date:

sort: modified
sort: modified asc
sort: modified desc
Content name

String name enables sorting by the Content name:

sort: name
sort: name asc
sort: name desc
Location priority

String priority enables sorting by the Location priority:

sort: priority
sort: priority asc
sort: priority desc
Content publication date

String published enables sorting by the Content publication/creation date:

sort: published
sort: published asc
sort: published desc
Tag field Content relations Query Type

This Query Type is used to build queries that fetch Content tag field relations from selected tag fields of a given Content.

Hint

Tag field Content relations are Content items tagged with a tag contained in a tag field of a given Content.

Hint

This query type assumes Netgen’s TagsBundle is used for tagging functionality.

Identifier SiteAPI:Content/Relations/TagFields
Own conditions
Common Content conditions
Common query parameters
Examples

Your project is a web shop, where Content of type product is tagged with tags that define product’s market. Specific tag field named market is used for that. For example, you could have a wireless keyboard product tagged with market tag components. Various other Content is also tagged with that tag, for example we could have files and articles using that same tag.

On the full view for Content of type product, fetch articles from the same market, sort them by their publication date and paginate them by 10 per page using URL query parameter page:

ezpublish:
    system:
        frontend_group:
            ngcontent_view:
                full:
                    product:
                        template: '@ezdesign/content/full/product.html.twig'
                        match:
                            Identifier\ContentType: product
                        queries:
                            market_articles:
                                query_type: SiteAPI:Content/Relations/TagFields
                                max_per_page: 10
                                page: '@=queryParam("page", 1)'
                                parameters:
                                    relation_field: market
                                    content_type: article
                                    sort: published desc
{% set articles = ng_query( 'market_articles' ) %}

<h3>Related market articles</h3>

<ul>
{% for article in articles %}
    <li>{{ article.name }}</li>
{% endfor %}
</ul>

{{ pagerfanta( articles, 'twitter_bootstrap' ) }}
Own conditions
content

Defines the source (from) relation Content, which is the one containing tag fields.

Note

This condition is required. It’s also automatically set to the Content instance resolved by the view builder if the query is defined in the view builder configuration.

  • value type: Content
  • value format: single
  • operators: none
  • target: none
  • required: true
  • default: not defined

Examples:

# this is also automatically set when using from view builder configuration
location: '@=content'
# fetch relations from Content's main Location parent Location's Content
location: '@=content.mainLocation.parent.content'
# fetch relations from Content's main Location parent Location's parent Location's Content
location: '@=content.mainLocation.parent.parent.content'
exclude_self

Defines whether to include Content defined by the content condition in the result set.

  • value type: boolean
  • value format: single
  • operators: none
  • target: none
  • required: false
  • default: true

Examples:

# do not include the source relation Content, this is also the default behaviour
exclude_self: true
# include the source relation Content
exclude_self: false
relation_field

Defines Content fields to take into account for determining relations.

  • value type: string
  • value format: single, array
  • operators: none
  • target: none
  • required: true
  • default: not defined

Examples:

relation_field: appellation
relation_field: [head, heart, base]
Common Content conditions
content_type

Defines ContentType of the Content by the identifier.

  • value type: string
  • value format: single, array
  • operators: eq, in
  • target: string ContentType identifier
  • required: false
  • default: not defined

Examples:

# identical to the example below
content_type: article
content_type:
    eq: article
# identical to the example below
content_type: [image, video]
content_type:
    in: [image, video]
field

Defines conditions on Content fields.

  • value type: integer, string, boolean
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between, like, contains
  • target: string Field identifier
  • required: false
  • default: not defined

Examples:

field:
    date_field:
        not:
            gt: 'today +5 days'
    price:
        between: [100, 200]
        not: 155
is_field_empty

Defines conditions on whether the Content fields are empty or not.

Note

IsEmptyField criterion is supported only by Solr search engine, so this condition can be used only with the FindService. In order to use it configure the query with parameter use_filter set to false.

  • value type: boolean, null
  • value format: single
  • operators: eq
  • target: string Field identifier
  • required: false
  • default: not defined

Examples:

is_field_empty:
    image: false
    video: true
# allow both empty and non-empty fields, which is also the default behaviour
is_field_empty:
    audio: ~
creation_date

Defines the creation (first publication) date of the Content as a timestamp or time string as accepted by PHP function strtotime.

  • value type: integer, string
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
creation_date: 1535117737
creation_date:
    eq: 1535117737
# identical to the example below
creation_date: [1435117737, 1535117737]
creation_date:
    in: [1435117737, 1535117737]
# multiple operators are combined with logical AND
creation_date:
    gt: '29 June 1991'
    lte: '5 August 1995'
creation_date:
    gt: 'today'
creation_date:
    between: ['-1 week 2 days 4 hours 2 seconds', 'today']
modification_date

Defines the modification (last publication) date of the Content as a timestamp or time string as accepted by PHP function strtotime.

  • value type: integer, string
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
modification_date: 1535117737
modification_date:
    eq: 1535117737
# identical to the example below
modification_date: [1435117737, 1535117737]
modification_date:
    in: [1435117737, 1535117737]
# multiple operators are combined with logical AND
modification_date:
    gt: '29 June 1991'
    lte: '5 August 1995'
modification_date:
    gt: 'today'
modification_date:
    between: ['-1 week 2 days 4 hours 2 seconds', 'today']
section

Defines Section of the Content by the identifier.

  • value type: string
  • value format: single, array
  • operators: eq, in
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
section: standard
section:
    eq: standard
# identical to the example below
section: [standard, restricted]
section:
    in: [standard, restricted]
state

Defines ObjectState of the Content by the ObjectStateGroup and ObjectState identifiers.

Note

Content can only exist in single ObjectState from the same ObjectStateGroup.

  • value type: string ObjectState identifier
  • value format: single
  • operators: eq
  • target: string ObjectStateGroup identifier
  • required: false
  • default: not defined

Examples:

# identical to the example below
state:
    ez_lock: not_locked
state:
    ez_lock:
        eq: not_locked
# multiple states are combined with logical AND
# identical to the example below
state:
    ez_lock: locked
    approval: rejected
state:
    ez_lock:
        eq: locked
    approval:
        eq: rejected
Common query parameters
limit

Defines the maximum number of items to return.

Note

This parameter will not be used if you execute the query from Twig using ng_query function. In that case Pargerfanta pager is used with semantic parameters page and max_per_page. To execute the query directly use ng_raw_query Twig function instead.

  • value type: integer
  • value format: single
  • required: false
  • default: 25

Examples:

limit: 10
offset

Defines the offset for search hits, used for paging the results.

Note

This parameter will not be used if you execute the query from Twig using ng_query function. In that case Pargerfanta pager is used with semantic parameters page and max_per_page. To execute the query directly use ng_raw_query Twig function instead.

  • value type: integer
  • value format: single
  • required: false
  • default: 0

Examples:

offset: 20
sort
  • value type: string, SortClause
  • value format: single, array
  • required: false
  • default: not defined

Here you can use any SortClause implementation. However, if you define the query in the view configuration, you won’t be able to instantiate the SortClause there. For that reason we provide a way to define the sort clause as a string instead. We this format a subset of commonly used SortClauses is supported. Sort direction is defined as asc for ascending and desc for descending. In can be omitted, in which case it will default to asc.

Strings can be used to define multiple sort clauses through an array of definitions:

sort:
    - depth asc
    - modified desc

Following sort clauses are available through string definition:

Location depth

String depth enables sorting by Location’s depth:

sort: depth
sort: depth asc
sort: depth desc
Content Field

String in form of of field/[content_type]/[field] enables sorting by any Content Field. For example by Field with identifier title in ContentType with identifier article:

sort: field/article/title
sort: field/article/title asc
sort: field/article/title desc
Content modification date

String modified enables sorting by the Content modification date:

sort: modified
sort: modified asc
sort: modified desc
Content name

String name enables sorting by the Content name:

sort: name
sort: name asc
sort: name desc
Location priority

String priority enables sorting by the Location priority:

sort: priority
sort: priority asc
sort: priority desc
Content publication date

String published enables sorting by the Content publication/creation date:

sort: published
sort: published asc
sort: published desc
Location hierarchy
Location children Query Type

This Query Type is used to build queries that fetch children Locations.

Identifier SiteAPI:Location/Children
Own conditions
Inherited Location conditions
Common Content conditions
Common query parameters
Examples

On full view for folder type Location fetch folder’s children Locations of the type document that are in restricted Section, sort them by priority descending and paginate them by 10 per page using URL query parameter page:

ezpublish:
    system:
        frontend_group:
            ngcontent_view:
                full:
                    folder:
                        template: '@ezdesign/content/full/folder.html.twig'
                        match:
                            Identifier\ContentType: folder
                        queries:
                            children_documents:
                                query_type: SiteAPI:Location/Children
                                max_per_page: 10
                                page: '@=queryParam("page", 1)'
                                parameters:
                                    content_type: document
                                    section: restricted
                                    sort: priority desc
{% set documents = ng_query( 'children_documents' ) %}

<h3>Documents in this folder</h3>

<ul>
{% for document in documents %}
    <li>{{ document.content.name }}</li>
{% endfor %}
</ul>

{{ pagerfanta( documents, 'twitter_bootstrap' ) }}
Own conditions
location

Defines the parent Location for children Locations.

Note

This condition is required. It’s also automatically set to the Location instance resolved by the view builder if the query is defined in the view builder configuration.

  • value type: Location
  • value format: single
  • operators: none
  • target: none
  • required: true
  • default: not defined

Examples:

# this is also automatically set when using from view builder configuration
location: '@=location'
# fetch children of the parent Location
location: '@=location.parent'
# fetch children of the parent Location's parent Location
location: '@=location.parent.parent'
Inherited Location conditions
main

Defines whether returned Locations are main Locations or not. Use true to get main Locations, false to get non-main Locations and null to get both (which is also the default behaviour).

  • value type: boolean, null
  • value format: single
  • operators: eq
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
main: true
main:
    eq: true
# get both main and non-main Locations, which is also the default behaviour
main: ~
priority

Defines the priority of the Location.

  • value type: integer
  • value format: single
  • operators: gt, gte, lt, lte, between
  • target: none
  • required: false
  • default: not defined

Examples:

# multiple operators are combined with logical AND
depth:
    gt: 4
    lte: 8
depth:
    between: [4, 7]
visible

Defines whether returned Locations are visible or not. Use true to get visible Locations, false to get hidden Locations and null to get both (which is also the default behaviour).

  • value type: boolean, null
  • value format: single
  • operators: eq
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
visible: false
visible:
    eq: false
# get both visible and hidden Locations, which also the default behaviour
visible: ~
Common Content conditions
content_type

Defines ContentType of the Content by the identifier.

  • value type: string
  • value format: single, array
  • operators: eq, in
  • target: string ContentType identifier
  • required: false
  • default: not defined

Examples:

# identical to the example below
content_type: article
content_type:
    eq: article
# identical to the example below
content_type: [image, video]
content_type:
    in: [image, video]
field

Defines conditions on Content fields.

  • value type: integer, string, boolean
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between, like, contains
  • target: string Field identifier
  • required: false
  • default: not defined

Examples:

field:
    date_field:
        not:
            gt: 'today +5 days'
    price:
        between: [100, 200]
        not: 155
is_field_empty

Defines conditions on whether the Content fields are empty or not.

Note

IsEmptyField criterion is supported only by Solr search engine, so this condition can be used only with the FindService. In order to use it configure the query with parameter use_filter set to false.

  • value type: boolean, null
  • value format: single
  • operators: eq
  • target: string Field identifier
  • required: false
  • default: not defined

Examples:

is_field_empty:
    image: false
    video: true
# allow both empty and non-empty fields, which is also the default behaviour
is_field_empty:
    audio: ~
creation_date

Defines the creation (first publication) date of the Content as a timestamp or time string as accepted by PHP function strtotime.

  • value type: integer, string
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
creation_date: 1535117737
creation_date:
    eq: 1535117737
# identical to the example below
creation_date: [1435117737, 1535117737]
creation_date:
    in: [1435117737, 1535117737]
# multiple operators are combined with logical AND
creation_date:
    gt: '29 June 1991'
    lte: '5 August 1995'
creation_date:
    gt: 'today'
creation_date:
    between: ['-1 week 2 days 4 hours 2 seconds', 'today']
modification_date

Defines the modification (last publication) date of the Content as a timestamp or time string as accepted by PHP function strtotime.

  • value type: integer, string
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
modification_date: 1535117737
modification_date:
    eq: 1535117737
# identical to the example below
modification_date: [1435117737, 1535117737]
modification_date:
    in: [1435117737, 1535117737]
# multiple operators are combined with logical AND
modification_date:
    gt: '29 June 1991'
    lte: '5 August 1995'
modification_date:
    gt: 'today'
modification_date:
    between: ['-1 week 2 days 4 hours 2 seconds', 'today']
section

Defines Section of the Content by the identifier.

  • value type: string
  • value format: single, array
  • operators: eq, in
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
section: standard
section:
    eq: standard
# identical to the example below
section: [standard, restricted]
section:
    in: [standard, restricted]
state

Defines ObjectState of the Content by the ObjectStateGroup and ObjectState identifiers.

Note

Content can only exist in single ObjectState from the same ObjectStateGroup.

  • value type: string ObjectState identifier
  • value format: single
  • operators: eq
  • target: string ObjectStateGroup identifier
  • required: false
  • default: not defined

Examples:

# identical to the example below
state:
    ez_lock: not_locked
state:
    ez_lock:
        eq: not_locked
# multiple states are combined with logical AND
# identical to the example below
state:
    ez_lock: locked
    approval: rejected
state:
    ez_lock:
        eq: locked
    approval:
        eq: rejected
Common query parameters
limit

Defines the maximum number of items to return.

Note

This parameter will not be used if you execute the query from Twig using ng_query function. In that case Pargerfanta pager is used with semantic parameters page and max_per_page. To execute the query directly use ng_raw_query Twig function instead.

  • value type: integer
  • value format: single
  • required: false
  • default: 25

Examples:

limit: 10
offset

Defines the offset for search hits, used for paging the results.

Note

This parameter will not be used if you execute the query from Twig using ng_query function. In that case Pargerfanta pager is used with semantic parameters page and max_per_page. To execute the query directly use ng_raw_query Twig function instead.

  • value type: integer
  • value format: single
  • required: false
  • default: 0

Examples:

offset: 20
sort
  • value type: string, SortClause
  • value format: single, array
  • required: false
  • default: as is defined on the parent Location (see location parameter)

Here you can use any SortClause implementation. However, if you define the query in the view configuration, you won’t be able to instantiate the SortClause there. For that reason we provide a way to define the sort clause as a string instead. We this format a subset of commonly used SortClauses is supported. Sort direction is defined as asc for ascending and desc for descending. In can be omitted, in which case it will default to asc.

Strings can be used to define multiple sort clauses through an array of definitions:

sort:
    - depth asc
    - modified desc

Following sort clauses are available through string definition:

Location depth

String depth enables sorting by Location’s depth:

sort: depth
sort: depth asc
sort: depth desc
Content Field

String in form of of field/[content_type]/[field] enables sorting by any Content Field. For example by Field with identifier title in ContentType with identifier article:

sort: field/article/title
sort: field/article/title asc
sort: field/article/title desc
Content modification date

String modified enables sorting by the Content modification date:

sort: modified
sort: modified asc
sort: modified desc
Content name

String name enables sorting by the Content name:

sort: name
sort: name asc
sort: name desc
Location priority

String priority enables sorting by the Location priority:

sort: priority
sort: priority asc
sort: priority desc
Content publication date

String published enables sorting by the Content publication/creation date:

sort: published
sort: published asc
sort: published desc
Location siblings Query Type

This Query Type is used to build queries that fetch Location siblings.

Identifier SiteAPI:Location/Siblings
Own conditions
Inherited Location conditions
Common Content conditions
Common query parameters
Examples

On the full view for article type Content fetch all siblings of type news that are in ObjectState review/approved, sort them by name and paginate them by 10 per page using URL query parameter page:

ezpublish:
    system:
        frontend_group:
            ngcontent_view:
                full:
                    article:
                        template: '@ezdesign/content/full/article.html.twig'
                        match:
                            Identifier\ContentType: article
                        queries:
                            news_siblings:
                                query_type: SiteAPI:Location/Siblings
                                max_per_page: 10
                                page: '@=queryParam("page", 1)'
                                parameters:
                                    content_type: news
                                    state:
                                        review: approved
                                    sort: name
{% set news_list = ng_query( 'news_siblings' ) %}

<h3>Article's news siblings</h3>

<ul>
{% for news in news_list %}
    <li>{{ news.content.name }}</li>
{% endfor %}
</ul>

{{ pagerfanta( news_list, 'twitter_bootstrap' ) }}
Own conditions
location

Defines sibling Location reference for fetching other siblings Locations.

Note

This condition is required. It’s also automatically set to the Location instance resolved by the view builder if the query is defined in the view builder configuration.

  • value type: Location
  • value format: single
  • operators: none
  • target: none
  • required: true
  • default: not defined

Examples:

# this is also automatically set when using from view builder configuration
location: '@=location'
# fetch siblings of the parent Location
location: '@=location.parent'
# fetch siblings of the parent Location's parent Location
location: '@=location.parent.parent'
Inherited Location conditions
main

Defines whether returned Locations are main Locations or not. Use true to get main Locations, false to get non-main Locations and null to get both (which is also the default behaviour).

  • value type: boolean, null
  • value format: single
  • operators: eq
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
main: true
main:
    eq: true
# get both main and non-main Locations, which is also the default behaviour
main: ~
priority

Defines the priority of the Location.

  • value type: integer
  • value format: single
  • operators: gt, gte, lt, lte, between
  • target: none
  • required: false
  • default: not defined

Examples:

# multiple operators are combined with logical AND
depth:
    gt: 4
    lte: 8
depth:
    between: [4, 7]
visible

Defines whether returned Locations are visible or not. Use true to get visible Locations, false to get hidden Locations and null to get both (which is also the default behaviour).

  • value type: boolean, null
  • value format: single
  • operators: eq
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
visible: false
visible:
    eq: false
# get both visible and hidden Locations, which also the default behaviour
visible: ~
Common Content conditions
content_type

Defines ContentType of the Content by the identifier.

  • value type: string
  • value format: single, array
  • operators: eq, in
  • target: string ContentType identifier
  • required: false
  • default: not defined

Examples:

# identical to the example below
content_type: article
content_type:
    eq: article
# identical to the example below
content_type: [image, video]
content_type:
    in: [image, video]
field

Defines conditions on Content fields.

  • value type: integer, string, boolean
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between, like, contains
  • target: string Field identifier
  • required: false
  • default: not defined

Examples:

field:
    date_field:
        not:
            gt: 'today +5 days'
    price:
        between: [100, 200]
        not: 155
is_field_empty

Defines conditions on whether the Content fields are empty or not.

Note

IsEmptyField criterion is supported only by Solr search engine, so this condition can be used only with the FindService. In order to use it configure the query with parameter use_filter set to false.

  • value type: boolean, null
  • value format: single
  • operators: eq
  • target: string Field identifier
  • required: false
  • default: not defined

Examples:

is_field_empty:
    image: false
    video: true
# allow both empty and non-empty fields, which is also the default behaviour
is_field_empty:
    audio: ~
creation_date

Defines the creation (first publication) date of the Content as a timestamp or time string as accepted by PHP function strtotime.

  • value type: integer, string
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
creation_date: 1535117737
creation_date:
    eq: 1535117737
# identical to the example below
creation_date: [1435117737, 1535117737]
creation_date:
    in: [1435117737, 1535117737]
# multiple operators are combined with logical AND
creation_date:
    gt: '29 June 1991'
    lte: '5 August 1995'
creation_date:
    gt: 'today'
creation_date:
    between: ['-1 week 2 days 4 hours 2 seconds', 'today']
modification_date

Defines the modification (last publication) date of the Content as a timestamp or time string as accepted by PHP function strtotime.

  • value type: integer, string
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
modification_date: 1535117737
modification_date:
    eq: 1535117737
# identical to the example below
modification_date: [1435117737, 1535117737]
modification_date:
    in: [1435117737, 1535117737]
# multiple operators are combined with logical AND
modification_date:
    gt: '29 June 1991'
    lte: '5 August 1995'
modification_date:
    gt: 'today'
modification_date:
    between: ['-1 week 2 days 4 hours 2 seconds', 'today']
section

Defines Section of the Content by the identifier.

  • value type: string
  • value format: single, array
  • operators: eq, in
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
section: standard
section:
    eq: standard
# identical to the example below
section: [standard, restricted]
section:
    in: [standard, restricted]
state

Defines ObjectState of the Content by the ObjectStateGroup and ObjectState identifiers.

Note

Content can only exist in single ObjectState from the same ObjectStateGroup.

  • value type: string ObjectState identifier
  • value format: single
  • operators: eq
  • target: string ObjectStateGroup identifier
  • required: false
  • default: not defined

Examples:

# identical to the example below
state:
    ez_lock: not_locked
state:
    ez_lock:
        eq: not_locked
# multiple states are combined with logical AND
# identical to the example below
state:
    ez_lock: locked
    approval: rejected
state:
    ez_lock:
        eq: locked
    approval:
        eq: rejected
Common query parameters
limit

Defines the maximum number of items to return.

Note

This parameter will not be used if you execute the query from Twig using ng_query function. In that case Pargerfanta pager is used with semantic parameters page and max_per_page. To execute the query directly use ng_raw_query Twig function instead.

  • value type: integer
  • value format: single
  • required: false
  • default: 25

Examples:

limit: 10
offset

Defines the offset for search hits, used for paging the results.

Note

This parameter will not be used if you execute the query from Twig using ng_query function. In that case Pargerfanta pager is used with semantic parameters page and max_per_page. To execute the query directly use ng_raw_query Twig function instead.

  • value type: integer
  • value format: single
  • required: false
  • default: 0

Examples:

offset: 20
sort
  • value type: string, SortClause
  • value format: single, array
  • required: false
  • default: not defined

Here you can use any SortClause implementation. However, if you define the query in the view configuration, you won’t be able to instantiate the SortClause there. For that reason we provide a way to define the sort clause as a string instead. We this format a subset of commonly used SortClauses is supported. Sort direction is defined as asc for ascending and desc for descending. In can be omitted, in which case it will default to asc.

Strings can be used to define multiple sort clauses through an array of definitions:

sort:
    - depth asc
    - modified desc

Following sort clauses are available through string definition:

Location depth

String depth enables sorting by Location’s depth:

sort: depth
sort: depth asc
sort: depth desc
Content Field

String in form of of field/[content_type]/[field] enables sorting by any Content Field. For example by Field with identifier title in ContentType with identifier article:

sort: field/article/title
sort: field/article/title asc
sort: field/article/title desc
Content modification date

String modified enables sorting by the Content modification date:

sort: modified
sort: modified asc
sort: modified desc
Content name

String name enables sorting by the Content name:

sort: name
sort: name asc
sort: name desc
Location priority

String priority enables sorting by the Location priority:

sort: priority
sort: priority asc
sort: priority desc
Content publication date

String published enables sorting by the Content publication/creation date:

sort: published
sort: published asc
sort: published desc
Location subtree Query Type

This Query Type is used to build queries that fetch from the Location subtree.

Identifier SiteAPI:Location/Subtree
Own conditions
Inherited Location conditions
Common Content conditions
Common query parameters
Examples

Subtree of the calendar type Location contains event type Locations. On the full view for calendar fetch all pending events from its subtree up to depth of 3, sort them by their start date and paginate them by 10 per page using URL query parameter page:

ezpublish:
    system:
        frontend_group:
            ngcontent_view:
                full:
                    calendar:
                        template: '@ezdesign/content/full/calendar.html.twig'
                        match:
                            Identifier\ContentType: calendar
                        queries:
                            pending_events:
                                query_type: SiteAPI:Location/Subtree
                                max_per_page: 10
                                page: '@=queryParam("page", 1)'
                                parameters:
                                    content_type: event
                                    relative_depth:
                                        lte: 3
                                    field:
                                        start_date:
                                            gt: '@=timestamp("today")'
                                    sort: field/event/start_date asc
{% set events = ng_query( 'pending_events' ) %}

<h3>Pending events</h3>

<ul>
{% for event in events %}
    <li>{{ event.content.name }}</li>
{% endfor %}
</ul>

{{ pagerfanta( events, 'twitter_bootstrap' ) }}
Own conditions
exclude_self

Defines whether to include Location defined by the location condition in the result set.

  • value type: boolean
  • value format: single
  • operators: none
  • target: none
  • required: false
  • default: true

Examples:

# do not include the subtree root Location, this is also default behaviour
exclude_self: true
# include the subtree root Location
exclude_self: false
location

Defines the root Location of the Location subtree.

Note

This condition is required. It’s also automatically set to the Location instance resolved by the view builder if the query is defined in the view builder configuration.

  • value type: Location
  • value format: single
  • operators: none
  • target: none
  • required: true
  • default: not defined

Examples:

# this is also automatically set when using from view builder configuration
location: '@=location'
# fetch from subtree of the parent Location
location: '@=location.parent'
# fetch from subtree of the parent Location's parent Location
location: '@=location.parent.parent'
relative_depth

Defines depth of the Location in the tree relative to the Location defined by location condition.

  • value type: integer
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
relative_depth: 2
relative_depth:
    eq: 2
# identical to the example below
relative_depth: [2, 3]
relative_depth:
    in: [2, 3]
# multiple operators are combined with logical AND
relative_depth:
    in: [2, 3]
    gt: 1
    lte: 3
relative_depth:
    between: [2, 4]
Inherited Location conditions
depth

Defines absolute depth of the Location in the tree.

  • value type: integer
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
depth: 3
depth:
    eq: 3
# identical to the example below
depth: [3, 4, 8]
depth:
    in: [3, 4, 8]
# multiple operators are combined with logical AND
depth:
    in: [3, 4, 5]
    gt: 4
    lte: 8
depth:
    between: [4, 7]
main

Defines whether returned Locations are main Locations or not. Use true to get main Locations, false to get non-main Locations and null to get both (which is also the default behaviour).

  • value type: boolean, null
  • value format: single
  • operators: eq
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
main: true
main:
    eq: true
# get both main and non-main Locations, which is also the default behaviour
main: ~
priority

Defines the priority of the Location.

  • value type: integer
  • value format: single
  • operators: gt, gte, lt, lte, between
  • target: none
  • required: false
  • default: not defined

Examples:

# multiple operators are combined with logical AND
depth:
    gt: 4
    lte: 8
depth:
    between: [4, 7]
visible

Defines whether returned Locations are visible or not. Use true to get visible Locations, false to get hidden Locations and null to get both (which is also the default behaviour).

  • value type: boolean, null
  • value format: single
  • operators: eq
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
visible: false
visible:
    eq: false
# get both visible and hidden Locations, which also the default behaviour
visible: ~
Common Content conditions
content_type

Defines ContentType of the Content by the identifier.

  • value type: string
  • value format: single, array
  • operators: eq, in
  • target: string ContentType identifier
  • required: false
  • default: not defined

Examples:

# identical to the example below
content_type: article
content_type:
    eq: article
# identical to the example below
content_type: [image, video]
content_type:
    in: [image, video]
field

Defines conditions on Content fields.

  • value type: integer, string, boolean
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between, like, contains
  • target: string Field identifier
  • required: false
  • default: not defined

Examples:

field:
    date_field:
        not:
            gt: 'today +5 days'
    price:
        between: [100, 200]
        not: 155
is_field_empty

Defines conditions on whether the Content fields are empty or not.

Note

IsEmptyField criterion is supported only by Solr search engine, so this condition can be used only with the FindService. In order to use it configure the query with parameter use_filter set to false.

  • value type: boolean, null
  • value format: single
  • operators: eq
  • target: string Field identifier
  • required: false
  • default: not defined

Examples:

is_field_empty:
    image: false
    video: true
# allow both empty and non-empty fields, which is also the default behaviour
is_field_empty:
    audio: ~
creation_date

Defines the creation (first publication) date of the Content as a timestamp or time string as accepted by PHP function strtotime.

  • value type: integer, string
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
creation_date: 1535117737
creation_date:
    eq: 1535117737
# identical to the example below
creation_date: [1435117737, 1535117737]
creation_date:
    in: [1435117737, 1535117737]
# multiple operators are combined with logical AND
creation_date:
    gt: '29 June 1991'
    lte: '5 August 1995'
creation_date:
    gt: 'today'
creation_date:
    between: ['-1 week 2 days 4 hours 2 seconds', 'today']
modification_date

Defines the modification (last publication) date of the Content as a timestamp or time string as accepted by PHP function strtotime.

  • value type: integer, string
  • value format: single, array
  • operators: eq, in, gt, gte, lt, lte, between
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
modification_date: 1535117737
modification_date:
    eq: 1535117737
# identical to the example below
modification_date: [1435117737, 1535117737]
modification_date:
    in: [1435117737, 1535117737]
# multiple operators are combined with logical AND
modification_date:
    gt: '29 June 1991'
    lte: '5 August 1995'
modification_date:
    gt: 'today'
modification_date:
    between: ['-1 week 2 days 4 hours 2 seconds', 'today']
section

Defines Section of the Content by the identifier.

  • value type: string
  • value format: single, array
  • operators: eq, in
  • target: none
  • required: false
  • default: not defined

Examples:

# identical to the example below
section: standard
section:
    eq: standard
# identical to the example below
section: [standard, restricted]
section:
    in: [standard, restricted]
state

Defines ObjectState of the Content by the ObjectStateGroup and ObjectState identifiers.

Note

Content can only exist in single ObjectState from the same ObjectStateGroup.

  • value type: string ObjectState identifier
  • value format: single
  • operators: eq
  • target: string ObjectStateGroup identifier
  • required: false
  • default: not defined

Examples:

# identical to the example below
state:
    ez_lock: not_locked
state:
    ez_lock:
        eq: not_locked
# multiple states are combined with logical AND
# identical to the example below
state:
    ez_lock: locked
    approval: rejected
state:
    ez_lock:
        eq: locked
    approval:
        eq: rejected
Common query parameters
limit

Defines the maximum number of items to return.

Note

This parameter will not be used if you execute the query from Twig using ng_query function. In that case Pargerfanta pager is used with semantic parameters page and max_per_page. To execute the query directly use ng_raw_query Twig function instead.

  • value type: integer
  • value format: single
  • required: false
  • default: 25

Examples:

limit: 10
offset

Defines the offset for search hits, used for paging the results.

Note

This parameter will not be used if you execute the query from Twig using ng_query function. In that case Pargerfanta pager is used with semantic parameters page and max_per_page. To execute the query directly use ng_raw_query Twig function instead.

  • value type: integer
  • value format: single
  • required: false
  • default: 0

Examples:

offset: 20
sort
  • value type: string, SortClause
  • value format: single, array
  • required: false
  • default: not defined

Here you can use any SortClause implementation. However, if you define the query in the view configuration, you won’t be able to instantiate the SortClause there. For that reason we provide a way to define the sort clause as a string instead. We this format a subset of commonly used SortClauses is supported. Sort direction is defined as asc for ascending and desc for descending. In can be omitted, in which case it will default to asc.

Strings can be used to define multiple sort clauses through an array of definitions:

sort:
    - depth asc
    - modified desc

Following sort clauses are available through string definition:

Location depth

String depth enables sorting by Location’s depth:

sort: depth
sort: depth asc
sort: depth desc
Content Field

String in form of of field/[content_type]/[field] enables sorting by any Content Field. For example by Field with identifier title in ContentType with identifier article:

sort: field/article/title
sort: field/article/title asc
sort: field/article/title desc
Content modification date

String modified enables sorting by the Content modification date:

sort: modified
sort: modified asc
sort: modified desc
Content name

String name enables sorting by the Content name:

sort: name
sort: name asc
sort: name desc
Location priority

String priority enables sorting by the Location priority:

sort: priority
sort: priority asc
sort: priority desc
Content publication date

String published enables sorting by the Content publication/creation date:

sort: published
sort: published asc
sort: published desc
Query configuration

Query Types have their own semantic configuration under queries key in configuration for a particular Content view. Under this key separate queries are defined under their own identifier keys, which are later used to reference the configured query from the Twig templates.

Available parameters and their default values are:

  • query_type - identifies the Query Type to be used
  • named_query - identifies named query to be used
  • max_per_page: 25 - pagination parameter for maximum number of items per page
  • page: 1 - pagination parameter for current page
  • use_filter: true - whether to use FilterService or FindService for executing the query
  • parameters: [] - contains the actual Query Type parameters

Parameters query_type and named_query are mutually exclusive, you are allowed to set only one or the other. But they are also mandatory - you will have to set one of them.

Example below shows how described configuration looks in practice:

ezpublish:
    system:
        frontend_group:
            ngcontent_view:
                full:
                    category:
                        template: '@ezdesign/content/full/category.html.twig'
                        match:
                            Identifier\ContentType: 'category'
                        queries:
                            children:
                                query_type: 'SiteAPI:Location/Children'
                                max_per_page: 10
                                page: 1
                                parameters:
                                    content_type: 'article'
                                    sort: 'published desc'
                            related_images:
                                query_type: 'SiteAPI:Content/Relations/ForwardFields'
                                max_per_page: 10
                                page: 1
                                parameters:
                                    content_type: 'image'
                                    sort: 'published desc'
                        params:
                            ...

Note

You can define unlimited number of queries on any controller.

Named query configuration

As hinted above with named_query parameter, it is possible to define “named queries”, which can be referenced in query configuration for a particular content view. They are configured under ng_named_query, which is a top section of a siteaccess configuration, on the same level as ng_content_view:

ezpublish:
    system:
        frontend_group:
            ng_named_query:
                children_named_query:
                    query_type: 'SiteAPI:Location/Children'
                    max_per_page: 10
                    page: 1
                    parameters:
                        content_type: 'article'
                        sort: 'published desc'
            ngcontent_view:
                full:
                    category:
                        template: '@ezdesign/content/full/category.html.twig'
                        match:
                            Identifier\ContentType: 'category'
                        queries:
                            children: 'children_named_query'
                            children_5_per_page:
                                named_query: 'children_named_query'
                                max_per_page: 5
                            images:
                                named_query: 'children_named_query'
                                parameters:
                                    content_type: 'image'
                        params:
                            ...

Note

You can override some of the parameters from the referenced named query.

You can notice that there are two ways of referencing a named query. In case when there are no other parameters, you can do it directly like this:.

queries:
    children: 'children_named_query'

The example above is really just a shortcut to the example below:

queries:
    children:
        named_query: 'children_named_query'

You can also notice that it’s possible to override parameters from the referenced named query. This is limited to first level keys from the main configuration and also first level keys under the parameters key.

Parameters with expressions

When defining parameters it’s possible to use expressions. These are evaluated by Symfony’s Expression Language component, whose syntax is based on Twig and is documented here.

Expression strings are recognized by @= prefix. Following sections describe available objects, services and functions.

View object

Site API View object is available as view. You can access any parameters injected into it, for example current page value in children query:

...
    queries:
        children:
            query_type: 'SiteAPI:Location/Children'
            max_per_page: 10
            page: '@=view.getParameter("page")'
            parameters:
                content_type: 'article'
                sort: 'published desc'

Method getParameter() on the View object does not support default value fallback, so if the requested parameter is not there an exception will be thrown. Function viewParam(name, default) is a wrapper around it that provides a default value fallback:

...
    queries:
        children:
            query_type: 'SiteAPI:Location/Children'
            max_per_page: 10
            page: '@=viewParam("page", 10)'
            parameters:
                content_type: 'article'
                sort: 'published desc'
Request object

Symfony’s Request object is available as request. For example, you can access current page directly from the parameter in the Request object:

...
    queries:
        children:
            query_type: 'SiteAPI:Location/Children'
            max_per_page: 10
            page: '@=request.query.get("page", 1)'
            parameters:
                content_type: 'article'
                sort: 'published desc'

Several functions relating to the Request object are also available. These provide access to the Request values in a more convenient way. First of these is:

queryParam(name, default, array allowed = null)

This function is a shortcut to GET / query string parameters on the Request object. Through optional third parameter allowed you can define an array of allowed values. This can be useful when you need to limit what is being passed through the query string. For example you can use it to limit filtering by ContentType to articles and news items:

...
    queries:
        children:
            query_type: 'SiteAPI:Location/Children'
            max_per_page: 10
            page: '@=queryParam("page", 1)'
            parameters:
                content_type: '@=queryParam("type", "article", ["article", "news"])'
                sort: 'published desc'

Query string parameters accessed through the Request object will always be of the string type, which can be a problem if you need to use them for configuration that expects a different scalar type. For that reason separate type-casting getter functions are also provided:

  • queryParamInt(name, default, array allowed = null)

    Performs type casting of the found value to integer type.

  • queryParamBool(name, default, array allowed = null)

    Performs type casting of the found value to boolean type.

  • queryParamFloat(name, default, array allowed = null)

    Performs type casting of the found value to float type.

  • queryParamString(name, default, allowed = [])

    Performs type casting of the found value to string type.

Content and Location objects

Site API Content object is available as content. For example you could store ContentType identifier for the children in a TextLine field content_type and access it like this:

...
    queries:
        children:
            query_type: 'SiteAPI:Location/Children'
            max_per_page: 10
            page: 1
            parameters:
                content_type: '@=content.fields.content_type.value.text'
                sort: 'published desc'

Site API Location object is available as location. In the following example we use it to find only children of the same ContentType as the parent:

...
    queries:
        children:
            query_type: 'SiteAPI:Location/Children'
            max_per_page: 10
            page: 1
            parameters:
                content_type: '@=location.contentInfo.contentTypeIdentifier'
                sort: 'published desc'
Configuration

eZ Platform ConfigResolver service is available as configResolver. Through it you can access dynamic (per siteaccess) configuration, for example maximum items per page:

ngsite.eng.max_per_page: 10 # limit to 10 items on English siteaccess
ngsite.jpn.max_per_page: 20 # and 20 items on Japanese siteaccess
...
    ng_named_query:
        children:
            query_type: 'SiteAPI:Location/Children'
            max_per_page: '@=configResolver.getParameter("max_per_page", "ngsite")'
            page: 1
            parameters:
                content_type: 'article'
                sort: 'published desc'

Function config(name, namespace = null, scope = null) is a shortcut to getParameter() method of ConfigResolver service:

ngsite.eng.max_per_page: 10 # limit to 10 items on English siteaccess
ngsite.jpn.max_per_page: 20 # and 20 items on Japanese siteaccess
...
    ng_named_query:
        children:
            query_type: 'SiteAPI:Location/Children'
            max_per_page: '@=config("max_per_page", "ngsite")'
            page: 1
            parameters:
                content_type: 'article'
                sort: 'published desc'
Named Objects

Named objects feature provides a way to configure specific objects (Content, Location and Tag) by name and ID, and a way to access them by name from PHP, Twig and Query Type configuration. Site API NamedObjectProvider service is available as namedObject. Its purpose is providing access to configured named objects.

Note

Configuration of named objects is documented in more detail on the Configuration page. Usage of named objects from PHP is documented on the Services page.

The following example shows how to configure named query that will fetch top categories (Locations of type category found below the root Location):

netgen_ez_platform_site_api:
    system:
        frontend_group:
            named_objects:
                location:
                    homepage: 2
ezpublish:
    system:
        frontend_group:
            ng_named_query:
                top_categories:
                    query_type: 'SiteAPI:Location/Children'
                    parameters:
                        location: '@=namedObject.getLocation("homepage")'
                        content_type: 'category'
                        sort: 'name desc'

Shortcut functions are available for accessing each type of named object directly:

  • namedContent(name)

    Provides access to named Content.

  • namedLocation(name)

    Provides access to named Location.

  • namedTag(name)

    Provides access to named Tag.

Miscellaneous
  • timestamp(value)

    This function is used to get a timestamp value, typically used to define time conditions on the query. For example you could use it to fetch only events that have not yet started:

    ...
        queries:
            pending_events:
                query_type: SiteAPI:Location/Subtree
                max_per_page: 10
                page: 1
                parameters:
                    content_type: event
                    field:
                        start_date:
                            gt: '@=timestamp("today")'
    

    Note

    Function timestamp() maps directly to the PHP’s function strtotime. That means it accepts any date and time format supported by that function.

Templating

Configured queries will be available in Twig templates, through ng_query or ng_raw_query. The difference it that the former will return a Pagerfanta instance, while the latter will return an instance of SearchResult. That also means ng_query will use max_per_page and page parameters to configure the pager, while ng_raw_query ignores them and executes the configured query directly.

Note

Queries are only executed as you access them through ng_query or ng_raw_query. If you don’t call those functions on any of the configured queries, none of them will be executed.

Both ng_query and ng_raw_query accept a single argument. This is the identifier of the query, which is the key under the queries section, under which the query is configured.

Example usage of ng_query:

{% set images = ng_query( 'images' ) %}

<p>Total images: {{ images.nbResults }}</p>

{% for image in images %}
    <p>{{ image.content.name }}</p>
{% endfor %}

{{ pagerfanta( images, 'twitter_bootstrap' ) }}

Example usage of ng_raw_query:

{% set searchResult = ng_raw_query( 'categories' ) %}

{% for categoryHit in searchResult.searchHits %}
    <p>{{ categoryHit.valueObject.content.name }}: {{ categoryHit.valueObject.score }}</p>
{% endfor %}

Note

You can’t execute named queries. They are only available for referencing in concrete query configuration for a particular view.

Hint

Execution of queries is not cached. If you call ng_query or ng_raw_query on the same query multiple times, the same query will be executed multiple times. If you need to access the query result multiple times, store it in a variable and access the variable instead.

Objects

Site API comes with its own set of entities and values. These are similar, but still different from their counterparts in eZ Platform’s Repository API. Main benefits they provide over them are:

  • Content is available in a single translation, this voids the need for various helper services
  • Additional properties otherwise available only through separate entities (like ContentType identifier, FieldType identifier and others)
  • Additional properties and methods that enable simple traversal and filtering of the content model (relations, parent, siblings, children)

Note

Note that content traversal that is achievable through the objects is not complete. It aims to cover only the most common use cases. For more complex use cases Query Types should be used.

Note

In Twig templates methods beginning with get and is are also available with that prefix removed. Also, parentheses can be omitted if there are no required arguments.

For example, method field.isEmpty() is also available as field.empty() or just field.empty, and method content.getLocations() is available as content.locations() or just content.locations.

Content on this page:

Content

The first difference from Repository Content is that it exist it a single translation only, meaning it contains the fields for only one translation. That will always be the translation to be rendered on the siteaccess. You won’t need to choose the field in the correct translation, manually or through some kind of helper service. The Content’s single translation is always the correct one.

Content fields are lazy-loaded, which means they are initially not loaded, but will be transparently loaded at the point you access them. This voids the need to have separate, lightweight version of Content (ContentInfo plays this role in Repository API). It also provides you with some additional properties and methods.

Example usage from Twig:

<h1>{{ content.name }}</h1>
<h2>Parent name: {{ content.mainLocation.parent.content.name }}</h2>
<h3>Number of Locations: {{ content.locations|length }}</h3>

{% for field in content.fields %}
    {% if not field.empty %}
        {{ ng_render_field(field) }}
    {% endif %}
{% endfor %}
Methods
hasField

Check if Content has a Field with the given $identifier.

Parameters string $identifier
Returns bool
Example in PHP
if ($content->hasField('title')) {
    // ...
}
Example in Twig
{% if content.hasField('title') %}
    ...
{% endif %}
getField

Get the Field with the given $identifier.

Note

This method can return null if Field with the given $identifier doesn’t exist.

Parameters string $identifier
Returns Field instance or null
Example in PHP
$field = $content->getField('title');
Example in Twig
{{ set field = content.field('title') }}
hasFieldById

Check if Content has a Field with the given $id.

Parameters int|string $id
Returns bool
Example in PHP
$content->hasFieldById(42);
Example in Twig
{{ content.hasFieldById(42) }}
getFieldById

Get the Field with the given $id.

Note

This method can return null if Field with the given $id doesn’t exist.

Parameters string $id
Returns Field instance or null
Example in PHP
$field = $content->getFieldById(42));
Example in Twig
{% set field = content.fieldById(42) %}
getFieldValue

Get the value of the Field with the given $identifier.

Note

This method can return null if Field with the given $identifier doesn’t exist.

Note

Returned value object depends of the FieldType. Best way to learn about the specific value format is reading the official FieldType reference documentation, or looking directly at code (for example the code of TextLine Value).

Parameters string $identifier
Returns Value instance of the Field or null
Example in PHP
$value = $content->getFieldValue('title'));
Example in Twig
{% set value = content.fieldValue('title') %}
getFieldValueById

Get the value of the Field with the given $id.

Note

This method can return null if Field with the given $id doesn’t exist.

Parameters string $id
Returns Value instance of the Field or null
Example in PHP
$value = $content->getFieldValueById(42));
Example in Twig
{% set value = content.fieldValueById(42) %}
getLocations

Used to get Content’s Locations, limited by the $limit. Locations will be sorted their path string (a string with materialized IDs, e.g. /1/2/45/67/).

Parameters int $limit = 25
Returns An array of Content’s Locations
Sorting method Location’s path string (e.g. /1/2/45/67/)
Example in PHP
$locations = $content->locations(10));
Example in Twig
{% set locations = content.locations %}
filterLocations

List a slice of Content’s Locations, by the $maxPerPage and $currentPage. Locations will be sorted their path string (a string with materialized IDs, e.g. /1/2/45/67/).

Parameters
  1. int $maxPerPage = 25
  2. int $currentPage = 1
Returns Pagerfanta instance with a slice of Content’s Locations
Sorting method Location’s path string (e.g. /1/2/45/67/)
Example in PHP
$locations = $content->filterLocations(10, 2));
Example in Twig
{% set locations = content.filterLocations(10, 2) %}
getFieldRelation

Used to get a single field relation from the Field with the given $identifier.

Parameters string $identifier
Returns Related Content or null if the relation does not exist
Example in PHP
$relation = $content->getFieldRelation('author'));
Example in Twig
{% set relation = content.fieldRelation('author') %}
getFieldRelations

Used to get $limit field relations from the Field with the given $identifier. Relations will be sorted as is defined by the relation field.

Parameters
  1. string $identifier
  2. int $limit = 25
Returns An array of related Content items
Sorting method Sorted as is defined by the relation Field
Example in PHP
$relations = $content->getFieldRelations('images', 10));
Example in Twig
{% set relations = content.fieldRelations('images') %}
filterFieldRelations

Used to filter field relations from the Field with the given $identifier.

Parameters
  1. string $identifier
  2. array $contentTypeIdentifiers = []
  3. int $maxPerPage = 25
  4. int $currentPage = 1
Returns Pagerfanta instance with related Content items
Example in PHP
$relations = $content->filterFieldRelations(
    'related_items',
    ['images', 'videos'],
    10,
    2
);
Example in Twig
{% set relations = content.fieldRelation(
    'related_items'
    ['images', 'videos']
    10,
    2
) %}
Properties
Name Type Description
$id string|int ID
$mainLocationId string|int|null Optional main Location ID
$name string Name
$languageCode string Translation language code
$contentInfo ContentInfo ContentInfo object
$fields Field[]
An array of Field instances, which can be accessed
in two different ways:
{{ set field = content.fields.title }}
{{ set field = content.fields['title'] }}
$mainLocation Location Optional Location object
$owner Content Optional owner user’s Content object
ContentInfo

Site ContentInfo object is similar to the Repository ContentInfo, additionally providing access to

Properties
Name Type Description
$id string|int ID of the Content
$contentTypeId string|int ID of the ContentType
$sectionId string|int ID of the Section
$currentVersionNo int Current version number
$published bool Indicates that the Content is published
$ownerId string|int ID of the owner user Content
$modificationDate \DateTime
Modification date
$publishedDate \DateTime Publication date
$alwaysAvailable bool
Indicates that the Content is always available in its
main translation
$remoteId string Remote ID of the Content
$mainLanguageCode string Main translation language code
$mainLocationId string|int ID of the main Location
$name string Content’s name
$languageCode string Language code of Content’s translation
$contentTypeIdentifier string Identifier of the Content Type
$contentTypeName string Name of the Content Type
$contentTypeDescription string Description of the Content Type
$mainLocation Location Content’s main Location object
Field

Site Field object is similar to the Repository Field, additionally providing access to the field’s Content and properties that are otherwise available only through the corresponding FieldDefinition object: name, description and FieldType identifier.

Methods
isEmpty

Checks if the field’s value is empty.

Parameters None
Returns bool
Example in PHP
if ($content->getField('title')->isEmpty()) {
    // ...
}
Example in Twig
{% if content.fields.title.empty %}
    ...
{% endif %}
isSurrogate

Checks if the field is of ngsurrogate type, returned when nonexistent field is requested from Content.

Parameters None
Returns bool
Example in PHP
if ($content->getField('title')->isSurrogate()) {
    // ...
}
Example in Twig
{% if content.fields.title.surrogate %}
    ...
{% endif %}
Properties
Name Type Description
$id string|int ID of the Field
$fieldDefIdentifier string Identifier (FieldDefinition identifier, e.g. title)
$value Value object Value object
$languageCode string Translation language code
$fieldTypeIdentifier string FieldType identifier (e.g. ezstring)
$name string ID of the Content
$description string ID of the Content
$content Content ID of the Content
Location

Site Location object is similar to the Repository Location, additionally providing methods and properties that enable simple traversal and filtering of the Location tree (siblings, children, parent, ancestors etc).

Methods
getChildren

List children Locations.

Children will be sorted as is defined by their parent Location, which is the Location the method is called on. The single optional parameter of this method is $limit, which limits the number of children returned and defaults to 25.

Parameters string $limit = 25
Returns An array of first $limit children Locations
Sorting method As is defined by the Location
Example in PHP
$children = $location->getChildren(10));
Example in Twig
{% set children = location.children(10) %}
filterChildren

Filter and paginate children Locations.

This enables filtering of the children by their ContentType with $contentTypeIdentifiers parameter and pagination using $maxPerPage and $currentPage parameters. The method returns a Pagerfanta instance.

Parameters
  1. array $contentTypeIdentifiers = []
  2. int $maxPerPage = 25
  3. int $currentPage = 1
Returns Pagerfanta instance with a slice of children Locations
Sorting method As is defined by the Location
Example in PHP
$children = $content->filterChildren(['articles'], 10, 2);
Example in Twig
{% set relation = content.filterChildren(
    ['articles'],
    10,
    2
) %}
getSiblings

List sibling Locations.

Siblings will be sorted as is defined by their parent Location, which is the parent Location of the Location the method is called on. The single optional parameter of this method is $limit, which limits the number of siblings returned and defaults to 25.

Parameters string $limit = 25
Returns An array of first $limit sibling Locations
Sorting method As is defined by the parent Location
Example in PHP
$siblings = $location->getSiblings(10);
Example in Twig
{% set siblings = location.siblings(10) %}
filterSiblings

Filter and paginate sibling Locations.

This enables filtering of the siblings by their ContentType with $contentTypeIdentifiers parameter and pagination using $maxPerPage and $currentPage parameters. The method returns a Pagerfanta instance.

Parameters
  1. array $contentTypeIdentifiers = []
  2. int $maxPerPage = 25
  3. int $currentPage = 1
Returns Pagerfanta instance with a slice of filtered sibling Locations
Sorting method As is defined by the parent Location
Example in PHP
$siblings = $location->filterSiblings(['articles'], 10, 2);
Example in Twig
{% set siblings = location.filterSiblings(
    ['articles'],
    10,
    2
) %}
Properties
Name Type Description
$id string|int ID of the Location
$status int Constant defining status (published or draft)
$priority int Priority
$hidden bool Own hidden state
$invisible bool Invisibility state (hidden by itself or by an ancestor)
$remoteId string Remote ID
$parentLocationId string|int Parent Location ID
$pathString string Path with materialized IDs (/1/2/42/56/)
$path int[] An array with materialized IDs ([1, 2, 42, 56])
$depth int Depth in the Location tree
$sortField int Constant defining field for sorting children Locations
$sortOrder int Constant defining sort order for children Locations
$contentId string|int ID of the Content
$contentInfo ContentInfo ContentInfo object
$parent Location Parent Location object (lazy loaded)
$content Content Content object (lazy loaded)

Services

First thing to know about the Site API services is that all of them handle language configuration in a completely transparent way. You can be sure that all objects you work with:

  1. can be rendered on the current siteaccess
  2. are loaded in the single correct translation to be rendered on the current siteaccess

This works for both Content and Locations, whether they are obtained through search, loading by the ID, as relations or otherwise. If the object doesn’t have a translation that can be rendered on a siteaccess, you won’t be able to load it in the first place. That means you can put the whole language logic off your mind and solve real problems instead.

Following services are available:

LoadService
Instance of Netgen\EzPlatformSiteApi\API\LoadService
Container service ID netgen.ezplatform_site.load_service

The purpose of LoadService is to load Site Content and Locations by their ID.

Methods
loadContent()

Load Content object by its ID.

Parameters string|int $id
Returns Content object
Example
$content = $loadService->loadContent(42);
loadContentByRemoteId()

Load Content object by its remote ID.

Parameters string $remoteId
Returns Content object
Example
$content = $loadService->loadContentByRemoteId('f2bfc25');
loadLocation()

Load Location object by its ID.

Parameters string|int $id
Returns Location object
Example
$content = $loadService->loadLocation(42);
loadLocationByRemoteId()

Load Location object by its remote ID.

Parameters string $remoteId
Returns Location object
Example
$content = $loadService->loadLocationByRemoteId('a44fd4e');
FindService
Instance of Netgen\EzPlatformSiteApi\API\FindService
Container service ID netgen.ezplatform_site.find_service

The purpose of the FindService is to find Content and Locations by using eZ Platform’s Repository Search API. This service will use the search engine that is configured for the Repository. That can be Legacy search engine or Solr search engine.

The service will return SearchResult object from the Repository API containing Site API objects.

Methods
findContent()

Find Content by the Content Query.

Parameters string|int $id
Returns Location object
Example
$content = $findService->findContent($query);
findLocations()

Find Locations by the LocationQuery.

Parameters eZ\Publish\API\Repository\Values\Content\LocationQuery $query
Returns eZ\Publish\API\Repository\Values\Content\Search\SearchResult
Example
$content = $findService->findLocations($locationQuery);
FilterService
Instance of Netgen\EzPlatformSiteApi\API\FilterService
Container service ID netgen.ezplatform_site.load_service

The purpose of the FindService is to find Content and Locations by using eZ Platform’s Repository Search API. That is the same as FindService, but with the difference that it will always use Legacy search engine.

While Solr search engine provides more features and more performance than Legacy search engine, it’s a separate system needs to be synchronized with changes in the database. This synchronization comes with a delay, which can be a problem in some cases.

FilterService gives you access to search that is always up to date, because it uses Legacy search engine that works directly with database. At the same time, search on top of Solr, with all the advanced features (like fulltext search or facets) is still available through FindService.

The service will return SearchResult object from the Repository API containing Site API objects.

Methods
filterContent()

Filter Content by the Content Query.

Parameters string|int $id
Returns Location object
Example
$content = $filterService->filterContent($query);
filterLocations()

Filter Locations by the LocationQuery.

Parameters eZ\Publish\API\Repository\Values\Content\LocationQuery $query
Returns eZ\Publish\API\Repository\Values\Content\Search\SearchResult
Example
$content = $filterService->filterLocations($locationQuery);
RelationService
Instance of Netgen\EzPlatformSiteApi\API\RelationService
Container service ID netgen.ezplatform_site.relation_service

The purpose of RelationService is to provide a way to load field relations. This needs to be done respecting permissions and sort order and actually requires surprising amount of code when using Repository API.

Methods
loadFieldRelation()

Load single field relation from a specific field of a specific Content.

The method will return null if the field does not contain relations that can be loaded by the current user. If the field contains multiple relations, the first one will be returned. The method supports optional filtering by ContentType.

Parameters
  1. string|int $contentId
  2. string $fieldDefinitionIdentifier
  3. array $contentTypeIdentifiers = []
Returns Content object or null
Example
$content = $relationService->loadFieldRelation(
    42,
    'relations',
    ['articles']
);
loadFieldRelations()

Load all field relations from a specific field of a specific Content. The method supports optional filtering by ContentType.

Parameters
  1. string|int $contentId
  2. string $fieldDefinitionIdentifier
  3. array $contentTypeIdentifiers = []
Returns An array of Content objects
Example
$content = $relationService->loadFieldRelations(
    42,
    'relations',
    ['articles']
);
Settings

The purpose of Settings object is to provide read access to current configuration.

Instance of Netgen\EzPlatformSiteApi\API\Settings
Container service ID netgen.ezplatform_site.settings
Properties
Property Type Description
$prioritizedLanguages string[] An array of prioritized languages of the current siteaccess
$useAlwaysAvailable bool
Whether always available Content is taken into account
when resolving translations
$rootLocationId string|int Root Location of the current siteaccess
Site

The purpose of Site service is to aggregate all other Site API services in one place. It implements a getter method for each of the services described above.

Instance of Netgen\EzPlatformSiteApi\API\Site
Container service ID netgen.ezplatform_site.site
Methods
Method Returns
getLoadService() LoadService
getFindService() FindService
getFilterService() FilterService
getRelationService() RelationService
getSettings() Settings
NamedObjectProvider

The purpose of NamedObjectProvider service is to provide access to named objects. Configuration of named objects is documented on the Configuration page.

Instance of Netgen\Bundle\EzPlatformSiteApiBundle\NamedObject\Provider
Container service ID netgen.ezplatform_site.named_object_provider

The purpose of NamedObjectProvider is to provide access to named objects.

Methods
hasContent()

Check if Content object with given name is configured.

Parameters string $name
Returns boolean
Example
$hasCertificate = $namedObjectProvider->hasContent('certificate');
getContent()

Get Content object by its name.

Parameters string $name
Returns Content object
Example
$certificate = $namedObjectProvider->getContent('certificate');
hasLocation()

Check if Location object with given name is configured.

Parameters string $name
Returns boolean
Example
$hasHomepage = $namedObjectProvider->hasLocation('homepage');
getLocation()

Get Location object by its name.

Parameters string $name
Returns Location object
Example
$homepage = $namedObjectProvider->getLocation('homepage');
hasTag()

Check if Tag object with given name is configured.

Parameters string $name
Returns boolean
Example
$hasColors = $namedObjectProvider->hasTag('colors');
getTag()

Get Tag object by its name.

Parameters string $name
Returns Tag object
Example
$colors = $namedObjectProvider->getTag('colors');

Custom controllers

Implementing a custom controller is similar to the vanilla eZ Platform. First, you have to implement it with extending the Site API base controller:

namespace AppBundle\Controller;

use Netgen\Bundle\EzPlatformSiteApiBundle\Controller\Controller;
use Netgen\Bundle\EzPlatformSiteApiBundle\View\ContentView;

class DemoController extends Controller
{
    /**
     * @param \Netgen\Bundle\EzPlatformSiteApiBundle\View\ContentView $view
     *
     * @return \Netgen\Bundle\EzPlatformSiteApiBundle\View\ContentView
     */
    public function viewArticleAction(ContentView $view)
    {
        $content = $view->getSiteContent();
        $location = $view->getSiteLocation();

        $filterService = $this->getSite()->getFilterService();

        $hasRelatedItems = false;

        if (!$content->getField('related')->isEmpty()) {
            $hasRelatedItems = true;
        }

        // Your other custom logic here
        // ...

        // Add variables to the view
        $view->addParameters([
            'has_related_items' => $hasRelatedItems,
        ]);

        return $view;
    }
}

Next, register your controller with the DI container. The Symfony’s base controller expects that setContainer() is called on instantiation. You can do this manually:

app.controller.demo:
    class: AppBundle\Controller\DemoController
    calls:
        - [setContainer, ['@service_container']]

Or by extending the base definition:

app.controller.demo:
    parent: netgen.ezplatform_site.controller.base
    class: AppBundle\Controller\DemoController

Now you can use your custom controller in the view configuration:

ezpublish:
    system:
        frontend_group:
            ngcontent_view:
                full:
                    article:
                        template: "@App/content/full/article.html.twig"
                        controller: "app.controller.demo:viewArticleAction"
                        match:
                            Identifier\ContentType: article

Migration

If you are starting with a new project on top of vanilla eZ Platform, then you’re starting with a clean slate and of course there is no need to migrate anything. In that case it’s enough to install and configure the Site API and you can start working with it.

If that’s the case, we recommend that you look into our Media Site, which is built with Site API and will provide you with a comprehensive base for building a web project on eZ Platform.

On the other hand if you want to add the Site API to an existing project or you have a base site of your own, read on to find out about your options.

Choosing your migration strategy

You can install the Site API on a existing project without worrying that something will break – everything should just keep working as before. However, nothing will use the Site API – you will first have to develop new features or migrate existing ones.

At this point, you can:

  1. use Site API services as you would normally do in a Symfony application. For example you could use it in a custom route.
  2. use Site API’s view configuration, available under ngcontent_view key. You need to know that eZ Platform URL alias routes still won’t be handled through it at this point. Until you explicitly turn that on for a siteaccess, you can only use it by making a subrequest to Site API’s Content view controller ng_content:viewAction.

Handling eZ Platform URL alias routes through Site API’s view configuration has to be enabled per siteaccess, with the following configuration:

netgen_ez_platform_site_api:
    system:
        frontend_group:
            override_url_alias_view_action: true

Once you do this, all URL alias routes on the siteaccess will be handled through Site API’s view configuration. That means you will need to migrate or adapt all full view templates, otherwise expect that things will break. Similar to the point 2. from above will be valid for eZ Platform’s view configuration, available under content_view key. You will still be able to use it, but only through explicit subrequests to eZ Platform’s view controller ez_content:viewAction.

In eZ Platform pagelayout is configured separately from content view configuration. The configured pagelayout is available in the content view templates as pagelayout variable, which is usually extended in full view templates. When using both views at the same time, you will have to choose which one to support with your configured pagelayout - eZ Platform with its Content and Location objects, or Site API with its own Content and Location counterparts. Whichever you choose, you can support the other one by defining the pagelayout explicitly, instead using it through a configured variable.

All Site API objects contain their eZ Platform counterparts. This will enable initial mixing of both Site API and vanilla eZ Platform ways of doing things, which means you will be able to migrate your project one step at a time.

Knowing all that gives you quite some flexibility in choosing exactly how you want to adapt your project to use Site API.

Comparison with eZ Platform

Here’s a comparison table of Site API and eZ Platform Twig functions to provide a quick overview of changes needed in the templates.

eZ Platform Netgen’s Site API
{{ ez_content_name( content ) }} {{ content.name }}
{{ ez_field_name( content, 'title' ) }} {{ content.fields.title.name }}
{{ ez_field_description( content, 'title' ) }} {{ content.fields.title.description }}
{{ ez_field( content, 'title' ) }} {{ content.fields.title }}
{{ ez_render_field( content, 'title' ) }} {{ ng_render_field( content.fields.title ) }}
{{ ez_field_value( content, 'title' ) }} {{ content.fields.title.value }}
{{ ez_is_field_empty( content, 'title' ) }} {{ content.fields.title.empty }}
{{ ez_image_alias(
    content.field( 'image' ),
    content.versionInfo,
    'large'
) }}
{{ ng_image_alias(
    content.fields.image,
     'large'
) }}
Search and replace regexes

Here are some regular expressions that you can use to migrate your Twig templates. The list is not complete, but it should get you started. If you’re using PHP Storm, follow the steps:

  1. Open your PHPStorm
  2. Navigate to template
  3. Press CTRL + R or Command + R
  4. Enter the one of the search/replace pairs from below and replace away
ez_is_field_empty
search for ez_is_field_empty\s*\(\s*([a-zA-Z0-9\_]+)\s*,\s*['"]([a-zA-Z0-9\_]+)['"]\s*\)
replace with $1.fields.$2.empty
ez_field_value
search for ez_field_value\s*\(\s*([a-zA-Z0-9\_]+)\s*,\s*['"]([a-zA-Z0-9\_]+)['"]\s*\)
replace with $1.fields.$2.value
ez_render_field
search for ez_render_field[ ]?\(\s+([a-zA-Z0-9\_]+),\s+['"]([a-zA-Z0-9\_]+)['"](.*?)?\)
replace with ng_render_field( $1.fields.$2$3 )

Upgrades

Upgrades

Upgrading from 2.7.0 to 3.0.0

Version 3.0.0 is a major release where all previous deprecations are removed.

Removed methods for loading ContentInfo
  • Netgen\EzPlatformSiteApi\API\FilterService::filterContentInfo()
  • Netgen\EzPlatformSiteApi\API\FindService::findContentInfo()
  • Netgen\EzPlatformSiteApi\API\LoadService::loadContentInfo()
  • Netgen\EzPlatformSiteApi\API\LoadService::loadContentInfoByRemoteId()

Since Content object lazy-loads its Fields, it is no longer necessary to have ContentInfo as a light weight version of the Content. ContentInfo is still kept to retain similarity with vanilla eZ Platform, but it’s only accessible from the Content object and all methods to load it separately are hereby removed. Upgrade by loading Content instead.

Removed methods for accessing Locations from ContentInfo
  • Netgen\EzPlatformSiteApi\API\Values\ContentInfo::getLocations()
  • Netgen\EzPlatformSiteApi\API\Values\ContentInfo::filterLocations()

Since ContentInfo is now “degraded” to a simple container of properties, methods to access Locations from it are also removed. Upgrade by accessing corresponding methods from the Content object instead.

Removed Node object
  • Netgen\EzPlatformSiteApi\API\Values\Node
  • Netgen\EzPlatformSiteApi\API\FindService::findNodes()
  • Netgen\EzPlatformSiteApi\API\LoadService::loadNode()
  • Netgen\EzPlatformSiteApi\API\LoadService::loadNodeByRemoteId()

Since it’s now possible to access Content from the Location object (lazy-loaded), it is no longer necessary to have a separate Node object, which was just a Location with the aggregated Content. Upgrade by using Location instead.

Removed PagerfantaFindTrait and corresponding adapters
  • Netgen\EzPlatformSiteApi\Core\Traits\PagerfantaFindTrait
  • Netgen\EzPlatformSiteApi\Core\Site\Pagination\Pagerfanta\ContentInfoSearchAdapter
  • Netgen\EzPlatformSiteApi\Core\Site\Pagination\Pagerfanta\ContentInfoSearchHitAdapter
  • Netgen\EzPlatformSiteApi\Core\Site\Pagination\Pagerfanta\ContentSearchAdapter
  • Netgen\EzPlatformSiteApi\Core\Site\Pagination\Pagerfanta\ContentSearchFilterAdapter
  • Netgen\EzPlatformSiteApi\Core\Site\Pagination\Pagerfanta\ContentSearchHitAdapter
  • Netgen\EzPlatformSiteApi\Core\Site\Pagination\Pagerfanta\LocationSearchAdapter
  • Netgen\EzPlatformSiteApi\Core\Site\Pagination\Pagerfanta\LocationSearchFilterAdapter
  • Netgen\EzPlatformSiteApi\Core\Site\Pagination\Pagerfanta\LocationSearchHitAdapter
  • Netgen\EzPlatformSiteApi\Core\Site\Pagination\Pagerfanta\NodeSearchAdapter
  • Netgen\EzPlatformSiteApi\Core\Site\Pagination\Pagerfanta\NodeSearchHitAdapter

Since searching for ContentInfo is removed and Node is completely removed, it’s possible to search only for Content and Locations. This is now distinguished by the type of query object. Upgrade by using new PagerfantaTrait, FilterAdapter and FindAdapter instead.

Removed BaseAdapter, Slice and SearchResultExtras
  • Netgen\EzPlatformSiteApi\Core\Site\Pagination\Pagerfanta\BaseAdapter
  • Netgen\EzPlatformSiteApi\Core\Site\Pagination\Pagerfanta\Slice
  • Netgen\EzPlatformSiteApi\Core\Site\Pagination\Pagerfanta\SearchResultExtras

These classes and interfaces are moved to netgen/ezplatform-search-extra, which is more appropriate place as other code aside from Site API can benefit from it. Upgrade by using the same classes and interfaces from netgen/ezplatform-search-extra repository.

Replaced Query Type condition publication_date with creation_date

Since with Site API we are normally (aside from preview) dealing only with published Content, creation_date is a more appropriate name, particularly considering we will introduce modification_date in the future. Upgrade by searching your view configuration for queries using publication_date and replace it with creation_date instead.

Upgrading from 2.3.0 to 2.4.0

Controllers that extend from Netgen\Bundle\EzPlatformSiteApiBundle\Controller\Controller and are registered inside dependency injection container should set two setter injection calls:

app.demo.controller.demo_controller:
    class: Acme\Bundle\DemoBundle\Controller\DemoController
    calls:
        - [setContainer, ['@service_container']]
        - [setSite, ['@netgen.ezplatform_site.site']]

Or if you want to avoid setter calls, just set parent service:

app.demo.controller.demo_controller:
    parent: netgen.ezplatform_site.controller.base
    class: Acme\Bundle\DemoBundle\Controller\DemoController

Upgrading from 1.0.0 to 2.0.0

eZ Platform Site API introduces a slight breaking change to ContentView value object, hence the bump to version 2.0.

  • Site API ContentView view object does not extend from eZ Platform ContentView value object any more to allow implementation of custom view providers. Class signature did not change, however, since all required interfaces are now implemented directly on Site API ContentView value object.
  • Also, Netgen\Bundle\EzPlatformSiteApiBundle\View\ContentValueView interface does not contain getSiteLocation method any more. It is moved to a new interface, LocationValueView, in the same namespace. If you used this method in your code, make sure to check for this new interface. This was done to keep in line on how eZ kernel uses its ContentView value object and its interfaces.