markjaquith / feedback

Ask @markjaquith anything!
42 stars 4 forks source link

Global Variables on a Theme #14

Closed sethta closed 10 years ago

sethta commented 10 years ago

Hi Mark,

I have developed my own framework for WordPress themes, and I plan on releasing to the community soon, but I have a question about a best practice. At the top of my functions file, I create an array called $global_vars which usually contains the following (it varies site to site):

$global_vars = array(
    'home_id' => get_option('page_on_front'), // get page ID for the home page
    'blog_id' => get_option('page_for_posts'), // get page ID for the blog posts page
    'slider' => true, // does site have a home page slider? true = yes; false = no.
        'slider_captions' => false, // does site have captions for the banners? true = yes; false = no.
        'home_banner_width' => '1200', // home banner width; Don't add px.
        'home_banner_height' => '400', // home banner height; Don't add px.
        'generic_banner' => '', // generic banner image url in case no banner is defined
    'ctas' => true, // does the site have three call to actions? true = yes; false = no;
        'cta_fields' => array('image', 'title', 'desc', 'link'), // list the parts included in the ctas
    'logo_slider' => false, // does site have logo slider? true = yes; false = no.
        'logo_desk' => '6', // number of slides on desktop
        'logo_sm_tab' => '4', // number of slides on sm-tab
        'logo_mobile' => '2', // number of slides on mobile
    'primary_nav_class' => 'inline', // classes for primary navigation
    'footer_nav_class' => 'inline', // classes for footer navigation
    'secondary_widget' => false, // does site have secondary widget? true = yes; false=no.
    'has_blog' => false, // does site have blog? true = yes; false=no.
    'primary_color' => '000000', // primary color for login page
    'secondary_color' => '262626', // secondary color for login page
    'js_ver' => '0', // Javascript cachebuster version number
    'css_ver' => '0', // CSS cachebuster version number
);

I then call in global $global_vars on many of my template files and some of the custom functions throughout the theme. Obviously, this gives me the ability to quickly turn on and off pre developed and partially styled features on a new site.

Is this a good practice, or is there some other way I should go about setting up specific options for a theme right at creation? I know I could technically set up theme options, and work with those, but I don't want the possibility of a client breaking something (I know I can set permission levels to keep them out) and I find it faster to update an array in my editor than using the WordPress interface.

What are your thoughts? Is there a better way I should be using that works with native WordPress functions?

I attended WordCamp North Canton this past weekend and @designsimply couldn't see an issue with using an array that I globally call into functions and files, but recommended I ask you.

Thanks!

bueltge commented 10 years ago

Maybe this link help you think about the practice of globals in php. http://stackoverflow.com/questions/1557787/are-global-variables-in-php-considered-bad-practice-if-so-why

But you can find much more posts and discussion about the topic. Maybe you refactor your framework without much globals.

markjaquith commented 10 years ago

It might be cleaner to use a simple storage class to hold these values:

<?php
class My_Awesome_Theme {
    public static $instance;

    private function __construct() {}

    static function get_instance() {
        if ( ! self::$instance ) {
            self::$instance = new self();
        }
    }

    static function get( $key ) {
        if ( isset( self::$instance->$key ) ) {
            return self::$instance->$key;
        } else {
            return null;
        }
    }

    static function set( $key, $value ) {
        self::$instance->$key = $value;
    }
}
My_Awesome_Theme::get_instance();

Then you can just do:

My_Awesome_Theme::set( 'foo', 'bar' );

And:

My_Awesome_Theme::get( 'foo' ); // 'bar'

Classes are already global, so you don't have to go around declaring a global variable. Plus, later, you could add stuff like sanitization and escaping to your options, to prevent errors.

sethta commented 10 years ago

I never thought of going with a class. That makes much more sense. Thanks Mark.