2

I wanted to filter the blog title displayed in the header to apply different CSS styles to different title parts/words, so I added the below function to my (WP 4.7) Twenty Seventeen child theme's functions.php and this worked very well. The problem is that this function added the CSS code also to the meta title displayed in the title bar. How to repair this?

/** Format the site title parts **/
add_filter( 'bloginfo', 'format_site_title_parts', 10, 2 );
function format_site_title_parts( $text, $show ){
   if ('name' == $show) {
      $text = "<span class='info-style'>Info</span>" . "<span class='psi-style'>Psi</span>" . "<span class='md-style'>.md</span>";
   }
   return $text;
}

title bar

3

Remove that filter/function and apply your markup in the PHP template/page file. If you need help post where you output the title.


CLASS

Here is how I might set this up using a class:

if ( ! class_exists( 'ThemeCustomizations' ) ) {
    class ThemeCustomizations {
        static $inBody = false;

        public static function set_in_body_true() {
            static::$inBody = true;
        }

        public static function set_in_body_false() {
            static::$inBody = false;
        }

        public static function filter_bloginfo( $name, $show = null ) {
            if ( 'name' == $show && static::$inBody ) {
                $name = "<span class='info-style'>Info</span>" . "<span class='psi-style'>Psi</span>" . "<span class='md-style'>.md</span>";
                return "$name";
            } else {
                return $name;
            }
        }
    }
}

add_action( 'wp_head',   array ( 'ThemeCustomizations', 'set_in_body_true' ), PHP_INT_MAX );
add_action( 'wp_footer', array ( 'ThemeCustomizations', 'set_in_body_false' ), 0 );
add_action( 'bloginfo',  array ( 'ThemeCustomizations', 'filter_bloginfo' ), 10, 2 );

STATIC

And using a function's statically scoped variable:

function prefix__is_in_body( $isTrue = null ) {

    // static initializer is false
    static $inBody = false;

    // only overwrite if boolean supplied
    if ( is_bool( $isTrue ) ) {
        $inBody = $isTrue;
    } 

    // return regardless of getter/setter
    return $inBody;
}

add_action( 'wp_head',   function(){ prefix__is_in_body(true); }, PHP_INT_MAX );
add_action( 'wp_footer', function(){ prefix__is_in_body(false); }, 0 );
add_action( 'bloginfo',  function($name, $show = null){
    if ( 'name' == $show && prefix__is_in_body() ) {
        $name = "<span class='info-style'>Info</span>" . "<span class='psi-style'>Psi</span>" . "<span class='md-style'>.md</span>";
        return "$name";
    } else {
        return $name;
    }
}, 10, 2 );

MAGIC

Singleton & Factory patterns + PHP magic methods.

if ( ! class_exists( 'Magic' ) ) {
    class Magic {
        private static $__ = array ();
        public         $_  = array ();

        function __construct( $args = null ) {
            if ( is_array( $args ) ) {
                foreach ( $args as $k => $v ) {
                    $this->{$k} = $v;
                }
            }
            return $this;
        }

        public static function instance( $id = '', $args = null ) {
            if ( ! isset( self::$__[ $id ] ) ) {
                self::$__[ $id ] = new Magic($args);
            }
            return self::$__[ $id ];
        }

        public function __get( $k ) {
            return isset( $this->_[ $k ] ) ? $this->_[ $k ] : null;
        }

        public function __set( $k, $v ) {
            return $this->_[ $k ] = $v;
        }

        public function __call( $k, $a ) {
            if ( isset($this->_[ $k ]) && is_callable( $this->_[ $k ] ) ) {
                return call_user_func_array( $this->_[ $k ], $a );
            }
        }
    }
}

Now with the Magic class you can do this;

$m = Magic::instance( '', array (
    'isBody'             => false,
    'action_wp_head'     => function() { Magic::instance()->isBody = true;  },
    'action_wp_footer'   => function() { Magic::instance()->isBody = false; },
    'filter_wp_bloginfo' => function( $output, $show ) {
        return ( 'name' == $show && Magic::instance()->isBody ) ? '<span class="info-style">Info</span><span class="psi-style">Psi</span><span class="md-style">.md</span>' : $output;
    },
));

add_action( 'wp_head',   array ( $m, 'action_wp_head' ), PHP_INT_MAX );
add_action( 'wp_footer', array ( $m, 'action_wp_footer' ), 0 );
add_filter( 'bloginfo',  array ( $m, 'filter_wp_bloginfo' ), 10, 2 );
  • Thank you! The title is outputted back to the header and I know how to customize a template file. Maybe I will do what you suggest, but I want also to learn how to do this with a function. – Iurie Malai Nov 8 '16 at 11:51
  • You can wrap the output in the template in your own filter, or use backtrace to determine which file called the output. But you would need to show the PHP code. – jgraup Nov 8 '16 at 11:52
  • I added a new answer. Can you comment it? – Iurie Malai Nov 8 '16 at 14:38
  • 1
    I think you just have to think of where you want your data to live. Making a class gives visibility to your whole site. Using a static variable in a function means that variable is only accessible inside that function. It's cool, but I'd make a customizations class for your theme or plugin and utilize it. Speed wise, I think creating a single variable instead of a new class with properties is probably faster. Note: I didn't instantiate anything here... so there is that. But you could create singleton pattern where applicable. – jgraup Nov 19 '16 at 23:44
  • 1
    Added a magic version just for fun. Essentially it's a dynamic class that creates variables if they don't exist. Same with functions. And uses a Singleton pattern to access instances which case be referenced by an id. ... just trying to push the limits... – jgraup Nov 20 '16 at 0:20
3

So, this is what I have finally used (code credit to Alexandros Georgiou). I don't know if this is a good solution, but I like to have a single common place (functions.php) to control my child theme.

$twentyseventeen_child_in_body = false;

function twentyseventeen_child_action_wp_head_finished() {
    global $twentyseventeen_child_in_body;
    $twentyseventeen_child_in_body = true;
}
add_action( 'wp_head', 'twentyseventeen_child_action_wp_head_finished', PHP_INT_MAX );

function twentyseventeen_child_action_wp_footer_started() {
    global $twentyseventeen_child_in_body;
    $twentyseventeen_child_in_body = false;
}
add_action( 'wp_footer', 'twentyseventeen_child_action_wp_footer_started', 0 );

function twentyseventeen_child_filter_bloginfo( $name, $show = null ) {
    global $twentyseventeen_child_in_body;
    if ( 'name' == $show && $twentyseventeen_child_in_body ) {
        $name = "<span class='info-style'>Info</span>" . "<span class='psi-style'>Psi</span>" . "<span class='md-style'>.md</span>";
        return "$name";
    } else {
        return $name;
    }
}
add_filter( 'bloginfo', 'twentyseventeen_child_filter_bloginfo', 10, 2 );
  • 1
    If you reeeally want to go that route, and it works for you, I would only suggest a solution that doesn't involve globals. You could easily create a static state inside a function or a class. – jgraup Nov 8 '16 at 14:52
  • Your suggestion was implemented here, thanks to @toscho: wordpress.stackexchange.com/a/245579/25187 – Iurie Malai Nov 19 '16 at 23:09
  • No, that's using a class which is different. – jgraup Nov 19 '16 at 23:11
  • 1
    I'm waiting for it :). – Iurie Malai Nov 19 '16 at 23:25
  • 1
    both versions added. Each avoiding the global. – jgraup Nov 19 '16 at 23:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.