Run a script on the home page?
-
I am trying to figure out what action hooks to use to run a script on a single page. I want to be able to specify which page or maybe pages to have the plugin run on. However, im not sure how to go about this. Any ideas?
-
The ideal hook depends on what your script is doing, what information it needs, what should happen with the information, etc. It may depend on what theme is being used, the ideal hook to work with all themes could be different than one that only needs to run on your installation only.
That said, you could try the ‘wp_head’ action that should run near the end of the header template of nearly every theme. Obviously, header.php is loaded for all pages, not just the home page or a single page. You have several template tags available, such as is_home(), is_single(), is_archive() etc. Use these tags to create a conditional if() block within which your code is executed only when the condition is met.
I am using the graphene theme. I’ve been told that it is very universal.
So my plugin-name.php would start off like this:
<?php
wp_head…. if(is_post’1557′)
?>
or something like that?I am very new to php. I have a specific HTML/java code that needs to execute other scripts based on the criteria entered in search field. Im not sure how to write it so that the HTML or JS script will be displayed in that specfic spot
Something like that, but different ??
Your main plugin file needs a specifically formatted comment block, see Writing a Plugin. Then you define your actual function that is called when the hook fires.
function my_action_hook() { global $wp_query; $post = $wp_query->get('queried_object'); if(is_single() && $post->ID == 123) { //do some cool stuff } }
Then finally you add your function to the hook queue:
add_action('wp_head', 'my_action_hook');
That is a generic example of how to get certain PHP code run when a particular single post is displayed, but is not an example of how to get javascript run. To run javascript, you hook the ‘init’ action, so that part is similar. You should still use an if() conditional so the javascript is not loaded unless it is needed, so that’s similar too. To get the browser to read the javascript file, use wp_enqueue_script(). The actual execution of javascript should be either triggered by a certain browser event, such as a click, or even document load, or a specific call embedded in the HTML.
To get javascript to enter content on the page, one typically identifies a particular HTML element such as a div that has an ID attribute. Your javascript gets a reference to that element with .getElementById() You can then either append or overwrite the element content with .innerHtml . There are other ways to accomplish such a task, but this is one you will often see.
This is just the briefest of overviews of course, I hope it gets you pointed in the right direction.
I have been reading the Writing a plugin page in the codex. I understand it all until i get the coding part. I understand what an action hook is and how it works. I just don’t quite understand how it is written.
This is probably basic, but what does the ‘$’ mean when writing in php with wordpress?On another related topic, so this bit of coding is basically defining my function?
function my_action_hook() { global $wp_query; $post = $wp_query->get('queried_object'); if(is_single() && $post->ID == 123) { //here is when i enter my code? } }
Then the:
add_action(‘wp_head’, ‘my_action_hook’);
is basically saying when ‘wp_head’ is loaded, run ‘my_action_hook’ and there, my script will run?
And off of that thought, my_action_hook may start to look like:
wp_enqueue_script(//my javascript here)
or
init(//javascript file name)?
I know that my java script will call another php upon a click and display the information back to the page.
I am not quite understanding the last paragraph at all.
And thank you so much for your help with all of this!Yeah. Im sorry. I didn’t realize that you were the same person.
No worries, it was slow to dawn on me as well ??
Yeah the $ thing! Not just WP, all PHP. It’s required as part of the language specification that all variables begin with $. Coming from other languages, this seemed really silly to me, but it’s useful when reading unfamiliar scripts.
Yes, the statement
function
signifies the start of a function definition. The next element is the function name, followed by any parameters inside the()
then the code between the{}
is what is executed any time the function is called.when ‘wp_head’ is loaded, run ‘my_action_hook’ and there, my script will run?
That’s the gist of it. To be more precise in terminology, a process calls do_action(‘wp_head’) which causes all functions added with add_action(‘wp_head’, *) to be executed before the process continues with the next statement.
Your action hook function may only have a call to wp_enqueue_script(), except to use that function, your action hook must be to ‘wp_enqueue_scripts’ action, not ‘init’, not ‘wp_head’. I told you I get confused sometimes! Sorry for that confusion. Take a look at Function Reference/wp enqueue script for more on enqueuing javascripts. Your script may actually look like this:
function my_scripts_function() { wp_enqueue_script('my_javascript'); // .js assumed } add_action( 'wp_enqueue_scripts', 'my_scripts_function' );
As for that last paragraph, I changed languages without warning, small wonder you were confused. So at this point, you’ve enqueued your javascript on the page using PHP. Let’s say you’ve set it up to run once the page loads. Let’s also say your page has the following content:
<body onload="changeTarget();"><div id="target">Text that bots see</div>
To replace the content of that div using javascript, the following javascript function is called for the onload event.
function changeTarget() { var targetDiv = document.getElementById("target"); targetDiv.innerHtml = "Only javascript users see this"; }
When a user with javascript enabled views the page, they will see “Only javascript users see this”. If they had javascript disabled, they would see “Text that bots see”.
Well. I am working on trying to write a basic php script. Nothing seems to be working for me. would you possibly be able to show me an example script? something basic that will display any text right before the content of the page using the ‘echo’ tag? once i have a basis with that, i can work from it using trial and error.
When defining a function between the curly braces, you do not need to add a <?php…?> correct?
also, when defining an action like this:
function my_scripts_function()
what is the between the brackets? Does anything go there or is just empty?I don’t have access to my usual files or I could just show you a working example, although the code above should be functional once the elements are in the right files. More on that later, first answers to your latest questions.
Yes, when defining a PHP function, it must be inside a <?php ?> block. The enqueue script function I showed you often resides on the theme’s functions.php, which often has no HTML content, so there is one <?php at the top of the page and it is not seen again. The closing ?> is not required if the last text on a page is PHP code. So when taking snippets out of context, sometimes you see the <?php, sometimes you don’t. But one must occur somewhere prior. It may be thousands of lines above, but it must be there somewhere or the code would be treated as HTML and sent to the client browser.
The parenthesis () after the function name may or may not contain variable parameters, depending on whether they are needed or not by the function. Some functions need no outside information so do not take any parameters. Others need outside information, so parameters are declared. Here’s a function that prints the title of any post ID passed to it:
function print_title($id){ echo get_the_title($id); }
Your script could call it like so:
print_title(237);
and the title of post 237 would be sent to the client browser.OK, here’s how to get a rudimentary plugin set up using the code above. Make a new folder in your plugins folder to hold your plugin file. Name it the same as your plugin name. Make a new .php file also with your plugin name as file name. Place the required comment header at the top. See Writing_a_Plugin#Standard_Plugin_Information. Below the header, place the wp_enqueue_script() example PHP code above. Save the file and upload to your server.
Create a folder in your plugin folder named ‘js’. Start a new javascript file and place the above changeTarget code in it. Save it as my_javascript.js and upload to the ‘js’ folder.
This last bit involves hacking your theme for illustration purposes. You’ll need to find a better way to do this for real at some point. This is just a short cut to illustrate the process. Make a backup copy of your theme’s header.php template, or whatever template has the
<body>
tag. Inside the body tag of the working header.php, insertonload="changeTarget();"
and immediately after the body tag add<div id="target">Text that bots see</div>
Save the file and upload.Log into your site and activate your plugin. View your site and you should see “Only javascript users see this” at the very top of the page. But when you view the source code of the page in your browser, after the body tag inside the
<div id="target">
you will still see “Text that bots see” because javascript does not alter source code, only what is displayed on the live page.If this does not work, check the browser error console for possible javascript errors. If you get a white screen, there was a PHP error. Either check your error logs or set WP_DEBUG to true in wp-config.php to see the error message.
I’m sorry I can’t give you a better example. For similar reasons, I can’t currently verify I’ve given you error free code either. I will not even consistently have access to a computer, so I could not say when I’ll be able to check back in again. But I will check back when I can. Good luck.
You have no idea how much of a help this is! Thank you so much!!
I am having a bit of trouble activating the js script. The plugin is activated, the information was inserted into header.php. However, no part of the javascript is being seen. I have it enabled on my browser. With the basic knowledge I have of all of this, I would assume that everything would activate. Although, as the script within header.php runs, how would it know where the “changeTarget” is? I would assume if ithat was within the plugin-name.php, it would be able to locate the file and the script within the file, but would the header.php file be bale to do the same?I thought about why it wouldnt run and i realized that the plugin-name.php did have an action hook that involved running when the header.php was ran. This is what i have for the code for the .php file:
<?php function my_scripts_function() { wp_enqueue_script('my_javascript'); // .js assumed } add_action( 'wp_head','wp_enqueue_scripts', 'my_scripts_function' ); ?>
I have the file header and license in the script as well. I didnt think there was a need to state it on here.
Something seems off about how is put into the script.. I’m not sure what it is because i am new to all of this.
The code:
add_action( ‘wp_enqueue_scripts’, ‘my_scripts_function’ );
is just saying, launch my javascript file, correct. But if ‘wp_enqueue_scripts’ is mentioned and ran in the ‘my_scripts_function’ actiction hook, is it needed to be ran again?
and after that train of thought, wouldn’t it just need to be:<?php function my_scripts_function() { wp_enqueue_script('my_javascript'); // .js assumed } add_action( 'wp_head', 'my_scripts_function' ); ?>
Isn’t that just saying, when wp_head is activated, activate the action hook ‘my_scripts_function’ and that will activate ‘wp_enqueue_script which will activate ‘my_javascript’?
If my thought is correct, im not sure how header.php gets the information from my_javascript.js
I tried just running:<?php function my_scripts_function() { echo:'hello world'; } add_action( 'wp_head', 'my_scripts_function' ); ?>
and the text ‘hello world’ was displayed on the page
Kudos to bcworkz for the clear and detailed descriptions. This should be turned into a beginner’s PHP tutorial or something.
I dont think i can thank him enough, i have learned so much from the questions he’s answered. i know many people will also learn a ton of info when googling anything somewhat related to this subject
Thanks all for your encouraging words, feedback like that encourages me to keep doing this support work.
@burgejos000, I’m afraid I changed tactics on you without adequate warning. Your PHP should be like this:
function my_scripts_function() { wp_enqueue_script('my_javascript'); // .js assumed } add_action( 'wp_enqueue_scripts', 'my_scripts_function' );
Note that the ‘wp_head’ tag was changed to ‘wp_enqueue_scripts’. Using ‘wp_head’ was a tag I used for a generic example. Once we started talking about a specific application, ‘wp_head’ no longer worked, ‘wp_enqueue_scripts’ is the only hook that will work for this specific application.
(There’s also a javascript error in the code I provided ?? More on this about 2/3 down below, search for “Oh crap!” if necessary)
As a learning experience, this is why your
add_action( 'wp_head','wp_enqueue_scripts', 'my_scripts_function' );
does not work. First, ‘wp_head’ is the wrong hook for what we’re doing. Some hooks can be substituted for others, but that is an unusual situation, one usually cannot substitute hooks.Second, when you add an action hook, the hook process tries to execute the second argument, in this case ‘wp_enqueue_scripts’. This is an actual WP function, which was executed, as it turns out, at the appropriate time, so no harm was done, but your real function was not executed either. The third parameter where you specified your function is supposed to be an integer for the execution priority. Not being an integer, I suspect your parameter was ignored.
To answer another stray quandary you had, yes you did not need to post the plugin header comment text because your hello world test demonstrated the plugin was activated properly, which is the only point of the text. If there was a question if activation was successful, then perhaps posting a copy might have helped locate the problem.
To hopefully clear up some confusion on how code gets triggered to run, here’s a summary. Somewhere in the WP core code, at the appropriate time, the function
do_action('wp_enqueue_scripts')
is executed. This causes all functions hooked to this action to be called, including ourmy_scripts_function()
, which of course enqueues our javascript file. What ‘enqueue’ actually does is cause a HTML meta link tag to be inserted into the page’s head section. Thus, when the page loads, the javascript file is loaded as well, so the page knows what functions are defined, and any code not in a function is executed immediately. Hold that thought.A minor sidebar: As our PHP is currently written, our javascript file is loaded on every page. As a 4 line file, not a big deal. But substantial files should not be loaded unless necessary. One would typically put the wp_enqueue_script() call inside a conditional so it is loaded only when needed. There are several template tags we can use to check the condition such as is_home(), is_archive() etc.
Anyway, now our javascript file is loaded along with the HTML page. On that page, various templates get loaded. Somewhere in these templates, a call to our javascript function
changeTarget()
needs to happen, or our function will never run. This could be where the problem is, but there is another possibility, more on that later.I choose to call our function from the ‘onload’ action of the
<body>
tag. This means once the entire body element is loaded, our function is called. To do this, our body tag should look like so:
<body onload="changeTarget();">
Ensure you edited your theme’s template file in the same manner.So when the body is loaded, our function is called. The javascript engine sees the
var targetDiv = document.getElementById("target");
line, so it searches the page for any element with the ID “target”. When found, it assigns that element’s properties and methods to the variable “targetDiv”. At this point, the .innerHTML property is “Text that bots see”Oh crap! There’s the problem! My bad! So sorry, novices should not have to be frustrated by my ineptness! I originally coded
.innerHtml
but the correct version is.innerHTML
, HTML all upper case! Fix that and it should work! Most javascript is camelCase where with each new word only the first character is upper case, like getElementById, and not getElementByID. .innerHTML is one of the few exceptions. I haven’t coded javascript for a while and this variance slipped my mind. I’m not trying to make excuses, it’s my bad and no two ways around it and I feel badly. I just wanted you to see even experienced coders like myself make really stupid errors that can be very difficult to discover. It’s a learning opportunity, not a mistake ??Anyway, to finish the explanation, our next line of code assigns a new value to the .innerHTML property and the javascript engine automatically updates the page display to reflect the newly assigned value.
The other thing that could go wrong that I alluded to earlier is some page element, such as perhaps the header image by some CSS directive, could have overlaid our text, such that even though it’s there, you cannot see it.
Finally, the best way to track down stupid javascript coding errors such as mine is to check you browser’s error console. In Firefox it’s under the Web Developer sub menu pick a few lines up from the bottom. Not sure where to find it in other browsers, but they all have one. You will see an error message similar to “targetDiv does not have innerHtml property defined in wp-content/plugins/myplugin/js/my_javascript.js”. If you follow the link, it’ll show you roughly where the error occurred, though sometimes this is where the processing failed, the actual error can be several lines above.
Whew! Lots of stuff to learn, eh? Don’t worry, while it takes time, it will all eventually sink in. I know it’s often frustrating, but revel in the sense of accomplishment when you get some code snippet working, for me it’s a nice little rush. I hope for you as well. I still only intermittently have computer access for now, I’ll check back in when I can. Cheers!
lol. its alright if you make a mistake, im learning a ton of information. and its actually a lot to process. i had to read through your post 3 or 4 times to soak it all in. You have no idea how big of a help this. the codex only tells you so much, and its not very helpful to those completely new to the subject.
one question i have that may be a little off topic, but a question that im pondering is, when i use the wp_enqueue_scrip(‘file-name’), is there a reason the file extension isn’t being used? like i may have two files with the same name, but with different extensions. Obviously it would be a lot less confusing if i named each file differently, but just out of curiosity, why isn’t the file extension needed?
Now back to the topic, I currently have two scrips in my plugin folder and i edited the header.php
header.php snip it:</head> <body onload="changeTarget();" <?php body_class(); ?>> <div id="target">Text that bots see</div> <?php if ( !get_theme_mod( 'background_image', false) && !get_theme_mod( 'background_color', false) ) : ?> <div class="bg-gradient"> <?php endif; ?>
my-pluglin.php:
<?php /* plugin details, licensing and such */ ?> //I don't need to end and start a new php code, correct? <?php function my_scripts_function() { wp_enqueue_script('my_javascript'); // .js assumed } add_action( 'wp_enqueue_scripts', 'my_scripts_function' ); ?>
my_javascript.js:
function changeTarget() { var targetDiv = document.getElementById("target"); targetDiv.innerHTML = "Only javascript users see this"; }
I believe this is all that i need at the moment, correct? also, the .js file should be put where?
in this directory: plugins/my-plugin/
or in this one: plugins/my-plugin/js
I believe you told me to put it in a folder called js. (i tried it in both directories to see if that might be a problem)
And off of that, yet another question. Would it matter if the .js file was in the same directory as the my-plugin.php or in its own folder?Thus, when the page loads, the javascript file is loaded as well, so the page knows what functions are defined, and any code not in a function is executed immediately.
How does the header.php know where that script is located?
If i might ask, what do the tags getElementByID and .innerHTML do?
and lastly, about what you said here:One would typically put the wp_enqueue_script() call inside a conditional so it is loaded only when needed.
If i only wanted it display on one or two pages, would i use something like:
if(is_post’1557′)?
and if so, how would that be set up? my guess is that it may look like:
function my_scripts_function(if(is_post’1557′)) {
wp_enqueue_script(‘my_javascript’); // .js assumed
}
or something like that, but while being new to this, im not sue if that is set correctly.Aren’t we the inquisitive one? ?? I love it! You ask some intriguing questions. About the file extensions for wp_enqueue_script(). I’ve no idea how this works. I’ve tracked through the source code and see no indication of where this happens. Perhaps it’s magic??? I would suggest experimenting once you have a working script and try providing various file extensions. From what I’ve seen, this may just work fine, but I can’t be sure, and I currently cannot access my test installation to try myself.
As far as where to put the file, I always put javascript files in the plugin’s
/js/
sub folder, thusplugins/my-plugin/js/
. This follows the convention of the WP core files and keeps things organized. I believe it can reside anywhere in the plugin folder structure and be found, but I’ve never actually tried anything different. Once again, experiment! The worst that will happen is your site will crash. Not like that hasn’t happened before, eh? ?? Easy enough to undo the test and restore functionality. At least this time you’ll know exactly what went wrong.Of course, this is all dependent on you getting the script functioning first of all, which it sounds like you have not yet achieved ?? That’s going to take some study, but first I’ll address your other questions.
How does the header.php know where that script is located?
Well, it doesn’t directly. The header file makes a call to wp_head() which in turn executes all functions hooked into the ‘wp_head’ action. WP actually uses it’s own hooks sometimes, they are not just for coders to use to extend WP functionality. This is where things get murky as I mentioned earlier, I could not find the part of the code that does this. Based on the results, my best guess is when you enqueue your script, the code walks through the folder structure starting with the folder in which the current code page making the call resides. Once the script is found, it’s actual path is stored in a global array, possibly $wp_scripts. An action hook is added to ‘wp_head’ just as you might do for one of your own scripts. This hook echoes out the link meta tag with the correct path when it is called by the wp_head() function by way of
do_action(wp_head);
.what do the tags getElementByID and .innerHTML do?
They are not tags actually, they are javascript object methods and properties. .getElementById() is a method of the
document
object, which represent the entire HTML page. The method finds the one HTML element that has the specified id attribute and returns it, which is assigned to whatever variable you want it to be, in our casetargetDiv
. So nowtargetDiv
is an object representing the div element with the id of ‘target’. .innerHTML is a property of any HTML element object which is set to what ever the HTML contents of that element happen to be. When we assign a new value to the property, it’s new value is immediately updated on the browser page. This is one of the ways we use javascript to change certain portions of page content without the need to reload the entire page.If i only wanted it display on one or two pages, would i use something like:
if(is_post'1557')
?Right idea, but the code looks different. For this example, you need two checks. One is that the hook fired for a single page, otherwise, because of the method we use in attempting to obtain the current post ID, the conditional could return true during an inappropriate condition, say an archive page. The other check of course is to confirm a particular post ID is being shown. There’s several ways to do this, one is to take advantage of the fact that when inside the ‘loop’, the current post object is stored in the global
$post
. So our code could look like this:function my_scripts_function() { global $post; if(is_single() && $post->ID == 1557){ wp_enqueue_script('my_javascript'); } }
Let’s also look at how your code is wrong, which is perhaps even more instructive than the correct example.
function my_scripts_function(if(is_post'1557')) {//more...
First, the parenthesis after a function name is for passing parameters, you cannot put code to be executed there, it must be after the parenthesis, inside the curly bracket {} portion.
Second, assuming is_post were a defined function (it’s not), you cannot append a parameter directly, it must be inside parenthesis. (also, the is_*() family of template tags do not accept parameters, they only determine if the current query is of a particular general type, not if the query is for a specific item).
Finally, post IDs are integers, so you do not use quotes to use integers, quotes are only used for strings. So assuming your is_post() function worked the way you expected, the correct form of your example would be like so:
function my_scripts_function() { if(is_post(1557)){ //more...
To illustrate passing parameters, which is what we are doing when we place a value inside the parenthesis following a function name, the definition if your is_post() function may look like this:
function is_post($id) { global $post; if($post->>ID == $id) return true; else return false; }
That out of the way, I’m now looking at your code, hoping to see what’s wrong, and I see another question! ?? Yes, you do not need to open and close php blocks if there is no intervening HTML content. Even if there is, to keep things tidy, there is the option of echoing out the HTML content within the single large php block instead of closing and opening the php blocks just to insert some HTML. Examples:
<!-- the next two lines are equivalent: --> <?php add_action('one'); ?><?php add_action('two'); ?> <?php add_action('one'); add_action('two'); ?> <!-- the next two lines are equivalent as well: --> <?php add_action('one'); ?><div><?php add_action('two'); ?> <?php add_action('one'); echo '<div>'; add_action('two'); ?>
The other thing is your inserted question as a comment is the wrong syntax:
?> //I don't need to end and start a new php code, correct? <?php
Text outside php blocks are treated as HTML, so your question here is output to the browser. It shouldn’t normally prevent your script from working. However, it does occur when WP is initiating itself, so HTML output at this point could break things, as no header() calls will not work after such HTML is output. I’m not sure how badly broken header() calls will break things, but you’d best simply remove this comment/question if it is in fact in your actual script.
Other than that, I don’t see any other issues. It’s quite possible I made some other stupid mistakes, and I’m too stupid to see them ?? I would normally test my script myself at this point, though I really should have done so when I first provided it. Yes, I’m lazy, I don’t test all the example scripts I provide. It’s usually not worth it, but this practice has bitten me back a few times. It appears to have done so once again ?? Unfortunately, I’m not able to test my script myself right now, and it’ll be a bit over a week more before I am able to do testing again.
We can continue to chat in between, limited by my erratic accessibility to the ‘net, but I can’t make any more suggestions as to what may be wrong without doing my own test. So you may have to put this little project aside until I can assure you the code I provided is flawless. You appear to have done everything right, code looks good, the files are in the right place, you know the activation works from the successful hello world test.
Maybe it’s time to learn about debugging! For PHP, this mainly means checking that code reaches certain points and that certain variables contain expected values by inserting calls to print_r() or var_dump() at strategic places in the code to be tested. Sometimes WP output will overwrite this test output, so sometimes you need to place a call to die() to stop execution to prevent overwriting. Continue with this process at various strategic points until you locate where things had gone wrong.
The other important thing to do is set WP_DEBUG to true in the wp-config.php file so you see actual error messages instead of a blank white screen when things go wrong.
Javascript is similar, you place alert() calls to pause execution and display a variable value or two. You are aided by the browser error console telling you roughly where the errors are occurring. For serious javascript development there is also a debugging browser plugin. It’s not that user friendly and is overkill for basic javascript code. Using these techniques and logical deduction, you should be able to identify the problem that is preventing successful execution of your script. See what you can do with that. Like I said, if all else fails I can do my own debugging in a bit over a week when I gain access to my test server. Sorry I can’t be of more immediate assistance.
Hello there, I’m back, and I’ve checked my scripts on my test server. The one problem is how your javascript file is specified when enqueued. It apparently must be explicit, as in:
wp_enqueue_script('my_javascript', plugins_url().'/my-plugin/js/my_javascript.js');
The simple form I previously suggested works fine in themes, but fails for plugins. When using the explicit form, my scripts work correctly. If need be, I can post my complete test scripts on pastebin, with the warning that they were altered for my test environment and do not exactly match up with your situation. I’m hoping this modification will get you going without more input, but I’ll post the scripts if need be.
- The topic ‘Run a script on the home page?’ is closed to new replies.