mindplay.dk Posted March 30, 2013 Author Share Posted March 30, 2013 Possibly what makes the most sense, is to just pass one variable? The developer can pass an array or a single string, or an object, e.g. for strongly typed view-models if wanted. If you did want to pass an array and have it extracted as local variables, all you'd have to do is call extract($data) in your child-template - it's not a lot of work... 2 Link to comment Share on other sites More sharing options...
ryan Posted March 31, 2013 Share Posted March 31, 2013 Possibly what makes the most sense, is to just pass one variable? The developer can pass an array or a single string, or an object, e.g. for strongly typed view-models if wanted. If you did want to pass an array and have it extracted as local variables, all you'd have to do is call extract($data) in your child-template - it's not a lot of work... I think this makes sense. Only issue is the template needs to be aware of that context, rather than just having a $var present like others are. But I think it's probably the right balance. Link to comment Share on other sites More sharing options...
mindplay.dk Posted March 31, 2013 Author Share Posted March 31, 2013 Templates need to be aware of context either way - this way, you can actually do a simple check to see if a context was provided at all: isset($data) - plus it makes it easier to pass the entire context on to another child-template. Link to comment Share on other sites More sharing options...
ryan Posted April 1, 2013 Share Posted April 1, 2013 Makes sense to me. I will get this in the dev branch soon. 1 Link to comment Share on other sites More sharing options...
mindplay.dk Posted April 1, 2013 Author Share Posted April 1, 2013 You rock, ryan Link to comment Share on other sites More sharing options...
ryan Posted April 13, 2013 Share Posted April 13, 2013 I added this to the dev branch last week, so that you can now pass additional things to $page->render(): https://github.com/ryancramerdesign/ProcessWire/blob/dev/wire/modules/PageRender.module#L212 One of the things I wasn't thinking about before is that $page->render() was already capable of accepting an array of options (though not commonly used, mostly internal). So we weren't starting from a blank slate, and had to make something that was compatible and complimentary to what was already there. In terms of API calls, you can now do any of these: $page->render($filename); // $filename assumed in /site/templates/ $page->render($pathname); // $pathname is full path, but must resolve somewhere in web root $page->render($options); // array of options and/or your own variables $page->render(array('foo' => 'bar')); // same as above $page->render($filename, $options); // specify filename and options/vars, etc. The $options variable was already something that $page->render() accepted before. Only it was used to specify some little-used modifiers to render(). Those are still there (and they are necessary), but now the utility of $options has been extended. When you want to specify options (outlined in the link above) you only need to specify the ones you want to change from the defaults (of course). Typically you don't need to change them, so I'm guessing that most would use $options to specify their own variables. Every rendered template now receives a copy of that $options array locally scoped. That $options array contains any variables you passed to $page->render(). It also contains PW's default options, should you want to examine any of them. If you made this render() call: echo $page->render('myfile.php', array('foo' => 'bar')); myfile.php could access the 'foo' variable like this: echo $options['foo']; // outputs "bar" One other addition that I'm thinking people might like is $options['pageStack']. That is an array containing a stack of pages that called render(). So if you are doing any recursive rendering of pages, any template can access $options['pageStack'] to see what page is rendering it, and any others before it. Previously this was not possible, and the only way a template could tell what other page was rendering it (if any) was for that renderer to tell the renderee, via $mypage->caller = $page; or something like that. 18 Link to comment Share on other sites More sharing options...
mindplay.dk Posted April 13, 2013 Author Share Posted April 13, 2013 Sounds good - though I am somewhat concerned about the reserved keys in $options, but I guess that's inevitable since they're already in use. They should probably be documented in the API, so that people don't accidentally overwrite reserved values. EDIT: you did already document them 1 Link to comment Share on other sites More sharing options...
owzim Posted May 2, 2013 Share Posted May 2, 2013 If you made this render() call: echo $page->render('myfile.php', array('foo' => 'bar')); myfile.php could access the 'foo' variable like this: echo $options['foo']; // outputs "bar" Why is the variable handling not the same as with the TemplateFile class? $tplf->setArray(array('foo' => 'bar')); and in the template I am able to access foo with: echo $foo; Link to comment Share on other sites More sharing options...
ryan Posted May 3, 2013 Share Posted May 3, 2013 Why is the variable handling not the same as with the TemplateFile class? With template files you generally have a documented set of API variables ($page, $pages, $user, etc.), and this is what the set() methods of TemplateFile are geared towards. On the other hand, when passing variables into a $page->render(), variables passed in may be unknown/undocumented to the template file, and will be installation-specific, since PW doesn't pass in API variables that way. By having them in a known array ($options), you have a way of inspecting them, or at least knowing where they will be. Otherwise, the template file would have no means of self discovery for these things. It decreases the unknowns, increases the portability, and introduces an appropriate level of separation from the system API variables. On the other hand, this is largely theoretical… I've never had the need to pass in variables to template files in this manner, so am mainly just trying to accommodate the needs brought up in this thread. 2 Link to comment Share on other sites More sharing options...
owzim Posted May 26, 2013 Share Posted May 26, 2013 Ryan, yes, I kind of missed the point. Since with TemplateFile class the actual template files is not automatically connected to the template itself which makes it necessary to pass certain variables if you want to use it like in this $page->render() context. So now I got how powerful it actually is to use context sensitive templates, and you can totally automate this too. Prefix your template files with contexts like: team-member.php home-team-member.php sidebar-team-member.php and use it like: $child->render($page->template . '-team-member.php'); If the template is called when being the actual page, render() is called automatically, so it's loaded the unprefixed team-member.php then. Awesome stuff. 2 Link to comment Share on other sites More sharing options...
adrian Posted June 6, 2013 Share Posted June 6, 2013 Fantastic enhancement Ryan. I was trying to pass some custom variables to render today and couldn't - found this post, upgraded to dev, and voila! Made things so much easier 1 Link to comment Share on other sites More sharing options...
ohthanks Posted June 19, 2013 Share Posted June 19, 2013 This is great btw, been rewriting the previous template/view setup I was using to incorporate these changes. The only issue I'm having right now is if I am rendering a partial template with a defined template filename argument TemplateFile.php is still checking & throwing an exception if isn't a file present in the base template folder. For example if I have something like this in a template foreach($packages as $package) { echo $package->render('markup/layouts/package.php', array('layout' => 'package')); } I have to have a empty placeholder /site/templates/package.php file to avoid an exception. I dunno if that is as intended or it is still just checking for the default template file and trying to ensure that's there. Link to comment Share on other sites More sharing options...
ryan Posted June 20, 2013 Share Posted June 20, 2013 If you are telling it to render using a specific template file, and that file doesn't exist, than an exception would be the right behavior. If there's a possibility the template might not be there, you should check yourself before asking it to render. Example: $file = 'markup/layouts/package.php'; if(is_file(wire('config')->paths->templates . $file)) { echo $package->render($file, array('layout' => 'package')); } Link to comment Share on other sites More sharing options...
Alessio Dal Bianco Posted July 8, 2013 Share Posted July 8, 2013 Hi guys, i was reading this thread and remind me something i have tried to do many months ago: http://processwire.com/talk/topic/2280-change-template-file-of-a-single-page/ http://processwire.com/talk/topic/2339-module-test-views/?hl=%2Bproof+%2Bconcept I think that we are all looking the same objective but in different ways, so i read that the "render()" method handles in a more cleaner way the change of the file that render the page but i don't know how to use it in a module, because i would manage that views directly from the admin. I hope i have explained well.... USSliberty Link to comment Share on other sites More sharing options...
ryan Posted July 11, 2013 Share Posted July 11, 2013 I think that we are all looking the same objective but in different ways, so i read that the "render()" method handles in a more cleaner way the change of the file that render the page but i don't know how to use it in a module, because i would manage that views directly from the admin. Not sure I understand the question. For the most part, ProcessWire's API works the same no matter where you use it from (whether a template or a module, etc). If you'd like, post a code sample of what's not working? Link to comment Share on other sites More sharing options...
Recommended Posts