Support » Theme: WP Bootstrap 4 » Stylesheet shows twice in child-theme

  • tradesouthwest

    (@tradesouthwestgmailcom)


    Have tried literally 10 different enqueues for a child theme and everyone of them shows two stylesheets for in the head –

    <link rel='stylesheet' id='wp-bootstrap-4-style-css'  href='mypath/wp-content/themes/wp-bootstrap-4-child/style.css?ver=1.0.2' type='text/css' media='all' />
    <link rel='stylesheet' id='js_composer_front-css'  href='mypath/wp-content/plugins/js_composer_theme/assets/css/js_composer.css?ver=4.5.3' type='text/css' media='all' />
    <link rel='stylesheet' id='wp-bootstrap-4-child_no-kirki-css'  href='mypath/wp-content/themes/wp-bootstrap-4-child/style.css' type='text/css' media='all' />
    <style id='wp-bootstrap-4-child_no-kirki-inline-css' type='text/css'>
    .custom-logo{height:60px;width:auto;}.nav........</style>
    <link rel='stylesheet' id='parent-style-css'  href='mypath/wp-content/themes/wp-bootstrap-4/style.css' type='text/css' media='all' />

    if you have a snippet, it would be highly appreciated. Github would be fine. I am hoping it is not due to Kirki not being installed. I really don’t want/need any customizer stuff.

    The page I need help with: [log in to see the link]

Viewing 14 replies - 1 through 14 (of 14 total)
  • tradesouthwest

    (@tradesouthwestgmailcom)

    Last try was

    
    add_action( 'wp_enqueue_scripts', 'schus_bootstrap_enqueue_child_theme_styles', 9999);
    function schus_bootstrap_enqueue_child_theme_styles() {
      wp_enqueue_style( 'wp-bootstrap-4-style', get_template_directory_uri().'/style.css', false, null );
    }
    Theme Author twopoints

    (@twopoints)

    Hello,

    Thank you for using our theme.

    It would be better if you could explain what exactly you are trying to achieve. I could not exactly understand the issue that you are facing.

    If you are facing some issue while creating the child theme, I would suggest using a plugin like https://wordpress.org/plugins/child-theme-configurator/ or https://wordpress.org/plugins/one-click-child-theme/.

    I have tested child theme created with https://wordpress.org/plugins/child-theme-configurator/ and it works perfect.

    Let me know if I am getting anything wrong.

    Regards.

    tradesouthwest

    (@tradesouthwestgmailcom)

    Template: wp-bootstrap-4
    in style of child and the above in functions. You got everything correct. I have set up hundreds of themes and this one is not letting me use similar function. I just was not sure if or why anyone would have to use a plugin to create a child theme. I know I never have but maybe there is something unique about the enqueues for this theme.

    Keep up the good work. This will be a classic theme once it gets rolling. If I can’t figure out why the stylesheet loads twice and also why the version of my child stylesheet does not change I will get back to you.

    note: there is no caching or conflicting plugins. Only have VisualComposer, that’s it. But the (no)_Kirki style is using the same name (appended) as my child them?????
    see: https://prnt.sc/ixcx70

    Theme Author twopoints

    (@twopoints)

    Hello,

    Looks like this issue is because of Kirki. If you install and activate Kirki, style.css does not load twice.

    I am looking into this. I’ll update it here once I get some solution.

    Regards.

    tradesouthwest

    (@tradesouthwestgmailcom)

    open-iconic-bootstrap’,’bootstrap-4 wanted to be enqueued according to chld_thm_cfg plugin. Yet now I still have two stylesheets pointing at the same file

    id=’wp-bootstrap-4-child_no-kirki-css’ href=’http://www.schusshoots.com/wp-content/themes/wp-bootstrap-4-child/style.css&#8217;
    and
    id=’wp-bootstrap-4-style-css’ href=’http://www.schusshoots.com/wp-content/themes/wp-bootstrap-4-child/style.css?ver=1.0.2&#8242;

    The biggest issue this creates is two of everything and is odd enough when you look at Inspector: https://prnt.sc/ixd2t6

    Also, I could be mistaken but I had to add screenreader text CSS to my styles.
    class="skip-link screen-reader-text"
    But it could just be from me moving the header down about 30% from the top of #page.site

    tradesouthwest

    (@tradesouthwestgmailcom)

    Ok, I was one thread ahead of you but I had a feeling it was Kirki. I never use Customizer if I can avoid it… although I like Kirki much better than native Customizer.

    tradesouthwest

    (@tradesouthwestgmailcom)

    Any luck yet… I tried to dequeue the wp-bootstrap-4-child_no-kirki-css with no luck.

    FYI: w3 Validator errors:
    At line 53, column 2444 400;line-height:;letter-spacing
    At line 53, column 2460;letter-spacing:;}h1,h2,h3,h4,
    At line 53, column 2696;letter-spacing:;}.container{m

    Also having some issues with footer (position-not sticking) on index/blog page but will troubleshoot later.

    Hey there! Kirki developer here.
    I haven’t checked this theme or its code, but it seems like it is using a fallback class when Kirki is not installed… Something like this: https://github.com/aristath/kirki/blob/develop/docs/files/class-my-theme-kirki.php

    If this is the case, then this issues looks like a duplicate of https://wordpress.org/support/topic/why-two-of-the-same-style-sheets-when-kirki-is-not-active/

    Perhaps that can help… a few changes are needed in the fallback class that loads the Kirki styles when Kirki is not installed – and that’s something that should be done on a per-use-case basis )which is why it hasn’t been done in the class inside the kirki docs by default. What kirki has by default is a simple implementation that should work is 99% of cases and is the safest option – but by no means is it optimized for each and every theme.

    tradesouthwest

    (@tradesouthwestgmailcom)

    I did install the Kirki and I still have the double stylesheets with the same rules showing in Inspector but the actual Kirki style sheet is blank—when clicking on the path from the page source. I even put one line of styles into the Customizer to see if it would show up in the Kirki file… no go.

    I can not see EVERYONE ( 99% ) of use cases being like mine. I would think it would be more like 50% would install wp-bootstrap-4 becuase they want Bootstrap 4 and NOT Kirki. In fact I had no idea that (if) Kirki was part of the theme I still would not have expected to use it. I rarely use the WP Customizer let alone MORE scripts to bog down poor wp engine.

    Hope someone can figure this one out. It is a bit involed when you have to delete two lines of attributes to make one set of rules work (Inspector).

    tradesouthwest

    (@tradesouthwestgmailcom)

    *correction/refinement about the mention of 99%…. I was mostly referring to the Theme and not Kirki. I understand the Kirki class is what it is and was not necassarily designed for every development use out there. Just wanted to be clear as I like the Kirki—mostly because it is an alternative to Customizer.

    I guess I’m old school. I like to have a full size editor for CSS and I can open a second window to refresh for changes. I don’t care for a lot of javascript, personally.

    • This reply was modified 1 year, 8 months ago by tradesouthwest. Reason: typo
    Theme Author twopoints

    (@twopoints)

    Hello,

    I just checked the other ticket which Aristeides Stathopoulos has referred to in above comment.

    I’m not sure about the total impact of this change on the theme. I’ll try this change in a test setup and let you know if everything works fine.

    If it works perfect, I’ll let you know how you can implement it in your child theme.

    Thanks.

    Theme Author twopoints

    (@twopoints)

    Hello,

    I just tested changes on my test site. Looks like things are working with 2 changes.

    You’ll have to do following 2 changes to make this work:
    1. Update the parent theme to new version 1.0.7. I have uploaded the version just now. It should be live within few minutes. I have added the conditional wrapper to the fallback class in this update.

    2. In your child theme’s function.php, you will have to overwrite the class. Just add following code in your child theme’s function.php file:

    if ( ! class_exists ( 'WP_Bootstrap_4_Kirki' )) :
        class WP_Bootstrap_4_Kirki {
        	/**
        	 * The config ID.
        	 *
        	 * @static
        	 * @access protected
        	 * @var array
        	 */
        	protected static $config = array();
        	/**
        	 * An array of all our fields.
        	 *
        	 * @static
        	 * @access protected
        	 * @var array
        	 */
        	protected static $fields = array();
        	/**
        	 * The class constructor
        	 */
        	public function __construct() {
        		// If Kirki exists then there's no reason to proceed.
        		if ( class_exists( 'Kirki' ) ) {
        			return;
        		}
        		// Add our CSS.
        		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_styles' ), 20 );
        		// Add google fonts.
        		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_fonts' ) );
        	}
        	/**
        	 * Get the value of an option from the db.
        	 *
        	 * @param string $config_id The ID of the configuration corresponding to this field.
        	 * @param string $field_id  The field_id (defined as 'settings' in the field arguments).
        	 * @return mixed            The saved value of the field.
        	 */
        	public static function get_option( $config_id = '', $field_id = '' ) {
        		// if Kirki exists, use it.
        		if ( class_exists( 'Kirki' ) ) {
        			return Kirki::get_option( $config_id, $field_id );
        		}
        		// Kirki does not exist, continue with our custom implementation.
        		// Get the default value of the field.
        		$default = '';
        		if ( isset( self::$fields[ $field_id ] ) && isset( self::$fields[ $field_id ]['default'] ) ) {
        			$default = self::$fields[ $field_id ]['default'];
        		}
        		// Make sure the config is defined.
        		if ( isset( self::$config[ $config_id ] ) ) {
        			if ( 'option' == self::$config[ $config_id ]['option_type'] ) {
        				// check if we're using serialized options.
        				if ( isset( self::$config[ $config_id ]['option_name'] ) && ! empty( self::$config[ $config_id ]['option_name'] ) ) {
        					// Get all our options.
        					$all_options = get_option( self::$config[ $config_id ]['option_name'], array() );
        					// If our option is not saved, return the default value.
        					// If option was set, return its value unserialized.
        					return ( ! isset( $all_options[ $field_id ] ) ) ? $default : maybe_unserialize( $all_options[ $field_id ] );
        				}
        				// If we're not using serialized options, get the value and return it.
        				// We'll be using a dummy default here to check if the option has been set or not.
        				// We'll be using md5 to make sure it's randomish and impossible to be actually set by a user.
        				$dummy = md5( $config_id . '_UNDEFINED_VALUE' );
        				$value = get_option( $field_id, $dummy );
        				// setting has not been set, return default.
        				return ( $dummy === $value ) ? $default : $value;
        			}
        			// We're not using options so fallback to theme_mod.
        			return get_theme_mod( $field_id, $default );
        		}
        	}
        	/**
        	 * Create a new panel.
        	 *
        	 * @param string $id   The ID for this panel.
        	 * @param array  $args The panel arguments.
        	 */
        	public static function add_panel( $id = '', $args = array() ) {
        		if ( class_exists( 'Kirki' ) ) {
        			Kirki::add_panel( $id, $args );
        		}
        		/* If Kirki does not exist then there's no reason to add any panels. */
        	}
        	/**
        	 * Create a new section.
        	 *
        	 * @param string $id   The ID for this section.
        	 * @param array  $args The section arguments.
        	 */
        	public static function add_section( $id, $args ) {
        		if ( class_exists( 'Kirki' ) ) {
        			Kirki::add_section( $id, $args );
        		}
        		/* If Kirki does not exist then there's no reason to add any sections. */
        	}
        	/**
        	 * Sets the configuration options.
        	 *
        	 * @param string $config_id The configuration ID.
        	 * @param array  $args      The configuration arguments.
        	 */
        	public static function add_config( $config_id, $args = array() ) {
        		// if Kirki exists, use it.
        		if ( class_exists( 'Kirki' ) ) {
        			Kirki::add_config( $config_id, $args );
        			return;
        		}
        		// Kirki does not exist, set the config arguments.
        		self::$config[ $config_id ] = $args;
        		// Make sure an option_type is defined.
        		if ( ! isset( self::$config[ $config_id ]['option_type'] ) ) {
        			self::$config[ $config_id ]['option_type'] = 'theme_mod';
        		}
        	}
        	/**
        	 * Create a new field
        	 *
        	 * @param string $config_id The configuration ID.
        	 * @param array  $args      The field's arguments.
        	 * @return null
        	 */
        	public static function add_field( $config_id, $args ) {
        		// if Kirki exists, use it.
        		if ( class_exists( 'Kirki' ) ) {
        			Kirki::add_field( $config_id, $args );
        			return;
        		}
        		// Kirki was not located, so we'll need to add our fields here.
        		// Check that the "settings" & "type" arguments have been defined.
        		if ( isset( $args['settings'] ) && isset( $args['type'] ) ) {
        			// Make sure we add the config_id to the field itself.
        			// This will make it easier to get the value when generating the CSS later.
        			if ( ! isset( $args['kirki_config'] ) ) {
        				$args['kirki_config'] = $config_id;
        			}
        			self::$fields[ $args['settings'] ] = $args;
        		}
        	}
        	/**
        	 * Enqueues the stylesheet.
        	 *
        	 * @access public
        	 * @return null
        	 */
        	public function enqueue_styles() {
        		// If Kirki exists there's no need to proceed any further.
        		if ( class_exists( 'Kirki' ) ) {
        			return;
        		}
        		// Get our inline styles.
        		$styles = $this->get_styles();
        		// If we have some styles to add, add them now.
        		if ( ! empty( $styles ) ) {
        			// Enqueue the theme's style.css file.
        			wp_add_inline_style( 'THEME_STYLESHEET_HANDLE', $styles );
        		}
        	}
        	/**
        	 * Gets all our styles and returns them as a string.
        	 *
        	 * @access public
        	 * @return string
        	 */
        	public function get_styles() {
        		// Get an array of all our fields.
        		$fields = self::$fields;
        		// Check if we need to exit early.
        		if ( empty( self::$fields ) || ! is_array( $fields ) ) {
        			return;
        		}
        		// Initially we're going to format our styles as an array.
        		// This is going to make processing them a lot easier
        		// and make sure there are no duplicate styles etc.
        		$css = array();
        		// Start parsing our fields.
        		foreach ( $fields as $field ) {
        			// No need to process fields without an output, or an improperly-formatted output.
        			if ( ! isset( $field['output'] ) || empty( $field['output'] ) || ! is_array( $field['output'] ) ) {
        				continue;
        			}
        			// Get the value of this field.
        			$value = self::get_option( $field['kirki_config'], $field['settings'] );
        			// Start parsing the output arguments of the field.
        			foreach ( $field['output'] as $output ) {
        				$output = wp_parse_args( $output, array(
        					'element'       => '',
        					'property'      => '',
        					'media_query'   => 'global',
        					'prefix'        => '',
        					'units'         => '',
        					'suffix'        => '',
        					'value_pattern' => '$',
        					'choice'        => '',
        				) );
        				// If element is an array, convert it to a string.
        				if ( is_array( $output['element'] ) ) {
        					$output['element'] = implode( ',', $output['element'] );
        				}
        				// Simple fields.
        				if ( ! is_array( $value ) ) {
        					$value = str_replace( '$', $value, $output['value_pattern'] );
        					if ( ! empty( $output['element'] ) && ! empty( $output['property'] ) ) {
        						$css[ $output['media_query'] ][ $output['element'] ][ $output['property'] ] = $output['prefix'] . $value . $output['units'] . $output['suffix'];
        					}
        				} else {
        					if ( 'typography' === $field['type'] ) {
        						foreach ( $value as $key => $subvalue ) {
        							// Add double quotes if needed to font-families.
        							if ( 'font-family' == $key && false !== strpos( $subvalue, ' ' ) && false === strpos( $subvalue, '"' ) ) {
        								$css[ $output['media_query'] ][ $output['element'] ]['font-family'] = '"' . $subvalue . '"';
        							}
        							// Variants contain both font-weight & italics.
        							if ( 'variant' === $key ) {
        								$font_weight = str_replace( 'italic', '', $subvalue );
        								$font_weight = ( in_array( $font_weight, array( '', 'regular' ) ) ) ? '400' : $font_weight;
        								$css[ $output['media_query'] ][ $output['element'] ]['font-weight'] = $font_weight;
        								// Is this italic?
        								if ( false !== strpos( $subvalue, 'italic' ) ) {
        									$css[ $output['media_query'] ][ $output['element'] ]['font-style'] = 'italic';
        								}
        							} else {
        								$css[ $output['media_query'] ][ $output['element'] ][ $key ] = $subvalue;
        							}
        						}
        					} elseif ( 'multicolor' == $field['type'] ) {
        						if ( ! empty( $output['element'] ) && ! empty( $output['property'] ) && ! empty( $output['choice'] ) ) {
        							$css[ $output['media_query'] ][ $output['element'] ][ $output['property'] ] = $output['prefix'] . $value[ $output['choice'] ] . $output['units'] . $output['suffix'];
        						}
        					} else {
        						foreach ( $value as $key => $subvalue ) {
        							$property = $key;
        							if ( false !== strpos( $output['property'], '%%' ) ) {
        								$property = str_replace( '%%', $key, $output['property'] );
        							} elseif ( ! empty( $output['property'] ) ) {
        								$output['property'] = $output['property'] . '-' . $key;
        							}
        							if ( 'background-image' === $output['property'] && false === strpos( $subvalue, 'url(' ) ) {
        								$subvalue = 'url("' . set_url_scheme( $subvalue ) . '")';
        							}
        							if ( $subvalue ) {
        								$css[ $output['media_query'] ][ $output['element'] ][ $property ] = $subvalue;
        							}
        						}
        					}
        				}
        			}
        		}
        		// Process the array of CSS properties and produce the final CSS.
        		$final_css = '';
        		if ( ! is_array( $css ) || empty( $css ) ) {
        			return '';
        		}
        		// Parse the generated CSS array and create the CSS string for the output.
        		foreach ( $css as $media_query => $styles ) {
        			// Handle the media queries.
        			$final_css .= ( 'global' != $media_query ) ? $media_query . '{' : '';
        			foreach ( $styles as $style => $style_array ) {
        				$final_css .= $style . '{';
        				foreach ( $style_array as $property => $value ) {
        					$value = ( is_string( $value ) ) ? $value : '';
        					// Make sure background-images are properly formatted.
        					if ( 'background-image' === $property ) {
        						if ( false === strrpos( $value, 'url(' ) ) {
        							$value = set_url_scheme( $value );
        							$value = 'url("' . esc_url_raw( $value ) . '")';
        						}
        					} else {
        						$value = esc_textarea( $value );
        					}
        					$final_css .= $property . ':' . $value . ';';
        				}
        				$final_css .= '}';
        			}
        			$final_css .= ( 'global' != $media_query ) ? '}' : '';
        		}
        		return $final_css;
        	}
        	/**
        	 * Enqueue google fonts.
        	 *
        	 * @access public
        	 * @return null
        	 */
        	public function enqueue_fonts() {
        		// Check if we need to exit early.
        		if ( empty( self::$fields ) || ! is_array( self::$fields ) ) {
        			return;
        		}
        		foreach ( self::$fields as $field ) {
        			// Process typography fields.
        			if ( isset( $field['type'] ) && 'typography' == $field['type'] ) {
        				// Check if we've got everything we need.
        				if ( ! isset( $field['kirki_config'] ) || ! isset( $field['settings'] ) ) {
        					continue;
        				}
        				$value = self::get_option( $field['kirki_config'], $field['settings'] );
        				if ( isset( $value['font-family'] ) ) {
        					$url = '//fonts.googleapis.com/css?family=' . str_replace( ' ', '+', $value['font-family'] );
        					$value['variant'] = ( isset( $value['variant'] ) ) ? $value['variant'] : '';
        					$url .= ( empty( $value['variant'] ) ) ? '' : ':' . $value['variant'];
        					$key = md5( $value['font-family'] . $value['variant'] );
        					// Check that the URL is valid. we're going to use transients to make this faster.
        					$url_is_valid = get_transient( $key );
        					// If transient does not exist.
        					if ( false === $url_is_valid ) {
        						$response = wp_remote_get( 'https:' . $url );
        						if ( ! is_array( $response ) ) {
        							// The url was not properly formatted,
        							// cache for 12 hours and continue to the next field.
        							set_transient( $key, null, 12 * HOUR_IN_SECONDS );
        							continue;
        						}
        						// Check the response headers.
        						if ( isset( $response['response'] ) && isset( $response['response']['code'] ) ) {
        							if ( 200 == $response['response']['code'] ) {
        								// URL was ok. Set transient to true and cache for a week.
        								set_transient( $key, true, 7 * 24 * HOUR_IN_SECONDS );
        								$url_is_valid = true;
        							}
        						}
        					}
        					// If the font-link is valid, enqueue it.
        					if ( $url_is_valid ) {
        						wp_enqueue_style( $key, $url, null, null );
        					}
        				}
        			}
        		}
        	}
        }
    endif;
    new WP_Bootstrap_4_Kirki();

    Let me know if you have some issue.

    Regards.

    tradesouthwest

    (@tradesouthwestgmailcom)

    Perfecto. Will try soon… I am glad your replied, I was coming here to post this Inspector error which is probably meaning less since it is a source map error only:

    Source map error: request failed with status 404
    Resource URL: http://www.schusshoots.com/wp-content/themes/wp-bootstrap-4/assets/css/bootstrap.css?ver=v4.0.0
    Source Map URL: bootstrap.css.map

    Get back to you soon.

    tradesouthwest

    (@tradesouthwestgmailcom)

    Update: Tested and works like a charm. I get the “blank” Kirki stylesheet AND the inline customizer head docs but at least I do not get the DOUBLE INSPECTOR RULES like I was getting. What a relief. Let me review the theme in repo for you when I get a chance.

    <link rel='stylesheet' id='kirki-styles-wp_bootstrap_4_theme-css'  href='http://www.schusshoots.com/wp-content/plugins/kirki/assets/css/kirki-styles.css?ver=3.0.25' type='text/css' media='all' />
    <style id='kirki-styles-wp_bootstrap_4_theme-inline-css' type='text/css'>

    Cheers!

Viewing 14 replies - 1 through 14 (of 14 total)
  • The topic ‘Stylesheet shows twice in child-theme’ is closed to new replies.