Jump to content

Recommended Posts

Posted

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;
            }
        }
       
        
    }
});
Posted (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 by kongondo
  • Like 2
Posted

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.

  • Like 1
Posted (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 by kongondo
Posted
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.

 

Posted
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 .

Posted
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.

Posted
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?

Posted
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. 

  • Like 2

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...