Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-04-07T13:39:24.060Z
Answers.Text: 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.
Answers.UserDisplayName: Ben Parizek
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-04-06T19:32:10.153Z
Answers.LastActivityDate: 2019-04-06T19:32:10.153Z
Answers.UserDisplayName: Robin Schambach
Body: <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>
  
Tags: <elementtype><elementquery>
Title: How to support chained Element queries with Twig tags
ThreadText: # 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.  
  
  ---
  
  