<p>You need to return the instance in every single <code>set</code> call. As you noticed correctly the last line in <strong>every</strong> function that changes properties of your query is <code>return $this</code> which allows you to chain another function after the call. Simple as that.</p>

<p>Always return the query until you execute it with <code>all()</code> or another function like that is enough </p>

CC BY-SA 4.0
2019-04-07T13:39:24.060Z
Thanks for the clarification. Not sure why things were not working originally. It may have had something to do with where I was killing the script to test in the variable class and how the chained methods get processed. Seems as if it's all working now.
Ben Parizek
CC BY-SA 4.0
2019-04-06T19:32:10.153Z
2019-04-06T19:32:10.153Z
Robin Schambach
<p>The <code>craft</code> variable allows you to chain queries for your Elements. For example, you can query the first Entry in a section with either of the following syntaxes:</p>

<pre><code>{% set entry = craft.entries({ section: 'news' }).one() %}
{% set entry = craft.entries.section('news').one() %}
</code></pre>

<p>How do we support both of these syntaxes in a Custom Element type?</p>

<p>The Craft Variable defines the <code>entries</code> tag like so:</p>

<pre><code>public function entries(array $criteria = []): EntryQuery
{
  $query = Entry::find();
  Craft::configure($query, $criteria);

  return $query;
}
</code></pre>

<p>And, within the <code>EntryQuery</code> class, a public <code>section</code> method is defined:</p>

<pre><code>public function section($value)
{
  if ($value instanceof Section) {
    $this-&gt;structureId = ($value-&gt;structureId ?: false);
    $this-&gt;sectionId = $value-&gt;id;
  } else if ($value !== null) {
    $this-&gt;sectionId = (new Query())
      -&gt;select(['id'])
      -&gt;from([Table::SECTIONS])
      -&gt;where(Db::parseParam('handle', $value))
      -&gt;column();
  } else {
    $this-&gt;sectionId = null;
  }

  return $this;
}
</code></pre>

<p>And there appears to be a <code>__set</code> method on the EntryQuery that also references the <code>section</code> method:</p>

<pre><code>public function __set($name, $value)
{
  switch ($name) {
    case 'section':
      $this-&gt;section($value);
      break;
    case 'type':
      $this-&gt;type($value);
      break;
    case 'authorGroup':
      $this-&gt;authorGroup($value);
      break;
    default:
      parent::__set($name, $value);
  }
}
</code></pre>

<p>I've experimented with all of those and still only seem to be able to support the first syntax:</p>

<pre><code>{% set entry = craft.entries({ section: 'news' }).one() %}
</code></pre>

<p>But can't seem to find a way to support the second syntax:</p>

<pre><code>{% set entry = craft.entries.section('news').one() %}
</code></pre>

<p>What am I overlooking? What does a custom Element Type need to add to support the chained syntax for an Element Query via a Twig variable?</p>

<elementtype><elementquery>
How to support chained Element queries with Twig tags
# How to support chained Element queries with Twig tags

(Asked by: username_0 on 2019-04-06)

The craft variable allows you to chain queries for your Elements. For example, you can query the first Entry in a section with either of the following syntaxes:
{% set entry = craft.entries({ section: 'news' }).one() %}
{% set entry = craft.entries.section('news').one() %}

How do we support both of these syntaxes in a Custom Element type?
The Craft Variable defines the entries tag like so:
public function entries(array $criteria = []): EntryQuery
{
  $query = Entry::find();
  Craft::configure($query, $criteria);

  return $query;
}

And, within the EntryQuery class, a public section method is defined:
public function section($value)
{
  if ($value instanceof Section) {
    $this->structureId = ($value->structureId ?: false);
    $this->sectionId = $value->id;
  } else if ($value !== null) {
    $this->sectionId = (new Query())
      ->select(['id'])
      ->from([Table::SECTIONS])
      ->where(Db::parseParam('handle', $value))
      ->column();
  } else {
    $this->sectionId = null;
  }

  return $this;
}

And there appears to be a __set method on the EntryQuery that also references the section method:
public function __set($name, $value)
{
  switch ($name) {
    case 'section':
      $this->section($value);
      break;
    case 'type':
      $this->type($value);
      break;
    case 'authorGroup':
      $this->authorGroup($value);
      break;
    default:
      parent::__set($name, $value);
  }
}

I've experimented with all of those and still only seem to be able to support the first syntax:
{% set entry = craft.entries({ section: 'news' }).one() %}

But can't seem to find a way to support the second syntax:
{% set entry = craft.entries.section('news').one() %}

What am I overlooking? What does a custom Element Type need to add to support the chained syntax for an Element Query via a Twig variable?

**Tags:** elementtype, elementquery

---

## 1 answers

### Answer by username_1 on 2019-04-06. Score: 3 | Accepted answer

You need to return the instance in every single `set` call. As you noticed correctly the last line in **every** function that changes properties of your query is `return $this` which allows you to chain another function after the call. Simple as that.

Always return the query until you execute it with `all()` or another function like that is enough

> **Comments:**
> **username_0**: Thanks for the clarification. Not sure why things were not working originally. It may have had something to do with where I was killing the script to test in the variable class and how the chained methods get processed. Seems as if it's all working now.  

---

