elabx Posted March 15, 2018 Share Posted March 15, 2018 Hi, I've gone a different way to achieve kind of "auto swap" of template files through hooking TemplateFile, because I wanted to swap template files if a template file with some naming convention exists (eg. home.custom.php replaces home.php) I'd like to ask for some opinions about the performance of this hook and if it makes a sensible approach because it feels a way too much to check for files on disk on every template render: $wire->addHookBefore("TemplateFile::render", function($event){ if($this->user->name == "admin"){ $templateFile = $event->object; if($templateFile->page->template == "repeater_content"){ $existingFiles = $this->files->find($this->config->paths->templates . "fields/content/"); $customFileName = $this->config->paths->templates . "fields/content/{$templateFile->page->type}.custom.php"; if(in_array($customFileName, $existingFiles)){ $templateFile->setFilename($customFileName); $event->return = $templateFile; } elseif($templateFile->page->template == "home" || $templateFile->page->template == "basic-content" ){ $existingFiles = $this->files->find($this->config->paths->templates); $customFileName = $this->config->paths->templates . "{$templateFile->page->template}.custom.php"; if(in_array($customFileName, $existingFiles)){ $templateFile->setFilename($customFileName); $event->return = $templateFile; } } } }); Link to comment Share on other sites More sharing options...
kongondo Posted March 15, 2018 Share Posted March 15, 2018 (edited) 27 minutes ago, elabx said: it feels a way too much to check for files on disk on every template render: Unless you will be storing the result of an initial check (e.g. in a session or cache), you will have to check for the existence of the file. That aside, do you really need a hook for this? If I got you correctly, couldn't you do the check in the template file itself or that would mean repetitive code? If you did the check in init.php, you wouldn't need to have the same code check in different template files. I don't know if I am making sense, so on to an example. If you had this in init.php (assuming you are using delayed output). $templateName = $page->template->name; $customTemplateFile = $config->paths->templates . 'fields/content/' . $templateName . '.custom.php'; // if user is superuser (or user of your choice) AND we have a readable template file (e.g. home.custom.php) // ... we include it if($user->isSuperuser() && is_readable($customTemplateFile)) { include($customTemplateFile); } // else, include normal template file for this page else { include("./basic-page.php"); } Edited March 15, 2018 by kongondo 2 Link to comment Share on other sites More sharing options...
Robin S Posted March 15, 2018 Share Posted March 15, 2018 To check if a given file exists, I think you would be better off using PHP's file_exists(). It's very fast and it caches so I doubt it would have any significant impact on performance. 1 Link to comment Share on other sites More sharing options...
kongondo Posted March 15, 2018 Share Posted March 15, 2018 (edited) 23 minutes ago, Robin S said: To check if a given file exists, I think you would be better off using PHP's file_exists(). It's very fast and it caches so I doubt it would have any significant impact on performance. I recently had to choose between the two and this swayed my preference: https://stackoverflow.com/questions/6604726/file-exists-or-is-readable I didn't find any other other pros/cons besides the potential 'false positives' mentioned in the SO link above. Btw, do you know if is_readable() caches too? Ta. Edit: In answer to my own question. Yes, is_readable results are also cached. Edited March 15, 2018 by kongondo Link to comment Share on other sites More sharing options...
elabx Posted March 15, 2018 Author Share Posted March 15, 2018 Was just driving back when I thought: Why the heck am I just not checking if the file exists, though I didn't know about is_readable Thanks @kongondo, @Robin S ! Link to comment Share on other sites More sharing options...
Robin S Posted March 15, 2018 Share Posted March 15, 2018 46 minutes ago, kongondo said: Btw, do you know if is_readable() caches too? The PHP docs for the function say "yes". Quote Note: The results of this function are cached. Link to comment Share on other sites More sharing options...
kongondo Posted March 15, 2018 Share Posted March 15, 2018 12 minutes ago, Robin S said: The PHP docs for the function say "yes". Thanks. My head is all over the place today . I checked the PHP docs just after I posted my question and edited my post . Link to comment Share on other sites More sharing options...
elabx Posted March 15, 2018 Author Share Posted March 15, 2018 2 hours ago, kongondo said: Unless you will be storing the result of an initial check (e.g. in a session or cache), you will have to check for the existence of the file. That aside, do you really need a hook for this? If I got you correctly, couldn't you do the check in the template file itself or that would mean repetitive code? If you did the check in init.php, you wouldn't need to have the same code check in different template files. I don't know if I am making sense, so on to an example. If you had this in init.php (assuming you are using delayed output). One issue is I am not using delayed output but rendering normally through each template/file. Another issue is that I am using also repeater matrix heavily and to keep things organized I also decided to declare the field rendering in each "matrix type" file, so I also wanted to had "alt templates" for this repeater matrix fields rendering. Link to comment Share on other sites More sharing options...
kongondo Posted March 19, 2018 Share Posted March 19, 2018 On 15/03/2018 at 10:35 PM, elabx said: One issue is I am not using delayed output but rendering normally through each template/file. Another issue is that I am using also repeater matrix heavily and to keep things organized I also decided to declare the field rendering in each "matrix type" file, so I also wanted to had "alt templates" for this repeater matrix fields rendering. Hi @elabx, Did you manage to sort this out? Link to comment Share on other sites More sharing options...
elabx Posted March 19, 2018 Author Share Posted March 19, 2018 48 minutes ago, kongondo said: Hi @elabx, Did you manage to sort this out? Yes!! It all worked perfectly, thanks!! Thought it was taken for granted lol sorry, this is the working code: $wire->addHookBefore("TemplateFile::render", function($event){ $templateFile = $event->object; if($templateFile->page->template == "repeater_content"){ $customFileName = $this->config->paths->templates . "fields/content/{$templateFile->page->type}.custom.php"; if(is_readable($customFileName)){ $templateFile->setFilename($customFileName); $event->return = $templateFile; } } elseif($templateFile->page->template == "home" || $templateFile->page->template == "basic-content" ){ $customFileName = $this->config->paths->templates . "{$templateFile->page->template}.custom.php"; if(is_readable($customFileName)){ $templateFile->setFilename($customFileName); $event->return = $templateFile; } } }); I have some hardcoded if statements because I don't want to be checking for EVERY template, but this works nice for repeater matrix (which uses TemplateFile to render the matrix types) and any other template. Also my first snippet was misleading because I didn't want to do a user check, so I removed that too. 2 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