<p>You're using <code>$view-&gt;resolveTemplate('_blog-entry')</code> which is returning the absolute path to the template as a string, and then passing that to <code>$view-&gt;render</code> which is expecting a <em>relative</em> path, not an absolute one. Internally I expect it's trying to run <code>resolveTemplate</code> on its argument, and it isn't sophisticated enough to recognize that a path is already absolute.</p>

<p>From your comment on the other answer it looks like you solved this, though didn't highlight it as the solution: <strong>just pass the relative template path straight to <code>render</code>; no need to use <code>resolveTemplate</code> first</strong>.</p>

<p>So corrected full code might be:</p>

<pre><code>$view = Craft::$app-&gt;getView();
$html = $view-&gt;render('_blog-entry', ['entry' =&gt; $blogpost]);
</code></pre>

<p>I don't believe switching the template mode, as suggested in the other answer, is actually required, at least not under all circumstances.</p>

CC BY-SA 4.0
2019-02-14T02:19:15.570Z
2019-02-14T02:19:15.570Z
tremby
<p>I wrote a transformer class that does exactly this:
    

<pre><code>namespace your\awesome\namespace;

use Craft;
use craft\elements\Entry;
use League\Fractal\TransformerAbstract;
use craft\web\View;

/**
 * Class TwigTransformer
 * Renders a TWIG entry for each item
 */

class TwigTransformer extends TransformerAbstract
{
    private $twigTemplateFilePath;

    public function __construct($twigTemplateFilePath)
    {
        $this-&gt;twigTemplateFilePath = $twigTemplateFilePath;
    }

    public function transform(Entry $entry)
    {
        $oldMode = Craft::$app-&gt;view-&gt;getTemplateMode();
        Craft::$app-&gt;view-&gt;setTemplateMode(View::TEMPLATE_MODE_SITE);
        $html = Craft::$app-&gt;view-&gt;renderTemplate( $this-&gt;twigTemplateFilePath, ['entry' =&gt; $entry]);
        Craft::$app-&gt;view-&gt;setTemplateMode($oldMode);

        return [
            'id' =&gt; $entry-&gt;id,
            'html' =&gt; $html
        ];
    }
}
</code></pre>

<p>You could use the class likes this:</p>

<pre><code>'transformer' =&gt; new TwigTransformer('includes/_overview-entry.twig'),
</code></pre>

CC BY-SA 4.0
2019-02-19T11:02:14.130Z
2019-02-19T11:02:14.130Z
Dimitri van der Vliet
<p>You didn’t tell where that Twig file is located, but I assume your issue has to do with being in the wrong “Template Mode”.</p>

<p>Here’s how you can switch mode:</p>

<pre><code>Craft::$app-&gt;view-&gt;setTemplateMode()
</code></pre>

<p>Documentation: <a href="https://docs.craftcms.com/v3/extend/updating-plugins.html#rendering-plugin-templates-on-front-end-requests" rel="nofollow noreferrer">https://docs.craftcms.com/v3/extend/updating-plugins.html#rendering-plugin-templates-on-front-end-requests</a></p>

CC BY-SA 3.0
2017-12-08T15:50:33.867Z
Thank you very much! I tried to render a template from my own "templates" folder, not for the Craft CP. So the solution was:

    `$view->setTemplateMode($view::TEMPLATE_MODE_SITE);`
    
    `$view->renderTemplate('_blog-entry', ['entry' => $blogpost])`
zauni
CC BY-SA 4.0
2017-12-08T14:20:33.300Z
2018-11-02T18:45:39.227Z
2018-11-02T18:45:39.227Z
carlcs
<p>I want to render a Twig template in an API endpoint. Specifically I need HTML for the JSON Feed field "content_html".</p>

<p>My attempts until now (inside the transformer function):</p>

<pre><code>$view = Craft::$app-&gt;getView();
$template = $view-&gt;resolveTemplate('_blog-entry');

// first attempt:
$html = $view-&gt;render($template, ['entry' =&gt; $blogpost]);

// second attempt:
$controller = Craft::$app-&gt;createController('templates/render')[0];

$html = $controller-&gt;render($template, ['entry' =&gt; $blogpost])
</code></pre>

<p>But in both ways it says "Template not found" even if the path after the "resolveTemplate" is correct.</p>

<p>Has anybody an idea how to do it? Thanks!</p>

<plugin-elementapi><craft3>
How to render a Twig template in the element-api plugin (v2.5)
# How to render a Twig template in the element-api plugin (v2.5)

(Asked by: username_0 on 2017-12-08)

I want to render a Twig template in an API endpoint. Specifically I need HTML for the JSON Feed field "content_html".
My attempts until now (inside the transformer function):
$view = Craft::$app->getView();
$template = $view->resolveTemplate('_blog-entry');

// first attempt:
$html = $view->render($template, ['entry' => $blogpost]);

// second attempt:
$controller = Craft::$app->createController('templates/render')[0];

$html = $controller->render($template, ['entry' => $blogpost])

But in both ways it says "Template not found" even if the path after the "resolveTemplate" is correct.
Has anybody an idea how to do it? Thanks!

**Tags:** plugin-elementapi, craft3

---

## 3 answers

### Answer by username_3 on 2017-12-08. Score: 4 | Accepted answer

You didn’t tell where that Twig file is located, but I assume your issue has to do with being in the wrong “Template Mode”.
Here’s how you can switch mode:
Craft::$app->view->setTemplateMode()

Documentation: https://docs.craftcms.com/v3/extend/updating-plugins.html#rendering-plugin-templates-on-front-end-requests

> **Comments:**
> **username_0**: Thank you very much! I tried to render a template from my own "templates" folder, not for the Craft CP. So the solution was:      `$view->setTemplateMode($view::TEMPLATE_MODE_SITE);`          `$view->renderTemplate('_blog-entry', ['entry' => $blogpost])`  

---

### Answer by username_1 on 2019-02-14. Score: 4

You're using $view->resolveTemplate('_blog-entry') which is returning the absolute path to the template as a string, and then passing that to $view->render which is expecting a relative path, not an absolute one. Internally I expect it's trying to run resolveTemplate on its argument, and it isn't sophisticated enough to recognize that a path is already absolute.
From your comment on the other answer it looks like you solved this, though didn't highlight it as the solution: just pass the relative template path straight to render; no need to use resolveTemplate first.
So corrected full code might be:
$view = Craft::$app->getView();
$html = $view->render('_blog-entry', ['entry' => $blogpost]);

I don't believe switching the template mode, as suggested in the other answer, is actually required, at least not under all circumstances.


---

### Answer by username_2 on 2019-02-19. Score: 1

I wrote a transformer class that does exactly this:
    

namespace your\awesome\namespace;

use Craft;
use craft\elements\Entry;
use League\Fractal\TransformerAbstract;
use craft\web\View;

/**
 * Class TwigTransformer
 * Renders a TWIG entry for each item
 */

class TwigTransformer extends TransformerAbstract
{
    private $twigTemplateFilePath;

    public function __construct($twigTemplateFilePath)
    {
        $this->twigTemplateFilePath = $twigTemplateFilePath;
    }

    public function transform(Entry $entry)
    {
        $oldMode = Craft::$app->view->getTemplateMode();
        Craft::$app->view->setTemplateMode(View::TEMPLATE_MODE_SITE);
        $html = Craft::$app->view->renderTemplate( $this->twigTemplateFilePath, ['entry' => $entry]);
        Craft::$app->view->setTemplateMode($oldMode);

        return [
            'id' => $entry->id,
            'html' => $html
        ];
    }
}

You could use the class likes this:
'transformer' => new TwigTransformer('includes/_overview-entry.twig'),


---

