Answers.Body: <p>First, you need to import your macro, and not just call <code>{{ _self.doPeriod() }}</code>. <a href="http://twig.sensiolabs.org/doc/1.x/tags/macro.html" rel="nofollow noreferrer">From the documentation</a>:</p>
  
  <blockquote>
    <p>When you define a macro in the template where you are going to use it, you might be tempted to call the macro directly via _self.input() instead of importing it; even if seems to work, this is just a side-effect of the current implementation and it won't work anymore in Twig 2.x.</p>
  </blockquote>
  
  <p>I always do: <code>{% import _self as self %}</code></p>
  
  <p><a href="http://twig.sensiolabs.org/doc/2.x/filters/slice.html" rel="nofollow noreferrer">slice</a> returns a sequence - in your case an array with one element, and the key is <code>0</code>. Your macro is expecting a matrix block, not an array, which is why you get that error.</p>
  
  <p>If you only want the first block, then <code>{% set period = timelineText.first %}</code> and <code>period</code> will be a matrix block. <code>{{ self.doPeriod(period) }}</code> will work.</p>
  
  <p>If you want to call <code>doPeriod</code> on all of the matrix blocks, then:</p>
  
  <pre><code>{% for period in timelineText %}
    ... {{ self.doPeriod(period) }} ...
  {% endfor %}
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-01-06T19:17:29.997Z
Answers.LastActivityDate: 2017-01-06T19:17:29.997Z
Answers.UserDisplayName: Marion Newlevant
Body: <p>I want to fetch a specific block from a Matrix global then pass it through a macro which returns a response based on the block type. However, if I try to use <code>slice</code> the type doesn't appear to be available to the macro. Has anyone experienced something similar?</p>
  
  <p>eg if I set <code>{% set timelineText = timeline.timeline %}</code> (where first <code>timeinline</code> is my global and second <code>timeline</code> is my Matrix field) then fetch a specific block from the Matrix: <code>{% set period = timelineText|slice(0,1) %}</code> should return the first instance/block from the field. I can then pass this to my macro: <code>{{ _self.doPeriod(period) }}</code></p>
  
  <p>My macro is</p>
  
  <pre><code>{% macro doPeriod(content) %}
  {% switch content.type %}
  {% case 'quote' %}
      ...
  {% case 'period' %}
      ...
  {% endswitch %}    
  {% endmacro %}```
  </code></pre>
  
  <p>But this returns the following error: <code>Key "type" for array with keys "0" does not exist</code></p>
  
  <p>Any thoughts?</p>
  
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2017-01-06T16:27:33.843Z
Comments.Text: To add some more detail, if I dump contents of, eg `timelineText|slice(0,1)` all the Matrix blocks are returned. However, if I do `timelineText.first` only the first block is returned. 
  
  Is `slice` the right filter in this instance/for this use?
Comments.UserDisplayName: Cole Henley
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2017-01-06T16:55:21.997Z
Comments.Text: Okay, if my initial request just fetches the ids then this works as I can fetch specific blocks via an id() request, eg:
  
  `{% set timelineIds = timeline.timeline.ids() %}`. Then
  `{% set period = timeline.timeline.id(timelineIds[0:1]).first %}` with `{{ _self.doPeriod(period) }}`
  
  However, this does mean a new DB request for each block which seems a bit excessive
Comments.UserDisplayName: Cole Henley
Tags: <matrix><switch>
Title: Passing Matrix block to a macro
ThreadText: # Passing Matrix block to a macro
  
  (Asked by: username_0 on 2017-01-06)
  
  I want to fetch a specific block from a Matrix global then pass it through a macro which returns a response based on the block type. However, if I try to use `slice` the type doesn't appear to be available to the macro. Has anyone experienced something similar?
  
  eg if I set `{% set timelineText = timeline.timeline %}` (where first `timeinline` is my global and second `timeline` is my Matrix field) then fetch a specific block from the Matrix: `{% set period = timelineText|slice(0,1) %}` should return the first instance/block from the field. I can then pass this to my macro: `{{ _self.doPeriod(period) }}`
  
  My macro is
  
  ```
  {% macro doPeriod(content) %}
  {% switch content.type %}
  {% case 'quote' %}
      ...
  {% case 'period' %}
      ...
  {% endswitch %}    
  {% endmacro %}```
  
  ```
  
  But this returns the following error: `Key "type" for array with keys "0" does not exist`
  
  Any thoughts?
  
  **Tags:** matrix, switch
  
  > **Comments:**
  > **username_0**: To add some more detail, if I dump contents of, eg `timelineText|slice(0,1)` all the Matrix blocks are returned. However, if I do `timelineText.first` only the first block is returned.   Is `slice` the right filter in this instance/for this use?  
  > **username_0**: Okay, if my initial request just fetches the ids then this works as I can fetch specific blocks via an id() request, eg:  `{% set timelineIds = timeline.timeline.ids() %}`. Then `{% set period = timeline.timeline.id(timelineIds[0:1]).first %}` with `{{ _self.doPeriod(period) }}`  However, this does mean a new DB request for each block which seems a bit excessive  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2017-01-06. Score: 2 | Accepted answer
  
  First, you need to import your macro, and not just call `{{ _self.doPeriod() }}`. [From the documentation](http://twig.sensiolabs.org/doc/1.x/tags/macro.html):
  
  > When you define a macro in the template where you are going to use it, you might be tempted to call the macro directly via \_self.input() instead of importing it; even if seems to work, this is just a side-effect of the current implementation and it won't work anymore in Twig 2.x.
  
  I always do: `{% import _self as self %}`
  
  [slice](http://twig.sensiolabs.org/doc/2.x/filters/slice.html) returns a sequence - in your case an array with one element, and the key is `0`. Your macro is expecting a matrix block, not an array, which is why you get that error.
  
  If you only want the first block, then `{% set period = timelineText.first %}` and `period` will be a matrix block. `{{ self.doPeriod(period) }}` will work.
  
  If you want to call `doPeriod` on all of the matrix blocks, then:
  
  ```
  {% for period in timelineText %}
    ... {{ self.doPeriod(period) }} ...
  {% endfor %}
  
  ```
  
  
  ---
  
  