Sage 9 child theme

How’d you get it working in beta 2? I’m happy to use beta 2 instead of 3.

Hey @Luke_Abell,

I’ll try and get this up for the weekend - my themes have quite a few customizations on top of sage so I need to clear out the unnecessary before sharing :thumbsup:

Thanks! Any luck getting this set up?

@Luke_Abell Really sorry about the delay with this I’m mid project and the heat is on. As a rough guide:

  • Grab the roots theme at this point before the directory change. Then cherry pick any other changes which have been merged to roots thereafter. You can cherry pick those improvements from the commit history but be sure to understand that this may well be a hands on manual process.

  • Duplicate that project as a child theme. Being sure the appropriate Template: parent-theme-folder is in your chld theme style.css in the top comments. And that your theme name is unique.

  • In the parent theme’s function file replace this block with the following:

/**
 * Sage required files
 *
 * The mapped array determines the code library included in your theme.
 * Add or remove files to the array as needed. Supports child theme overrides.
 */
array_map(function ( $file ) use ( $sage_error ) {
	if ( is_child_theme() ) {
		$file = "../src/{$file}.php";
	} else {
		$file = "src/{$file}.php";
	}

	if ( ! locate_template( $file, true, true ) ) {
		$sage_error(sprintf( __( 'Error locating <code>%s</code> for inclusion.', 'sage' ), $file ), 'File not found');
	}
}, [ 'helpers', 'setup', 'filters', 'admin' ]);
  • In the child theme functions file replace this block with the one below:
/**
 * Here's what's happening with these hooks:
 * 1. WordPress initially detects theme in themes/sage
 * 2. Upon activation, we tell WordPress that the theme is actually in themes/sage/templates
 * 3. When we call get_template_directory() or get_template_directory_uri(), we point it back to themes/sage
 *
 * We do this so that the Template Hierarchy will look in themes/sage/templates for core WordPress themes
 * But functions.php, style.css, and index.php are all still located in themes/sage
 *
 * This is not compatible with the WordPress Customizer theme preview prior to theme activation
 *
 * get_template_directory()   -> /srv/www/example.com/current/web/app/themes/sage
 * get_stylesheet_directory() -> /srv/www/example.com/current/web/app/themes/sage
 * locate_template()
 * ├── STYLESHEETPATH         -> /srv/www/example.com/current/web/app/themes/sage
 * └── TEMPLATEPATH           -> /srv/www/example.com/current/web/app/themes/sage/templates
 */
if ( is_customize_preview() && isset( $_GET['theme'] ) ) {
	$sage_error(__( 'Theme must be activated prior to using the customizer.', 'sage' ));
}

if ( basename( $stylesheet = get_option( 'template' ) ) !== 'templates' ) {
	update_option( 'template', "{$stylesheet}/templates" );
	wp_redirect( $_SERVER['REQUEST_URI'] );
	exit();
}

Finally in your child theme remove the includes which only need to be part of the parent, so for example change this block to this:

array_map(function ( $file ) use ( $sage_error ) {
	$file = "src/{$file}.php";

	if ( ! locate_template( $file, true, true ) ) {

		// $sage_error(sprintf( __( 'Error locating <code>%s</code> for inclusion.', 'sage' ), $file ), 'File not found');
	}
}, [ 'setup' ]);
  • Finally, and this is the hackiest part, manually include your parents functions file. By adding this line to very bottom of your childs functions.php file like so. Be sure to change both parent-theme-folder lines
require_once( get_theme_root( 'parent-theme-folder-name' ) . '/parent-theme-folder-name/functions.php' );

Now the reason there’s a delay in me getting this to you is that this isn’t the most elequent way, and I have got a more pragmatic solution as opposed to a manual include of the parent functions file. However that code is wrongly entwined with some other must use plugins. I’ll update this thread as soon as I can with that solution, hopefully in ~2 weeks

NB in your setup file in your child you may also want to include your parent css file, or alternatively alter your main.scss file to import your parents main.scss file depending on how you want your CSS/JS relationship to work

2 Likes

Thanks @craigpearson – have you looked into their new child theme support in beta 4?

Yep, I’d recommend updating, it works like a dream!

There’s still some modifications to make on getting JS and SASS inheriting from the parent (if needed) but definitely a lot more reliable than my hacky solution!

Hey @craigpearson! Can you point me in the right direction for the beta 4 child theme modifications? I’m having trouble finding any official documentation and I’d really like to use child themes across a multisite I’m starting development on. Thanks!

Sure, here’s my process

Set the child theme’s parent

Add the correct template name by appending /resources to the parent theme folder:

// child-theme/resources/style.css
/*
Theme Name:         Sage Starter Theme
... etc

Template:           parent-theme/resources
*/

Remove conflicts / duplicates
You need to remove functions in the child which are already inherited from the parent theme

// Remove duplicate files
child-theme/app/admin.php
child-theme/app/filters.php
child-theme/app/setup.php

Start fresh (optional)
I’d recommend removing all template files in the child theme, overwriting them as needed

// Remove view files, overwrite later
child-theme/resources/views/*

From here we can use child template overwrites as we normally would

Import parent styles (optional)
Using your parent theme styles as a base can be helpful and more maintainable

// child-theme/resources/assets/styles/main.scss
@import "/../../../../parent-theme/resources/assets/styles/main";

Note There are issues when using @import '/autoload/**/*'; within the parent theme - manually including assets is your friend again here.

Import parent JS (optional)
Remove all contents of main.js in the child theme, and import the parent

// child-theme/resources/assets/scripts/main.js
import '../../../../parent-theme/resources/assets/scripts/main.js';

You need to run yarn and composer install within both themes. Your build process is done the same ol way as you always have per theme

Oh, and
This doesn’t account for any node modules, images or other assets between themes. If you do roll with the import options above, you’ll need to decide on whether to duplicate those or go a little further with customisation

11 Likes

@craigpearson you are MVP. Thanks for responding so fast, and with so much detail! :hugs:

1 Like

Thanks for the continued updating on this post.
I’m attempting to import parent JS as indicated here but am getting the error:

This relative module was not found:

./autoload/**/* in ../my-parent-theme/resources/assets/scripts/main.js

Do you have any guidance on this?

Note There are issues when using @import '/autoload/**/*'; within the parent theme - manually including assets is your friend again here.

When using wildcards to autoload in a child theme - from the parent, there’s issues.

For our projects we don’t need this autoload behaviour so to keep this functionality might need further customisation.

To resolve your issue (at a loss of auto imports) just include your autoloaded scss/JS files in your parent theme manually. For example, in scss:

@import '/autoload/bootstrap.scss';

I wish I could verbalise more succinctly why this is the case, but in all honesty I’ve had a couple of wines because of that Santa guy

1 Like

I’m struggling to get a child theme going with the latest release – has anyone been able to get things running?

Thanks @craigpearson for the pointers so far, should it be a matter of updating the paths you’ve provided in your instructions above?

Is the idea to follow both of your posts? This Sage 9 child theme and then this Sage 9 child theme?

Hey @canarystudio,

Sorry for the confusion but the steps to follow would be these steps alone: Sage 9 child theme

Following steps previous that post are no longer relevant.

Just to confirm the approach mentioned in there still works with the stable release of Sage V 9.0.0

If you’re getting any specific errors / issues feel free to share and hopefully I can offer some advice

1 Like

I’m trying to build a child theme with Sage 9, and the parent theme is using OceanWP.

I managed to get the Sage templates load on the pages I need, but having issues trying to reuse the Parent’s theme actions. All the actions from the parent theme does not seem to be executing. For eg. do_action( 'ocean_before_main' )

Is there something else I need to do to call on the parent theme’s actions?

Hey, sorry to bump this thread, but it is the most relevant to my current issue.

I’m on Sage 9 beta 4 trying to create a Sage 9 child theme from a Sage 9 parent theme. I followed the latest instructions from craigpearson, and I have it working for the most part. The one issue I’m experiencing is that data from the controllers in the child theme are NULL in the corresponding blade views. It looks like data coming from the parent controllers work just fine, but I need to create custom page templates in the child theme that are not relevant to the parent theme. Functions in the child theme’s helpers.php also work in the child blade views, so it seems like an issue with the controllers.

Has anyone been successful with this? Thank you for any insights!

@travis unfortunately the controllers from sober controller 2.0.0 are not compatible with child themes, I raised an issue on this here: https://github.com/soberwp/controller/issues/91 which was recently closed

Child theme support did work for < 2.0.0 so you could roll back the version of sober controller or alternatively not use them / make some noise on the issue

Thanks for the response @craigpearson. I appreciate the info even if it wasn’t good news! :slight_smile:

followed the instructions above, I got this error.Any official doc about this?

I tried this one, do i have to do the functions.php changes? I can’t make it work it is asking for files that are supposed to be inherited alread

hi @craigpearson is this applicable to Sage version 9.0.10, I think there is a conflict on how Sage gets the app/ files.