Answers.Body: <p>I see a few problems. The first is that <code>{{ grid.item(entry.image) }}</code> is actually an <a href="http://buildwithcraft.com/docs/templating/elementcriteriamodel" rel="nofollow">ElementCriteriaModel</a> (i.e. which behaves like an array of images) and not an ElementModel (i.e. a single image), even if only one image is defined. To get the first image you can use <code>entry.image.first</code> or <code>entry.image[0]</code>.</p>
  
  <p>The second problem is that in your macro, <code>&lt;img src="{{ thumbnail }}"/&gt;</code> is trying to set the url string using the whole <code>ElementModel</code> (or in your case the ElementCriteriaModel). Instead use: <code>{{ thumbnail.url }}</code></p>
  
  <pre><code>{% macro item(thumbnail) %}
      {% if thumbnail %}
          &lt;img src="{{ thumbnail.url }}"/&gt;
      {% endif %}
  {% endmacro %}
  
  {% from _self import item %}
  
  {% for entry in craft.entries.section('handle') %}
      {{ item(entry.image.first) }}
  {% endfor %}
  </code></pre>
  
  <p><strong>Update:</strong> If on the other hand, for some reason you want to pass the ElementCriteriaModel then you just need to handle it appropriately in the macro:</p>
  
  <pre><code>{% macro item(thumbnail) %}
      {% if thumbnail.first %}
          &lt;img src="{{ thumbnail.first.url }}"/&gt;
      {% endif %}
  {% endmacro %}
  
  {% from _self import item %}
  
  {% for entry in craft.entries.section('handle') %}
      {{ item(entry.image) }}
  {% endfor %}
  </code></pre>
  
  <p>As a side note — keep in mind that the macro can also exist in the same template and imported using <code>_self</code>.</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-10-27T15:20:51.263Z
Answers.Text: Thing is I would like to make the check if there's any image select in my macro to keep the code of my template more clean. So I would like to pass the entire ElementCriteriaModel into my macro and in there run my *if model|length > 0* to get any image selected. Possible?
Answers.UserDisplayName: naboovalley
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-10-27T15:22:10.460Z
Answers.Text: I would like to do this since I'm reusing my macro across multiple templates. Maybe that's bad practice?
Answers.UserDisplayName: naboovalley
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-10-27T15:49:05.993Z
Answers.Text: @naboo Id say it's no bad practice at all to import macros, but I can also imagine that importing many files could indeed increase load time. What I do is to put my macros all in one file "includes/macros.html" that I import from my base template "_layout.html". On the other hand, I read somewhere that Twig does `extends` and `include` very performant and `import` is maybe not that different.
Answers.UserDisplayName: carlcs
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-10-27T15:52:47.400Z
Answers.Text: Oh sorry. I meant the practice of passing an ElementCriteriaModel to my macro and within the macro making the check if there's an image present or not :)
Answers.UserDisplayName: naboovalley
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-10-27T15:53:28.553Z
Answers.Text: ... also importing the macro at the top of the template and reusing it further down... will that increase page load? Isn't the import only made once?
Answers.UserDisplayName: naboovalley
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-10-27T15:53:57.900Z
Answers.Text: @naboo to help you with your problem: you could try and feed your macro an array of element models instead of that elementcriteriamodel, by adding `find()`. Additionally it is always good to use the plural with your vars or fieldnames if there's multiple elements: `{{ grid.item(entry.images.find()) }}` :)
Answers.UserDisplayName: carlcs
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-10-27T15:56:23.443Z
Answers.Text: The user can only select one image, so the naming should be fine. Regarding my original question I'm taking it that passing the entire "ElementCriteriaModel" isn't doable. I can only pass the "ElementModel"?
Answers.UserDisplayName: naboovalley
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-10-27T15:56:48.877Z
Answers.Text: Ouups... no you can always have your macro output nothing, I don't see any bad practice there. And yes, if you don't call the import multiple times, say with a loop :)
Answers.UserDisplayName: carlcs
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-10-27T15:59:28.753Z
Answers.Text: It's not what the user selects, but how Craft returns request. It's always multiple images and you have to use `first()` to get the one selected. Did `find()` do the trick?
Answers.UserDisplayName: carlcs
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-10-27T16:01:49.507Z
Answers.Text: To better understand what I mean with an array of element models read here about the difference to ecm: http://buildwithcraft.com/docs/templating/elementcriteriamodel#find
Answers.UserDisplayName: carlcs
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-10-27T20:27:23.633Z
Answers.Text: You can pass anything you want to the macro, including ElementCriteriaModel. You just need to handle it correctly in the macro. So, instead the macro would be `{% if thumbnail.first %}<img src="{{ thumbnail.first.url }}">{% endif %}`. I only mentioned the macro import thing because this was such a simple macro and could easily be inline vs a macro at all. By all means, import your macros! That's what it's there for.
Answers.UserDisplayName: Douglas McDonald
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-10-27T20:32:46.190Z
Answers.Text: Ah Douglas - right on. It's not the macro complaining, it's the code _WITHIN_ the macro. I didn't realize this at first, now I see what's wrong. Thank you for pointing this out! :)
Answers.UserDisplayName: naboovalley
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-10-27T22:28:55.960Z
Answers.Text: @naboovalley if this correct, can you hit the checkmark? This will help others. Thanks.
Answers.UserDisplayName: Douglas McDonald
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-10-27T14:41:46.007Z
Answers.LastActivityDate: 2014-10-27T20:39:08.037Z
Answers.LastEditDate: 2014-10-27T20:39:08.037Z
Answers.UserDisplayName: Douglas McDonald
Body: <p>I'm trying to pass an AssetModel into a twig macro but all I'm getting is:</p>
  
  <pre><code>Object of class Craft\ElementCriteriaModel could not be converted to string 
  </code></pre>
  
  <p>Is there any way to define my twig macro variable to be an object instead of a string?</p>
  
  <p>This is my macro</p>
  
  <pre><code>{% macro item(thumbnail) %}
      {% if thumbnail %}
          &lt;img src="{{ thumbnail }}"/&gt;
      {% endif %}
  {% endmacro %}
  </code></pre>
  
  <p>This is my template</p>
  
  <pre><code>{% import "macros/grid.html" as grid %}
  
  {% for entry in craft.entries.section('handle') %}
      {{ grid.item(entry.image) }}
  {% endfor %}
  </code></pre>
  
  <p><em>entry.image</em> is an Asset field</p>
  
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2014-10-27T13:45:39.170Z
Comments.Text: Can you share your code, so we can see it in context?
Comments.UserDisplayName: Douglas McDonald
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2014-10-27T13:57:46.317Z
Comments.Text: code added Douglas
Comments.UserDisplayName: naboovalley
Tags: <templating><macro>
Title: How pass an ElementModel to a Macro in Twig
ThreadText: # How pass an ElementModel to a Macro in Twig
  
  (Asked by: username_0 on 2014-10-27)
  
  I'm trying to pass an AssetModel into a twig macro but all I'm getting is:
  
  ```
  Object of class Craft\ElementCriteriaModel could not be converted to string 
  
  ```
  
  Is there any way to define my twig macro variable to be an object instead of a string?
  
  This is my macro
  
  ```
  {% macro item(thumbnail) %}
      {% if thumbnail %}
          <img src="{{ thumbnail }}"/>
      {% endif %}
  {% endmacro %}
  
  ```
  
  This is my template
  
  ```
  {% import "macros/grid.html" as grid %}
  
  {% for entry in craft.entries.section('handle') %}
      {{ grid.item(entry.image) }}
  {% endfor %}
  
  ```
  
  *entry.image* is an Asset field
  
  **Tags:** templating, macro
  
  > **Comments:**
  > **username_1**: Can you share your code, so we can see it in context?  
  > **username_0**: code added username_1  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2014-10-27. Score: 3 | Accepted answer
  
  I see a few problems. The first is that `{{ grid.item(entry.image) }}` is actually an [ElementCriteriaModel](http://buildwithcraft.com/docs/templating/elementcriteriamodel) (i.e. which behaves like an array of images) and not an ElementModel (i.e. a single image), even if only one image is defined. To get the first image you can use `entry.image.first` or `entry.image[0]`.
  
  The second problem is that in your macro, `<img src="{{ thumbnail }}"/>` is trying to set the url string using the whole `ElementModel` (or in your case the ElementCriteriaModel). Instead use: `{{ thumbnail.url }}`
  
  ```
  {% macro item(thumbnail) %}
      {% if thumbnail %}
          <img src="{{ thumbnail.url }}"/>
      {% endif %}
  {% endmacro %}
  
  {% from _self import item %}
  
  {% for entry in craft.entries.section('handle') %}
      {{ item(entry.image.first) }}
  {% endfor %}
  
  ```
  
  **Update:** If on the other hand, for some reason you want to pass the ElementCriteriaModel then you just need to handle it appropriately in the macro:
  
  ```
  {% macro item(thumbnail) %}
      {% if thumbnail.first %}
          <img src="{{ thumbnail.first.url }}"/>
      {% endif %}
  {% endmacro %}
  
  {% from _self import item %}
  
  {% for entry in craft.entries.section('handle') %}
      {{ item(entry.image) }}
  {% endfor %}
  
  ```
  
  As a side note — keep in mind that the macro can also exist in the same template and imported using `_self`.
  
  > **Comments:**
  > **username_0**: Thing is I would like to make the check if there's any image select in my macro to keep the code of my template more clean. So I would like to pass the entire ElementCriteriaModel into my macro and in there run my *if model|length > 0* to get any image selected. Possible?  
  > **username_0**: I would like to do this since I'm reusing my macro across multiple templates. Maybe that's bad practice?  
  > **username_2**: @naboo Id say it's no bad practice at all to import macros, but I can also imagine that importing many files could indeed increase load time. What I do is to put my macros all in one file "includes/macros.html" that I import from my base template "_layout.html". On the other hand, I read somewhere that Twig does `extends` and `include` very performant and `import` is maybe not that different.  
  > **username_0**: Oh sorry. I meant the practice of passing an ElementCriteriaModel to my macro and within the macro making the check if there's an image present or not :)  
  > **username_0**: ... also importing the macro at the top of the template and reusing it further down... will that increase page load? Isn't the import only made once?  
  > **username_2**: @naboo to help you with your problem: you could try and feed your macro an array of element models instead of that elementcriteriamodel, by adding `find()`. Additionally it is always good to use the plural with your vars or fieldnames if there's multiple elements: `{{ grid.item(entry.images.find()) }}` :)  
  > **username_0**: The user can only select one image, so the naming should be fine. Regarding my original question I'm taking it that passing the entire "ElementCriteriaModel" isn't doable. I can only pass the "ElementModel"?  
  > **username_2**: Ouups... no you can always have your macro output nothing, I don't see any bad practice there. And yes, if you don't call the import multiple times, say with a loop :)  
  > **username_2**: It's not what the user selects, but how Craft returns request. It's always multiple images and you have to use `first()` to get the one selected. Did `find()` do the trick?  
  > **username_2**: To better understand what I mean with an array of element models read here about the difference to ecm: http://buildwithcraft.com/docs/templating/elementcriteriamodel#find  
  > **username_1**: You can pass anything you want to the macro, including ElementCriteriaModel. You just need to handle it correctly in the macro. So, instead the macro would be `{% if thumbnail.first %}<img src="{{ thumbnail.first.url }}">{% endif %}`. I only mentioned the macro import thing because this was such a simple macro and could easily be inline vs a macro at all. By all means, import your macros! That's what it's there for.  
  > **username_0**: Ah username_1 - right on. It's not the macro complaining, it's the code _WITHIN_ the macro. I didn't realize this at first, now I see what's wrong. Thank you for pointing this out! :)  
  > **username_1**: @username_0 if this correct, can you hit the checkmark? This will help others. Thanks.  
  
  ---
  
  