<p>We've designed <a href="http://sprout.barrelstrengthdesign.com/craft-plugins/seo" rel="nofollow">Sprout SEO</a> to help you handle situations like these.  Personally, I think it's the easiest path to take for dealing with this situation.  So, my first answer would be to consider using it.</p>

<p>There is an example on how to assign meta values in included Matrix blocks in the Sprout SEO docs here <a href="http://sprout.barrelstrengthdesign.com/craft-plugins/seo/docs/examples/extending-a-base-layout" rel="nofollow">Extending a Base Layout</a></p>

<hr>

<p>But, this is a question on StackExchange so that answer alone is unsatisfying. If you'd like to dig into solving this issue yourself, to start, I'd recommend you try to get the best understanding you can of the <a href="http://straightupcraft.com/index.php/articles/twig-processing-order" rel="nofollow">Twig Processing Order</a>. While part of the challenge your facing is how to grab the specific text you need from the field variable (Bill Chriswell's answer addresses that), another part of it may be where your variable exists in your templates.</p>

<p>For example, if you are managing your variables in a parent <code>_layout</code> template and trying to assign your excerpt within a block tag extending it, you're description variable is getting set after you are outputting your meta variables.</p>

<p>So, however you are assigning your meta variables you need to make sure that you are assigning the description variable in a way that it gets updated before you are actually outputting the meta values in your header.</p>

<p>I'll quote a couple paragraphs from the Twig Processing Order article linked above:</p>

<blockquote>
  <p>[T]he Twig processing order flows down the page. Variables are processed and become available farther down the page to be output.
  Sometimes however, we can only determine a value farther down the
  page, and the value itself needs to be output higher on the page.</p>
  
  <p>Out of the box, some scenarios like this can be handled by Twig but things can get messy quick, and code that once felt dry can begin to
  feel harder to maintain. Other scenarios simply can't be solved
  without extending Twig or managing your variable with the help of a
  plugin.</p>
</blockquote>

<p>Here are three methods mentioned in the article to consider if you want to get around this:</p>

<ol>
<li>Try to set your variables as high on the page as you can. Even
arrays of data can be queried and set as variables higher on the
page. Once a variable exists, it's much easier to refer to that
variable anywhere below it's first instance in your templates.</li>
<li>Create your page variables in a plugin. Craft allows you to set up
routes to point to a Controller action instead of a page template.</li>
<li>Consider building a plugin and and managing the variable of the
content you need access to in a Twig Global or public variable in
the service layer of your plugin.</li>
</ol>

CC BY-SA 3.0
2015-02-20T16:09:19.920Z
Wow! Pretty comprehensive Ben :^)
The method Bill suggested above works for me though. I had to declare the variable as blank outside of the for loop first and then it all works.
Dan Owen
CC BY-SA 3.0
2015-02-20T16:24:05.257Z
*"[if you are] trying to assign your excerpt **within a block** tag extending [a parent _layout template]"* – you can use the `set` tag **outside of blocks** to pass vars to the parent template.
carlcs
CC BY-SA 3.0
2015-02-20T17:03:41.817Z
Good clarification @carlcs.  Dan Owen, glad you have it working.  Out of curiosity, are you extending a layout or is everything just in one template?
Ben Parizek
CC BY-SA 3.0
2015-02-20T17:32:42.733Z
Extending a layout. So in my articles/_entry template i have Bill's code from above (before my {% block content %}) and before Bill's code i set the variable as blank. Then in _layout i'm calling ogDescription in my <head>
Dan Owen
CC BY-SA 3.0
2015-02-20T16:01:56.763Z
2015-02-20T16:01:56.763Z
Ben Parizek
<p>You can filter by block type: <a href="http://buildwithcraft.com/docs/matrix-fields#filtering-by-block-type" rel="nofollow">http://buildwithcraft.com/docs/matrix-fields#filtering-by-block-type</a></p>

<p>In short:</p>

<pre><code>{% set ogDescription = false %}

{% for block in entry.myMatrixField.type('richText').limit(1) %}
  {% set ogDescription = block.text | striptags | slice(0, 155) %}
{% endfor %}

{% if ogDescription %}
  ...
{% endif %}
</code></pre>

<p>Also, this was suggested in the comments:</p>

<pre><code>{{ entry.myMatrixField.type('richText').first() | striptags | slice(0, 155) }}
</code></pre>

CC BY-SA 3.0
2015-02-20T15:31:26.253Z
Very cool! I tried it before you made edits and it output to the screen just fine. However if i try it now i get Unexpected tag name "assign". I tried changing it to set and i get no error, but no output either (using {{ ogDescription }})
Dan Owen
CC BY-SA 3.0
2015-02-20T15:37:43.553Z
Opps, my mistake. I'll change assign to set. Are you sure the handle of the field you're trying to get is named "text"? I was just trying to make it a little less error prone haha.
Bill Criswell
CC BY-SA 3.0
2015-02-20T15:40:44.047Z
It doesn't output anything for me if i use set. If i try removing the if defined and just put {{ ogDescription }} after the for loop, i get the error "Variable "ogDescription" does not exist". Yep my block is just called text. The code you posted worked fine when it was just straight up outputting the value (before you added the assign / set etc) so... when it was this "{{ block.text | striptags | slice(0, 155) }}"
Dan Owen
CC BY-SA 3.0
2015-02-20T15:54:23.450Z
Ok, i discovered if i put the if is defined inside the for loop, it works! But that wont work for passing the variable to my _layout template. Not sure how to pass that variable outside of the for loop...!
Dan Owen
CC BY-SA 3.0
2015-02-20T16:01:38.780Z
Ok i have it working! I had to declare the set outside of the for loop first. So i have this before the for loop starts: {% set ogDescription = "" %} and now i can call it outside of the for loop.
Dan Owen
CC BY-SA 3.0
2015-02-20T16:08:17.223Z
`for` loops are scoped in Twig. So you have to set it before the loop. But in this cause I'd rather use `first()` method to get the first block of this type.
carlcs
CC BY-SA 3.0
2015-02-20T16:36:28.697Z
I'll update my answer a bit.
Bill Criswell
CC BY-SA 3.0
2015-02-20T15:00:38.927Z
2015-02-20T18:24:18.010Z
2015-02-20T18:24:18.010Z
Bill Criswell
<p>I have blog articles set up on the site i'm working on to be built using a matrix, much the same way as in the <a href="http://buildwithcraft.com/features/matrix" rel="nofollow">features video</a> about the matrix field. So it is entirely possible for an article to start with an image or a video.</p>

<p>What i'd like to be able to do is find the first text entry in the matrix and pull the first 155 characters out of it, creating an excerpt. The point of this is to pass that into a meta og:description tag (and i guess meta description too!)</p>

<p>Is it possible to do that with matrix content?</p>

CC BY-SA 3.0
2015-02-20T15:47:02.813Z
You might try modifying the code [in this answer](http://craftcms.stackexchange.com/questions/685/is-there-a-way-to-output-only-the-first-paragraph-of-a-rich-text-field/733#733).
James Muspratt
<matrix>
Is it possible to take an excerpt from the first rich text area in a matrix?
# Is it possible to take an excerpt from the first rich text area in a matrix?

(Asked by: username_0 on 2015-02-20)

I have blog articles set up on the site i'm working on to be built using a matrix, much the same way as in the [features video](http://buildwithcraft.com/features/matrix) about the matrix field. So it is entirely possible for an article to start with an image or a video.

What i'd like to be able to do is find the first text entry in the matrix and pull the first 155 characters out of it, creating an excerpt. The point of this is to pass that into a meta og:description tag (and i guess meta description too!)

Is it possible to do that with matrix content?

**Tags:** matrix
> **Comments:**
> **username_1**: You might try modifying the code [in this answer](http://craftcms.stackexchange.com/questions/685/is-there-a-way-to-output-only-the-first-paragraph-of-a-rich-text-field/733#733).  

---

## 2 answers

### Answer by username_4 on 2015-02-20. Score: 6 | Accepted answer

You can filter by block type: http://buildwithcraft.com/docs/matrix-fields#filtering-by-block-type
In short:
{% set ogDescription = false %}

{% for block in entry.myMatrixField.type('richText').limit(1) %}
  {% set ogDescription = block.text | striptags | slice(0, 155) %}
{% endfor %}

{% if ogDescription %}
  ...
{% endif %}

Also, this was suggested in the comments:
{{ entry.myMatrixField.type('richText').first() | striptags | slice(0, 155) }}

> **Comments:**
> **username_0**: Very cool! I tried it before you made edits and it output to the screen just fine. However if i try it now i get Unexpected tag name "assign". I tried changing it to set and i get no error, but no output either (using {{ ogDescription }})  
> **username_4**: Opps, my mistake. I'll change assign to set. Are you sure the handle of the field you're trying to get is named "text"? I was just trying to make it a little less error prone haha.  
> **username_0**: It doesn't output anything for me if i use set. If i try removing the if defined and just put {{ ogDescription }} after the for loop, i get the error "Variable "ogDescription" does not exist". Yep my block is just called text. The code you posted worked fine when it was just straight up outputting the value (before you added the assign / set etc) so... when it was this "{{ block.text | striptags | slice(0, 155) }}"  
> **username_0**: Ok, i discovered if i put the if is defined inside the for loop, it works! But that wont work for passing the variable to my _layout template. Not sure how to pass that variable outside of the for loop...!  
> **username_0**: Ok i have it working! I had to declare the set outside of the for loop first. So i have this before the for loop starts: {% set ogDescription = "" %} and now i can call it outside of the for loop.  
> **username_3**: `for` loops are scoped in Twig. So you have to set it before the loop. But in this cause I'd rather use `first()` method to get the first block of this type.  
> **username_4**: I'll update my answer a bit.  

---

### Answer by username_2 on 2015-02-20. Score: 2

We've designed [Sprout SEO](http://sprout.barrelstrengthdesign.com/craft-plugins/seo) to help you handle situations like these. Personally, I think it's the easiest path to take for dealing with this situation. So, my first answer would be to consider using it.

There is an example on how to assign meta values in included Matrix blocks in the Sprout SEO docs here [Extending a Base Layout](http://sprout.barrelstrengthdesign.com/craft-plugins/seo/docs/examples/extending-a-base-layout)

---

But, this is a question on StackExchange so that answer alone is unsatisfying. If you'd like to dig into solving this issue yourself, to start, I'd recommend you try to get the best understanding you can of the [Twig Processing Order](http://straightupcraft.com/index.php/articles/twig-processing-order). While part of the challenge your facing is how to grab the specific text you need from the field variable (Bill Chriswell's answer addresses that), another part of it may be where your variable exists in your templates.

For example, if you are managing your variables in a parent `_layout` template and trying to assign your excerpt within a block tag extending it, you're description variable is getting set after you are outputting your meta variables.

So, however you are assigning your meta variables you need to make sure that you are assigning the description variable in a way that it gets updated before you are actually outputting the meta values in your header.

I'll quote a couple paragraphs from the Twig Processing Order article linked above:

> [T]he Twig processing order flows down the page. Variables are processed and become available farther down the page to be output.
> Sometimes however, we can only determine a value farther down the
> page, and the value itself needs to be output higher on the page.
>
> Out of the box, some scenarios like this can be handled by Twig but things can get messy quick, and code that once felt dry can begin to
> feel harder to maintain. Other scenarios simply can't be solved
> without extending Twig or managing your variable with the help of a
> plugin.

Here are three methods mentioned in the article to consider if you want to get around this:

1. Try to set your variables as high on the page as you can. Even
   arrays of data can be queried and set as variables higher on the
   page. Once a variable exists, it's much easier to refer to that
   variable anywhere below it's first instance in your templates.
2. Create your page variables in a plugin. Craft allows you to set up
   routes to point to a Controller action instead of a page template.
3. Consider building a plugin and and managing the variable of the
   content you need access to in a Twig Global or public variable in
   the service layer of your plugin.

> **Comments:**
> **username_0**: Wow! Pretty comprehensive Ben :^) The method Bill suggested above works for me though. I had to declare the variable as blank outside of the for loop first and then it all works.  
> **username_3**: *"[if you are] trying to assign your excerpt **within a block** tag extending [a parent _layout template]"* – you can use the `set` tag **outside of blocks** to pass vars to the parent template.  
> **username_2**: Good clarification @carlcs.  Dan Owen, glad you have it working.  Out of curiosity, are you extending a layout or is everything just in one template?  
> **username_0**: Extending a layout. So in my articles/_entry template i have Bill's code from above (before my {% block content %}) and before Bill's code i set the variable as blank. Then in _layout i'm calling ogDescription in my <head>  

---

