LAPS Posted March 5, 2020 Share Posted March 5, 2020 Hi there, I'm working on an email message template and would like to render a custom one to be sent. I tried to use $files->render() this way // rendering file e.g. a template file or a hook statement in ready.php $body = $files->render('emails/myfile', array( 'myVar1' => $var1, 'myVar2' => $var2, ... )); but $vars seems to be not accessible from within the rendered file. That is, $vars seems to be not set: // rendered file emails/myfile.php $myVar1 = $vars['myVar1']; // is not set $myVar2 = $vars['myVar2']; // is not set ... // is not set How can I get the $vars so to properly render the custom message template for sending the email? Notes: By using $files->include() the $vars is accessible but I cannot use this method because I should retrieve the output $body as a return value for sending the email later. So, I'm still looking to render the custom message using $files->render(). This thread is someway related to this one. Link to comment Share on other sites More sharing options...
Robin S Posted March 5, 2020 Share Posted March 5, 2020 When you pass in variables to $files->render() as ['myVar1' => $var1, 'myVar2' => $var2] then they are available in the rendered file as $myVar1 and $myVar2. Link to comment Share on other sites More sharing options...
LAPS Posted March 5, 2020 Author Share Posted March 5, 2020 @Robin S OK for $myVar1 and $myVar2 (string variables) ? ... but it seems do not work when I pass a PW Page ? // rendering file $myPage = $pages->get(12345); $body = $files->render('emails/myfile', array( 'myPageVar' => $myPage )); // rendered file emails/myfile.php isset($myPageVar); // returns false Strange ? Link to comment Share on other sites More sharing options...
Robin S Posted March 5, 2020 Share Posted March 5, 2020 On 3/5/2020 at 9:57 PM, LAPS said: but it seems do not work when I pass a PW Page Expand Perhaps a typo or other error in your code. I use $files->render() regularly and can pass in objects without any problem. Link to comment Share on other sites More sharing options...
LAPS Posted March 5, 2020 Author Share Posted March 5, 2020 On 3/5/2020 at 10:02 PM, Robin S said: Perhaps a typo or other error in your code. Expand You are right. Thanks Link to comment Share on other sites More sharing options...
psy Posted August 21, 2020 Share Posted August 21, 2020 Had the same issue as @LAPS, ie $vars not accessible in the rendered template. Fixed by including an empty array for $options, ie: <?php $vars = [ 'items' => $items, 'homepage' => pages(1), 'category' => $category ]; echo $files->render('inc/item-detail',$vars,[]); Link to comment Share on other sites More sharing options...
gebeer Posted April 27, 2023 Share Posted April 27, 2023 On 8/21/2020 at 3:10 AM, psy said: Had the same issue as @LAPS, ie $vars not accessible in the rendered template. Fixed by including an empty array for $options, ie: <?php $vars = [ 'items' => $items, 'homepage' => pages(1), 'category' => $category ]; echo $files->render('inc/item-detail',$vars,[]); Expand I just tried this and $vars is still null inside the render file, even when sending $options. Also $options is null. I am using this to render files (views) inside a module. So the render files sit inside /site/modules/myModule/views. I am rendering those with $this->files->render('/full/path/to/viewFile', [...], []); Can't find anything in the docs on how to retrieve $vars here. I need to pass them on to another render file. With ReflectionMethod, we can get all the parameter names passed to $files->render(). But not the values passed to that instance of the method. $f = new ReflectionMethod(wire('files'), 'render'); bd($f->getParameters()); If anybody knows how to get $vars inside the render files, would be much appreciated ? Link to comment Share on other sites More sharing options...
Jan Romero Posted April 27, 2023 Share Posted April 27, 2023 On 4/27/2023 at 10:53 AM, gebeer said: $vars is still null inside the render file Expand It’s not going to be in $vars. Instead, every key of the dictionary becomes a global variable, so psy’s example would introduce the variables $items, $homepage and $category to your template file. Link to comment Share on other sites More sharing options...
gebeer Posted April 27, 2023 Share Posted April 27, 2023 On 4/27/2023 at 11:10 AM, Jan Romero said: It’s not going to be in $vars. Instead, every key of the dictionary becomes a global variable, so psy’s example would introduce the variables $items, $homepage and $category to your template file. Expand Thanks. I'm aware of that. But I'm looking for a way to get the $vars variable like it was sent to the render method so I can pass it on easily. Imagine you pass a $vars array with 10 items to render(). Then from the render file that you passed them to you want to take $vars and pass it on to another partial with the render() method. ATM you have to write each one out again in the new render() call. That is tedious and it would be much easier if we could just grab $vars and pass it on. Link to comment Share on other sites More sharing options...
Jan Romero Posted April 27, 2023 Share Posted April 27, 2023 I see. I suppose the easiest way would be to just nest a single array in $vars and only ever use that. A more generic solution could involve hooking before TemplateFile::render: https://github.com/processwire/processwire/blob/6ff498f503db118d5b6c190b35bd937b38b80a77/wire/core/TemplateFile.php#L305 You could add something like $this->addHookBefore('TemplateFile::render', function(HookEvent $e) { $tpl = $e->object; $tpl->data('passedVars', array_diff_key($tpl->getArray(), wire()->fuel->getArray())); }); That should make the passed variables available as usual and additionally inside an array called $passedVars. I don’t think you’re going to get around the whole array_diff_key business at that point, unfortunately? The way passing vars to a file works in the core seems to immediately conflate those vars with the general globals. It happens even before render() is called, for instance here: https://github.com/processwire/processwire/blob/6ff498f503db118d5b6c190b35bd937b38b80a77/wire/core/WireFileTools.php#L1478. Link to comment Share on other sites More sharing options...
bernhard Posted April 27, 2023 Share Posted April 27, 2023 On 4/27/2023 at 10:53 AM, gebeer said: Can't find anything in the docs on how to retrieve $vars here. I need to pass them on to another render file. Expand If I understand correctly you should be able to just put this on top of the rendered view: $vars = get_defined_vars(); ...and then you can pass those $vars to the next ->render() call. We don't have a PW/API way all the time. Sometimes there's still a PHP way of doing it ? Link to comment Share on other sites More sharing options...
gebeer Posted May 3, 2023 Share Posted May 3, 2023 On 4/27/2023 at 8:18 PM, bernhard said: If I understand correctly you should be able to just put this on top of the rendered view: $vars = get_defined_vars(); ...and then you can pass those $vars to the next ->render() call. We don't have a PW/API way all the time. Sometimes there's still a PHP way of doing it ? Expand Thanks for the suggestion. This is throwing all kinds of errors. If I want to bd($vars), I get: User Error Exception: Method RockMigrations::getModuleInfo does not exist or is not callable in this context (in /var/www/html/wire/core/Wire.php line 563) #0 /var/www/html/wire/core/Wire.php(419): ProcessWire\Wire->___callUnknown('getModuleInfo', Array) #1 /var/www/html/wire/core/WireHooks.php(952): ProcessWire\Wire->_callMethod('___callUnknown', Array) #2 /var/www/html/wire/core/Wire.php(484): ProcessWire\WireHooks->runHooks(Object(ProcessWire\RockMigrations), 'callUnknown', Array) #3 /var/www/html/wire/core/Wire.php(487): ProcessWire\Wire->__call('callUnknown', Array) #4 /var/www/html/site/modules/RockMigrations/RockMigrations.module.php(4560): ProcessWire\Wire->__call('getModuleInfo', Array) #5 /var/www/html/site/modules/TracyDebugger/tracy-2.9.x/src/Tracy/Dumper/Describer.php(295): ProcessWire\RockMigrations->__debugInfo() With print_r($vars) I get: Fatal Error __debuginfo() must return an array Related to RockMigrations::__debugInfo(). Seems like this method is interfering with print_r(). After uninstalling Tracy I finally got to outputting var_dump($vars). Still throwing a Warning about RockMigrations::__debugInfo(). $vars contains all defined vars including fuel which contains wire and so on. So this is not feasable for the simple purpose of passing on some vars. What I finally did, is putting all vars that I need to pass on into an array $arr, then passing $arr to the render file. In the render file I can retrieve it with $arr and pass it on. Sometimes solutions are so simple. But the other day it was getting late already. Braindead just around the corner ? Link to comment Share on other sites More sharing options...
bernhard Posted May 3, 2023 Share Posted May 3, 2023 On 5/3/2023 at 1:40 AM, gebeer said: Still throwing a Warning about RockMigrations::__debugInfo() Expand The error that you are seeing comes from RockMigrations and not from get_defined_vars() - sorry for that. It has been fixed in the dev branch here already: https://github.com/baumrock/RockMigrations/commit/3ab756003e697f5fb2af0e2357094613464bd901#diff-f2f9bf51d98ac65f5b9abedff5f904a71b54b3ba563b1756756a37c5e9852635L4326 The problem was that ->getInfo()['version'] did not work anymore since I split the module info into it's own file to support PHP8 requirement. I'll merge everything into main soon ? 1 Link to comment Share on other sites More sharing options...
poljpocket Posted July 12, 2023 Share Posted July 12, 2023 You could actually pass an array which contains all other content like <?php $vars = [ 'items' => $items, 'homepage' => pages(1), 'category' => $category ]; echo $files->render('path/to/file.inc', [ 'vars' => $vars, ]); and then use that to pass on. To still have the convenience of global variables, you can use <?php extract($vars); in the template file to be rendered. My code is untested though! Link to comment Share on other sites More sharing options...
interrobang Posted July 12, 2023 Share Posted July 12, 2023 I just took a look at the source code and saw that in WireFileTools::render() all variables are added to data() of the rendered TemplateFile. You can get an array of the variables in your rendered file by $this->data(). Docs for data(): https://processwire.com/api/ref/wire-data/data/ 3 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now