Jump to content

UnionFS for "parent" and "child" site profiles?


Jonathan Lahijani
 Share

Recommended Posts

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

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

 

  • Like 1
  • Thanks 2
Link to comment
Share on other sites

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

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

  • Like 1
Link to comment
Share on other sites

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.
  • Like 1
Link to comment
Share on other sites

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.

  • Like 1
Link to comment
Share on other sites

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.

  • Like 1
Link to comment
Share on other sites

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

 Share

  • Recently Browsing   0 members

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