Paulina Hetman aka @PeHaa
Paulina Hetman aka @PeHaa
Does not exist without another theme, called parent theme
Inherits the functionalities and the templates from its parent
Without touching the parent theme, a child theme allows:
Your modifications will be preserved when the parent theme is updated.
stylesheet : | ? ... |
template : | ? ... |
stylesheet : | ? ... |
template : | ? ... |
stylesheet : | ? ... |
template : | ? ... |
stylesheet : | theme-1 |
template : | ? ... |
stylesheet : | theme-1 |
template : | ? ... |
stylesheet : | theme-1 |
template : | theme-1 |
stylesheet : | ? ... |
template : | ? ... |
stylesheet : | theme-1-child |
template : | ? ... |
stylesheet : | theme-1-child |
template : | theme-1 |
If a directory in wp-content/themes does not contain a style.css in its root, all its first-level subfolders will be scanned as the potential themes.
This would be ok:
If a directory in wp-content/themes does not contain a style.css in its root, all its first-level subfolders will be scanned as the potential themes.
This is no longer ok:
template | vs | stylesheet |
TEMPLATEPATH | STYLESHEETPATH | |
get_template(); | get_stylesheet(); | |
get_template_directory(); | get_stylesheet_directory(); | |
... | ... | |
template directory | stylesheet directory | |
parent directory | ≠ | theme directory (child) |
template | vs | stylesheet |
TEMPLATEPATH | = | STYLESHEETPATH |
get_template(); | = | get_stylesheet(); |
get_template_directory(); | = | get_stylesheet_directory(); |
... | = | ... |
template directory | = | stylesheet directory |
parent directory | ≠ | theme directory (child) |
template | vs | stylesheet |
TEMPLATEPATH | ≠ | STYLESHEETPATH |
get_template(); | ≠ | get_stylesheet(); |
get_template_directory(); | ≠ | get_stylesheet_directory(); |
... | ≠ | ... |
template directory | ≠ | stylesheet directory |
parent directory | ≠ | theme directory (child) |
Important child-ready theme tip:
Be careful when using get_stylesheet_directory() / get_template_directory() etc. These functions are not interchangeable.
They will be no longer equivalent if a child theme is activated.
Any template file found in the child directory (STYLESHEETPATH) overrides its counterpart from the parent directory (TEMPLATEPATH).
New template files can be added to the child directory.
/* wp-includes/template.php */
if ( file_exists(STYLESHEETPATH . '/' . $template_name)) {
$located = STYLESHEETPATH . '/' . $template_name;
break;
} else if ( file_exists(TEMPLATEPATH . '/' . $template_name) ) {
$located = TEMPLATEPATH . '/' . $template_name;
break;
}
/* wp-settings.php */
if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists( STYLESHEETPATH . '/functions.php' ) )
include( STYLESHEETPATH . '/functions.php' );
if ( file_exists( TEMPLATEPATH . '/functions.php' ) )
include( TEMPLATEPATH . '/functions.php' );
Create functions.php in your child theme and add an new function.
/* pehaa-theme-child/functions.php */
function my_child_function() {
...
}
/* pehaa-theme/functions.php */
function my_function() {
...
}
How do I modify my_function?
/* pehaa-theme-child/functions.php */
function my_function() {
...
}
Fatal error: Cannot redeclare my_function()
/* pehaa-theme-child/functions.php */
function my_function() {
...
}
/* pehaa-theme/functions.php */
if ( !function_exists( 'my_function' ) ) :
function my_function() {
...
}
endif;
OK: my_function is declared in the child theme.
Important child-ready theme tip:
make the user functions pluggable by declaring them conditionally.
I guess you do it this way
/* child style.css */
@import url('../parent-theme/style.css');
/* Theme customization starts here */
/* parent : functions.php */
add_action( 'wp_enqueue_scripts', 'my_enqueue_styles' );
function my_enqueue_styles() {
wp_enqueue_style( 'style', get_stylesheet_uri() );
}
The @import method has a negative impact on web page performance.
I guess you do it this way
/* child style.css */
@import url('../parent-theme/style.css');
/* Theme customization starts here */
/* parent : functions.php */
add_action( 'wp_enqueue_scripts', 'my_enqueue_styles' );
function my_enqueue_styles() {
wp_enqueue_style( 'style', get_stylesheet_uri() );
}
Codex : Note that the previous method was to import the parent theme stylesheet using @import: this is no longer best practice.
Codex
/* child : functions.php */
add_action( 'wp_enqueue_scripts', 'theme_enqueue_styles' );
function theme_enqueue_styles() {
wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' );
}
/* twentyfifteen-child : functions.php */
add_action( 'wp_enqueue_scripts', 'theme_enqueue_styles' );
function theme_enqueue_styles() {
wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' );
}
/* twentyfifteen : functions.php */
add_action( 'wp_enqueue_scripts', 'twentyfifteen_scripts' );
function twentyfifteen_scripts() {
...
// Load our main stylesheet.
wp_enqueue_style( 'twentyfifteen-style', get_stylesheet_uri() );
...
}
1 (default) : modify your css in the child | 2 : build your site css from scratch in the child | 3 : do not modify css in the child at all |
T S |
- S |
T - |
/* parent : functions.php */
add_action( 'wp_enqueue_scripts', 'my_enqueue_styles' );
function my_enqueue_styles() {
$deps = array();
if ( apply_filters( 'load_template_css', is_child_theme() ) ) {
wp_enqueue_style( 'T-style', get_template_directory_uri().'/style.css', $deps );
$deps[] = 'T-style';
}
if ( apply_filters( 'load_stylesheet_css', true ) ) {
wp_enqueue_style( 'S-style', get_stylesheet_uri(), $deps );
}
}
Parent theme is activated : S-style is loaded
The 3rd paramenter of 'wp_enqueue_style' (dependencies) ensures that the 'T-style' (parent) will be loaded before the 'S-style' (child).
/* parent : functions.php */
add_action( 'wp_enqueue_scripts', 'my_enqueue_styles' );
function my_enqueue_styles() {
$deps = array();
if ( apply_filters( 'load_template_css', is_child_theme() ) ) {
wp_enqueue_style( 'T-style', get_template_directory_uri().'/style.css', $deps );
$deps[] = 'T-style';
}
if ( apply_filters( 'load_stylesheet_css', true ) ) {
wp_enqueue_style( 'S-style', get_stylesheet_uri(), $deps );
}
}
Child theme is activated : both T and S are loaded (S after T)
The 3rd paramenter of 'wp_enqueue_style' (dependencies) ensures that the 'T-style' (parent) will be loaded before the 'S-style' (child).
Build your site css from scratch in the child
/* child situation 2 : functions.php */
add_filter( 'load_template_css', 'do_not_load' );
function do_not_load() {
return false;
}
/* parent : functions.php */
add_action( 'wp_enqueue_scripts', 'my_enqueue_styles' );
function my_enqueue_styles() {
$deps = array();
if ( apply_filters( 'load_template_css', is_child_theme() ) ) {
wp_enqueue_style( 'T-style', get_template_directory_uri().'/style.css', $deps );
$deps[] = 'T-style';
}
if ( apply_filters( 'load_stylesheet_css', true ) ) {
wp_enqueue_style( 'S-style', get_stylesheet_uri(), $deps );
}
}
Do not modify css in the child at all
/* child situation 3 : functions.php */
add_filter( 'load_stylesheet_css', 'do_not_load' );
function do_not_load() {
return false;
}
/* parent : functions.php */
add_action( 'wp_enqueue_scripts', 'my_enqueue_styles' );
function my_enqueue_styles() {
$deps = array();
if ( apply_filters( 'load_template_css', is_child_theme() ) ) {
wp_enqueue_style( 'T-style', get_template_directory_uri().'/style.css', $deps );
$deps[] = 'T-style';
}
if ( apply_filters( 'load_stylesheet_css', true ) ) {
wp_enqueue_style( 'S-style', get_stylesheet_uri(), $deps );
}
}
apply_filters( $tag, $value, $var, ... );
The callback functions attached to filter hook $tag are invoked.
do_action( $tag, $args );
Execute functions hooked on a specific action hook.
add_filter( $tag, $function, $priority, $acccepted_args );
add_action( $tag, $function, $priority, $acccepted_args );
Hook a function to a specific filter action, $priority specifies the order in which the functions associated with a particular action are executed.
/* twentyfifteen-child : functions.php */
add_action( 'twentyfifteen_credits', 'pehaa_credits' );
function pehaa_credits() {
echo 'Customized by PeHaa.';
}
/* twentyfifteen : footer.php */
do_action( 'twentyfifteen_credits' );
/* parent : functions.php */
require get_template_directory() . 'my_file.php';
I'd rather use:
/* parent : functions.php */
require apply_filters( 'my_file_directory', get_template_directory() ) . 'my_file.php';
since it allows to add and modify 'my_file.php' in the child :
/* child : functions.php */
add_filter( 'my_file_directory', 'my_stylesheet_dir' );
function my_stylesheet_dir() {
return get_stylesheet_directory();
}
Follow @PeHaa sur Twitter
Thanks and happy coding in 2015!