$style ) { if ( 'theme' === ( $style['__unstableType'] ?? '' ) ) { $at = $i; break; } } array_splice( $settings['styles'], $at, 0, array( array( 'css' => file_get_contents( $file ), // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- a theme file, not a remote one. 'baseURL' => get_template_directory_uri() . '/style.css', '__unstableType' => 'theme', 'isGlobalStyles' => false, ), ) ); return $settings; } ); add_action( 'after_setup_theme', function () { add_editor_style( 'style.css' ); /* WooCommerce readiness: declared support silences Woo's "unsupported theme" notice and turns on the product-gallery zoom, lightbox and slider. Shop styling is in style.css. */ add_theme_support( 'woocommerce' ); add_theme_support( 'wc-product-gallery-zoom' ); add_theme_support( 'wc-product-gallery-lightbox' ); add_theme_support( 'wc-product-gallery-slider' ); /* Pages here are built from pasted sections, so WordPress's stock pattern library is noise in the inserter and the Site Editor. A plugin's own patterns (WooCommerce's) stay. */ remove_theme_support( 'core-block-patterns' ); } ); /* The same for the patterns WordPress downloads from wordpress.org. */ add_filter( 'should_load_remote_block_patterns', '__return_false' ); /* Every page gets one h1. templates/page.html prints the title as the h1, which a page typed in the editor needs (a legal page, WooCommerce's account page); a page built from sections already carries the hero's h1, so for it the title block is left out before it is drawn and the page keeps exactly one. Read from the stored content: sections, heading blocks and classic content all store their h1 there. A page built with Elementor keeps its design in its own field: an h1 heading there, or Elementor's Hide Title, counts too. A page behind a password shows only the form, so it keeps the title. */ add_filter( 'pre_render_block', function ( $pre, $block ) { if ( 'core/group' !== $block['blockName'] || ! in_array( 'pt-page-title', explode( ' ', $block['attrs']['className'] ?? '' ), true ) ) { return $pre; } $post = get_post(); if ( ! $post || post_password_required( $post ) ) { return $pre; } if ( preg_match( '/]/i', $post->post_content ) ) { return ''; } if ( 'builder' === get_post_meta( $post->ID, '_elementor_edit_mode', true ) ) { $settings = get_post_meta( $post->ID, '_elementor_page_settings', true ); if ( 'yes' === ( is_array( $settings ) ? ( $settings['hide_title'] ?? '' ) : '' ) || str_contains( (string) get_post_meta( $post->ID, '_elementor_data', true ), '"header_size":"h1"' ) ) { return ''; } } return $pre; }, 10, 2 ); /* The page's own background for the section edges in style.css: a see-through lower section paints it so its shape shows. Core prints the background picked in Styles on body alone, with no variable a rule can read, so it is handed on as --pt-ground. Not printed while it is the theme's own (base), which style.css falls back to. A palette pick is stored as var:preset|color|slug and becomes the variable the way core does it. */ add_action( 'wp_enqueue_scripts', function () { $ground = wp_get_global_styles( array( 'color', 'background' ) ); if ( ! is_string( $ground ) || preg_match( '/[{}<>;]/', $ground ) ) { return; } if ( str_starts_with( $ground, 'var:' ) ) { $ground = 'var(--wp--' . str_replace( '|', '--', substr( $ground, 4 ) ) . ')'; } if ( '' !== $ground && 'var(--wp--preset--color--base)' !== $ground ) { wp_add_inline_style( 'pastetheme', 'body{--pt-ground:' . $ground . '}' ); } }, 20 ); /* The parent stylesheet always; a child theme's own style.css on top of it. */ add_action( 'wp_enqueue_scripts', function () { wp_enqueue_style( 'pastetheme', get_parent_theme_file_uri( 'style.css' ), array(), wp_get_theme( get_template() )->get( 'Version' ) ); if ( is_child_theme() ) { wp_enqueue_style( 'pastetheme-child', get_stylesheet_uri(), array( 'pastetheme' ), wp_get_theme()->get( 'Version' ) ); } } ); /* While the body or the headings use Quicksand (theme.json's choice until the owner picks another font in Styles), the latin file is asked for with the page's first files instead of after the stylesheet has been read, so it usually lands before the first paint rather than swapping in after it (style.css holds the size-matched fallback for when it is late). The address is the one theme.json's file:./ resolves to, get_theme_file_uri(), or the browser would fetch the file twice. Core prints and escapes the link. */ add_filter( 'wp_preload_resources', function ( $resources ) { $paths = array( array( 'typography', 'fontFamily' ), array( 'elements', 'heading', 'typography', 'fontFamily' ), ); foreach ( $paths as $path ) { $family = wp_get_global_styles( $path ); // A path that is not set returns an array. if ( is_string( $family ) && preg_match( '/quicksand(?![\w-])/i', $family ) ) { $resources[] = array( 'href' => get_theme_file_uri( 'assets/fonts/quicksand-latin.woff2' ), 'as' => 'font', 'type' => 'font/woff2', 'crossorigin' => 'anonymous', ); break; } } return $resources; } );