+ +

diff --git a/wp/10up-theme/includes/block-collection.js b/wp/10up-theme/includes/block-collection.js new file mode 100644 index 000000000..c57caa6b9 --- /dev/null +++ b/wp/10up-theme/includes/block-collection.js @@ -0,0 +1,13 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { registerBlockCollection } from '@wordpress/blocks'; + +/** + * Register block collection. + * See https://developer.wordpress.org/block-editor/reference-guides/block-api/block-registration/#registerblockcollection + */ +registerBlockCollection('tenup', { + title: __('Custom Blocks', 'tenup-theme'), +}); diff --git a/wp/10up-theme/includes/block-editor-script.js b/wp/10up-theme/includes/block-editor-script.js new file mode 100644 index 000000000..b496e068c --- /dev/null +++ b/wp/10up-theme/includes/block-editor-script.js @@ -0,0 +1,8 @@ +/** + * Entry point for all block editor specific scripts. + */ + +import './block-collection'; +// import './block-filters'; +// import './block-styles'; +// import './block-variations'; diff --git a/wp/10up-theme/includes/block-filters/index.js b/wp/10up-theme/includes/block-filters/index.js new file mode 100644 index 000000000..7da76c652 --- /dev/null +++ b/wp/10up-theme/includes/block-filters/index.js @@ -0,0 +1,6 @@ +/** + * Entry point for block filters. + */ + +// Each block that needs filters to be applied, should have it's own file. +// import './button' diff --git a/wp/10up-theme/includes/block-styles/index.js b/wp/10up-theme/includes/block-styles/index.js new file mode 100644 index 000000000..4c44ad49f --- /dev/null +++ b/wp/10up-theme/includes/block-styles/index.js @@ -0,0 +1,6 @@ +/** + * Entry point for block styles. + */ + +// Each block that needs custom styles should have it's own file. +// import './button' diff --git a/wp/10up-theme/includes/block-variations/index.js b/wp/10up-theme/includes/block-variations/index.js new file mode 100644 index 000000000..801a24d33 --- /dev/null +++ b/wp/10up-theme/includes/block-variations/index.js @@ -0,0 +1,6 @@ +/** + * Entry point for block variations. + */ + +// Each block that needs variations should have it's own file. +// import './button' diff --git a/wp/10up-theme/includes/blocks.php b/wp/10up-theme/includes/blocks.php new file mode 100644 index 000000000..05d9ca357 --- /dev/null +++ b/wp/10up-theme/includes/blocks.php @@ -0,0 +1,146 @@ +context; + + // get the actual markup from the markup.php file + ob_start(); + include $block_folder . '/markup.php'; + return ob_get_clean(); + }; + }; + + register_block_type_from_metadata( $block_folder, $block_options ); + }; + }; + + if ( $is_pre_wp_6 ) { + // Remove the filter after we register the blocks + remove_filter( 'plugins_url', __NAMESPACE__ . '\filter_plugins_url', 10, 2 ); + } +} + +/** + * Filter the plugins_url to allow us to use assets from theme. + * + * @param string $url The plugins url + * @param string $path The path to the asset. + * + * @return string The overridden url to the block asset. + */ +function filter_plugins_url( $url, $path ) { + $file = preg_replace( '/\.\.\//', '', $path ); + return trailingslashit( get_stylesheet_directory_uri() ) . $file; +} + + +/** + * Enqueue editor-only JavaScript/CSS for blocks. + * + * @return void + */ +function blocks_editor_styles() { + wp_enqueue_style( + 'editor-style-overrides', + TENUP_THEME_TEMPLATE_URL . '/dist/css/editor-style-overrides.css', + [], + Utility\get_asset_info( 'editor-style-overrides', 'version' ) + ); + + if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) { + wp_enqueue_script( + 'editor-style-overrides', + TENUP_THEME_TEMPLATE_URL . '/dist/js/editor-style-overrides.js', + Utility\get_asset_info( 'editor-style-overrides', 'dependencies' ), + Utility\get_asset_info( 'editor-style-overrides', 'version' ), + true + ); + } + +} + +/** + * Register block pattern categories + * + * @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-patterns/ + * + * @return void + */ +function register_block_pattern_categories() { + + // Register a block pattern category + register_block_pattern_category( + '10up-theme', + [ 'label' => __( '10up Theme', 'tenup-theme' ) ] + ); +} diff --git a/wp/10up-theme/includes/blocks/example-block/block.json b/wp/10up-theme/includes/blocks/example-block/block.json new file mode 100644 index 000000000..ffc2a9c4c --- /dev/null +++ b/wp/10up-theme/includes/blocks/example-block/block.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 2, + "title": "Example Block", + "description": "An Example Block", + "textdomain": "tenup-theme", + "name": "tenup/example", + "icon": "feedback", + "category": "formatting", + "attributes":{ + "button-label": { + "type" : "string" + }, + "image": { + "type": "object" + } + }, + "example": { + "attributes":{ + "title": "Example Block" + } + }, + "supports": { + "html": false + }, + "editorScript": "file:./index.js" +} diff --git a/wp/10up-theme/includes/blocks/example-block/edit.js b/wp/10up-theme/includes/blocks/example-block/edit.js new file mode 100644 index 000000000..abdc964f0 --- /dev/null +++ b/wp/10up-theme/includes/blocks/example-block/edit.js @@ -0,0 +1,35 @@ +/** + * WordPress dependencies + */ +import { useBlockProps } from '@wordpress/block-editor'; + +// eslint-disable-next-line import/no-unresolved +import Block from '@headstartwp/blocks-primitives/block'; +// eslint-disable-next-line import/no-unresolved +import { Button } from '@headstartwp/component-library/button'; + +/** + * Edit component. + * See https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-edit-save/#edit + * + * @param {object} props The block props. + * @param {object} props.attributes Block attributes. + * @param {string} props.attributes.title Custom title to be displayed. + * @param {string} props.className Class name for the block. + * @param {Function} props.setAttributes Sets the value for block attributes. + * @returns {Function} Render the edit screen + */ +const ExampleBlockEdit = (props) => { + const { attributes, setAttributes } = props; + + const blockProps = useBlockProps(); + + return ( +
+ +
+ ); +}; +export default ExampleBlockEdit; diff --git a/wp/10up-theme/includes/blocks/example-block/index.js b/wp/10up-theme/includes/blocks/example-block/index.js new file mode 100644 index 000000000..695b437b5 --- /dev/null +++ b/wp/10up-theme/includes/blocks/example-block/index.js @@ -0,0 +1,24 @@ +/** + * Example-block + * Custom title block -- feel free to delete + */ + +/** + * WordPress dependencies + */ +import { registerBlockType } from '@wordpress/blocks'; + +/** + * Internal dependencies + */ +import edit from './edit'; +import save from './save'; +import block from './block.json'; + +/** + * Register block + */ +registerBlockType(block, { + edit, + save, +}); diff --git a/wp/10up-theme/includes/blocks/example-block/markup.php b/wp/10up-theme/includes/blocks/example-block/markup.php new file mode 100644 index 000000000..627608199 --- /dev/null +++ b/wp/10up-theme/includes/blocks/example-block/markup.php @@ -0,0 +1,18 @@ + +
> +

+ +

+
diff --git a/wp/10up-theme/includes/blocks/example-block/save.js b/wp/10up-theme/includes/blocks/example-block/save.js new file mode 100644 index 000000000..daa1ee545 --- /dev/null +++ b/wp/10up-theme/includes/blocks/example-block/save.js @@ -0,0 +1,8 @@ +/** + * See https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-edit-save/#save + * + * @returns {null} Dynamic blocks do not save the HTML. + */ +const ExampleBlockSave = () => null; + +export default ExampleBlockSave; diff --git a/wp/10up-theme/includes/classes/.gitkeep b/wp/10up-theme/includes/classes/.gitkeep new file mode 100755 index 000000000..c1df4390b --- /dev/null +++ b/wp/10up-theme/includes/classes/.gitkeep @@ -0,0 +1 @@ +# Basically just want to ignore the directory contents diff --git a/wp/10up-theme/includes/classes/Module.php b/wp/10up-theme/includes/classes/Module.php new file mode 100644 index 000000000..894e0b74d --- /dev/null +++ b/wp/10up-theme/includes/classes/Module.php @@ -0,0 +1,40 @@ +get_classes() as $class ) { + // Create a slug for the class name. + $slug = $this->slugify_class_name( $class ); + + // If the class has already been initialized, skip it. + if ( isset( $this->classes[ $slug ] ) ) { + continue; + } + + // Create a new reflection of the class. + $reflection_class = new ReflectionClass( $class ); + + // Using reflection, check if the class can be initialized. + // If not, skip. + if ( ! $reflection_class->isInstantiable() ) { + continue; + } + + // Make sure the class is a subclass of Module, so we can initialize it. + if ( ! $reflection_class->isSubclassOf( '\TenUpTheme\Module' ) ) { + continue; + } + + // Initialize the class. + $instantiated_class = new $class(); + + // Assign the classes into the order they should be initialized. + $load_class_order[ intval( $instantiated_class->load_order ) ][] = [ + 'slug' => $slug, + 'class' => $instantiated_class, + ]; + } + + // Sort the initialized classes by load order. + ksort( $load_class_order ); + + // Loop through the classes and initialize them. + foreach ( $load_class_order as $class_objects ) { + foreach ( $class_objects as $class_object ) { + $class = $class_object['class']; + $slug = $class_object['slug']; + + // If the class can be registered, register it. + if ( $class->can_register() ) { + // Call its register method. + $class->register(); + // Store the class in the list of initialized classes. + $this->classes[ $slug ] = $class; + } + } + } + } + + /** + * Slugify a class name. + * + * @param string $class_name The class name. + * + * @return string + */ + protected function slugify_class_name( $class_name ) { + return sanitize_title( str_replace( '\\', '-', $class_name ) ); + } + + /** + * Get a class by its full class name, including namespace. + * + * @param string $class_name The class name & namespace. + * + * @return false|\TenUpTheme\Module + */ + public function get_class( $class_name ) { + $class_name = $this->slugify_class_name( $class_name ); + + if ( isset( $this->classes[ $class_name ] ) ) { + return $this->classes[ $class_name ]; + } + + return false; + } + + /** + * Get all the initialized classes. + * + * @return array + */ + public function get_all_classes() { + return $this->classes; + } + +} diff --git a/wp/10up-theme/includes/core.php b/wp/10up-theme/includes/core.php new file mode 100755 index 000000000..2660d2602 --- /dev/null +++ b/wp/10up-theme/includes/core.php @@ -0,0 +1,320 @@ +

%2$s

', esc_attr( $class ), esc_html( $message ) ); + } + ); + return; + } + + ModuleInitialization::instance()->init_classes(); + do_action( 'tenup_theme_init' ); +} + +/** + * Makes Theme available for translation. + * + * Translations can be added to the /languages directory. + * If you're building a theme based on "tenup-theme", change the + * filename of '/languages/TenUpTheme.pot' to the name of your project. + * + * @return void + */ +function i18n() { + load_theme_textdomain( 'tenup-theme', TENUP_THEME_PATH . '/languages' ); +} + +/** + * Sets up theme defaults and registers support for various WordPress features. + */ +function theme_setup() { + add_theme_support( 'automatic-feed-links' ); + add_theme_support( 'title-tag' ); + add_theme_support( 'post-thumbnails' ); + add_theme_support( + 'html5', + array( + 'search-form', + 'gallery', + 'navigation-widgets', + ) + ); + + add_theme_support( 'editor-styles' ); + add_editor_style( 'dist/css/frontend.css' ); + + remove_theme_support( 'core-block-patterns' ); + + // by adding the `theme.json` file block templates automatically get enabled. + // because the template editor will need additional QA and work to get right + // the default is to disable this feature. + remove_theme_support( 'block-templates' ); + + // This theme uses wp_nav_menu() in three locations. + register_nav_menus( + array( + 'primary' => esc_html__( 'Primary Menu', 'tenup-theme' ), + ) + ); +} + +/** + * Enqueue scripts for front-end. + * + * @return void + */ +function scripts() { + + /** + * Enqueuing frontend.js is required to get css hot reloading working in the frontend + * If you're not shipping any front-end js wrap this enqueue in a SCRIPT_DEBUG check. + */ + wp_enqueue_script( + 'frontend', + TENUP_THEME_TEMPLATE_URL . '/dist/js/frontend.js', + Utility\get_asset_info( 'frontend', 'dependencies' ), + Utility\get_asset_info( 'frontend', 'version' ), + true + ); + + if ( is_page_template( 'templates/page-styleguide.php' ) ) { + wp_enqueue_script( + 'styleguide', + TENUP_THEME_TEMPLATE_URL . '/dist/js/styleguide.js', + Utility\get_asset_info( 'styleguide', 'dependencies' ), + Utility\get_asset_info( 'styleguide', 'version' ), + true + ); + } + + /** + * Enqueuing shared.js is required to get css hot reloading working in the frontend + * If you're not shipping any shared js wrap this enqueue in a SCRIPT_DEBUG check. + */ + + /* + * Uncoment this to use the shared.js file. + wp_enqueue_script( + 'shared', + TENUP_THEME_TEMPLATE_URL . '/dist/js/shared.js', + Utility\get_asset_info( 'shared', 'dependencies' ), + Utility\get_asset_info( 'shared', 'version' ), + true + ); + */ + +} + +/** + * Enqueue scripts for admin + * + * @return void + */ +function admin_scripts() { + wp_enqueue_script( + 'admin', + TENUP_THEME_TEMPLATE_URL . '/dist/js/admin.js', + Utility\get_asset_info( 'admin', 'dependencies' ), + Utility\get_asset_info( 'admin', 'version' ), + true + ); + + /* + * Uncoment this to use the shared.js file. + wp_enqueue_script( + 'shared', + TENUP_THEME_TEMPLATE_URL . '/dist/js/shared.js', + Utility\get_asset_info( 'shared', 'dependencies' ), + Utility\get_asset_info( 'shared', 'version' ), + true + ); + */ +} + +/** + * Enqueue core block filters, styles and variations. + * + * @return void + */ +function enqueue_block_editor_scripts() { + wp_enqueue_script( + 'block-editor-script', + TENUP_THEME_DIST_URL . 'js/block-editor-script.js', + Utility\get_asset_info( 'block-editor-script', 'dependencies' ), + Utility\get_asset_info( 'block-editor-script', 'version' ), + true + ); +} + +/** + * Enqueue styles for admin + * + * @return void + */ +function admin_styles() { + + wp_enqueue_style( + 'admin-style', + TENUP_THEME_TEMPLATE_URL . '/dist/css/admin.css', + [], + Utility\get_asset_info( 'admin-style', 'version' ) + ); + + /* + * Uncoment this to use the shared.css file. + wp_enqueue_style( + 'shared-style', + TENUP_THEME_TEMPLATE_URL . '/dist/css/shared.css', + [], + Utility\get_asset_info( 'shared', 'version' ) + ); + */ +} + +/** + * Enqueue styles for front-end. + * + * @return void + */ +function styles() { + + wp_enqueue_style( + 'styles', + TENUP_THEME_TEMPLATE_URL . '/dist/css/frontend.css', + [], + Utility\get_asset_info( 'frontend', 'version' ) + ); + + if ( is_page_template( 'templates/page-styleguide.php' ) ) { + wp_enqueue_style( + 'styleguide', + TENUP_THEME_TEMPLATE_URL . '/dist/css/styleguide.css', + [], + Utility\get_asset_info( 'styleguide-style', 'version' ) + ); + } + +} + +/** + * Handles JavaScript detection. + * + * Adds a `js` class to the root `` element when JavaScript is detected. + * + * @return void + */ +function js_detection() { + + echo "\n"; +} + +/** + * Add async/defer attributes to enqueued scripts that have the specified script_execution flag. + * + * @link https://core.trac.wordpress.org/ticket/12009 + * @param string $tag The script tag. + * @param string $handle The script handle. + * @return string + */ +function script_loader_tag( $tag, $handle ) { + $script_execution = wp_scripts()->get_data( $handle, 'script_execution' ); + + if ( ! $script_execution ) { + return $tag; + } + + if ( 'async' !== $script_execution && 'defer' !== $script_execution ) { + return $tag; + } + + // Abort adding async/defer for scripts that have this script as a dependency. _doing_it_wrong()? + foreach ( wp_scripts()->registered as $script ) { + if ( in_array( $handle, $script->deps, true ) ) { + return $tag; + } + } + + // Add the attribute if it hasn't already been added. + if ( ! preg_match( ":\s$script_execution(=|>|\s):", $tag ) ) { + $tag = preg_replace( ':(?=>):', " $script_execution", $tag, 1 ); + } + + return $tag; +} + +/** + * Inlines ct.css in the head + * + * Embeds a diagnostic CSS file written by Harry Roberts + * that helps diagnose render blocking resources and other + * performance bottle necks. + * + * The CSS is inlined in the head of the document, only when requesting + * a page with the query param ?debug_perf=1 + * + * @link https://csswizardry.com/ct/ + * @return void + */ +function embed_ct_css() { + + $debug_performance = rest_sanitize_boolean( filter_input( INPUT_GET, 'debug_perf', FILTER_SANITIZE_NUMBER_INT ) ); + + if ( ! $debug_performance ) { + return; + }; + + wp_register_style( 'ct', false ); // phpcs:ignore + wp_enqueue_style( 'ct' ); + wp_add_inline_style( 'ct', 'head{--ct-is-problematic:solid;--ct-is-affected:dashed;--ct-notify:#0bce6b;--ct-warn:#ffa400;--ct-error:#ff4e42}head,head [rel=stylesheet],head script,head script:not([src])[async],head script:not([src])[defer],head script~meta[http-equiv=content-security-policy],head style,head>meta[charset]:not(:nth-child(-n+5)){display:block}head [rel=stylesheet],head script,head script~meta[http-equiv=content-security-policy],head style,head title,head>meta[charset]:not(:nth-child(-n+5)){margin:5px;padding:5px;border-width:5px;background-color:#fff;color:#333}head ::before,head script,head style{font:16px/1.5 monospace,monospace;display:block}head ::before{font-weight:700}head link[rel=stylesheet],head script[src]{border-style:var(--ct-is-problematic);border-color:var(--ct-warn)}head script[src]::before{content:"[Blocking Script – " attr(src) "]"}head link[rel=stylesheet]::before{content:"[Blocking Stylesheet – " attr(href) "]"}head script:not(:empty),head style:not(:empty){max-height:5em;overflow:auto;background-color:#ffd;white-space:pre;border-color:var(--ct-notify);border-style:var(--ct-is-problematic)}head script:not(:empty)::before{content:"[Inline Script] "}head style:not(:empty)::before{content:"[Inline Style] "}head script:not(:empty)~title,head script[src]:not([async]):not([defer]):not([type=module])~title{display:block;border-style:var(--ct-is-affected);border-color:var(--ct-error)}head script:not(:empty)~title::before,head script[src]:not([async]):not([defer]):not([type=module])~title::before{content:"[ blocked by JS] "}head [rel=stylesheet]:not([media=print]):not(.ct)~script,head style:not(:empty)~script{border-style:var(--ct-is-affected);border-color:var(--ct-warn)}head [rel=stylesheet]:not([media=print]):not(.ct)~script::before,head style:not(:empty)~script::before{content:"[JS blocked by CSS – " attr(src) "]"}head script[src][src][async][defer]{display:block;border-style:var(--ct-is-problematic);border-color:var(--ct-warn)}head script[src][src][async][defer]::before{content:"[async and defer is redundant: prefer defer – " attr(src) "]"}head script:not([src])[async],head script:not([src])[defer]{border-style:var(--ct-is-problematic);border-color:var(--ct-warn)}head script:not([src])[async]::before{content:"The async attribute is redundant on inline scripts"}head script:not([src])[defer]::before{content:"The defer attribute is redundant on inline scripts"}head [rel=stylesheet][href^="//"],head [rel=stylesheet][href^=http],head script[src][src][src^="//"],head script[src][src][src^=http]{border-style:var(--ct-is-problematic);border-color:var(--ct-error)}head script[src][src][src^="//"]::before,head script[src][src][src^=http]::before{content:"[Third Party Blocking Script – " attr(src) "]"}head [rel=stylesheet][href^="//"]::before,head [rel=stylesheet][href^=http]::before{content:"[Third Party Blocking Stylesheet – " attr(href) "]"}head script~meta[http-equiv=content-security-policy]{border-style:var(--ct-is-problematic);border-color:var(--ct-error)}head script~meta[http-equiv=content-security-policy]::before{content:"[Meta CSP defined after JS]"}head>meta[charset]:not(:nth-child(-n+5)){border-style:var(--ct-is-problematic);border-color:var(--ct-warn)}head>meta[charset]:not(:nth-child(-n+5))::before{content:"[Charset should appear as early as possible]"}link[rel=stylesheet].ct,link[rel=stylesheet][media=print],script[async],script[defer],script[type=module],style.ct{display:none}' ); + +} diff --git a/wp/10up-theme/includes/helpers.php b/wp/10up-theme/includes/helpers.php new file mode 100644 index 000000000..48f81236d --- /dev/null +++ b/wp/10up-theme/includes/helpers.php @@ -0,0 +1,19 @@ +<?php +/** + * Theme specific helpers. + * + * @package TenUpTheme + */ + +namespace TenUpTheme; + +/** + * Get an initialized class by its full class name, including namespace. + * + * @param string $class_name The class name including the namespace. + * + * @return false|Module + */ +function get_module( $class_name ) { + return \TenUpTheme\ModuleInitialization::instance()->get_class( $class_name ); +} diff --git a/wp/10up-theme/includes/overrides.php b/wp/10up-theme/includes/overrides.php new file mode 100644 index 000000000..0edf99702 --- /dev/null +++ b/wp/10up-theme/includes/overrides.php @@ -0,0 +1,85 @@ +<?php +/** + * This file contains hooks and functions that override the behavior of WP Core. + * + * @package TenUpTheme + */ + +namespace TenUpTheme\Overrides; + +/** + * Registers instances where we will override default WP Core behavior. + * + * @link https://developer.wordpress.org/reference/functions/print_emoji_detection_script/ + * @link https://developer.wordpress.org/reference/functions/print_emoji_styles/ + * @link https://developer.wordpress.org/reference/functions/wp_staticize_emoji/ + * @link https://developer.wordpress.org/reference/functions/wp_staticize_emoji_for_email/ + * @link https://developer.wordpress.org/reference/functions/wp_generator/ + * @link https://developer.wordpress.org/reference/functions/wlwmanifest_link/ + * @link https://developer.wordpress.org/reference/functions/rsd_link/ + * + * @return void + */ +function setup() { + // Remove the Emoji detection script. + remove_action( 'wp_head', 'print_emoji_detection_script', 7 ); + + // Remove inline Emoji detection script. + remove_action( 'admin_print_scripts', 'print_emoji_detection_script' ); + + // Remove Emoji-related styles from front end and back end. + remove_action( 'wp_print_styles', 'print_emoji_styles' ); + remove_action( 'admin_print_styles', 'print_emoji_styles' ); + + // Remove Emoji-to-static-img conversion. + remove_filter( 'the_content_feed', 'wp_staticize_emoji' ); + remove_filter( 'comment_text_rss', 'wp_staticize_emoji' ); + remove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' ); + + add_filter( 'tiny_mce_plugins', __NAMESPACE__ . '\disable_emojis_tinymce' ); + add_filter( 'wp_resource_hints', __NAMESPACE__ . '\disable_emoji_dns_prefetch', 10, 2 ); + + // Remove WordPress generator meta. + remove_action( 'wp_head', 'wp_generator' ); + // Remove Windows Live Writer manifest link. + remove_action( 'wp_head', 'wlwmanifest_link' ); + // Remove the link to Really Simple Discovery service endpoint. + remove_action( 'wp_head', 'rsd_link' ); + +} + +/** + * Filter function used to remove the TinyMCE emoji plugin. + * + * @link https://developer.wordpress.org/reference/hooks/tiny_mce_plugins/ + * + * @param array $plugins An array of default TinyMCE plugins. + * @return array An array of TinyMCE plugins, without wpemoji. + */ +function disable_emojis_tinymce( $plugins ) { + if ( is_array( $plugins ) && in_array( 'wpemoji', $plugins, true ) ) { + return array_diff( $plugins, array( 'wpemoji' ) ); + } + + return $plugins; +} + +/** + * Remove emoji CDN hostname from DNS prefetching hints. + * + * @link https://developer.wordpress.org/reference/hooks/emoji_svg_url/ + * + * @param array $urls URLs to print for resource hints. + * @param string $relation_type The relation type the URLs are printed for. + * @return array Difference betwen the two arrays. + */ +function disable_emoji_dns_prefetch( $urls, $relation_type ) { + if ( 'dns-prefetch' === $relation_type ) { + /** This filter is documented in wp-includes/formatting.php */ + $emoji_svg_url = apply_filters( 'emoji_svg_url', 'https://s.w.org/images/core/emoji/2/svg/' ); + + $urls = array_values( array_diff( $urls, array( $emoji_svg_url ) ) ); + } + + return $urls; +} diff --git a/wp/10up-theme/includes/template-tags.php b/wp/10up-theme/includes/template-tags.php new file mode 100644 index 000000000..034f35402 --- /dev/null +++ b/wp/10up-theme/includes/template-tags.php @@ -0,0 +1,17 @@ +<?php +/** + * Custom template tags for this theme. + * + * This file is for custom template tags only and it should not contain + * functions that will be used for filtering or adding an action. + * + * All functions should be prefixed with TenUpTheme in order to prevent + * pollution of the global namespace and potential conflicts with functions + * from plugins. + * Example: `tenup_theme_function()` + * + * @package TenUpTheme\Template_Tags + * + */ + +// phpcs:ignoreFile diff --git a/wp/10up-theme/includes/utility.php b/wp/10up-theme/includes/utility.php new file mode 100755 index 000000000..2caf8e8eb --- /dev/null +++ b/wp/10up-theme/includes/utility.php @@ -0,0 +1,91 @@ +<?php +/** + * Utility functions for the theme. + * + * This file is for custom helper functions. + * These should not be confused with WordPress template + * tags. Template tags typically use prefixing, as opposed + * to Namespaces. + * + * @link https://developer.wordpress.org/themes/basics/template-tags/ + * @package TenUpTheme + */ + +namespace TenUpTheme\Utility; + +/** + * Get asset info from extracted asset files + * + * @param string $slug Asset slug as defined in build/webpack configuration + * @param string $attribute Optional attribute to get. Can be version or dependencies + * @return string|array + */ +function get_asset_info( $slug, $attribute = null ) { + if ( file_exists( TENUP_THEME_PATH . 'dist/js/' . $slug . '.asset.php' ) ) { + $asset = require TENUP_THEME_PATH . 'dist/js/' . $slug . '.asset.php'; + } elseif ( file_exists( TENUP_THEME_PATH . 'dist/css/' . $slug . '.asset.php' ) ) { + $asset = require TENUP_THEME_PATH . 'dist/css/' . $slug . '.asset.php'; + } else { + return null; + } + + if ( ! empty( $attribute ) && isset( $asset[ $attribute ] ) ) { + return $asset[ $attribute ]; + } + + return $asset; +} + +/** + * Extract colors from a CSS or Sass file + * + * @param string $path the path to your CSS variables file + */ +function get_colors( $path ) { + + $dir = get_stylesheet_directory(); + + if ( file_exists( $dir . $path ) ) { + $css_vars = file_get_contents( $dir . $path ); // phpcs:ignore WordPress.WP.AlternativeFunctions + // HEX(A) | RGB(A) | HSL(A) - rgba & hsla alpha as decimal or percentage + // https://regex101.com/r/l7AZ8R/ + // this is a loose match and will accept almost anything within () for rgb(a) & hsl(a) + // a more optinionated solution is WIP here if you can improve on it https://regex101.com/r/FEtzDu/ + preg_match_all( '(#(?:[\da-f]{3}){1}\b|#(?:[\da-f]{2}){3,4}\b|(rgb|hsl)a?\((\s|\d|[a-zA-Z]+|,|-|%|\.|\/)+\))', $css_vars, $matches ); + + return $matches[0]; + } + +} + +/** + * Adjust the brightness of a color (HEX) + * + * @param string $hex The hex code for the color + * @param number $steps amount you want to change the brightness + * @return string new color with brightness adjusted + */ +function adjust_brightness( $hex, $steps ) { + + // Steps should be between -255 and 255. Negative = darker, positive = lighter + $steps = max( -255, min( 255, $steps ) ); + + // Normalize into a six character long hex string + $hex = str_replace( '#', '', $hex ); + if ( 3 === strlen( $hex ) ) { + $hex = str_repeat( substr( $hex, 0, 1 ), 2 ) . str_repeat( substr( $hex, 1, 1 ), 2 ) . str_repeat( substr( $hex, 2, 1 ), 2 ); + } + + // Split into three parts: R, G and B + $color_parts = str_split( $hex, 2 ); + $return = '#'; + + foreach ( $color_parts as $color ) { + $color = hexdec( $color ); // Convert to decimal + $color = max( 0, min( 255, $color + $steps ) ); // Adjust color + $return .= str_pad( dechex( $color ), 2, '0', STR_PAD_LEFT ); // Make two char hex code + } + + return $return; + +} diff --git a/wp/10up-theme/index.php b/wp/10up-theme/index.php new file mode 100755 index 000000000..d096e7454 --- /dev/null +++ b/wp/10up-theme/index.php @@ -0,0 +1,18 @@ +<?php +/** + * The main template file + * + * @package TenUpTheme + */ + +get_header(); ?> + + <?php if ( have_posts() ) : ?> + <?php while ( have_posts() ) : the_post(); ?> + <h2><?php the_title(); ?></h2> + <?php the_content(); ?> + <?php endwhile; ?> + <?php endif; ?> + +<?php +get_footer(); diff --git a/wp/10up-theme/languages/TenUpTheme.pot b/wp/10up-theme/languages/TenUpTheme.pot new file mode 100644 index 000000000..0cc386aa5 --- /dev/null +++ b/wp/10up-theme/languages/TenUpTheme.pot @@ -0,0 +1,15 @@ +msgid "" +msgstr "" +"Project-Id-Version: TenUpTheme\n" +"POT-Creation-Date: 2015-03-03T12:53:58.231Z\n" +"PO-Revision-Date: 2015-03-03T12:53:58.231Z\n" +"Last-Translator: 10up <info@10up.com>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;" +"_n_noop:1,2;_x:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2;_ex:1,2c;" +"esc_attr__;esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c\n" +"X-Poedit-Basepath: .\n" +"X-Poedit-SearchPath-0: ..\n" diff --git a/wp/10up-theme/package.json b/wp/10up-theme/package.json new file mode 100644 index 000000000..c16296d79 --- /dev/null +++ b/wp/10up-theme/package.json @@ -0,0 +1,35 @@ +{ + "name": "tenup-theme", + "version": "1.0.0", + "scripts": { + "start": "npm run watch", + "watch": "10up-toolkit watch --port=5000 --hot", + "build": "10up-toolkit build", + "format-js": "10up-toolkit format-js", + "lint-js": "10up-toolkit lint-js", + "lint-style": "10up-toolkit lint-style", + "clean-dist": "rm -rf ./dist", + "scaffold:block": "cd includes/blocks/ && wp-create-block --no-plugin --template ../../../../bin/create-block-template" + }, + "engines": { + "node": ">=18.0.0" + }, + "devDependencies": { + "10up-toolkit": "^6.0.0" + }, + "dependencies": { + "modern-normalize": "^2.0.0", + "@headstartwp/component-library": "*" + }, + "10up-toolkit": { + "useBlockAssets": true, + "entry": { + "admin": "./assets/js/admin/admin.js", + "editor-style-overrides": "./assets/js/admin/editor-style-overrides.js", + "frontend": "./assets/js/frontend/frontend.js", + "shared": "./assets/js/shared/shared.js", + "styleguide": "./assets/js/styleguide/styleguide.js", + "block-editor-script": "./includes/block-editor-script.js" + } + } +} diff --git a/wp/10up-theme/partials/.gitkeep b/wp/10up-theme/partials/.gitkeep new file mode 100755 index 000000000..c1df4390b --- /dev/null +++ b/wp/10up-theme/partials/.gitkeep @@ -0,0 +1 @@ +# Basically just want to ignore the directory contents diff --git a/wp/10up-theme/patterns/example-pattern.php b/wp/10up-theme/patterns/example-pattern.php new file mode 100644 index 000000000..bafcd167b --- /dev/null +++ b/wp/10up-theme/patterns/example-pattern.php @@ -0,0 +1,13 @@ +<?php +/** + * Title: Example Pattern + * Slug: tenup-theme/example + * Categories: 10up-theme + * + * @package TenUpTheme + */ + +?> +<!-- wp:heading --> +<h2>Example Pattern</h2> +<!-- /wp:heading --> diff --git a/wp/10up-theme/screenshot.png b/wp/10up-theme/screenshot.png new file mode 100644 index 000000000..3318d911d Binary files /dev/null and b/wp/10up-theme/screenshot.png differ diff --git a/wp/10up-theme/search.php b/wp/10up-theme/search.php new file mode 100644 index 000000000..725ecb69d --- /dev/null +++ b/wp/10up-theme/search.php @@ -0,0 +1,46 @@ +<?php +/** + * The template for displaying search results pages. + * + * @package TenUpTheme + */ + +get_header(); ?> + + <section itemscope itemtype="https://schema.org/SearchResultsPage"> + <?php if ( have_posts() ) : ?> + <h1> + <?php + /* translators: the search query */ + printf( esc_html__( 'Search Results for: %s', 'tenup-theme' ), '<span>' . esc_html( get_search_query() ) . '</span>' ); + ?> + </h1> + + <ul> + <?php + while ( have_posts() ) : + the_post(); + ?> + + <li itemscope itemtype="https://schema.org/Thing"> + <?php + if ( has_post_thumbnail() ) { + the_post_thumbnail(); + } + + the_title( '<span itemprop="name"><a href="' . esc_url( get_permalink() ) . '" itemprop="url">', '</a></span>' ); + ?> + <div itemprop="description"> + <?php the_excerpt(); ?> + </div> + </li> + + <?php endwhile; ?> + </ul> + + <?php the_posts_navigation(); ?> + <?php endif; ?> + </section> + +<?php +get_footer(); diff --git a/wp/10up-theme/searchform.php b/wp/10up-theme/searchform.php new file mode 100644 index 000000000..8b55ffe0f --- /dev/null +++ b/wp/10up-theme/searchform.php @@ -0,0 +1,19 @@ +<?php +/** + * The template for displaying the search form. + * + * @package TenUpTheme + */ + +?> + +<div itemscope itemtype="http://schema.org/WebSite"> + <form role="search" id="searchform" class="search-form" method="get" action="<?php echo esc_url( home_url( '/' ) ); ?>"> + <meta itemprop="target" content="<?php echo esc_url( home_url() ); ?>/?s={s}" /> + <label for="search-field"> + <?php echo esc_html_x( 'Search for:', 'label', 'tenup-theme' ); ?> + </label> + <input itemprop="query-input" type="search" id="search-field" value="<?php echo get_search_query(); ?>" placeholder="<?php echo esc_attr_x( 'Search …', 'placeholder', 'tenup-theme' ); ?>" name="s" /> + <input type="submit" value="<?php echo esc_attr_x( 'Submit', 'submit button', 'tenup-theme' ); ?>"> + </form> +</div> diff --git a/wp/10up-theme/style.css b/wp/10up-theme/style.css new file mode 100755 index 000000000..9cf09868b --- /dev/null +++ b/wp/10up-theme/style.css @@ -0,0 +1,10 @@ +/** + * Theme Name: 10up Theme + * Theme URI: https://10up.com + * Description: Project description. + * Author: 10up + * Author URI: https://10up.com + * Version: 0.1.0 + * Tags: + * Text Domain: tenup-theme + */ diff --git a/wp/10up-theme/templates/page-styleguide.php b/wp/10up-theme/templates/page-styleguide.php new file mode 100644 index 000000000..a33b4215d --- /dev/null +++ b/wp/10up-theme/templates/page-styleguide.php @@ -0,0 +1,265 @@ +<?php +/** + * Template Name: Style Guide + * + * @package TenUpTheme + */ + +namespace TenUpTheme\Utility; + +use function TenUpTheme\Utility\adjust_brightness; +use function TenUpTheme\Utility\get_colors; + +get_header(); +?> + +<div class="uikit__container"> + + <h1 class="uikit__heading"> + <div class="uikit__block"> + <span><?php echo esc_html( get_the_title() ); ?></span> + </div> + </h1> + + <div class="uikit__content"> + + <?php + $colors = get_colors( '/assets/css/frontend/global/colors.css' ); + + if ( ! empty( $colors ) ) : + ?> + <section class="uikit__section" id="colors"> + <h2 class="heading">Primary Palette</h2> + + <div class="content"> + <ul class="uikit__colors"> + + <?php foreach ( $colors as $color ) : ?> + + <li class="uikit__color" style="background: <?php echo esc_attr( $color ); ?>; border-color: <?php echo esc_attr( adjust_brightness( $color, -25 ) ); ?>"> + <p class="uikit__color--label uikit__text--small"><?php echo esc_html( $color ); ?></p> + </li> + + <?php endforeach; ?> + + </ul> + </div><!--/.content--> + + </section><!--/.uikit__section--> + <?php endif; ?> + + <section class="uikit__section" id="headings"> + <h2 class="heading">Headings</h2> + + <div class="content"> + <h1>H1, Heading 1 {64px}</h1> + <h2>H2, Heading 2 {48px}</h2> + <h3>H3, Heading 3 {38px}</h3> + <h4>H4, Heading 4 {30px}</h4> + <h5>H5, Heading 5 {26px}</h5> + </div><!--/.content--> + + </section><!--/.uikit__section--> + + <section class="uikit__section" id="body"> + <h2 class="heading">Body</h2> + + <div class="content"> + <p> + 22pt, Acta Book, line 36 ( 1.5rem ). Lorem ipsum dolor sit amet, + consectetur adipiscing elit. Multa sunt dicta ab antiquis de contemnendis + ac despiciendis rebus humanis; Hoc mihi cum tuo fratre convenit. Fortasse + id optimum, sed ubi illud: Plus semper voluptatis? Haec quo modo conveniant, + non sane intellego. Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Multa sunt dicta ab antiquis de contemnendis ac despiciendis rebus + humanis; Hoc mihi cum tuo fratre convenit. Fortasse id optimum, sed ubi + illud: Plus semper voluptatis? Haec quo modo conveniant, non sane intellego. + </p> + + <p> + This is an <a href="#!">inline link text</a> example and hover link example. + </p> + </div><!--/.content--> + + </section><!--/.uikit__section--> + + <section class="uikit__section" id="buttons"> + <h2 class="heading">Buttons</h2> + + <div class="content"> + <button type="button" class="button-primary">Button</button> + <button type="button" class="button-secondary">Button</button> + <button type="button" class="button-tertiary">Button</button> + </div><!--/.content--> + + </section><!--/.uikit__section--> + + <section class="uikit__section" id="inputs"> + <h2 class="heading">Inputs</h2> + + <div class="content"> + + <div class="uikit-mb-1"> + <label for="w1">Text Input</label> + <input type="text" id="w1" name="" placeholder="Input placeholder text" /> + </div> + + <div class="uikit-mb-1"> + <label for="pwd">Password Input</label> + <input type="password" id="pwd" name="" placeholder="password placeholder text" /> + </div> + + <div class="uikit-mb-1"> + <label for="email">Email Input</label> + <input type="email" id="email" name="" placeholder="you@example.com" /> + </div> + + <div class="uikit-mb-1"> + <label for="w2">Label</label> + <textarea id="w2" cols="10" rows="10"></textarea> + </div> + + <div class="uikit-mb-1"> + <label for="volume">Range Input</label> + <input type="range" id="start" name="" min="0" max="11" /> + </div> + + <div class="uikit-mb-1"> + <label for="date">Date Input</label> + <input type="date" id="date" name="" value="" /> + </div> + + <div class="uikit-mb-1"> + <label for="num">Number Input</label> + <input type="number" id="num" name="" value="" /> + </div> + + <div class="uikit-mb-1"> + <label for="w3">Label</label> + <select id="w3"> + <option disabled selected>Select an Option</option> + <option value="1">Option 1</option> + <option value="2">Option 2</option> + <option value="3">Option 3</option> + <option value="4">Option 4</option> + <option value="5">Option 5</option> + </select> + </div> + + <div class="uikit-mb-1"> + <fieldset> + <legend>Checkbox Field Grouping</legend> + <div> + <input type="checkbox" id="w4-1"> + <label for="w4-1">Label</label> + </div> + <div> + <input type="checkbox" id="w4-2"> + <label for="w4-2">Label</label> + </div> + <div> + <input type="checkbox" id="w4-3"> + <label for="w4-3">Label</label> + </div> + </fieldset> + </div> + + <div class="uikit-mb-1"> + <fieldset> + <legend>Radio Button Field Grouping</legend> + <div> + <input type="radio" id="w5" name="group"> + <label for="w5">Label</label> + </div> + <div> + <input type="radio" id="w6" name="group"> + <label for="w6">Label</label> + </div> + <div> + <input type="radio" id="w7" name="group"> + <label for="w7">Label</label> + </div> + </fieldset> + </div> + + </div><!--/.content--> + + </section><!--/.uikit__section--> + + <section class="uikit__section" id="lists"> + <h2 class="heading">Lists</h2> + + <div class="content"> + <ul> + <li>Morbi natoque habitasse</li> + <li>Magnis ullamcorper risus taciti + <ul> + <li>Justo metus turpis habitant nisl</li> + <li>Platea primis semper</li> + </ul> + </li> + <li>Nibh id natoque elementum</li> + </ul> + + <ol> + <li>Morbi natoque habitasse</li> + <li>Magnis ullamcorper risus taciti + <ol> + <li>Justo metus turpis habitant nisl</li> + <li>Platea primis semper</li> + </ol> + </li> + <li>Nibh id natoque elementum</li> + </ol> + </div><!--/.content--> + </section><!--/.uikit__section--> + + <section class="uikit__section" id="tables"> + <h2 class="heading">Tables</h2> + + <div class="content"> + <table> + <caption>Egestas duis tincidunt cum</caption> + <thead> + <tr> + <td scope="col">ID</td> + <th scope="col">Item</th> + <th scope="col">Purchase Date</th> + <th scope="col">Price</th> + </tr> + </thead> + <tfoot> + <tr> + <th scope="row" colspan="3">Sum</th> + <td>$15.55</td> + </tr> + </tfoot> + <tbody> + <tr> + <th scope="row">1</th> + <td>Stick of gum</td> + <td>02/13/15</td> + <td>$0.19</td> + </tr> + <tr> + <th scope="row">2</th> + <td>Toothbrush</td> + <td>11/03/14</td> + <td>$2.37</td> + </tr> + <tr> + <th scope="row">3</th> + <td>Umbrella</td> + <td>05/12/17</td> + <td>$12.99</td> + </tr> + </tbody> + </table> + </div><!--/.content--> + </section><!--/.uikit__section--> + + </div><!--/.uikit__content--> + +</div><!--/.uikit__container--> + +<?php get_footer(); ?> diff --git a/wp/10up-theme/theme.json b/wp/10up-theme/theme.json new file mode 100644 index 000000000..9657fa95d --- /dev/null +++ b/wp/10up-theme/theme.json @@ -0,0 +1,55 @@ +{ + "$schema": "https://schemas.wp.org/wp/6.2/theme.json", + "version": 2, + "settings": { + "color": { + "defaultPalette": false, + "defaultGradients": false, + "defaultDuotone": false, + "custom": false, + "customDuotone": false, + "customGradient": false, + "duotone": [], + "gradients": [], + "link": false, + "palette": [] + }, + "custom": {}, + "layout": { + "contentSize": "800px", + "wideSize": "1000px" + }, + "spacing": { + "margin": false, + "padding": false, + "units": [] + }, + "typography": { + "customFontSize": false, + "lineHeight": false, + "dropCap": false, + "fontSizes": [] + }, + "blocks": { + "core/button": { + "color": { + "palette": [] + } + } + } + }, + "styles": { + "color": {}, + "elements": { + "h1": {}, + "h2": {}, + "h3": {}, + "h4": {}, + "h5": {}, + "h6": {}, + "link": {} + }, + "typography": {}, + "blocks": {} + } +} diff --git a/wp/10up-theme/webpack.config.js b/wp/10up-theme/webpack.config.js new file mode 100644 index 000000000..50f12b083 --- /dev/null +++ b/wp/10up-theme/webpack.config.js @@ -0,0 +1,7 @@ +const config = require('10up-toolkit/config/webpack.config'); + +config.resolve = { + conditionNames: ['block-editor'], +}; + +module.exports = config; diff --git a/wp/headless-wp/.wp-env.json b/wp/headless-wp/.wp-env.json index 13524fa13..31b41d71a 100644 --- a/wp/headless-wp/.wp-env.json +++ b/wp/headless-wp/.wp-env.json @@ -5,15 +5,16 @@ "https://downloads.wordpress.org/plugin/wordpress-seo.22.1.zip", "https://downloads.wordpress.org/plugin/safe-redirect-manager.2.1.1.zip" ], + "themes": ["../10up-theme"], "env": { "tests": { - "plugins": [ - ".", - "../local-plugin", - "https://downloads.wordpress.org/plugin/wordpress-seo.22.1.zip", - "https://downloads.wordpress.org/plugin/safe-redirect-manager.2.1.1.zip", - "https://downloads.wordpress.org/plugin/polylang.3.5.4.zip" - ] + "plugins": [ + ".", + "../local-plugin", + "https://downloads.wordpress.org/plugin/wordpress-seo.22.1.zip", + "https://downloads.wordpress.org/plugin/safe-redirect-manager.2.1.1.zip", + "https://downloads.wordpress.org/plugin/polylang.3.5.4.zip" + ] } -} + } }