6

I have come across an interesting problem regarding the get_template_part() .

I have created a theme options page (named sitewideSettings.php)

normally I would include this in functions.php like so:

include(TEMPLATEPATH."sitewideSettings.php");

which works fine.

But now I am trying to use get_template_part();

get_template_part('sitewideSettings');

which is also working fine except that when clicking 'update' to update the settings I get an error message: "Are you sure you want to do this? Please try again".

"Please try again" links back to the theme options page and clicking update takes you back to the error message which takes you back to Theme options and round and round we go.

Nothing else has changed other than the use of get_template_part();

Anyone else come across this problem? How did you get around it? I am sure its something simple and obvious, but exactly what it is totally escapes me.

(Its not a nonce issue as a nonce is created in both instances)

2
  • Please paste the URL here that is used to request the admin page. Additionally please paste the URL here that is used when the form get's submitted. If you can, please add all POST parameters as well.
    – hakre
    Commented Nov 10, 2010 at 13:53
  • I'd get this error for some plugins when wp-config.php DEBUG is set to true.
    – icc97
    Commented Feb 8, 2012 at 14:49

5 Answers 5

6

I know you say it's not a nonce issue, but it clearly is. That notice is the default 'This nonce didn't check out' message. I don't know exactly why the nonce is failing, but that is what is happening.

I would double check how your nonces are created and checked. If you're using wp_nonce_field() make sure both action values and argument values are the same. Also, double check spelling of variables, or any scope-related issues that could be causing the nonce to fail.

EDIT

Following up on your insistence that it's not a nonce issue (which it is. The nonce issue is caused by a scope issue), here's what's probably happened. Included/required files are executed in the scope in which they're included. My guess is you're using a variable to build either the nonce action or the nonce name. Because get_template_part() includes the template file in the scope of that function, it's no longer being executed in the scope of your admin page's display callback. You either need to globalize those variables in all locations, or you need to use constants instead of variables.

7
  • Nonces work fine when the code is not segmented with get_template_part so if it's a nonce issue why is it working when not using get_template_part? Also, the nonce is created and visible in view source Commented Nov 10, 2010 at 4:20
  • Like I said, it's probably scope related. Edit added above. Commented Nov 10, 2010 at 13:49
  • @John P Bloch - that can be an explanation of it. But in the end this leads to not using that function to include your code. It's just not a template, it's code. So the wrong function is used. But good catch, this can really be the explanation.
    – hakre
    Commented Nov 10, 2010 at 13:58
  • @hakre I think it's imbecilic to insist that he not use this function for the admin. Maybe he's building a framework that has a certain admin page that child themes should be able to override. The point is, the use case should dictate the use, not your silly declaration of segregation of front and back end. Commented Nov 10, 2010 at 14:07
  • @John P Bloch - I beg your pardon. I do not claim the authorship of differentation between what is called wp-admin and what is called a theme or template. If you call that silly to me, you're addressing the wrong person. I also didn't wanted to question what Ash is trying to achieve, I just wanted to point out that using that function is causing the issue and you provided a technical explanation for what might cause the issue. Nothing else. Practically it might just mean to not use that function or to globalize scope within that code. Whatever seem fit. Just choose the right tool for the job.
    – hakre
    Commented Nov 10, 2010 at 14:53
4

Please do not use get_template_part() in the Admin / Backend. It has been designed for template use (displaying the theme, please see codex), so this is intended to be used for templates and template-parts within themes:

Function Reference/get template part

Load a template part into a template (other than header, sidebar, footer). Makes it easy for a theme to reuse sections of code in an easy to overload way for child themes.

The function does actually includes general source code as well, but what you experience (as John pointed out) might be related to scope. As I do not know your code, I can not say for sure, if that is the exact cause of the issue you're facing (variable scope), so I tend to keep it simple in my answer:

The function is just not desgined to replace as standard php code include, for example to write an admin page.

So just do not use it if for your admin page unless you really know what you are doing.


Update:

If you want to load a php file into the global scope while looking in the child and parent theme directory, you can make use of a function that does the search for the file for you: locate_template():

Retrieve the name of the highest priority template file that exists.

Searches in the STYLESHEETPATH before TEMPLATEPATH so that themes which inherit from a parent theme can just overload one file.

For your given example include include(TEMPLATEPATH."sitewideSettings.php"); this can be written as:

include(locate_template('sitewideSettings.php'));

This allows you to control where and how the file is included (include/_once; require/_cone) and it prevents you to have the scope issue in your example which breaks the NONCE mechanism.


The "Please try again" message is there because wp-admin is not able to verify the request, more specifically the so called nonce. There can be two reasons for that: There is none in the request (e.g. the form does not provide any or it does not get's transferred or read by the admin code) or the nonce is invalid. Nonces always represent a chain of actions, and if that chain is broken, you'll get that message. But the message does not tells you where that chain is broken.

Those error messages in the admin are not always very informative and can be even misleading (Related: #14060). To find out what happens here, it's most effective to debug that on the system where the error appears as it can be quite specific which part of the chain is broken.

Please see the codex on how to create Admin Pages for your Theme or Plugin for more in-depth information about nonces, admin pages etc. . It's not possible for the Admin request to validate the nonce for some reason.

6
  • Hi Hakre, I have read the codex and I do not see any mention of it being restricted for use to the front end. A nonce is created in fact, and can even be viewed in 'view source' so again I say nonce is not an issue or if it is I do not understand how (which is very possible and probably more likely) I am well aware of how to create admin pages I have been creating them for years and until now have never had a problem. Commented Nov 10, 2010 at 4:23
  • @Ash G - Well nonce must be an issue based on the error message that get's displayed after submitting the form. Maybe not the generation but the verification of it? Oh, well there are other reasons for that message, I remember it now. If the page is not properly registerd, this can happen as well. So this can become quite specific. For the get_template_part() this is just a theme function, and to my best knowledge, just use it on frontpage only. I think your include variant is perfectly working and I do not see any reason why to change that. But it does not remove the error, right?
    – hakre
    Commented Nov 10, 2010 at 13:46
  • Include does in fact remove the error, the error only happens when using get template part. In either case when viewing source code of the generated page everything appears the same right down to the nonce. Commented Nov 10, 2010 at 13:51
  • See my updated answer. It's a scope issue causing the nonce failure. Commented Nov 10, 2010 at 13:55
  • @Ash G - just checked codex again. It's not talked about restriction, but the scope is template (not backend): "Load a template part into a template". codex.wordpress.org/Function_Reference/get_template_part
    – hakre
    Commented Nov 10, 2010 at 13:59
0

Hard to make a guess, it's whole ladder of functions. get_template_part() calls locate_template() which calls load_template() which does require.

I suggest you try these from bottom to top to determine if it is get_template_part() exactly or some function in between.

7
  • Hi Rast, I did look through that but saw nothing that could explain it. Guess I need to dig through again. It's gotta be there. Commented Sep 14, 2010 at 12:43
  • Just try loading your file with load_template() and locate_template(), see if it makes a difference. If something breaks in one of these functions first need to know which one is it.
    – Rarst
    Commented Sep 14, 2010 at 12:48
  • After much digging, still no clues as to exactly what is going wrong, but I suspect it has something to do with nonces Commented Sep 28, 2010 at 8:37
  • Managed to get around it by simply using require for the template bits that have to do with saving. That works fine, until I tried creating a child theme. The child theme inherits everything but will not save options. Looks like you just can't use get_template_part on the backend Commented Oct 18, 2010 at 6:31
  • 1
    disregard above. A moment of stupidity... my stupidity an extra space in the theme name in the style sheet was causing the problem Commented Oct 18, 2010 at 7:44
0

locate_template( array( 'sitewideSettings.php' ), true )?

2
  • Hi, Thanks for the answer, but can you provide some context? Should I use this with get_template_part() or in place of? Commented Oct 15, 2010 at 18:09
  • Infact that answer isn't that bad. As Ash specified to use include (and not require), this is an alternative: include locate_template('sitewideSettings.php'); - the conversion to array is not necessary. This will locate the php file with a check first in the child theme directory and then in the parent theme while being still in control of the scope and the type of inclusion (include instead of require/_once).
    – hakre
    Commented Nov 16, 2010 at 16:40
0

This is a more detailed explanation of the first answer - i.e. "scope is you're problem"

My simple visualisation of get_template_part is like this:

function get_template_part($slug) {
  require("$slug.php");
}

So if you have the following in sitewideSettings.php:

<?php
echo $nonce;
?>

Template with include:

<?php
$nonce = 'xxx';
include('sitewideSettings.php');
?>

Gets translated (by PHP) into:

<?php
$nonce = 'xxx';
echo $nonce;
?>

Template with get_template_part:

<?php
$nonce = 'xxx';
get_template_part('sitewideSettings');
?>

Gets translated into:

<?php
$nonce = 'xxx';
get_template_part(
  echo $nonce;
);
?>

So now anything in the template part is wrapped inside a function and any variables you have in your template part need a global on them.

Thus to get it to work you need a global in the sitewideSettings.php, which would get translated into:

<?php
$nonce = 'xxx';
get_template_part(
  global $nonce;
  echo $nonce;
);
?>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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