<p>I've been able to render CP templates in the front end using some methods in <code>PathService</code> and <code>TemplatesService</code>, which you could use inside your own Template Variable to render the macros:</p>

<pre><code>class YourVariable {

    public function renderFormMacro($macro, array $args)
    {
        // Get the current template path
        $originalPath = craft()-&gt;path-&gt;getTemplatesPath();

        // Point Twig at the CP templates
        craft()-&gt;path-&gt;setTemplatesPath(craft()-&gt;path-&gt;getCpTemplatesPath());

        // Render the macro.
        $html = craft()-&gt;templates-&gt;renderMacro('_includes/forms', $macro, array($args));

        // Restore the original template path
        craft()-&gt;path-&gt;setTemplatesPath($originalPath);

        return TemplateHelper::getRaw($html);
    }
}
</code></pre>

<p>Which would be used like:</p>

<p><code>craft.yourVariable.renderFormMacro('textField', { label: 'Name' })</code></p>

<p>I've not tested it but I think that should be close. </p>

CC BY-SA 3.0
2017-02-26T15:37:14.723Z
Confirming that it works. I think this is best answer
Yuri Salimovskiy
CC BY-SA 3.0
2014-11-20T21:06:34.370Z
I'm going to have to give that a try soon, thanks Mike.
Jason McCallister
CC BY-SA 3.0
2014-11-20T11:38:34.573Z
2014-11-20T11:38:34.573Z
Mike Pepper
<p>Here’s a Craft 3-friendly way of achieving what Mike suggested. This assumes your app already has a custom twig extension, if it doesn’t you can easily <a href="https://pluginfactory.io/" rel="nofollow noreferrer">create one</a>.</p>

<p>Add <code>use craft\web\View;</code> to the top of your TwigExtension, then in <code>getFunctions()</code> add your function definition:</p>

<pre><code>new \Twig\TwigFunction('field', [$this, 'renderFormMacro'], ['is_safe' =&gt; ['html']]),
</code></pre>

<p>Then the function itself:</p>

<pre><code>public function renderFormMacro(string $fieldType, array $fieldOptions) : string
{
    $oldMode = \Craft::$app-&gt;view-&gt;getTemplateMode();
    \Craft::$app-&gt;view-&gt;setTemplateMode(View::TEMPLATE_MODE_CP);
    $html = \Craft::$app-&gt;view-&gt;renderTemplateMacro('_includes/forms', $fieldType, [$fieldOptions]);
    \Craft::$app-&gt;view-&gt;setTemplateMode($oldMode);

    return $html;
}
</code></pre>

<p>You can then display fields in your frontend templates with code like this:</p>

<pre><code>{{ field('text', {
    name: 'location',
    value: 'Timbuktu'
}) }}
</code></pre>

CC BY-SA 4.0
2022-05-02T18:38:24.827Z
A heads up that renderTemplateMacro is now deprecated since Craft CMS 3.6 and removed in Craft CMS 4 I think.
James White
CC BY-SA 4.0
2019-03-11T12:01:57.303Z
2019-03-11T12:12:55.677Z
2019-03-11T12:12:55.677Z
Dom Stubbs
<p>For those looking at this in Craft 4, the renderTemplateMacro function in the View class was deprecated in Craft 3 and has been removed in Craft 4, so the Craft 3 example won't work.</p>
<p><a href="https://craftcms.com/docs/4.x/extend/updating-plugins.html#view-rendertemplatemacro-has-been-removed" rel="nofollow noreferrer">https://craftcms.com/docs/4.x/extend/updating-plugins.html#view-rendertemplatemacro-has-been-removed</a></p>
<p>However, the Cp helper class can provide access to the various form field macros, which you can link up with a Twig function.</p>
<p><a href="https://docs.craftcms.com/api/v4/craft-helpers-cp.html#public-methods" rel="nofollow noreferrer">https://docs.craftcms.com/api/v4/craft-helpers-cp.html#public-methods</a>.</p>
<p>Using the Cp helper class, means you don't have to do the template mode switching if you call the field in Twig like this:</p>
<pre class="lang-php prettyprint-override"><code>public function getFunctions(): array
{
    return [
        new TwigFunction('textField', [$this, 'renderTextField'], ['is_safe' =&gt; ['html']])
    ];
}

public function renderTextField(array $options)
{
    return Cp::textFieldHtml($options);
}
</code></pre>
<p>This could get repetitive for multiple fields, but there are a few ways to retain the same functionality as the renderTemplateMacro example.</p>
<p>Another approach, could be to use a twig function like this, calling the fieldHtml() to render a full field with label.</p>
<pre class="lang-php prettyprint-override"><code>// Full field with label
public function renderCpFieldHtml(string $fieldType, array $fieldOptions = [])
{
    return Cp::fieldHtml('template:_includes/forms/' . $fieldType, $fieldOptions);
}
</code></pre>
<pre class="lang-php prettyprint-override"><code>// Just the field
public function renderCpField(string $fieldType, array $fieldOptions = [])
{
    return Cp::renderTemplate('_includes/forms/' . $fieldType, $fieldOptions);
}
</code></pre>
<p>In both cases fieldType would be a value like <code>text</code> or <code>select</code>.</p>
<p>You can also do this in Craft CMS 3 as well, so if you wanted to avoid having a deprecation issue, it's one less problem when you do upgrade to Craft 4.</p>

CC BY-SA 4.0
2022-05-27T17:20:35.443Z
2022-05-28T08:05:32.540Z
2022-05-28T08:05:32.540Z
James White
<p>We've done this on a few sites and you're right it's extremely helpful. The only way I've found to get it to work is to simply copy the "_includes/forms" folder from craft/app/templates to the sites craft/templates</p>

<p>It works but I'd love a less hacks way to do it, either through a plugin or some built-in means.</p>

CC BY-SA 3.0
2014-11-19T20:38:54.153Z
I thought symlinking the directory might work, but then subsequent imports get messed up :(
Tim Kelty
CC BY-SA 3.0
2014-07-25T09:52:10.133Z
2014-07-25T09:52:10.133Z
Keith Mancuso
<p>From working on plugin development, importing (I believe the correct term for this is macro) the 'forms' to quickly generate text areas, selects and etc. is incredibly useful. Adding the import now fails as '_includes' is only accessible from the control panel. </p>

<p>So in my template I could add this line:</p>

<pre><code>{% import "_includes/forms" as forms %}
</code></pre>

<p>Then use something similar to this to output my forms fields?</p>

<pre><code>{{ forms.textField({
    label: "First Name"|t,
    id: 'firstName',
    name: 'firstName',
    instructions: "First name (i.e John)",
    placeholder: "John",
    first: true,
    autofocus: true,
    required: true
}) }}
</code></pre>

<p>I know when using Symfony and Twig you can specify the namespace on where to grab the template from. Does Craft include a way to access those templates from the front end? Has anyone managed to perform this outside of the control panel?</p>

<p><strong>Edit</strong>: <em>if this is not possible, or p&amp;t doesn't plan on making this possible (for security concerns) is there a way for a plugins template path to allow anonymous access? This way the developer could create an '_includes' and allow people to access it in the same manor?</em></p>

<templating><import><macro>
Is it possible to use _includes/forms outside of the Control Panel?
# Is it possible to use _includes/forms outside of the Control Panel?

(Asked by: username_0 on 2014-07-25)

From working on plugin development, importing (I believe the correct term for this is macro) the 'forms' to quickly generate text areas, selects and etc. is incredibly useful. Adding the import now fails as '_includes' is only accessible from the control panel. 
So in my template I could add this line:
{% import "_includes/forms" as forms %}

Then use something similar to this to output my forms fields?
{{ forms.textField({
    label: "First Name"|t,
    id: 'firstName',
    name: 'firstName',
    instructions: "First name (i.e John)",
    placeholder: "John",
    first: true,
    autofocus: true,
    required: true
}) }}

I know when using Symfony and Twig you can specify the namespace on where to grab the template from. Does Craft include a way to access those templates from the front end? Has anyone managed to perform this outside of the control panel?
Edit: if this is not possible, or p&t doesn't plan on making this possible (for security concerns) is there a way for a plugins template path to allow anonymous access? This way the developer could create an '_includes' and allow people to access it in the same manor?

**Tags:** templating, import, macro

---

## 4 answers

### Answer by username_5 on 2014-07-25. Score: 4 | Accepted answer

We've done this on a few sites and you're right it's extremely helpful. The only way I've found to get it to work is to simply copy the "\_includes/forms" folder from craft/app/templates to the sites craft/templates

It works but I'd love a less hacks way to do it, either through a plugin or some built-in means.

> **Comments:**
> **username_6**: I thought symlinking the directory might work, but then subsequent imports get messed up :(  

---

### Answer by username_1 on 2014-11-20. Score: 9

I've been able to render CP templates in the front end using some methods in PathService and TemplatesService, which you could use inside your own Template Variable to render the macros:
class YourVariable {

    public function renderFormMacro($macro, array $args)
    {
        // Get the current template path
        $originalPath = craft()->path->getTemplatesPath();

        // Point Twig at the CP templates
        craft()->path->setTemplatesPath(craft()->path->getCpTemplatesPath());

        // Render the macro.
        $html = craft()->templates->renderMacro('_includes/forms', $macro, array($args));

        // Restore the original template path
        craft()->path->setTemplatesPath($originalPath);

        return TemplateHelper::getRaw($html);
    }
}

Which would be used like:
craft.yourVariable.renderFormMacro('textField', { label: 'Name' })
I've not tested it but I think that should be close.

> **Comments:**
> **username_0**: I'm going to have to give that a try soon, thanks Mike.  
> **username_2**: Confirming that it works. I think this is best answer  

---

### Answer by username_3 on 2019-03-11. Score: 2

Here’s a Craft 3-friendly way of achieving what Mike suggested. This assumes your app already has a custom twig extension, if it doesn’t you can easily create one.
Add use craft\web\View; to the top of your TwigExtension, then in getFunctions() add your function definition:
new \Twig\TwigFunction('field', [$this, 'renderFormMacro'], ['is_safe' => ['html']]),

Then the function itself:
public function renderFormMacro(string $fieldType, array $fieldOptions) : string
{
    $oldMode = \Craft::$app->view->getTemplateMode();
    \Craft::$app->view->setTemplateMode(View::TEMPLATE_MODE_CP);
    $html = \Craft::$app->view->renderTemplateMacro('_includes/forms', $fieldType, [$fieldOptions]);
    \Craft::$app->view->setTemplateMode($oldMode);

    return $html;
}

You can then display fields in your frontend templates with code like this:
{{ field('text', {
    name: 'location',
    value: 'Timbuktu'
}) }}

> **Comments:**
> **username_4**: A heads up that renderTemplateMacro is now deprecated since Craft CMS 3.6 and removed in Craft CMS 4 I think.  

---

### Answer by username_4 on 2022-05-27. Score: 1

For those looking at this in Craft 4, the renderTemplateMacro function in the View class was deprecated in Craft 3 and has been removed in Craft 4, so the Craft 3 example won't work.
https://craftcms.com/docs/4.x/extend/updating-plugins.html#view-rendertemplatemacro-has-been-removed
However, the Cp helper class can provide access to the various form field macros, which you can link up with a Twig function.
https://docs.craftcms.com/api/v4/craft-helpers-cp.html#public-methods.
Using the Cp helper class, means you don't have to do the template mode switching if you call the field in Twig like this:
public function getFunctions(): array
{
    return [
        new TwigFunction('textField', [$this, 'renderTextField'], ['is_safe' => ['html']])
    ];
}

public function renderTextField(array $options)
{
    return Cp::textFieldHtml($options);
}

This could get repetitive for multiple fields, but there are a few ways to retain the same functionality as the renderTemplateMacro example.
Another approach, could be to use a twig function like this, calling the fieldHtml() to render a full field with label.
// Full field with label
public function renderCpFieldHtml(string $fieldType, array $fieldOptions = [])
{
    return Cp::fieldHtml('template:_includes/forms/' . $fieldType, $fieldOptions);
}

// Just the field
public function renderCpField(string $fieldType, array $fieldOptions = [])
{
    return Cp::renderTemplate('_includes/forms/' . $fieldType, $fieldOptions);
}

In both cases fieldType would be a value like text or select.
You can also do this in Craft CMS 3 as well, so if you wanted to avoid having a deprecation issue, it's one less problem when you do upgrade to Craft 4.


---

