Support » Theme: GeneratePress » Override defaults.php

  • Resolved mvenkadesan

    (@mvenkadesan)


    Hi GP team,

    I have created a child theme and trying to do a few things:

    1. Customize many default settings by copying over defaults.php into a subfolder called inc and editing the values. I have added the following line into my child theme’s functions.php:
      $child_theme_dir = get_stylesheet_directory();
      require $child_theme_dir . '/inc/defaults.php';

      Making changes to the child theme’s defaults.php works as intended. However, I am worried whether these functions are being called twice when every page loads. Once from the parent and then again from the child. Do you know if that is the case? What do you recommend?

    2. Programmatically create a top bar. To do this, I am using,
      add_action( 'generate_before_header','child_top_bar' );
      and manually using top bar styles by wrapping my code inside <div class="top-bar grid-container". It seems fragile because the styling that I apply to body > .grid-container seems to override the .top-bar styling. Is there a more robust way to create a top-bar programmatically?
    3. A more worrisome question is that using hooks to create the top bar seems inefficient in creating static content. Is there a better option?

    As always, thank you for your awesome help!

    • This topic was modified 2 months, 3 weeks ago by mvenkadesan.
Viewing 11 replies - 1 through 11 (of 11 total)
  • Thread Starter mvenkadesan

    (@mvenkadesan)

    Hi GP team,

    A simpler question that I am facing is how to update the text color. I know that I can do this ad-hoc using CSS .body {color:...}. But I am trying to do this more systematically using the settings structure so that the dynamically generated inline CSS does not have to be overridden by manual CSS additions. Just trying to keep things clean and structured. So I tried using add_filter ( 'generate_option_defaults' , 'customize_gp_defaults' );. But making changes like, 'text_color' => '#112a3a' inside that filter function has no effect and the text color remains #222222 and the browser’s inspector tells me that it is set by the inline style for .body.

    What am I missing here to set the text color within my child theme?

    Thanks!

    Theme Author Tom

    (@edge22)

    Hi there,

    1. Overwriting core files like this is a bad idea, as it can cause breakages in the future when we serve updates.

    Instead, it’s best to filter the defaults using custom functions.

    However, from your second post, it sounds like you tried the filter and it didn’t work. This means the value is already saved to your database (it’s no longer using the default). In this case, you need to filter the setting itself. For example:

    add_filter( 'option_generate_settings', function( $settings ) {
        $settings['text_color'] = '#112a3a';
    
        return $settings;
    } );

    2. Not sure I understand the goal here – why not use the built-in top bar?

    Let me know πŸ™‚

    Thread Starter mvenkadesan

    (@mvenkadesan)

    Hi @edge22 ,

    Thank you for the response. Filtering option_generate_settings appears to have no effect. That is why I tried the other approach. In order to debug the issue, I have a local setup with no plugins and a minimal functions.php. Here are the contents of that file.

    <?php
    /**
     * GeneratePress child theme functions and definitions.
     *
     * @package kokuin_gp_child
     */
    
    if ( ! defined( 'ABSPATH' ) ) {
    	exit; // Exit if accessed directly.
    }
    
    add_filter( 'option_generate_settings', function( $settings ) {
    	$settings['hide_title'] = true;
    	$settings['text_color'] = '#112a3a';
    
    	return $settings;
    } );

    The text color is unchanged and the title text continues to be visible. But if I did the same by filtering generate_option_defaults, I am able to hide the title but still has no effect on the text color. What am I doing wrong?

    If it helps, I used FirePHP to examine some of the variables by inserting the following commands in a test file:

    $saved_settings = get_option( 'generate_settings');
    fb ($saved_settings);
    
    $default_settings = generate_get_defaults();
    fb ($default_settings);

    The variable dumps are:

    • $saved_settings:
      FALSE
    • $default_settings:
      map(
      'hide_title'=>'',
      'hide_tagline'=>TRUE,
      'logo'=>'',
      'inline_logo_site_branding'=>FALSE,
      'retina_logo'=>'',
      'logo_width'=>'',
      'top_bar_width'=>'full',
      'top_bar_inner_width'=>'contained',
      'top_bar_alignment'=>'right',
      'container_width'=>'1200',
      'container_alignment'=>'text',
      'header_layout_setting'=>'fluid-header',
      'header_inner_width'=>'contained',
      'nav_alignment_setting'=>'left',
      'header_alignment_setting'=>'left',
      'nav_layout_setting'=>'fluid-nav',
      'nav_inner_width'=>'contained',
      'nav_position_setting'=>'nav-float-right',
      'nav_drop_point'=>'',
      'nav_dropdown_type'=>'hover',
      'nav_dropdown_direction'=>'right',
      'nav_search'=>'disable',
      'content_layout_setting'=>'separate-containers',
      'layout_setting'=>'right-sidebar',
      'blog_layout_setting'=>'right-sidebar',
      'single_layout_setting'=>'right-sidebar',
      'post_content'=>'excerpt',
      'footer_layout_setting'=>'fluid-footer',
      'footer_inner_width'=>'contained',
      'footer_widget_setting'=>'3',
      'footer_bar_alignment'=>'right',
      'back_to_top'=>'',
      'background_color'=>'#f7f8f9',
      'text_color'=>'#222222',
      'link_color'=>'#1e73be',
      'link_color_hover'=>'#000000',
      'link_color_visited'=>'',
      'font_awesome_essentials'=>TRUE,
      'icons'=>'svg',
      'combine_css'=>TRUE,
      'dynamic_css_cache'=>TRUE,
      'structure'=>'flexbox'
      )

    Re: 2: I want to do this programmatically instead of the built-in top bar widget because I want to be able to move from local to live or between servers without having to use mouse clicks and manually creating a new top bar every time. For example, see the test page https://beta.thekokuin.com/.

    • This reply was modified 2 months, 2 weeks ago by mvenkadesan.
    Thread Starter mvenkadesan

    (@mvenkadesan)

    Hi Tom @edge22 :

    After more debugging efforts, I can report what I think is an oddity.

    As a reminder, the objective is to change some of the settings, such as hide_title, using add_filter ( ‘option_generate_settings’, … ) Previously, I started with a fresh WordPress install, no plugins, blank child theme, and added the add_filter line with no effect.

    Now, I manually tried to hide the title using the tickbox within the Customizer and it worked. Then, I unchecked that tickbox and the title reappeared. After having done that once, I am able to apply the filter from within functions.php and it takes effect. I am going to hypothesize that it is the same with the other settings that are presently proving ineffective from within functions.php.

    I can replicate this in a fresh WordPress install and confirm that to be the case for the hide_title being modified by the PHP within functions.php only after I manually change the setting within the Customizer at least once.

    In both cases, I examined the database tables. The wp_options table did not have a generate_settings entry to start with. Only after I manually set an option using the customizer is that entry created. The option_value for generate_settings in the table includes only those settings that I have tried manually editing, and those seem to be available for filtering. So it seems that I should manually update the table once so that generate_settings is updated with default values for every single possible option. Then I may be able to modify them within functions.php using the filter.

    Is there any way to avoid the need to manually use the Customizer or manually create the table entry?

    • This reply was modified 2 months, 2 weeks ago by mvenkadesan.
    Theme Author Tom

    (@edge22)

    Ah, that makes sense.

    So there are two filters:

    option_generate_settings – this filter applies to options that are saved in your database already. They must exist in the database in order to be overwritten by the filter.

    generate_option_defaults – this filter applies to options that are not saved in your database already. If they do exist in the database, the above option needs to be changed.

    So you need to either:

    a) Make sure nothing is saved to the database, and use generate_option_defaults
    b) Use a combination of the two filters to make sure the new value you’re using applies to both. I wonder if something like this would work for both scenarios?:

    add_filter( 'generate_option_defaults', 'tu_filtered_options' );
    add_filter( 'option_generate_settings', 'tu_filtered_options' );
    
    function tu_filtered_options( $options ) {
        $options['hide_title'] = true;
        $options['text_color'] = '#000000';
    
        return $options;
    }
    Thread Starter mvenkadesan

    (@mvenkadesan)

    @edge22 : I have bad news after trying that out. Having either one of those two filtering lines or both of them made no difference to the text_color. Any one of them by itself was able to modify the tagline state but not the title. So I looked at the database as I was doing these trials and saw that the generate_settings remained unaffected by either of those filters. The current value of generate_setting in the database is a:1:{s:10:"hide_title";b:1;}. The title’s display state was altered by option_generate_settings but not by the other filter. So the settings from generate_option_defaults was not being written to the database at all, which is quite puzzling.

    As for the text_color, it was whatever is specified in the database by generate_dynamic_css_output. The option filters made no difference to it. Here is the functions.php that I used for the tests.

    <?php
    /**
     * GeneratePress child theme functions and definitions.
     *
     * Add your custom PHP in this file.
     * Only edit this file if you have direct access to it on your server (to fix errors if they happen).
     */
    
    if ( ! defined( 'ABSPATH' ) ) {
    	exit; // Exit if accessed directly.
    }
    
    add_filter ( 'generate_option_defaults' , 'test_options' );
    add_filter ( 'option_generate_settings' , 'test_options' );
    
    function test_options ( $options ) {
    	$options['hide_title'] = false;
    	$options['hide_tagline'] = true;
    	$options['text_color'] = '#666666';
    
    	return $options;
    }
    • This reply was modified 2 months, 2 weeks ago by mvenkadesan.
    Theme Author Tom

    (@edge22)

    Make sure you turn off the dynamic CSS cache in Customize > General, as it will prevent these filters from doing anything.

    option_generate_settings will filter options that appear in the generate_settings option in the database.

    generate_option_defaults will filter options that do not appear in the generate_settings option in the database.

    generate_option_defaults is for defaults, when the setting hasn’t been saved yet. option_generate_settings is for options that have been saved to the database already.

    Thread Starter mvenkadesan

    (@mvenkadesan)

    That certainly fixed it. But I am a fan of your approach of using inline styles and cached dynamic CSS because it seems like the best of two worlds. Is there any way to manually trigger a cache bust, much as the Customizer would? Perhaps update_option on generate_dynamic_css_cached_version to update the version number from 3.0.2 to 3.0.2.NNN, where NNN is incremented when I want to bust the cache and use the manual settings? I know that I can manually do that by going into Customizer, changing some option, and then changing it back to its old value again (publishing at every step). Would programmatically updating the version number have the same effect?

    This is what I am suggesting,

    $CACHE_VER = '3.0.2.0001';
    $CACHE_VER_CUR = get_option( 'generate_dynamic_css_cached_version', '3.0.2' );
    
    if ( $CACHE_VER !== $CACHE_VER_CUR ) {
        update_option( 'generate_dynamic_css_cached_version' , $CACHE_VER );
    }
    • This reply was modified 2 months, 2 weeks ago by mvenkadesan.
    Theme Author Tom

    (@edge22)

    You can simply empty the cache and it will re-fill itself:

    update_option( 'generate_dynamic_css_output, '' );

    Thread Starter mvenkadesan

    (@mvenkadesan)

    @edge22 Tom: Your support is most appreciated! I am not a GP Premium subscriber, but I just made a donation. At some point, I should admit that there is no better theme and simply sign up to become a lifetime subscriber. πŸ™‚

    Theme Author Tom

    (@edge22)

    Thank you! I really appreciate it πŸ™‚

Viewing 11 replies - 1 through 11 (of 11 total)
  • You must be logged in to reply to this topic.