enqueue_script( $entry, $base ); if ( ! $handle ) { return false; } /* * Stylesheets are written by hand and loaded as they are. Only the * JavaScript needs compiling, because the browser cannot read JSX; * CSS it can read already. Putting stylesheets through the build too * meant a colour could not be changed without installing half a * gigabyte of tooling and running webpack, which is a poor trade for * nesting and a handful of variables. */ $rel_css = 'css/' . $entry . '.css'; wp_enqueue_style( 'wp-components' ); if ( is_readable( $base_dir . $rel_css ) ) { wp_enqueue_style( $handle, $base_url . $rel_css, array( 'wp-components' ), self::file_version( $base_dir . $rel_css ) ); // A right to left stylesheet is picked up when one is written // beside the normal one, which WordPress expects to be named // with an -rtl suffix. if ( is_readable( $base_dir . 'css/' . $entry . '-rtl.css' ) ) { wp_style_add_data( $handle, 'rtl', 'replace' ); } } wp_add_inline_script( $handle, 'window.pageCore = ' . wp_json_encode( $this->boot_data( $data ) ) . ';', 'before' ); return true; } /** * Enqueue one built entry's script and nothing else. * * For code that extends the block editor rather than rendering a screen of * its own. It needs no stylesheet in the admin document, and no boot data: * enqueue_app() assigns window.pageCore whole, so a second application in * the same editor would replace the data the first one was handed. * * @param string $entry Entry name, matching a directory under build/. * @param array $base Optional. Keys: dir, url, domain, as enqueue_app(). * @return string|false The script handle, or false when the bundle is missing. */ public function enqueue_script( $entry, $base = array() ) { $base_dir = isset( $base['dir'] ) ? trailingslashit( $base['dir'] ) : PAGECORE_DIR; $base_url = isset( $base['url'] ) ? trailingslashit( $base['url'] ) : PAGECORE_URL; $domain = isset( $base['domain'] ) ? (string) $base['domain'] : 'pagecore'; $handle = 'pagecore-' . $entry; $rel_js = 'build/' . $entry . '/index.js'; $path_js = $base_dir . $rel_js; $path_meta = $base_dir . 'build/' . $entry . '/index.asset.php'; if ( ! is_readable( $path_js ) ) { return false; } $meta = is_readable( $path_meta ) ? require $path_meta : array(); $deps = isset( $meta['dependencies'] ) && is_array( $meta['dependencies'] ) ? $meta['dependencies'] : self::FALLBACK_DEPS; $version = ( isset( $meta['version'] ) && is_string( $meta['version'] ) && '' !== $meta['version'] ) ? $meta['version'] : PAGECORE_VERSION; wp_enqueue_script( $handle, $base_url . $rel_js, $deps, $version, true ); if ( function_exists( 'wp_set_script_translations' ) ) { wp_set_script_translations( $handle, $domain, $base_dir . 'languages' ); } return $handle; } /** * Version string for a stylesheet, from when the file last changed. * * Stylesheets are written by hand and loaded as they are, so unlike the * built scripts they carry no content hash. The plugin version alone * would leave a browser holding an old copy after the file is edited * without a release, which is exactly when a design change is checked. * * @param string $path Absolute path to the file. * @return string */ public static function file_version( $path ) { $time = is_readable( $path ) ? filemtime( $path ) : false; return $time ? PAGECORE_VERSION . '.' . $time : PAGECORE_VERSION; } /** * Data every PageCore application receives. * * @param array $data Module specific additions. * @return array */ private function boot_data( $data ) { return array_merge( array( // The REST address in the form WordPress answers under every // permalink setting. An import changes the permalinks while // the screen stays open, a demo setting its own and a replace // putting the site's back, and the /wp-json/ form stops // working the moment they become Plain. 'restUrl' => esc_url_raw( add_query_arg( 'rest_route', '/' . PAGECORE_REST_NAMESPACE, trailingslashit( home_url() ) . 'index.php' ) ), 'adminUrl' => esc_url_raw( admin_url() ), 'pluginUrl' => esc_url_raw( PAGECORE_URL ), 'theme' => Theme_Setup::state(), ), $data ); } }