esc_html__( 'No Label Selected', 'analytica' ), 'img' => $framework->theme_url . '/assets/admin/images/layouts/none.gif', 'type' => 'site', ]; $args = wp_parse_args( $args, $defaults ); $_analytica_layouts[ $id ] = $args; return $args; } /** * Set a default layout. * * Allow a user to identify a layout as being the default layout on a new install, as well as serve as the fallback layout. * * @since 1.0.0 * * @global array $_analytica_layouts Holds all layouts data. * * @param string $id ID of layout to set as default. * * @return bool|string Return false if ID is empty or layout is not registered. Return ID otherwise. */ function analytica_set_default_layout( $id = '' ) { global $_analytica_layouts; if ( ! is_array( $_analytica_layouts ) ) { $_analytica_layouts = []; } // Don't allow empty $id, or unregistered layouts if ( ! $id || ! isset( $_analytica_layouts[ $id ] ) ) { return false; } // Remove default flag for all other layouts foreach ( (array) $_analytica_layouts as $key ) { if ( isset( $_analytica_layouts[ $key ]['default'] ) ) { unset( $_analytica_layouts[ $key ]['default'] ); } } $_analytica_layouts[ $id ]['default'] = true; return $id; } /** * Unregister a layout in. * * Modifies the global $_analytica_layouts variable. * * @since 1.0.0 * * @global array $_analytica_layouts Holds all layout data. * * @param string $id ID of the layout to unregister. * * @return bool Returns false if ID is empty, or layout is not registered. */ function analytica_unregister_layout( $id = '' ) { global $_analytica_layouts; if ( ! $id || ! isset( $_analytica_layouts[ $id ] ) ) { return false; } unset( $_analytica_layouts[ $id ] ); return true; } /** * Output markup conditionally. * * Supported keys for `$args` are: * * - `element` (`sprintf()` pattern markup), * - `context` (name of context), * - `echo` (default is true). * * This function will output the `element` value, with a call to `analytica_attr()` * with the same context added in. * * Applies a `analytica_markup_{context}` filter early to allow shortcutting the function. * * Applies a `analytica_markup_{context}_output` filter at the end. * * @since 1.0.0 * * @uses analytica_attr() Contextual attributes. * * @param array $args Array of arguments. * * @return string Markup. */ function analytica_markup( $args = [] ) { $defaults = [ 'element' => '', 'context' => '', 'echo' => true, ]; $args = wp_parse_args( $args, $defaults ); if ( ! $args['element'] ) { return ''; } $tag = $args['context'] ? sprintf( $args['element'], analytica_attr( $args['context'] ) ) : $args['element']; // Contextual filter $tag = $args['context'] ? apply_filters( "analytica_markup_{$args['context']}_output", $tag, $args ) : $tag; if ( $args['echo'] ) { echo $tag; // WPCS: XSS ok. } else { return $tag; } } /** * Potentially echo or return a structural wrap div. * * A check is made to see if the `$context` is in the `analytica-structural-wraps` theme support data. If so, then the * `$output` may be echoed or returned. * * @since 1.0.0 * * @param string $context The location ID. * @param string $output Optional. The markup to include. Can also be 'open' * (default) or 'closed' to use pre-determined markup for consistency. * @param bool $echo Optional. Whether to echo or return. Default is true (echo). * * @return string Wrap HTML. */ function analytica_structural_wrap( $context = '', $output = 'open', $echo = true ) { $wraps = get_theme_support( 'analytica-structural-wraps' ); // If theme doesn't support structural wraps, bail. if ( ! $wraps ) { return; } if ( ! in_array( $context, (array) $wraps[0] ) ) { return ''; } // Save original output param $original_output = $output; switch ( $output ) { case 'open': $output = sprintf( '
', analytica_attr( 'structural-wrap' ) ); break; case 'close': $output = '
'; break; } $output = apply_filters( "analytica_structural_wrap-{$context}", $output, $original_output ); if ( $echo ) { echo analytica_sanitize_html( $output ); // WPCS: XSS ok. } else { return $output; } } /** * Merge array of attributes with defaults, and apply contextual filter on array. * * The contextual filter is of the form `analytica_attr_{context}`. * * @since 1.0.0 * * @param string $context The context, to build filter name. * @param array $attributes Optional. Extra attributes to merge with defaults. * * @return array Merged and filtered attributes. */ function analytica_parse_attr( $context, $attributes = [] ) { $defaults = [ 'class' => sanitize_html_class( $context ), ]; $attributes = wp_parse_args( $attributes, $defaults ); // Contextual filter return apply_filters( "analytica_attr_{$context}", $attributes, $context ); } /** * Build list of attributes into a string and apply contextual filter on string. * * The contextual filter is of the form `analytica_attr_{context}_output`. * * @since 1.0.0 * * @uses analytica_parse_attr() Merge array of attributes with defaults, and apply contextual filter on array. * * @param string $context The context, to build filter name. * @param array $attributes Optional. Extra attributes to merge with defaults. * * @return string String of HTML attributes and values. */ function analytica_attr( $context, $attributes = [] ) { $attributes = analytica_parse_attr( $context, $attributes ); $output = ''; // Cycle through attributes, build tag attribute string foreach ( $attributes as $key => $value ) { if ( !$value ) { continue; } $output .= sprintf( '%s="%s" ', esc_html( $key ), esc_attr( $value ) ); } $output = apply_filters( 'analytica_attr_' . $context . '_output', $output, $attributes, $context ); return trim( $output ); } add_filter( 'analytica_attr_body', 'analytica_attributes_body' ); /** * Add attributes for body element. * * @since 1.0.0 * * @param array $attributes Existing attributes. * * @return array Amended attributes. */ function analytica_attributes_body( $attributes ) { $attributes['class'] = implode( ' ', get_body_class() ); $attributes['itemscope'] = 'itemscope'; $attributes['itemtype'] = 'https://schema.org/WebPage'; // Search results pages if ( is_search() ) { $attributes['itemtype'] = 'https://schema.org/SearchResultsPage'; } if ( is_singular( 'post' ) || is_archive() || is_home() || is_page_template( 'blog.php' ) ) { $attributes['itemtype'] = 'https://schema.org/Blog'; } $attributes['itemscope'] = 'itemscope'; return $attributes; } add_filter( 'analytica_attr_nav-primary', 'analytica_attributes_nav' ); add_filter( 'analytica_attr_nav-secondary', 'analytica_attributes_nav' ); add_filter( 'analytica_attr_nav-header', 'analytica_attributes_nav' ); /** * Add typical attributes for navigation elements. * * Used for primary navigation, secondary navigation, and custom menu widgets in the header right widget area. * * @since 1.0.0 * * @param array $attributes Existing attributes. * * @return array Amended attributes. */ function analytica_attributes_nav( $attributes ) { $attributes['role'] = 'navigation'; $attributes['itemscope'] = 'itemscope'; $attributes['itemtype'] = 'https://schema.org/SiteNavigationElement'; return $attributes; } add_filter( 'analytica_attr_breadcrumb', 'analytica_attributes_breadcrumb' ); /** * Add attributes for breadcrumb wrapper. * * @since 1.0.0 * * @param array $attributes Existing attributes. * * @return array Ammended attributes */ function analytica_attributes_breadcrumb( $attributes ) { $attributes['itemprop'] = 'breadcrumb'; $attributes['itemscope'] = 'itemscope'; $attributes['itemtype'] = 'https://schema.org/BreadcrumbList'; return $attributes; } add_filter( 'analytica_attr_structural-wrap', 'analytica_attributes_structural_wrap' ); /** * Add attributes for structural wrap element. * * @since 1.0.0 * * @param array $attributes Existing attributes. * * @return array Amended attributes. */ function analytica_attributes_structural_wrap( $attributes ) { $attributes['class'] = 'analytica-container'; return $attributes; } add_filter( 'analytica_attr_site-inner', 'analytica_attributes_site_inner' ); /** * Add attributes for site inner element. * * @since 1.0.0 * * @param array $attributes Existing attributes. * * @return array Amended attributes. */ function analytica_attributes_site_inner( $attributes ) { $attributes['class'] = 'site-inner'; return $attributes; } add_filter( 'analytica_attr_sidebar-primary', 'analytica_attributes_sidebar_primary' ); /** * Add attributes for primary sidebar element. * * @since 1.0.0 * * @param array $attributes Existing attributes. * * @return array Amended attributes. */ function analytica_attributes_sidebar_primary( $attributes ) { $attributes['class'] = 'site-sidebar sidebar-primary widget-area'; $attributes['aria-label'] = esc_html__( 'Primary Sidebar', 'analytica' ); $attributes['itemscope'] = 'itemscope'; $attributes['itemtype'] = 'https://schema.org/WPSideBar'; return $attributes; } add_filter( 'analytica_attr_sidebar-secondary', 'analytica_attributes_sidebar_secondary' ); /** * Add attributes for secondary sidebar element. * * @since 1.0.0 * * @param array $attributes Existing attributes. * * @return array Amended attributes. */ function analytica_attributes_sidebar_secondary( $attributes ) { $attributes['class'] = 'site-sidebar sidebar-secondary widget-area'; $attributes['aria-label'] = esc_html__( 'Secondary Sidebar', 'analytica' ); $attributes['itemscope'] = 'itemscope'; $attributes['itemtype'] = 'https://schema.org/WPSideBar'; return $attributes; } add_filter( 'analytica_attr_site-footer', 'analytica_attributes_site_footer' ); /** * Add attributes for site footer wrapper element. * * @since 1.0.0 * * @param array $attributes Existing attributes. * * @return array Amended attributes. */ function analytica_attributes_site_footer( $attributes ) { if ( ! analytica_get_option( 'site-footer-width' ) ) { $attributes['class'] = 'site-footer has-container'; } else { $attributes['class'] = 'site-footer fullwidth'; } return $attributes; } add_filter( 'analytica_attr_site-footer-widgets', 'analytica_attributes_site_footer_widgets' ); /** * Add attributes for site footer element. * * @since 1.0.0 * * @param array $attributes Existing attributes. * * @return array Amended attributes. */ function analytica_attributes_site_footer_widgets( $attributes ) { if ( ! analytica_get_option( 'site-footer-width' ) ) { $attributes['class'] .= ' has-container'; } else { $attributes['class'] .= ' fullwidth'; } return $attributes; } add_filter( 'analytica_attr_site-colophon', 'analytica_attributes_site_colophon' ); /** * Add attributes for site footer element. * * @since 1.0.0 * * @param array $attributes Existing attributes. * * @return array Amended attributes. */ function analytica_attributes_site_colophon( $attributes ) { $attributes['itemscope'] = 'itemscope'; $attributes['itemtype'] = 'https://schema.org/WPFooter'; if ( 'layout-fullwidth' != analytica_get_option( 'footer-colophon-width' ) ) { $attributes['class'] = 'site-colophon has-container'; } else { $attributes['class'] = 'site-colophon fullwidth'; } return $attributes; }