Child Theme – Enqeue conditional sub functions.php
-
Hi
Multi Site:
In my child theme functions.php I enqeue a number of sub functions.php files. 1 to add logic to the chaos, 2 to be able to seperate functions for different purposes such as is Woocommerce active/installed or not.
I am adding this snippet to mother functions.php cause ChatGPT thinks it is a really good idea:
// Establish conditional function that checks for plugin presence before loading it's functions.php
function draupnir_9_enqueue_plugin_functions() {
// Check if WooCommerce is active
if ( class_exists( 'WooCommerce' ) ) {
require_once get_stylesheet_directory() . '/sub-functions/woocommerce-functions.php';
}
}
// Hook into 'wp_loaded' to ensure plugins are fully loaded
add_action( 'wp_loaded', 'draupnir_9_enqueue_plugin_functions' );As I understand require_once stops and stalls if nothing is returned. I kind of like that, cause this way I get to see if nothing works. Also get_stylesheet_directory is correct since this is a child theme. I was struggling with that a lot, but it now works for my unconditional enqeues.
So question is why will this not fly. It crashes my site. I have checked path! and file does indeed exist.
Thx
-
Hiya hebhansen,
Yes, if a required file is inaccessible, it’ll cause a fatal error. I don’t see anything wrong with your concept, nor its implementation. If it crashes your site, I suspect there’s something wrong with the required file. Using
require_once()is functionally equivalent to you copy/pasting the file’s entire contents into where the require_once() call is made, replacing the call itself.Check your error logs for further clues about why your site crashed. And/or define WP_DEBUG as
truein wp-config.php so you can see error messages right on screen. On production sites, the defined value should be returned tofalsewhen you’re done testing. There’s a moderate security risk in leaving it astrueindefinitely.Hi @bcworkz. I hope you are well …
I have altered the if part like so:
// Check if WooCommerce is active and it's class exists
if ( class_exists( 'WooCommerce' ) ) {
$file_path = get_stylesheet_directory() . '/my-path/woocommerce-functions.php';
// Check if the file exists before including it
if ( file_exists( $file_path ) ) {
require_once $file_path;
} else {
// Optional: Log an error if the file does not exist
error_log( 'WooCommerce functions file not found: ' . $file_path );
}
}When activating debug, I do not see any outputs, so I think it works….. I have deleted debug entirely again.
Transferring snippets from Code Snippets to child theme does at times leave some ghost code. I test in incognito, purge and also other browsers. For now I have not encountered that it does not work. And site does not crash using the above.
However, I do see some odd behaviour. Twenty Twenty Four has Cardo font as headings and inter as text. This shows correct in incognito / not signed in, but as admin text shows as cardo. Why is that? This started when adding my child theme to the equation, but I simply don’t get why?
To explain the strange font behavior, I’d normally suspect caching, but you say you’ve purged and tried different browsers. I recommend using your browser’s element inspector tool to determine why the appropriate CSS is not being applied. You should still see the correct rule in the tool, but for some reason a rule with greater precedence is overriding it.
Once you know what rule is overriding the desired font style, you could then compose a similar rule that specifies the correct font. If this rule is loaded onto the page later than the others, it will have precedence despite the selectors being exactly the same. The best way to ensure a style is loaded later is to place it in the Additional CSS section of the style book. Using Additional CSS is preferable to your child theme’s style.css or theme.json when it comes to issues with precedence.
Font inconsistency
I suspect it is more complicated than that. Here is a compare view of signed in admin (left) and not signed in visitor incognito (right). Note: this has been the issue since intro of my child theme on top of TT4, so something is not checking into the parent theme correctly. My takes are:
- Simple text (Should be Inter) Signed in gets some kind of condensed font (Times New Roman’ish). Not signed in gets something correct’ish unless it is just plain Arial.
- Core Button – Please ignore. I am in the process of restyle, however, issue persists. Different fonts for different roles that follow the pattern under 1.
- Heading (Should be Cardo) Signed in get’s the same as for paragraph. Looks a bit like Cardo, but assumably it’s not. Visitor heading is different font again. Maybe Cardo maybe not.
- Let’s ignore pricing table for now. There is some custom plugin css that I cannot get to load after the plugin. I will address that below.
What do you mean by style book? I am transferring additional functions and css out of Code Snippets and into child theme. 1) I do not wish DB look ups for code 2) Code Snippet editor is below beginner, so I want to edit functions and css in VS Code editor. This is setup and working smooth.
Regarding fonts. Is there something I need to declare in child theme.json for fonts to work correctly?
Child Functions.php loading
As mentioned functions seems to work now and it appears that sub functions also kick in.
To whom it may concern, here is what is going on. In a child theme I have my child functions.php. Some functions are not relevant here there and everywhere, so I am in the process og creating dependencies and code seperation in sub functions.php. Does a sub function file include the php open tag? Yes it does! Do sub functions need to declare to anything. No they do not. Can I locate those in a sub folder of my choice? Yes you can. Here is my enqeue code so far (WP 6.7, Theme: Child, Parent Theme TT4, PHP8.3). You will find examples of conditional loads based on plugin check, user role check or both. This matters especially on a multisite where sites differ, hence, woocommerce may not be active. Note: require_once does crash your site if there is no logic response to it such as: file is not there etc. Cool thing is, then you know something is wrong. Not so cool is that site is gone. So activate one by one and test if site loads. Adjust to your customisation and file logic. Below I am enqeueing 10 sub function files in my child theme after WP is loaded… see bottom add action.
/*******************************************************************
*********** Enque functions - functions.php includes **************
********* Sub functions may be targeted conditionally *************
******************************************************************/
// Include the theme setup functions (for theme-specific setup like image sizes, theme support, etc.)
require_once get_stylesheet_directory() . '/your-file-path/theme-setup.php';
// Include custom post types functions
require_once get_stylesheet_directory() . '/your-file-path/custom-post-types.php';
// Include enqueue scripts/styles (for handling the enqueueing of scripts and styles)
require_once get_stylesheet_directory() . '/your-file-path/enqeue-scripts.php';
// Include other custom functions
require_once get_stylesheet_directory() . '/your-file-path/custom-functions.php';
// Optionally, you can include admin-specific functionality as well
if ( is_admin() ) {
require_once get_stylesheet_directory() . '/your-file-path/admin-functions.php';
}
// Conditional sub functions.php - Check if plugin is active and only then call the functions
function draupnir_9_enqueue_plugin_functions() {
// Check if WooCommerce is active and it's class exists
if ( class_exists( 'WooCommerce' ) ) {
$file_path = get_stylesheet_directory() . '/your-file-path/woocommerce-functions.php';
// Check if the file exists before including it
if ( file_exists( $file_path ) ) {
require_once $file_path;
} else {
// Optional: Log an error if the file does not exist
error_log( 'WooCommerce functions file not found: ' . $file_path );
}
}
// Check if WCFM is active and it's class exists
if ( class_exists( 'wcfm' ) ) {
$file_path = get_stylesheet_directory() . '/your-file-path/wcfm-functions.php';
// Check if the file exists before including it
if ( file_exists( $file_path ) ) {
require_once $file_path;
} else {
// Optional: Log an error if the file does not exist
error_log( 'WCFM functions file not found: ' . $file_path );
}
}
// Check if WCFM is active and user is vendor
if ( class_exists( 'wcfm' ) && current_user_can( 'wcfm_vendor' ) ) {
$file_path = get_stylesheet_directory() . '/your-file-path/wcfm-vendor-functions.php';
// Check if the file exists before including it
if ( file_exists( $file_path ) ) {
require_once $file_path;
} else {
// Optional: Log an error if the file does not exist
error_log( 'Vendor WCFM functions file not found: ' . $file_path );
}
}
// Check if Plugin is active and user is admin
if ( class_exists( 'plugin ID' ) && current_user_can( 'administrator' ) ) {
$file_path = get_stylesheet_directory() . '/your-file-path/wcfm-admin-functions.php';
// Check if the file exists before including it
if ( file_exists( $file_path ) ) {
require_once $file_path;
} else {
// Optional: Log an error if the file does not exist
error_log( 'Admin WCFM functions file not found: ' . $file_path );
}
}
// Check if Amelia Booking is active and it's class exists
if ( class_exists( 'Amelia\Classes\Context' ) ) {
$file_path = get_stylesheet_directory() . '/your-file-path/amelia-functions.php';
// Check if the file exists before including it
if ( file_exists( $file_path ) ) {
require_once $file_path;
} else {
// Optional: Log an error if the file does not exist
error_log( 'Amelia functions file not found: ' . $file_path );
}
}
}
// Hook into 'wp' to ensure WordPress is fully loaded
add_action( 'wp', 'draupnir_9_enqueue_plugin_functions' );Child CSS Load Order – Out of Order
Finally css load order is messing up. Sub function enqeue-script.php loads my child style.css and then again sub css files for code seperation and relevance where they load, where one should style the pricing table mentioned above, but it does not!
Below is full css enqeue function. I tried adding a dependency to style.css to load after WP load. That messed up things and I removed it again. I also enqeue to display the effect inside editor. These work randomly. Right now they don’t. Yesterday they did.
Paths are working. I have debug checked in inspector that files load. The plugin dependent files take no effect, so I suspect they load before the respective plugin, hence, custom styles take no effect as they do not overwrite the plugin css. I am simply not sure if I am getting the plugin array dependency right or where to check it? array( ‘woocommerce-general’ ), array( ‘wcfm’ ), array( ‘amelia’ ), etc.
Since these may not work I have delayed the entire function load to 100 (maximum) for it to load absolutely last. Styles still do not apply/overwrite. I have no experience with this, so I am in the blind.
/******************************************************************
********* Enque Stylessheets - style.css and sub css *************
********** Sub styles reside in folder /assets/css/ **************
******************************************************************/
function draupnir_9_enqueue_styles() {
// Enqueue the child theme's style.css with a dependency on WordPress core styles
wp_enqueue_style(
'draupnir-9-style',
get_stylesheet_uri(),
array(), // No dependencies here
null, // No version number
'all' // For all media types
);
// Enqueue the child theme's editor style, dependent on WordPress and WooCommerce styles
wp_enqueue_style(
'draupnir-9-editor-style',
get_stylesheet_uri(), // This will load style.css in the editor as well
array(),
null,
'all'
);
// Enqueue global.css for general styles
wp_enqueue_style(
'draupnir-9-global',
get_stylesheet_directory_uri() . '/your-style-path/global.css', // Correct path to global.css
array(),
null,
'all'
);
// Enqueue forms.css for form styles
wp_enqueue_style(
'draupnir-9-forms',
get_stylesheet_directory_uri() . '/your-style-path/forms.css', // Correct path to forms.css
array(),
null,
'all'
);
// Enqueue woo.css for WooCommerce styles (conditionally loaded if WooCommerce is active)
if ( class_exists( 'WooCommerce' ) ) {
wp_enqueue_style(
'draupnir-9-woo',
get_stylesheet_directory_uri() . '/your-style-path/woo.css', // Path to woo.css
array( 'woocommerce-general' ), // Dependencies on WooCommerce styles
null,
'all'
);
}
// Enqueue wcfm.css for WCFM styles (conditionally loaded if WCFM is active)
if ( class_exists( 'wcfm' ) ) {
wp_enqueue_style(
'draupnir-9-wcfm',
get_stylesheet_directory_uri() . '/your-style-path/wcfm.css', // Path to wcfm.css
array( 'wcfm' ), // Loads after WCFM's CSS
null,
'all'
);
}
// Enqueue wcfm-vendor.css for WCFM styles (conditionally loaded if WCFM is active)
if ( class_exists( 'wcfm' ) ) {
wp_enqueue_style(
'draupnir-9-wcfm-vendor',
get_stylesheet_directory_uri() . '/your-style-path/wcfm-vendor.css', // Path to wcfm.css
array( 'wcfm' ), // Loads after WCFM's CSS
null,
'all'
);
}
// Enqueue amelia.css for Amelia Bookings & Events styles (conditionally loaded if Amelia is active)
if ( class_exists( 'Amelia\Classes\Context' ) ) {
wp_enqueue_style(
'draupnir-9-amelia',
get_stylesheet_directory_uri() . '/your-style-path/amelia.css', // Path to amelia.css
array( 'amelia' ), // Loads after Amelia's CSS
null,
'all'
);
}
// Enqueue product-page.css on product pages (conditionally loaded on product pages only)
if ( is_product() ) {
wp_enqueue_style(
'draupnir-9-product-page',
get_stylesheet_directory_uri() . '/your-style-path/product-page.css',
);
}
}
// We enqeue child css with priority 20 to load after default actions.
add_action( 'wp_enqueue_scripts', 'draupnir_9_enqueue_styles', 100 );
// We enqeue child css inside the FSE Editor with priority 30 to load including custom actions.
add_action( 'enqueue_block_editor_assets', 'draupnir_9_enqueue_styles', 100 );
// Priorities are default 10 and max 100What am I missing? Why do some css work fine, while some does not?
Full disclosure — I have limited experience with children of block themes. Regardless, your font discrepancy issues are likely due to your styles not being loaded in the desired order. AFAIK, anything in your child theme.json should override the same in the parent’s theme.json. Anything you do not override will be inherited from the parent.
If you have .css files that you want to override styles in parent theme.json, I’m unsure what to specify as a dependency since 2024 doesn’t enqueue its styles in the traditional sense. You’re probably better off using your child theme.json to override 2024 theme.json styles.
If there are certain styles you’re having trouble overriding, placing such overrides in Additional CSS in the style book is a good option. To get there, enter the site editor. Go to Styles, Edit Styles (pencil icon). In the editor’s right side bar near the bottom you’ll find Additional CSS. You can get there through the actual Style Book (eye icon), but the above path takes fewer clicks.
The following is rather hacky and not “proper” WP procedure. But it might help you get stylesheets loaded late enough to override other undesired styling. You could output your own inline
<style>...</style>content (actual CSS code, or if in the head section, a stylesheet link) via any of the many later WP action hooks. Try hooking “wp_print_scripts”, “wp_head”, or even an action that fires when page content is being output. Add your style output callback with add_action() using a large $priority arg value to help ensure your callback runs after anything else hooked into the same action.If all else fails, and if you can alter a specific element’s HTML you could add a
styleattribute to that particular element. Be advised though that the block editor is very finicky about how HTML can be altered. It can complain that your style attribute is invalid even though it is absolutely correct, valid HTML. The block editor will suggest that it can repair it for you. Do not do it, it will only make things worse. Your choices then are to either ignore the warning, or implement the element by other means such as custom HTML.@bcworkz thx
Inherit from theme.json
I am porting all the css into child theme.json I can. I am aware it will overwrite what is there and inherit what is not. Due to lack of support yet, that leaves a lot still in external css. That said, almost all my css points to plugins that try to be a theme rather than inherit ruling buttons, fonts etc. This is not a block theme issue. It has been always. WP Forms do extensive styling as does Wordfence as does WCFM etc. Why the f*** they do not inherit is IMO a bug in their flawed design. For WCFM it’s a deliberate strategy to sell own themes and trust me, they are not impressive. So correcting those into normal behaviour is extensive and require both functions and css (read: a lot).
Regarding inherit, if I do not add default colors here, they do not appear in editor > settings as color options. Only custom color show. I want them to inherit from parent, so they update with theme updates. What’s the issue and why do they need to be added in child?
"settings": {
"typography": {
"fluid": true,
"defaultFontSizes": false,
"fontSizes": [
{
"fluid": {
"min": "0.7rem",
"max": "0.9rem"
},
"name": "Small",
"size": "0.9rem",
"slug": "small"
},
{
"fluid": {
"min": "0.9rem",
"max": "1.05rem"
},
"name": "Medium",
"size": "1.05rem",
"slug": "medium"
},
{
"fluid": {
"min": "1.39rem",
"max": "1.85rem"
},
"name": "Large",
"size": "1.85rem",
"slug": "large"
},
{
"fluid": {
"min": "1.85rem",
"max": "2.5rem"
},
"name": "Extra Large",
"size": "2.5rem",
"slug": "x-large"
},
{
"fluid": {
"min": "2.5rem",
"max": "3.27rem"
},
"name": "Extra Extra Large",
"size": "3.27rem",
"slug": "xx-large"
},
{
"fluid": {
"min": "3rem",
"max": "8rem"
},
"name": "3x Extra Large",
"size": "8rem",
"slug": "3x-large"
},
{
"fluid": {
"min": "8rem",
"max": "12rem"
},
"name": "4x Extra Large",
"size": "12rem",
"slug": "4x-large"
}
]
},
"color": {
"palette": [
{
"color": "#f9f9f9",
"name": "Base",
"slug": "base"
},
{
"color": "#ffffff",
"name": "Base / Two",
"slug": "base-2"
},
{
"color": "#111111",
"name": "Contrast",
"slug": "contrast"
},
{
"color": "#636363",
"name": "Contrast / Two",
"slug": "contrast-2"
},
{
"color": "#A4A4A4",
"name": "Contrast / Three",
"slug": "contrast-3"
},
{
"color": "#cfcabe",
"name": "Accent",
"slug": "accent"
},
{
"color": "#c2a990",
"name": "Accent / Two",
"slug": "accent-2"
},
{
"color": "#d8613c",
"name": "Accent / Three",
"slug": "accent-3"
},
{
"color": "#b1c5a4",
"name": "Accent / Four",
"slug": "accent-4"
},
{
"color": "#b5bdbc",
"name": "Accent / Five",
"slug": "accent-5"
},
{
"name": "Black",
"slug": "black",
"color": "#000000"
},
{
"name": "White",
"slug": "white",
"color": "#ffffff"
},
{
"name": "Draupnir / 8",
"slug": "draupnir-8",
"color": "#171717"
},
{
"name": "Draupnir / Shadow",
"slug": "draupnir-shadow",
"color": "#BABECC"
},
{
"name": "Draupnir / Red",
"slug": "draupnir-red",
"color": "#ae1100"
},
{
"name": "Post-It / Yellow",
"slug": "post-it-yellow",
"color": "#f1f58f"
},
{
"name": "Post-It / Orange",
"slug": "post-it-orange",
"color": "#ffa930"
},
{
"name": "Post-It / Pink",
"slug": "post-it-pink",
"color": "#ff32b2"
},
{
"name": "Post-It / Blue",
"slug": "post-it-blue",
"color": "#a9edf1"
},
{
"name": "Post-It / Green",
"slug": "post-it-green",
"color": "#74ed4b"
}
],
"custom": true
},Overwrite theme.json with css
I don’t want that. I control all I can in theme.json and plan to evolve my T.J with the schema version changes. My child is currently version 3. However, what I cannot style in T.J I style from css. Within css I use T.J variables so they uppdate with new styles and themes. Like so:
.select-container select {
color: var(--wp--preset--color--draupnir-shadow);
font-size: var(--wp--preset--font-size--medium);
font-weight: normal;
max-width: 100%;
padding: 12px 32px 12px 16px;
border: 0;
background-color: transparent /*var(--wp--preset--color--base) !important*/; /* We need to check if this should be transparent*/
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
text-shadow: 1px 1px 0 var(--wp--preset--color--base-2);
box-shadow: inset 2px 2px 5px var(--wp--preset--color--draupnir-shadow), inset -5px -5px 10px var(--wp--preset--color--base-2);
transition: all 0.2s ease-in-out;
&:hover {
box-shadow: inset 1px 1px 2px var(--wp--preset--color--draupnir-shadow), inset -1px -1px 2px var(--wp--preset--color--base-2);
}
}Load CSS
“wp_print_scripts”, “wp_head”, does not work either. I am already using priority 100 for a late load, as shown in code above.
I know that some css does work and some does not. I suspect that the conditional ones are not correct or load too soon, hence, not working.
I am not going into html alterations, since these styles apply just about everywhere. Some target anything wcfm and some target anything WooCommerce etc. and on several sites.
plugins that try to be a theme rather than inherit ruling buttons, fonts etc.
I hear you, it’s annoying. Part of the problem is these plugins add HTML content with their own class attributes. Plugins have no way of knowing what classes a theme might use, so they use their own classes with styling rules to match. Obviously far from ideal, but a more workable solution escapes me.
In the case of plugins enqueuing their own stylesheets, it is possible to dequeue the same if you find them undesirable. You then can implement your own styling without being concerned about precedence higher than the plugin’s styles. Just be sure your dequeue calls occur after the plugins have already enqueued their stylesheets.
I do not know why you need to re-declare default colors that should be inherited. I’m not familiar enough with the inner workings of theme.json to even take a guess. IMO they ought to be inherited unless overridden. Sounds like a bug to me, but maybe it’s intentional for some reason that escapes me. If it seems like a bug to you as well, you could file a Trac ticket pointing out the problem. Please do a search first to ensure there’s not already a ticket for this issue.
It’s not my intention to tell you what you should do. I suggest possible courses of action. Feel free to ignore any suggestions that are not appealing. I’m sure you will anyway. Know that I take no offense at being ignored.
The topic ‘Child Theme – Enqeue conditional sub functions.php’ is closed to new replies.