esc_url_raw( rest_url( REST_Controller::REST_NAMESPACE . '/grid' ) ), // The route only returns published content, the nonce is sent so // that logged in visitors keep their own REST context. 'nonce' => is_user_logged_in() ? wp_create_nonce( 'wp_rest' ) : '', 'i18n' => array( 'loading' => __( 'Loading', 'mm-post-grid' ), /* translators: %d: Number of posts that were added to the grid. */ 'added' => __( 'Posts added: %d', 'mm-post-grid' ), 'done' => __( 'All posts are loaded.', 'mm-post-grid' ), 'error' => __( 'The posts could not be loaded. Please try again.', 'mm-post-grid' ), ), ) ); } /** * Enqueues the grid stylesheet and the settings driven custom properties. * * @since 0.1 * @return void */ public static function enqueue() { if ( self::$enqueued ) { return; } self::$enqueued = true; if ( Settings::get( 'disable_css' ) ) { return; } self::register_handles(); wp_enqueue_style( self::STYLE ); $css = self::inline_css(); // The values are sanitized when built, but mmpg_inline_css may return // anything. Stripping tags means a filter can never close the style // element and inject markup. $css = wp_strip_all_tags( $css ); if ( '' !== $css ) { wp_add_inline_style( self::STYLE, $css ); } } /** * Enqueues the load more script. * * @since 0.1 * @return void */ public static function enqueue_load_more() { self::register_handles(); wp_enqueue_script( self::SCRIPT ); } /** * Whether the shortcode is present in the content of the requested post. * * @since 0.1 * @return bool */ private static function content_has_shortcode() { if ( ! is_singular() ) { return false; } $post = get_queried_object(); if ( ! $post instanceof \WP_Post ) { return false; } return has_shortcode( (string) $post->post_content, Plugin::SHORTCODE ); } /** * Maps settings to the CSS custom properties they drive. * * Each entry holds the property name, a unit suffix, an optional divisor * (percent settings such as line height are stored as integers), and the * value to print when an optional colour is left empty. An empty value * without a replacement prints nothing, so the stylesheet default applies. * * @since 0.1 * @return array> */ public static function properties() { return array( 'columns' => array( 'var' => '--mmpg-columns' ), 'columns_tablet' => array( 'var' => '--mmpg-columns-tablet' ), 'columns_mobile' => array( 'var' => '--mmpg-columns-mobile' ), 'gap' => array( 'var' => '--mmpg-gap', 'unit' => 'px', ), 'card_bg' => array( 'var' => '--mmpg-card-bg', 'empty' => 'transparent', ), 'card_border_color' => array( 'var' => '--mmpg-card-border-color' ), 'card_border_width' => array( 'var' => '--mmpg-card-border-width', 'unit' => 'px', ), 'card_border_hover' => array( 'var' => '--mmpg-card-border-hover' ), 'card_radius' => array( 'var' => '--mmpg-card-radius', 'unit' => 'px', ), 'card_padding' => array( 'var' => '--mmpg-card-padding', 'unit' => 'px', ), 'content_gap' => array( 'var' => '--mmpg-content-gap', 'unit' => 'px', ), 'image_radius' => array( 'var' => '--mmpg-image-radius', 'unit' => 'px', ), 'media_width' => array( 'var' => '--mmpg-media-width', 'unit' => '%', ), 'overlay_opacity' => array( 'var' => '--mmpg-overlay-opacity', 'divide' => 100, ), 'title_color' => array( 'var' => '--mmpg-title-color' ), 'title_hover_color' => array( 'var' => '--mmpg-title-hover-color' ), 'title_size' => array( 'var' => '--mmpg-title-size', 'unit' => 'px', ), 'title_weight' => array( 'var' => '--mmpg-title-weight' ), 'title_line_height' => array( 'var' => '--mmpg-title-line-height', 'divide' => 100, ), 'title_lines' => array( 'var' => '--mmpg-title-lines' ), 'meta_color' => array( 'var' => '--mmpg-meta-color' ), 'meta_size' => array( 'var' => '--mmpg-meta-size', 'unit' => 'px', ), 'excerpt_color' => array( 'var' => '--mmpg-excerpt-color' ), 'excerpt_size' => array( 'var' => '--mmpg-excerpt-size', 'unit' => 'px', ), 'excerpt_line_height' => array( 'var' => '--mmpg-excerpt-line-height', 'divide' => 100, ), 'excerpt_lines' => array( 'var' => '--mmpg-excerpt-lines' ), 'term_color' => array( 'var' => '--mmpg-term-color' ), 'accent_color' => array( 'var' => '--mmpg-accent-color' ), 'button_bg' => array( 'var' => '--mmpg-button-bg' ), 'button_bg_hover' => array( 'var' => '--mmpg-button-bg-hover' ), 'button_color' => array( 'var' => '--mmpg-button-color' ), 'button_radius' => array( 'var' => '--mmpg-button-radius', 'unit' => 'px', ), ); } /** * Builds the custom property declarations for one setting. * * Returns an empty array when the setting has no property, or when an * optional colour is empty and the stylesheet default should apply. * Presets that expand into several properties are handled here too. * * @since 0.1 * * @param string $key Setting key. * @param mixed $value Sanitized value. * @return string[] Declarations such as "--mmpg-gap:28px". */ public static function declarations( $key, $value ) { if ( 'card_shadow' === $key ) { $shadow = Helpers::shadow( (string) $value ); return array( '--mmpg-card-shadow:' . Helpers::css_value( $shadow['shadow'] ), '--mmpg-card-shadow-hover:' . Helpers::css_value( $shadow['hover'] ), ); } if ( 'image_ratio' === $key ) { return array( '--mmpg-image-ratio:' . Helpers::css_value( Helpers::ratio( (string) $value ) ) ); } $properties = self::properties(); if ( ! isset( $properties[ $key ] ) ) { return array(); } $property = $properties[ $key ]; $value = (string) $value; if ( '' === $value ) { if ( ! isset( $property['empty'] ) ) { return array(); } $value = $property['empty']; } elseif ( isset( $property['divide'] ) ) { $value = (string) round( (float) $value / (float) $property['divide'], 2 ); } elseif ( isset( $property['unit'] ) ) { $value .= $property['unit']; } $value = Helpers::css_value( $value ); return '' === $value ? array() : array( $property['var'] . ':' . $value ); } /** * Builds the inline custom properties for the saved settings. * * Only settings that differ from the shipped defaults are printed, since * the stylesheet already holds every default value. * * @since 0.1 * @return string */ private static function inline_css() { $settings = Settings::all(); $defaults = Settings::defaults(); $keys = array_merge( array_keys( self::properties() ), array( 'card_shadow', 'image_ratio' ) ); $declarations = array(); foreach ( $keys as $key ) { if ( ! array_key_exists( $key, $settings ) || ! array_key_exists( $key, $defaults ) ) { continue; } if ( (string) $defaults[ $key ] === (string) $settings[ $key ] ) { continue; } $declarations = array_merge( $declarations, self::declarations( $key, $settings[ $key ] ) ); } $css = empty( $declarations ) ? '' : '.mmpg{' . implode( ';', $declarations ) . '}'; /** * Filters the inline custom properties printed after the stylesheet. * * @since 0.1 * * @param string $css Inline CSS. * @param array $settings Current settings. */ return (string) apply_filters( 'mmpg_inline_css', $css, $settings ); } }