Jump to content

change current pages template file at runtime?


applab
 Share

Recommended Posts

Hi,

I'm trying to change a template file at runtime based on the logged in users name.

in addition to the /site/templates/ folder I have a /site/templates-dev/ folder, and under that is a folder for each developer.

so, if I'm logged in as `timmy` and a file exists at `/site/templates-dev/timmy/article.php`  then that file should be used, otherwise use `/site/templates/article.php`.

in /site/ready.php I have

$fp = $config->path('site') . 'templates-dev/' . $user->name . '/' . $page->template . '.php';
if(file_exists($fp)) {
    //echo "found tpl!";
    $page->template->filename($fp);
}

If I uncomment the `echo` statement then I can see that it's finding the alternate template but if I view the page it's just blank (status 200, 'this request has no response data available').

Is anyone able to point me in the right direction please?

Thanks,
Martin.

 

 

 

 

Link to comment
Share on other sites

Thanks @androbey, I hadn't seen that post but I have used render() plenty of times, I might end up going that way.

I've sort of got it working but I had to put my dev templates in the main template folder (with a different name) otherwise all my include paths are wrong.  I was hoping to keep them separate. 

Link to comment
Share on other sites

@applab

I actually encountered a similar problem some time ago.
But there is actually a setting option so that the paths can also remain separated. Hopefully this works for you, too.

$config->setLocation('templates', $config->path('site') . 'templates-dev/' . $user->name . '/');

 

Link to comment
Share on other sites

I actually share a similar setup but for another use (templates-dev is for local development / preview) and in my case I use this in my config.php:

$config->urls->templates = $config->urls->site . "templates-dev/";
$config->paths->templates = $config->paths->site . "templates-dev/";
$config->urls->fieldTemplates = $config->urls->site . "templates-dev/fields/";
$config->paths->fieldTemplates = $config->paths->site . "templates-dev/fields/";

Similar to what @androbey suggested. However I don’t switch based on the user but it's easy to do so in your site/init.php

if($user->name === "username") {
	// ...
} elseif($user->name === "admin") {
	// ...
}
Link to comment
Share on other sites

13 hours ago, androbey said:

@applab

I actually encountered a similar problem some time ago.
But there is actually a setting option so that the paths can also remain separated. Hopefully this works for you, too.

$config->setLocation('templates', $config->path('site') . 'templates-dev/' . $user->name . '/');

 

This is exactly how I usually approach it.  In this case though I was hoping to achieve a setup where each dev's folder does not need to contain a full set of template files, just the one or two they are working on, and for any template not found in the dev's folder it will  fallback to the main template directory, ie. the same way Wordpress child themes work.

Link to comment
Share on other sites

13 hours ago, monollonom said:

I actually share a similar setup but for another use (templates-dev is for local development / preview) and in my case I use this in my config.php:

$config->urls->templates = $config->urls->site . "templates-dev/";
$config->paths->templates = $config->paths->site . "templates-dev/";
$config->urls->fieldTemplates = $config->urls->site . "templates-dev/fields/";
$config->paths->fieldTemplates = $config->paths->site . "templates-dev/fields/";

Similar to what @androbey suggested. However I don’t switch based on the user but it's easy to do so in your site/init.php

if($user->name === "username") {
	// ...
} elseif($user->name === "admin") {
	// ...
}

Thanks @monollonom, though as per @androbey's suggestion the conditional is not necessary if the username matches the folder name and can be used directly to construct a path.

On a side note, I wasn't aware that fieldTemplates was a thing until I saw your post so I've learned something very useful :-)

  • Like 1
Link to comment
Share on other sites

Ah, somehow I missed the part where you said you needed to fallback should the file not be there, my bad!
Edit: I even missed the fact you already had a similar code 😑

From what I'm reading in PW’s source code, you could hook before TemplateFile::render (...time passing doing tests...) I think the best is to check if the dev’s file exists and then use setFilename() in init.php:

wire()->addHookBefore("TemplateFile::render", function(HookEvent $event) {
    /** @var TemplateFile $tpl */
    $tpl = $event->object;
    $userTpl = str_replace("templates/", "templates-dev/" . $event->user->name, $tpl->filename);
    if(file_exists($userTpl)) {
        $tpl->setFilename($userTpl);
    }
});

Try and let me know if it works for you!

Edited by monollonom
I was tired, I think
Link to comment
Share on other sites

Hi @monollonom

Doing it this way still encounters the problem I had with my original method, ie. it finds the alternate template but require/include files aren't found as relative paths are now different.  I'm not sure how I'm going to approach that, I will give it some thought over the weekend.

BTW, because I have an extra level of folders I had to modify your code slightly to append a / after the username.

$userTpl = str_replace("templates/", "templates-dev/" . $event->user->name . '/', $tpl->filename);

Thanks for giving it some thought :-)

Link to comment
Share on other sites

Seems like you could also hook into WireFileTools::include, which is used behind $files->include or $files->render, maybe you could do the same check / filename replacement there.

(as per my edit in the previous message I managed to not only miss an important point but also the fact you already had a similar code... 🙄)

Link to comment
Share on other sites

I haven't read everything carefully and I have never used the feature myself, but TracyDebugger has a feature to render different template files with a customizable suffix. Here is how adrian implemented it: https://github.com/adrianbj/TracyDebugger/blob/f2fbcd88fcecad45b2ce7b428cfe80c1527c1122/TracyDebugger.module.php#L1481-L1494

  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...
On 3/10/2023 at 6:44 PM, bernhard said:

I haven't read everything carefully and I have never used the feature myself, but TracyDebugger has a feature to render different template files with a customizable suffix. Here is how adrian implemented it: https://github.com/adrianbj/TracyDebugger/blob/f2fbcd88fcecad45b2ce7b428cfe80c1527c1122/TracyDebugger.module.php#L1481-L1494

Hi @bernhard, sorry for the delayed response but I'm flitting between 2 projects and have just come back to this.

From looking at that Tracy source code and reading the Tracy docs it looks like the method used relies on the alt-template being in the main /site/templates/ folder and having a recognisable suffix.  My goal is:
1) to keep dev templates outside of the main templates folder (eg. have /site/templates/ and /site/dev-templates/)
2) for /site/dev-templates/ not to require a full set of templates, just one or two that are being worked on, and to 'fallback' to the main templates folder if there is no tpl for the current request in dev-templates.

My problem is that include files and  assets are no longer in the same relative location if the alt-template is used  when the dev-tpl is not in the same folder as the main tpl.

TBH, it's not super-high priority but I think it would be useful both when collaborating or when modifying a live site so I will come back to it at some point.

Link to comment
Share on other sites

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
 Share

  • Recently Browsing   0 members

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