Answers.Body: <p>There is no <code>craft()</code> function in Craft 3 and there are no Modules in Craft 2.
  You probably mix the two different versions.</p>
  <h3>Craft 3</h3>
  <pre><code>Craft::$app-&gt;getView()-&gt;renderTemplate('/path/to/template');
  </code></pre>
  <p>Of course you need to be in the correct namespace. You have to either <code>use Craft</code> or do <code>\Craft</code></p>
  <h3>Craft 2</h3>
  <pre><code>craft()-&gt;templates-&gt;render('path/to/template')
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2018-04-28T18:14:56.743Z
Answers.Text: Ah of course! Thanks @RobinSchambach. My problem now is that `Craft::$app->getView()->renderTemplate` appears to be setting the Content-Type header to `application/json`. So when I use the Twig function in a Twig template, it's trying to render the template as JSON rather than HTML.  I don't suppose you know how I can stop it from doing that?
Answers.UserDisplayName: Pete H
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2018-04-28T18:17:51.510Z
Answers.Text: No. The function does not change the response type at all and it does not change the headers either. When you call the function inside a template it returns normal html - like everywhere else. The response object in your Controller is responsible for the headers. If you are going to return JSON in your controller you have to to `return $this->asJson($data)` if not, do `return $this->renderTemplate()`
Answers.UserDisplayName: Robin Schambach
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2018-04-28T18:44:05.303Z
Answers.Text: OK thanks @Robin. My module doesn't currently have a controller; just the main module class and the twig extension class. I think I'll need to learn a bit more about how modules work! If you don't mind, in the context of `return $this->asJson($data)`, what is `$this`?
Answers.UserDisplayName: Pete H
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2018-04-28T18:45:22.600Z
Answers.Text: `$this` is the controller that is responsible for the request. I'm still not sure what you are trying to achieve. If you want to return json in a Twig function just decode it like you are used to in PHP, if not return the html
Answers.UserDisplayName: Robin Schambach
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2018-04-28T18:53:04.527Z
Answers.Text: I'm trying to create a custom twig function that gets JSON data from a template, then returns that data in a way that it can be used in the template where the twig function has been used. For example, in my HTML template, I could do `{% set data = importJSON('path/to/template') %} {{ data.something }} {{ data.somethingElse }}` where `importJSON()` is my custom twig function.
Answers.UserDisplayName: Pete H
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2018-04-28T18:57:22.517Z
Answers.Text: That's usually a really bad idea and bad practice as well because Twig is used to be a template engine and not meant to be abused in that way. In general templates produce HTML and no JSON, you **can** do it but I would not recommend so. However - you could do `$html = Craft::$app->getView()->renderTemplate($path); return json_encode($html);` But you will have to `json_decode` your string in Twig... not sure what this should be good for
Answers.UserDisplayName: Robin Schambach
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2018-04-28T19:05:43.957Z
Answers.Text: OK, maybe I'll have to have a rethink. Thanks for your help!
Answers.UserDisplayName: Pete H
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2018-04-28T19:06:48.883Z
Answers.Text: Why don't you create the data you want to return in PHP and return an Object from the beginning?
Answers.UserDisplayName: Robin Schambach
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2018-04-28T19:13:31.950Z
Answers.Text: I'm actually just thinking the same thing. I originally wanted the data available as JSON so I could access it from JavaScript as well, but actually that might not be a requirement anymore.
Answers.UserDisplayName: Pete H
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2018-04-28T19:14:49.627Z
Answers.Text: If that's the case just do `var json = {{ yourObject|json_encode|raw }}`
Answers.UserDisplayName: Robin Schambach
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2018-04-28T19:17:52.867Z
Answers.Text: Yeah, good idea.  OK I think I have enough to make this work. Thanks for your help, I really appeciate it!
Answers.UserDisplayName: Pete H
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2018-04-28T16:22:21.723Z
Answers.LastActivityDate: 2018-04-28T16:22:21.723Z
Answers.LastEditDate: 2020-06-17T08:56:27.903Z
Answers.UserDisplayName: Robin Schambach
Body: <p>I have a template that outputs some JSON formatted data.</p>
  
  <p>I've built a simple module that needs to get the contents of that template, decode the JSON data, and return it.</p>
  
  <p>I believe I need to use <code>craft()-&gt;templates-&gt;render('path/to/template')</code>, but when I do, I get:</p>
  
  <p><code>Call to undefined function modules\importjsonmodule\twigextensions\craft()</code></p>
  
  <p>The only explanation I can think of is that <code>craft()</code> cannot be used in a module in the way it can in a plugin. Is that the case? If so, is there any way I can access the Templates service from within a module?</p>
  
  <p>Thanks</p>
  
Tags: <plugin-development><craft3><modules>
Title: Return the contents of a template from a custom Twig function in a module?
ThreadText: # Return the contents of a template from a custom Twig function in a module?
  
  (Asked by: username_0 on 2018-04-28)
  
  I have a template that outputs some JSON formatted data.
  
  I've built a simple module that needs to get the contents of that template, decode the JSON data, and return it.
  
  I believe I need to use `craft()->templates->render('path/to/template')`, but when I do, I get:
  
  `Call to undefined function modules\importjsonmodule\twigextensions\craft()`
  
  The only explanation I can think of is that `craft()` cannot be used in a module in the way it can in a plugin. Is that the case? If so, is there any way I can access the Templates service from within a module?
  
  Thanks
  
  **Tags:** plugin-development, craft3, modules
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2018-04-28. Score: 5 | Accepted answer
  
  There is no `craft()` function in Craft 3 and there are no Modules in Craft 2.
  You probably mix the two different versions.
  
  ### Craft 3
  
  ```
  Craft::$app->getView()->renderTemplate('/path/to/template');
  
  ```
  
  Of course you need to be in the correct namespace. You have to either `use Craft` or do `\Craft`
  
  ### Craft 2
  
  ```
  craft()->templates->render('path/to/template')
  
  ```
  
  > **Comments:**
  > **username_0**: Ah of course! Thanks @username_1. My problem now is that `Craft::$app->getView()->renderTemplate` appears to be setting the Content-Type header to `application/json`. So when I use the Twig function in a Twig template, it's trying to render the template as JSON rather than HTML.  I don't suppose you know how I can stop it from doing that?  
  > **username_1**: No. The function does not change the response type at all and it does not change the headers either. When you call the function inside a template it returns normal html - like everywhere else. The response object in your Controller is responsible for the headers. If you are going to return JSON in your controller you have to to `return $this->asJson($data)` if not, do `return $this->renderTemplate()`  
  > **username_0**: OK thanks @username_1. My module doesn't currently have a controller; just the main module class and the twig extension class. I think I'll need to learn a bit more about how modules work! If you don't mind, in the context of `return $this->asJson($data)`, what is `$this`?  
  > **username_1**: `$this` is the controller that is responsible for the request. I'm still not sure what you are trying to achieve. If you want to return json in a Twig function just decode it like you are used to in PHP, if not return the html  
  > **username_0**: I'm trying to create a custom twig function that gets JSON data from a template, then returns that data in a way that it can be used in the template where the twig function has been used. For example, in my HTML template, I could do `{% set data = importJSON('path/to/template') %} {{ data.something }} {{ data.somethingElse }}` where `importJSON()` is my custom twig function.  
  > **username_1**: That's usually a really bad idea and bad practice as well because Twig is used to be a template engine and not meant to be abused in that way. In general templates produce HTML and no JSON, you **can** do it but I would not recommend so. However - you could do `$html = Craft::$app->getView()->renderTemplate($path); return json_encode($html);` But you will have to `json_decode` your string in Twig... not sure what this should be good for  
  > **username_0**: OK, maybe I'll have to have a rethink. Thanks for your help!  
  > **username_1**: Why don't you create the data you want to return in PHP and return an Object from the beginning?  
  > **username_0**: I'm actually just thinking the same thing. I originally wanted the data available as JSON so I could access it from JavaScript as well, but actually that might not be a requirement anymore.  
  > **username_1**: If that's the case just do `var json = {{ yourObject|json_encode|raw }}`  
  > **username_0**: Yeah, good idea.  OK I think I have enough to make this work. Thanks for your help, I really appeciate it!  
  
  ---
  
  