0

I am building a wordpress theme. In my index.php I use get_theme_mod() to get an option and I have some code that will or will not fire depending on that option.

<!-- index.php -->
<?php
/**
 * The main template file
*
*/
if (!empty(get_theme_mod( 'czen_hero' ))) {
    $header_logo = get_theme_mod( 'czen_hero' );
}

if (!empty(get_theme_mod( 'czen_hero_text' ))) {
    $header_text = get_theme_mod( 'czen_hero_text' );
}

These options are defined in functions.php and set via wordpress' Customizer.

// HOMEPAGE HEADER
$wp_customize->add_section( 'czen_hero_section' , array(
        'title'       => __( 'Custom Homepage Header', 'coffee-zen' ),
        'priority'    => 40,
        'description' => 'Upload an image and enter some text to create a custom header',
) );

$wp_customize->add_setting( 'czen_hero' , array ( 'sanitize_callback' => 'czen_sanitize_setting', ) );
$wp_customize->add_setting( 'czen_hero_text', array ( 'sanitize_callback' => 'czen_sanitize_setting', ) );

$wp_customize->add_control( new WP_Customize_Image_Control( $wp_customize, 'czen_hero', array(
        'label'    => __( 'Header Image', 'coffee-zen' ),
        'section'  => 'czen_hero_section',
        'settings' => 'czen_hero',
) ) );

$wp_customize->add_control( 'header_text', array(
        'label'    => __( 'Header Text', 'coffee-zen' ),
        'section'  => 'czen_hero_section',
        'settings' => 'czen_hero_text',
        'type'    => 'text',
) );

The code works. When those settings are set, the html shows up where it is supposed to. However, every time I load a page on the front end, I see this when I inspect:

<!-- index.php -->
<br />
<b>Fatal error</b>:  Uncaught Error: Call to undefined function get_theme_mod() in /var/www/vhosts/zentest/wp-content/themes/coffee-zen/index.php:7
Stack trace:
#0 {main}
  thrown in <b>/var/www/vhosts/zentest/wp-content/themes/coffee-zen/index.php</b> on line <b>7</b><br />

I can confirm that the function IS defined in /wp-includes/theme.php, line 855 to line 879:

function get_theme_mod( $name, $default = false ) {
    $mods = get_theme_mods();

    if ( isset( $mods[$name] ) ) {
        /**
         * Filters the theme modification, or 'theme_mod', value.
         *
         * The dynamic portion of the hook name, `$name`, refers to
         * the key name of the modification array. For example,
         * 'header_textcolor', 'header_image', and so on depending
         * on the theme options.
         *
         * @since 2.2.0
         *
         * @param string $current_mod The value of the current theme modification.
         */
        return apply_filters( "theme_mod_{$name}", $mods[$name] );
    }

    if ( is_string( $default ) )
        $default = sprintf( $default, get_template_directory_uri(), get_stylesheet_directory_uri() );

    /** This filter is documented in wp-includes/theme.php */
    return apply_filters( "theme_mod_{$name}", $default );
}

So my question is, how can I prevent this "Fatal Error"? What is causing it? I can use other Wordpress core functions fine.

I disabled all plugins, issue persists. Issue occurs in all major browsers. I am using wordpress version 4.8.

Thanks in advance.

  • Would assume that `/wp-includes/theme.php` is not being included. – ficuscr Aug 02 '17 at 19:32
  • It sounds like your theme's `index.php` file is being loaded directly somewhere along the line – Nathan Dawson Aug 02 '17 at 19:34
  • It looks to me like some ajax-y thing is trying to load the index file directly perhaps. An easy fix would be to wrap those get_theme_mod() bits in a `function_exists('get_theme_mod')` call. – JakeParis Aug 02 '17 at 19:34
  • Is the index.php in the root of your theme? If so, try before you run your code to include the header and footer. with `` and `` – justkidding96 Aug 02 '17 at 19:35
  • I thought of that JakeParis , but then the functionality would never happen because that if check will always fail. And @justkidding96 I tried that (I put get_footer at the very top of index.php) and I got the same fatal error: undefined function. The funny thing is the footer actually did display... Just at the top of the page obviously – Jeremy Muckel Aug 02 '17 at 19:40
  • Also nowhere in my code am I referencing "index.php". So I doubt I am accidentally trying to load it manually or something. – Jeremy Muckel Aug 02 '17 at 19:41
  • @JeremyMuckel For as I know `index.php` which located in the root of the theme is a fallback of `page.php`. Do you have `page.php` in the root of the theme? – justkidding96 Aug 02 '17 at 19:42
  • I've had that trouble before, where something internal to WordPress was trying to load the index file. It's not anything you're doing wrong. – JakeParis Aug 02 '17 at 19:43
  • You could wrap the the `get_theme_mod()` in a try/catch block. That way, you'd at least be catching the error and not get the fatal. – JakeParis Aug 02 '17 at 19:48
  • @JakeParis you can not catch a fatal error due to an undefined function using try/catch, that's for stuff that throws exceptions only. – CBroe Aug 02 '17 at 19:50
  • @CBroe ah, ok. I was seeing the "Uncaught: " language and immediately thought of "catching" it. Thanks – JakeParis Aug 02 '17 at 19:52
  • I do have a page.php and all the other basic template files. Adding if (!defined('ABSPATH')) die(); fixed it... Although I still am not sure why. – Jeremy Muckel Aug 02 '17 at 19:54
  • If you want to find out what was actually going on, then I'd start by checking what requests are being made in browser dev tools ... – CBroe Aug 02 '17 at 19:55

1 Answers1

1

You can prevent the direct loading of a WordPress theme file with

if (!defined('ABSPATH')) die();

Perhaps by adding this to your theme's index file, you can prevent the error.

JakeParis
  • 11,056
  • 3
  • 42
  • 65
  • Adding this fixed it.... So strange. So I guess wordpress was trying to do something like load it directly, or something... – Jeremy Muckel Aug 02 '17 at 19:53