<p>Definitely possible; you'd need to write a plugin or module in PHP to do it though. Probably it could listen to for the <code>View::EVENT_BEGIN_PAGE</code> event, and get the injected element via <code>$element = Craft::$app-&gt;urlManager-&gt;getMatchedElement()</code></p>

<p>Something sorta like this:</p>

<pre class="lang-php prettyprint-override"><code>use craft\web\View;

// ...

    $request = Craft::$app-&gt;getRequest();
    if ($request-&gt;getIsSiteRequest()) {
        // Handler: View::EVENT_BEGIN_PAGE
        Event::on(
            View::class,
            View::EVENT_BEGIN_PAGE,
            function () {
                Craft::debug(
                    'View::EVENT_BEGIN_PAGE',
                    __METHOD__
                );
                $element = Craft::$app-&gt;urlManager-&gt;getMatchedElement();
                if ($element !== null &amp;&amp; ...) {
                    // ...do something
                }
            }
        );
    }
</code></pre>

<p>To make things clean, rather than modifying the element itself, I'd probably inject a new Twig variable, something like <code>entryTransformed</code> or something that your templating code could access.</p>

CC BY-SA 4.0
2020-05-25T18:39:06.440Z
Ok thanks this seems like a good idea. What would be the best way to add the variable inside the callback?
Callum
CC BY-SA 4.0
2020-05-26T18:37:48.290Z
Yeah so the answer above isn't quite correct for what you're trying to do specifically. Check out my answer to that here: https://craftcms.stackexchange.com/questions/35427/add-variable-to-twig-context
andrew.welch
CC BY-SA 4.0
2020-05-25T14:13:49.523Z
2020-05-25T17:43:18.747Z
2020-05-25T17:43:18.747Z
andrew.welch
<p>What format are you trying to get your data into?</p>
<p>I can think of a few different ways to handle this depending on what you might want to do:</p>
<h1>Element API</h1>
<p>You don't mention what format you need but JSON is a popular format and the <a href="https://github.com/craftcms/element-api" rel="nofollow noreferrer">Element API</a> is a first party solution in Craft.</p>
<h1>Hidden Field</h1>
<p>Another way to accomplish this would be to setup an <a href="https://github.com/mmikkel/IncognitoField-Craft3" rel="nofollow noreferrer">Incognito field</a> on your entry.  Then, listen to the <code>EVENT_BEFORE_SAVE_ELEMENT</code> event using a plugin to transform your data and save it to the format you need. This is similar to how you're doing it in Twig now, except just in a different &quot;place&quot; in the request.</p>
<p>This also has the advantage of doing the data transform once when the entry is saved (instead of every page load or messing around with <code>{% cache %}</code> tags). Then you just grab it in Twig like any other field, similar to how you're doing it now.</p>
<h1>Twig Filter</h1>
<p>You mentioned this in your question. Since we don't have access to your Twig template, it's hard to know what you're trying to accomplish but I don't necessarily see a downside to doing it this way if your page performance is good. The only thing you might want to consider is adding {% cache %} tags around your output to give your server a break in that respect.</p>
<h1>Page Injection</h1>
<p>See <a href="https://craftcms.stackexchange.com/a/35417/1016">Andrew's answer</a> if you need to do things even &quot;higher up&quot; before the template layer.</p>

CC BY-SA 4.0
2020-05-25T22:02:30.453Z
Thanks for the feedback. I ended up going with Andrew's answer. Do you know a good method of adding a variable to the template context in the event in his example?
Callum
CC BY-SA 4.0
2020-05-26T15:19:57.263Z
That's a good question, you might get more action if you ask it as  a new question but one way to do it would be to create a [Twig extension](https://docs.craftcms.com/v3/extend/extending-twig.html).
RitterKnight
CC BY-SA 4.0
2020-05-25T16:41:09.317Z
2020-05-25T16:41:09.317Z
2020-06-17T08:56:27.903Z
RitterKnight
<p>I am using a pattern library which expects a different data structure to what is in <code>entry</code>. Is there a way to parse the <code>entry</code> through a transformer class before the template is rendered?</p>

<p>Currently I have created a Twig function to run: <code>{% set job = single(entry) %}</code> which returns the mapped data for each different entry type. </p>

<p>I would like to hook into Craft to do this before the template is rendered and remove any mapping logic from the templates. Is this possible/practical? </p>

CC BY-SA 4.0
2020-05-25T15:55:12.297Z
Can you elaborate on your use case a bit as to what you're trying to do?
RitterKnight
<templating>
How do you modify the entry data before the template is rendered?
# How do you modify the entry data before the template is rendered?

(Asked by: username_0 on 2020-05-25)

I am using a pattern library which expects a different data structure to what is in `entry`. Is there a way to parse the `entry` through a transformer class before the template is rendered?

Currently I have created a Twig function to run: `{% set job = single(entry) %}` which returns the mapped data for each different entry type.

I would like to hook into Craft to do this before the template is rendered and remove any mapping logic from the templates. Is this possible/practical?

**Tags:** templating

> **Comments:**
> **username_1**: Can you elaborate on your use case a bit as to what you're trying to do?  

---

## 2 answers

### Answer by username_2 on 2020-05-25. Score: 3

Definitely possible; you'd need to write a plugin or module in PHP to do it though. Probably it could listen to for the View::EVENT_BEGIN_PAGE event, and get the injected element via $element = Craft::$app->urlManager->getMatchedElement()
Something sorta like this:
use craft\web\View;

// ...

    $request = Craft::$app->getRequest();
    if ($request->getIsSiteRequest()) {
        // Handler: View::EVENT_BEGIN_PAGE
        Event::on(
            View::class,
            View::EVENT_BEGIN_PAGE,
            function () {
                Craft::debug(
                    'View::EVENT_BEGIN_PAGE',
                    __METHOD__
                );
                $element = Craft::$app->urlManager->getMatchedElement();
                if ($element !== null && ...) {
                    // ...do something
                }
            }
        );
    }

To make things clean, rather than modifying the element itself, I'd probably inject a new Twig variable, something like entryTransformed or something that your templating code could access.

> **Comments:**
> **username_0**: Ok thanks this seems like a good idea. What would be the best way to add the variable inside the callback?  
> **username_2**: Yeah so the answer above isn't quite correct for what you're trying to do specifically. Check out my answer to that here: https://craftcms.stackexchange.com/questions/35427/add-variable-to-twig-context  

---

### Answer by username_1 on 2020-05-25. Score: 2

What format are you trying to get your data into?

I can think of a few different ways to handle this depending on what you might want to do:

# Element API

You don't mention what format you need but JSON is a popular format and the [Element API](https://github.com/craftcms/element-api) is a first party solution in Craft.

# Hidden Field

Another way to accomplish this would be to setup an [Incognito field](https://github.com/mmikkel/IncognitoField-Craft3) on your entry. Then, listen to the `EVENT_BEFORE_SAVE_ELEMENT` event using a plugin to transform your data and save it to the format you need. This is similar to how you're doing it in Twig now, except just in a different "place" in the request.

This also has the advantage of doing the data transform once when the entry is saved (instead of every page load or messing around with `{% cache %}` tags). Then you just grab it in Twig like any other field, similar to how you're doing it now.

# Twig Filter

You mentioned this in your question. Since we don't have access to your Twig template, it's hard to know what you're trying to accomplish but I don't necessarily see a downside to doing it this way if your page performance is good. The only thing you might want to consider is adding {% cache %} tags around your output to give your server a break in that respect.

# Page Injection

See [Andrew's answer](https://craftcms.stackexchange.com/a/35417/1016) if you need to do things even "higher up" before the template layer.

> **Comments:**
> **username_0**: Thanks for the feedback. I ended up going with Andrew's answer. Do you know a good method of adding a variable to the template context in the event in his example?  
> **username_1**: That's a good question, you might get more action if you ask it as  a new question but one way to do it would be to create a [Twig extension](https://docs.craftcms.com/v3/extend/extending-twig.html).  

---

