/**
* Twenty Twenty functions and definitions
*
* @link https://developer.wordpress.org/themes/basics/theme-functions/
*
* @package WordPress
* @subpackage Twenty_Twenty
* @since Twenty Twenty 1.0
*/
/**
* Table of Contents:
* Theme Support
* Required Files
* Register Styles
* Register Scripts
* Register Menus
* Custom Logo
* WP Body Open
* Register Sidebars
* Enqueue Block Editor Assets
* Enqueue Classic Editor Styles
* Block Editor Settings
*/
/**
* Sets up theme defaults and registers support for various WordPress features.
*
* Note that this function is hooked into the after_setup_theme hook, which
* runs before the init hook. The init hook is too late for some features, such
* as indicating support for post thumbnails.
*
* @since Twenty Twenty 1.0
*/
function twentytwenty_theme_support() {
// Add default posts and comments RSS feed links to head.
add_theme_support( 'automatic-feed-links' );
// Custom background color.
add_theme_support(
'custom-background',
array(
'default-color' => 'f5efe0',
)
);
// Set content-width.
global $content_width;
if ( ! isset( $content_width ) ) {
$content_width = 580;
}
/*
* Enable support for Post Thumbnails on posts and pages.
*
* @link https://developer.wordpress.org/themes/functionality/featured-images-post-thumbnails/
*/
add_theme_support( 'post-thumbnails' );
// Set post thumbnail size.
set_post_thumbnail_size( 1200, 9999 );
// Add custom image size used in Cover Template.
add_image_size( 'twentytwenty-fullscreen', 1980, 9999 );
// Custom logo.
$logo_width = 120;
$logo_height = 90;
// If the retina setting is active, double the recommended width and height.
if ( get_theme_mod( 'retina_logo', false ) ) {
$logo_width = floor( $logo_width * 2 );
$logo_height = floor( $logo_height * 2 );
}
add_theme_support(
'custom-logo',
array(
'height' => $logo_height,
'width' => $logo_width,
'flex-height' => true,
'flex-width' => true,
)
);
/*
* Let WordPress manage the document title.
* By adding theme support, we declare that this theme does not use a
* hard-coded
tag in the document head, and expect WordPress to
* provide it for us.
*/
add_theme_support( 'title-tag' );
/*
* Switch default core markup for search form, comment form, and comments
* to output valid HTML5.
*/
add_theme_support(
'html5',
array(
'search-form',
'comment-form',
'comment-list',
'gallery',
'caption',
'script',
'style',
'navigation-widgets',
)
);
// Add support for full and wide align images.
add_theme_support( 'align-wide' );
// Add support for responsive embeds.
add_theme_support( 'responsive-embeds' );
/*
* Adds starter content to highlight the theme on fresh sites.
* This is done conditionally to avoid loading the starter content on every
* page load, as it is a one-off operation only needed once in the customizer.
*/
if ( is_customize_preview() ) {
require get_template_directory() . '/inc/starter-content.php';
add_theme_support( 'starter-content', twentytwenty_get_starter_content() );
}
// Add theme support for selective refresh for widgets.
add_theme_support( 'customize-selective-refresh-widgets' );
/*
* Adds `async` and `defer` support for scripts registered or enqueued
* by the theme.
*/
$loader = new TwentyTwenty_Script_Loader();
if ( version_compare( $GLOBALS['wp_version'], '6.3', '<' ) ) {
add_filter( 'script_loader_tag', array( $loader, 'filter_script_loader_tag' ), 10, 2 );
} else {
add_filter( 'print_scripts_array', array( $loader, 'migrate_legacy_strategy_script_data' ), 100 );
}
}
add_action( 'after_setup_theme', 'twentytwenty_theme_support' );
/**
* REQUIRED FILES
* Include required files.
*/
require get_template_directory() . '/inc/template-tags.php';
// Handle SVG icons.
require get_template_directory() . '/classes/class-twentytwenty-svg-icons.php';
require get_template_directory() . '/inc/svg-icons.php';
// Handle Customizer settings.
require get_template_directory() . '/classes/class-twentytwenty-customize.php';
// Require Separator Control class.
require get_template_directory() . '/classes/class-twentytwenty-separator-control.php';
// Custom comment walker.
require get_template_directory() . '/classes/class-twentytwenty-walker-comment.php';
// Custom page walker.
require get_template_directory() . '/classes/class-twentytwenty-walker-page.php';
// Custom script loader class.
require get_template_directory() . '/classes/class-twentytwenty-script-loader.php';
// Non-latin language handling.
require get_template_directory() . '/classes/class-twentytwenty-non-latin-languages.php';
// Custom CSS.
require get_template_directory() . '/inc/custom-css.php';
/**
* Registers block patterns and pattern categories.
*
* @since Twenty Twenty 2.8
*/
function twentytwenty_register_block_patterns() {
require get_template_directory() . '/inc/block-patterns.php';
}
add_action( 'init', 'twentytwenty_register_block_patterns' );
/**
* Registers and Enqueues Styles.
*
* @since Twenty Twenty 1.0
* @since Twenty Twenty 2.6 Enqueue the CSS file for the variable font.
*/
function twentytwenty_register_styles() {
$theme_version = wp_get_theme()->get( 'Version' );
wp_enqueue_style( 'twentytwenty-style', get_stylesheet_uri(), array(), $theme_version );
wp_style_add_data( 'twentytwenty-style', 'rtl', 'replace' );
// Enqueue the CSS file for the variable font, Inter.
wp_enqueue_style( 'twentytwenty-fonts', get_theme_file_uri( '/assets/css/font-inter.css' ), array(), $theme_version, 'all' );
// Add output of Customizer settings as inline style.
$customizer_css = twentytwenty_get_customizer_css( 'front-end' );
if ( $customizer_css ) {
wp_add_inline_style( 'twentytwenty-style', $customizer_css );
}
// Add print CSS.
wp_enqueue_style( 'twentytwenty-print-style', get_template_directory_uri() . '/print.css', null, $theme_version, 'print' );
}
add_action( 'wp_enqueue_scripts', 'twentytwenty_register_styles' );
/**
* Registers and Enqueues Scripts.
*
* @since Twenty Twenty 1.0
*/
function twentytwenty_register_scripts() {
$theme_version = wp_get_theme()->get( 'Version' );
if ( ( ! is_admin() ) && is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
wp_enqueue_script( 'comment-reply' );
}
/*
* This script is intentionally printed in the head because it involves the page header. The `defer` script loading
* strategy ensures that it does not block rendering; being in the head it will start loading earlier so that it
* will execute sooner once the DOM has loaded. The $args array is not used here to avoid unintentional footer
* placement in WP<6.3; the wp_script_add_data() call is used instead.
*/
wp_enqueue_script( 'twentytwenty-js', get_template_directory_uri() . '/assets/js/index.js', array(), $theme_version );
wp_script_add_data( 'twentytwenty-js', 'strategy', 'defer' );
}
add_action( 'wp_enqueue_scripts', 'twentytwenty_register_scripts' );
/**
* Fixes skip link focus in IE11.
*
* This does not enqueue the script because it is tiny and because it is only for IE11,
* thus it does not warrant having an entire dedicated blocking script being loaded.
*
* @since Twenty Twenty 1.0
* @deprecated Twenty Twenty 2.3 Removed from wp_print_footer_scripts action.
*
* @link https://git.io/vWdr2
*/
function twentytwenty_skip_link_focus_fix() {
// The following is minified via `terser --compress --mangle -- assets/js/skip-link-focus-fix.js`.
?>
}
/**
* Enqueues non-latin language styles.
*
* @since Twenty Twenty 1.0
*
* @return void
*/
function twentytwenty_non_latin_languages() {
$custom_css = TwentyTwenty_Non_Latin_Languages::get_non_latin_css( 'front-end' );
if ( $custom_css ) {
wp_add_inline_style( 'twentytwenty-style', $custom_css );
}
}
add_action( 'wp_enqueue_scripts', 'twentytwenty_non_latin_languages' );
/**
* Registers navigation menus.
*
* This theme uses wp_nav_menu() in five places.
*
* @since Twenty Twenty 1.0
*/
function twentytwenty_menus() {
$locations = array(
'primary' => __( 'Desktop Horizontal Menu', 'twentytwenty' ),
'expanded' => __( 'Desktop Expanded Menu', 'twentytwenty' ),
'mobile' => __( 'Mobile Menu', 'twentytwenty' ),
'footer' => __( 'Footer Menu', 'twentytwenty' ),
'social' => __( 'Social Menu', 'twentytwenty' ),
);
register_nav_menus( $locations );
}
add_action( 'init', 'twentytwenty_menus' );
/**
* Gets the information about the logo.
*
* @since Twenty Twenty 1.0
*
* @param string $html The HTML output from get_custom_logo() (core function).
* @return string
*/
function twentytwenty_get_custom_logo( $html ) {
$logo_id = get_theme_mod( 'custom_logo' );
if ( ! $logo_id ) {
return $html;
}
$logo = wp_get_attachment_image_src( $logo_id, 'full' );
if ( $logo ) {
// For clarity.
$logo_width = esc_attr( $logo[1] );
$logo_height = esc_attr( $logo[2] );
// If the retina logo setting is active, reduce the width/height by half.
if ( get_theme_mod( 'retina_logo', false ) ) {
$logo_width = floor( $logo_width / 2 );
$logo_height = floor( $logo_height / 2 );
$search = array(
'/width=\"\d+\"/iU',
'/height=\"\d+\"/iU',
);
$replace = array(
"width=\"{$logo_width}\"",
"height=\"{$logo_height}\"",
);
// Add a style attribute with the height, or append the height to the style attribute if the style attribute already exists.
if ( false === strpos( $html, ' style=' ) ) {
$search[] = '/(src=)/';
$replace[] = "style=\"height: {$logo_height}px;\" src=";
} else {
$search[] = '/(style="[^"]*)/';
$replace[] = "$1 height: {$logo_height}px;";
}
$html = preg_replace( $search, $replace, $html );
}
}
return $html;
}
add_filter( 'get_custom_logo', 'twentytwenty_get_custom_logo' );
if ( ! function_exists( 'wp_body_open' ) ) {
/**
* Shim for wp_body_open(), ensuring backward compatibility with versions of WordPress older than 5.2.
*
* @since Twenty Twenty 1.0
*/
function wp_body_open() {
/**
* Triggered after the opening tag.
*
* @since Twenty Twenty 1.0
*/
do_action( 'wp_body_open' );
}
}
/**
* Include a skip to content link at the top of the page so that users can bypass the menu.
*
* @since Twenty Twenty 1.0
*/
function twentytwenty_skip_link() {
echo '' .
/* translators: Hidden accessibility text. */
__( 'Skip to the content', 'twentytwenty' ) .
'';
}
add_action( 'wp_body_open', 'twentytwenty_skip_link', 5 );
/**
* Registers widget areas.
*
* @since Twenty Twenty 1.0
*
* @link https://developer.wordpress.org/themes/functionality/sidebars/#registering-a-sidebar
*/
function twentytwenty_sidebar_registration() {
// Arguments used in all register_sidebar() calls.
$shared_args = array(
'before_title' => '
',
'after_title' => '
',
'before_widget' => '
',
'after_widget' => '
',
);
// Footer #1.
register_sidebar(
array_merge(
$shared_args,
array(
'name' => __( 'Footer #1', 'twentytwenty' ),
'id' => 'sidebar-1',
'description' => __( 'Widgets in this area will be displayed in the first column in the footer.', 'twentytwenty' ),
)
)
);
// Footer #2.
register_sidebar(
array_merge(
$shared_args,
array(
'name' => __( 'Footer #2', 'twentytwenty' ),
'id' => 'sidebar-2',
'description' => __( 'Widgets in this area will be displayed in the second column in the footer.', 'twentytwenty' ),
)
)
);
}
add_action( 'widgets_init', 'twentytwenty_sidebar_registration' );
/**
* Enqueues supplemental block editor styles.
*
* @since Twenty Twenty 1.0
* @since Twenty Twenty 2.4 Removed a script related to the obsolete Squared style of Button blocks.
* @since Twenty Twenty 2.6 Enqueue the CSS file for the variable font.
*/
function twentytwenty_block_editor_styles() {
$theme_version = wp_get_theme()->get( 'Version' );
// Enqueue the editor styles.
wp_enqueue_style( 'twentytwenty-block-editor-styles', get_theme_file_uri( '/assets/css/editor-style-block.css' ), array(), $theme_version, 'all' );
wp_style_add_data( 'twentytwenty-block-editor-styles', 'rtl', 'replace' );
// Add inline style from the Customizer.
$customizer_css = twentytwenty_get_customizer_css( 'block-editor' );
if ( $customizer_css ) {
wp_add_inline_style( 'twentytwenty-block-editor-styles', $customizer_css );
}
// Enqueue the CSS file for the variable font, Inter.
wp_enqueue_style( 'twentytwenty-fonts', get_theme_file_uri( '/assets/css/font-inter.css' ), array(), $theme_version, 'all' );
// Add inline style for non-latin fonts.
$custom_css = TwentyTwenty_Non_Latin_Languages::get_non_latin_css( 'block-editor' );
if ( $custom_css ) {
wp_add_inline_style( 'twentytwenty-block-editor-styles', $custom_css );
}
}
if ( is_admin() && version_compare( $GLOBALS['wp_version'], '6.3', '>=' ) ) {
add_action( 'enqueue_block_assets', 'twentytwenty_block_editor_styles', 1, 1 );
} else {
add_action( 'enqueue_block_editor_assets', 'twentytwenty_block_editor_styles', 1, 1 );
}
/**
* Enqueues classic editor styles.
*
* @since Twenty Twenty 1.0
* @since Twenty Twenty 2.6 Enqueue the CSS file for the variable font.
*/
function twentytwenty_classic_editor_styles() {
$classic_editor_styles = array(
'/assets/css/editor-style-classic.css',
'/assets/css/font-inter.css',
);
add_editor_style( $classic_editor_styles );
}
add_action( 'init', 'twentytwenty_classic_editor_styles' );
/**
* Output Customizer settings in the classic editor.
* Adds styles to the head of the TinyMCE iframe. Kudos to @Otto42 for the original solution.
*
* @since Twenty Twenty 1.0
*
* @param array $mce_init TinyMCE styles.
* @return array TinyMCE styles.
*/
function twentytwenty_add_classic_editor_customizer_styles( $mce_init ) {
$styles = twentytwenty_get_customizer_css( 'classic-editor' );
if ( ! $styles ) {
return $mce_init;
}
if ( ! isset( $mce_init['content_style'] ) ) {
$mce_init['content_style'] = $styles . ' ';
} else {
$mce_init['content_style'] .= ' ' . $styles . ' ';
}
return $mce_init;
}
add_filter( 'tiny_mce_before_init', 'twentytwenty_add_classic_editor_customizer_styles' );
/**
* Output non-latin font styles in the classic editor.
* Adds styles to the head of the TinyMCE iframe. Kudos to @Otto42 for the original solution.
*
* @param array $mce_init TinyMCE styles.
* @return array TinyMCE styles.
*/
function twentytwenty_add_classic_editor_non_latin_styles( $mce_init ) {
$styles = TwentyTwenty_Non_Latin_Languages::get_non_latin_css( 'classic-editor' );
// Return if there are no styles to add.
if ( ! $styles ) {
return $mce_init;
}
if ( ! isset( $mce_init['content_style'] ) ) {
$mce_init['content_style'] = $styles . ' ';
} else {
$mce_init['content_style'] .= ' ' . $styles . ' ';
}
return $mce_init;
}
add_filter( 'tiny_mce_before_init', 'twentytwenty_add_classic_editor_non_latin_styles' );
/**
* Block Editor Settings.
* Adds custom colors and font sizes to the block editor.
*
* @since Twenty Twenty 1.0
*/
function twentytwenty_block_editor_settings() {
// Block Editor Palette.
$editor_color_palette = array(
array(
'name' => __( 'Accent Color', 'twentytwenty' ),
'slug' => 'accent',
'color' => twentytwenty_get_color_for_area( 'content', 'accent' ),
),
array(
'name' => _x( 'Primary', 'color', 'twentytwenty' ),
'slug' => 'primary',
'color' => twentytwenty_get_color_for_area( 'content', 'text' ),
),
array(
'name' => _x( 'Secondary', 'color', 'twentytwenty' ),
'slug' => 'secondary',
'color' => twentytwenty_get_color_for_area( 'content', 'secondary' ),
),
array(
'name' => __( 'Subtle Background', 'twentytwenty' ),
'slug' => 'subtle-background',
'color' => twentytwenty_get_color_for_area( 'content', 'borders' ),
),
);
// Add the background option.
$background_color = get_theme_mod( 'background_color' );
if ( ! $background_color ) {
$background_color_arr = get_theme_support( 'custom-background' );
$background_color = $background_color_arr[0]['default-color'];
}
$editor_color_palette[] = array(
'name' => __( 'Background Color', 'twentytwenty' ),
'slug' => 'background',
'color' => '#' . $background_color,
);
// If we have accent colors, add them to the block editor palette.
if ( $editor_color_palette ) {
add_theme_support( 'editor-color-palette', $editor_color_palette );
}
// Block Editor Font Sizes.
add_theme_support(
'editor-font-sizes',
array(
array(
'name' => _x( 'Small', 'Name of the small font size in the block editor', 'twentytwenty' ),
'shortName' => _x( 'S', 'Short name of the small font size in the block editor.', 'twentytwenty' ),
'size' => 18,
'slug' => 'small',
),
array(
'name' => _x( 'Regular', 'Name of the regular font size in the block editor', 'twentytwenty' ),
'shortName' => _x( 'M', 'Short name of the regular font size in the block editor.', 'twentytwenty' ),
'size' => 21,
'slug' => 'normal',
),
array(
'name' => _x( 'Large', 'Name of the large font size in the block editor', 'twentytwenty' ),
'shortName' => _x( 'L', 'Short name of the large font size in the block editor.', 'twentytwenty' ),
'size' => 26.25,
'slug' => 'large',
),
array(
'name' => _x( 'Larger', 'Name of the larger font size in the block editor', 'twentytwenty' ),
'shortName' => _x( 'XL', 'Short name of the larger font size in the block editor.', 'twentytwenty' ),
'size' => 32,
'slug' => 'larger',
),
)
);
add_theme_support( 'editor-styles' );
// If we have a dark background color then add support for dark editor style.
// We can determine if the background color is dark by checking if the text-color is white.
if ( '#ffffff' === strtolower( twentytwenty_get_color_for_area( 'content', 'text' ) ) ) {
add_theme_support( 'dark-editor-style' );
}
}
add_action( 'after_setup_theme', 'twentytwenty_block_editor_settings' );
/**
* Overwrite default more tag with styling and screen reader markup.
*
* @param string $html The default output HTML for the more tag.
* @return string
*/
function twentytwenty_read_more_tag( $html ) {
return preg_replace( '/(.*)<\/a>/iU', sprintf( '