Jonathan Lahijani Posted March 28, 2019 Share Posted March 28, 2019 I'm creating what's essentially a starter site profile that I'll release one day, in the same vein as Underscores or Sage, which are WordPress starter themes. Both of those themes are meant to be used as standalone themes, meaning they should not be a "parent" theme that is overridden by a child theme. For my starter theme, I do actually want to see what methods exist for some sort of override approach for the /site/ folder, or perhaps just the /site/templates/ folder. This wouldn't be a requirement however. ProcessWire does not have such a feature natively, but I read about UnionFS which seems quite slick. I did a little experiment with it on some simple folders and files, and Apache does handle it well with a few simple adjustments. If anyone has any techniques or thoughts on ProcessWire overriding template files at the PHP level or UnionFS (which is at the Linux filesystem level), I'd love to hear your thoughts. Link to comment Share on other sites More sharing options...
Robin S Posted March 29, 2019 Share Posted March 29, 2019 I think you could achieve this using PHP logic without any special file system needed. I haven't used WordPress but from the docs you linked to it sounds like any existing child template replaces the parent template of the same. This would be easy to achieve in PW. The following examples assume a Markup Regions approach to templating. Your parent template files go in /site/templates/: _main.php basic-page.php home.php Your child template files go in /site/templates/child-templates/. You only create files for templates that you want to be different from the parent templates. Likewise for _main.php if you want to change that in your child theme. child-templates/_main.php child-templates/basic-page.php In /site/ready.php: $wire->addHookBefore('Page::render', function(HookEvent $event) { $page = $event->object; $templates_path = $event->wire('config')->paths->templates; // See if a replacement template file exists in child-templates $alt_template_path = "{$templates_path}child-templates/{$page->template->name}.php"; if(is_file($alt_template_path)) { // If so, use it as the template file $page->template->filename = $alt_template_path; } // See if a replacement _main.php file exists in child-templates if(is_file("{$templates_path}child-templates/_main.php")) { // If so, disable the default _main.php and use the replacement $page->template->noAppendTemplateFile = true; $page->template->appendFile = 'child-templates/_main.php'; } }); So that would cover template replacement as per WordPress (if I understand it right). But with Markup Regions it would be nice to have the option to sort of "extend" an existing template file rather than replace it. You could do this by putting files in /site/templates/child-templates/ with an "_append" suffix. The contents of these files gets included after the markup of the parent template of the same name, so you could use Markup Regions features like pw-append, pw-before, etc, to add to the markup of the parent template. child-templates/home_append.php And at the top of your _main.php file before the DOCTYPE (and same with child-templates/_main.php if you are using that): <?php // See if an append template file exists in child-templates $append_template_path = "{$config->paths->templates}child-templates/{$page->template->name}_append.php"; // If so, include it if(is_file($append_template_path)) include $append_template_path; ?> 1 2 Link to comment Share on other sites More sharing options...
Jonathan Lahijani Posted March 29, 2019 Author Share Posted March 29, 2019 Nice Robin. I will experiment with this code. Link to comment Share on other sites More sharing options...
Jonathan Lahijani Posted March 29, 2019 Author Share Posted March 29, 2019 It works for overriding a template file (let's say /site/templates/child-templates/basic-page.php for our example), but with partials that get included using PHPs 'include' function, it fails. For example, in /site/templates/_main.php I have: <?php include './_menu.php'; ?> The location of _menu.php is in /site/templates/_menu.php. But since we're overriding basic-page.php, it expects _menu.php in /site/templates/child-templates/_menu.php as opposed to falling back to /site/templates/_menu.php. I wonder if there's a way around this using either include or wireIncludeFile. I was hacking away at this last night but couldn't come up with a solution. Link to comment Share on other sites More sharing options...
Robin S Posted March 29, 2019 Share Posted March 29, 2019 6 minutes ago, Jonathan Lahijani said: For example, in /site/templates/_main.php I have: <?php include './_menu.php'; ?> You can use a full path to the file rather than a relative one. I think it's a good practice to do this for all includes as it's more robust than a relative path. If you get tired of typing $config->paths->templates you can do something like define a shorter constant/variable in an auto-prepended _init.php, or just a shorter version in config.php, eg. $config->tp 1 Link to comment Share on other sites More sharing options...
LostKobrakai Posted March 29, 2019 Share Posted March 29, 2019 I'm not really in favor of "inheritance" for this kind of usecase. I like code generation much more if something shall be editable. Like put all you basic, low-level components in some class or helper functions and have some means (cli or otherwise) to generate higher level composed template files in the users project. This way you're doing a bunch things: Show/teach users how to compose your low-level components. Give them the ability to modify with hardly any restrictions. The "your update broke my changes" problem is much less of an issue and easier to control. It's just the low-level components which need to be backwards compatible and not a maze of hooks and overrides and stuff. Generators can be split up and used more focuses and all throughout a projects lifetime. It's not going to get harder the older the project gets. Generators can change without code of users breaking. They might just complain that the old results are no longer available to be generated. 1 Link to comment Share on other sites More sharing options...
bernhard Posted March 29, 2019 Share Posted March 29, 2019 Which CSS Framework are you going to use? I've built a FrontendThemeUikit module last November and used it for two sites, but it's nothing releasable yet. If you are interested I can share my work with you. The concept is similar to what Robin posted above. https://screencast-o-matic.com/watch/cFXnX1Y72l The goal would be to have one master theme that does all the tedious tasks (rendering menus, injecting styles and scripts, do the basic setup with markup regions) and have a second theme only for customisations. 1 Link to comment Share on other sites More sharing options...
Jonathan Lahijani Posted March 29, 2019 Author Share Posted March 29, 2019 7 hours ago, LostKobrakai said: I like code generation much more if something shall be editable. Like put all you basic, low-level components in some class or helper functions and have some means (cli or otherwise) to generate higher level composed template files in the users project. This is a good argument and something to think about. Of course the drawback as you said is that any new code in the generator would have to manually be added to sites that were generated in an older version of the generator. 7 hours ago, bernhard said: Which CSS Framework are you going to use? Very nice demo. I'm using UIkit 3 of course. I'd love to check it out. 1 Link to comment Share on other sites More sharing options...
LostKobrakai Posted March 30, 2019 Share Posted March 30, 2019 14 hours ago, Jonathan Lahijani said: Of course the drawback as you said is that any new code in the generator would have to manually be added to sites that were generated in an older version of the generator. Personally I really favor it though. It might be more manual work to update, but also less prone to break stuff. Link to comment Share on other sites More sharing options...
Recommended Posts