-1

MY SETUP (AND CODE)


  • Wordpress Version 4.4.3 (Latest at time of writing)
  • Installed on a local server using XAMPP

I am using the WordPress Theme Customizer, and updating settings via Javascript (and jQuery).

My homepage is separated into several sections, and the Theme Customizer has checkboxes to show and hide each section.

  • When the section is to be hidden, I use jQuery's .remove() to remove it.
  • When the section is to be shown, I use the following code:

$('#section-cont-id').load(theme_folder + '/file.php')

Where theme_folder is the directory of the theme, and file.php is the section I want to load.

By default, the section is shown (the setting is set to true). Un-ticking the checkbox to hide the section works fine, it gets .removeed. However, when I try and show the section by re-ticking the checkbox, it does not work as planned.


THE PROBLEM


file.php has a <style> at the start, with one little bit of PHP code. Then there are various other elements, <h1>, <h3>, <p> etc. When the section is meant to get shown, I instead get an empty, white box. I used Inspect Element to view the code and found something interesting:

The <style> tag gets loaded, but the rest of the elements do not, they do not even exist. There is only one line of PHP that in the <style> tag, it gets a setting for the background of that section like so: <?php echo get_theme_mod('setting'); ?>. When I look at the CSS for the section background image, it shows the following:

url('<br /> <b>Fatal error</b>: Call to undefined function get_theme_mod() in <b>C:XAMPPhtdocsWPwp-contentthemesmythemefile.php</b> on line <b>7</b><br />')

It seems the function get_theme_mod() is not defined? Also I am not sure why the path was echoed with no backslashes, but that may be Firefox Inspector Tools removing them. The correct path should be:

C:\XAMPP\htdocs\WP\wp-content\themes\mytheme\file.php

The elements after the <style> are set out like follows:

<h1><?php echo get_theme_mod('setting1'); ?></h1>
<h3><?php echo get_theme_mod('setting2'); ?></h3>
<p><?php echo get_theme_mod('setting3'); ?></p>

However, they do not even appear as empty (no content, e.g. <h1></h1>). They do not exist at all.

So my question is:

How can I remove the Fatal error: Call to undefined function... and get the rest of file.php to load correctly


PROBLEM CONCLUSION


What I think is happening:


First of all, I think the elements after the <style> do not exist because, after the PHP code throws the error, the rest of the file is not loaded.

However, all the code in file.php is inside a <div>, and that div closing tag loads. So maybe it loads elements and closing tags using DOM, rather than line-by-line?


To deal with the error of get_theme_mod() not being defined, here is my theory:

  • (FACT) WordPress registers get_theme_mod() in a file called theme.php (as mentioned in the Codex, full path is wp-includes/theme.php)

I think WordPress includes that file, then all the theme files, and after they have all been loaded, theme.php is removed. (I don't exactly think PHP works like that, but I think that is what happening)

My evidence to back this up is:

  1. The Fatal Error: Call to undefined function.... If the function is not defined, the file must not be loaded
  2. When I Inspect Element the page (Firefox 46), if you click the Debugger tab you can see all the included / linked files. It shows a variety of Javascript and PHP files, but not theme.php

NOTES


This is very different to the other questions on Fatal error: Call to undefined function.... I am not getting the error when the page loads, whether the section is shown or not. I am only getting the error in the Theme Customizer when I try and show the section (from previously being hidden)

  • instead of arguing with the moderators while writing the question you should have spent the time learning how to properly to do ajax in wordpress. Hopefully once you will understand how to do it right you will also understand why you get the error. – Mark Kaplun Feb 14 '16 at 20:34
  • First of all, I have no idea what you mean by "arguing with the moderators while writing the question". I looked at the question on SO and tried to use jQuery .load(). I was not aware you had to do something different for WordPress functions to work. However, now that you mentioned that AJAX works differently in WordPress, I followed the tutorial on this site and have learned to use AJAX with WordPress – Kaspar Lee Feb 15 '16 at 9:18
  • "This is very different to the other questions on..." is obviously preemptive arguing. It is exactly the same. The error is easy to understand it its meaning is very obvious - you have not included the proper files. – Mark Kaplun Feb 15 '16 at 11:09
  • No. Most, if not all of the other questions with this problem have not installed WP correct,y or some Theme / Plugin they have installed is not working for whatever reason. I am developing a theme and am loading the file differently to how you would normally. I was not arguing, just making it clear so I did not get comment like "Try disabling Plugins and Themes". – Kaspar Lee Feb 15 '16 at 11:28
  • 2
    I think you are wrong in the concept. Ajax is the same technology everywhere. You don't have to use it differently to run WordPress PHP functions. What is happening is quite simple: if you load a PHP script directly, you execute that script, not another. Your problem is that you expect WordPress be loaded in that PHP script, but have you loaded WordPress in your script? No; so you can not use WordPress there. So, or you manually load WordPress in your PHP script (which is, in general, not recommended), or you use WordPress Ajax API, so WordPress is already loaded in the Ajax request. – cybmeta Feb 15 '16 at 11:41
1

Apparently, for the PHP code to run (with the WordPress functions), you have to use AJAX differently

First, you need to add wp_localize_script() to add data to the script. I used the following code:

// For AJAX loading of sections
wp_localize_script('customizer', 'ajax', array(
    'url' => admin_url('admin-ajax.php')
));

Where customizer is the unique ID for the Customizer Script.

In the customizer script, I used the following code (Inside the function listening for changes to settings in the Theme Customizer):

jQuery.ajax({
    url : ajax.url,
    type : 'post',
    data : { action : 'load_section', section_name: 'section1' },
    success : function(data) {
        $('div').append(data) // On success, add section to page
    }
});

ajax.url contains the URL that was set in wp_localize_script(). You use ajax. because 'ajax was the second argument passed

Then you need to use add_action() like so:

// To get file.php ($_POST['data'] can be used to access data from the "data" object)
function load_a_section() {
    get_template_part(echo $_POST['section'], echo $_POST['section'] + '_template');
    die(); // To stop a "0" being added to the end of the data
}

// This is the "action" stored in the "data" object, prepended with wp_ajax_
add_action('wp_ajax_load_section', 'load_a_section');

The data returned from load_a_section() can be accessed from the success function inside the AJAX request

  • No, AJAX in wordpress works exactly like it works anywhere else. Wordpress core just includes some specific patterns to help you implement it faster with less errors and in more web server enviroment tolerant way. The patterns exist and it is smart to use them, but you are free to write your own (and there are some scenarios that make sense for that). Your code snippet is ok if you just want to handle logged in users, but for not loggedin users you also need to handle the wp_ajax_no_priv_load_section hook. – Mark Kaplun Feb 15 '16 at 11:16
  • Yeah, I know about the wp_ajax_no_priv_ hook, I didn't include this since if the user is using the theme customizer they are logged in. And I have re-worded my answer slightly. I know AJAX is the same, I meant you need to use it differently to run the WP PHP functions – Kaspar Lee Feb 15 '16 at 11:25
  • See my comment in the question. I think you are understanding things incorrectly in the concept. – cybmeta Feb 15 '16 at 11:42
  • 3
    The ajaxurl is always defined on the admin side, so there is no need to redeclare it. – Nicolai Feb 15 '16 at 11:51

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.