There is absolutely no recommended way of overwriting core files, and we haven’t had to do this in more than 7 years of working with WordPress. There are so many hooks it’s unbelievable, and anything that doesn’t have a hook could still be included in some way through custom PHP in your theme or a plugin.
This isn’t just moderators being tentative or holding back – there is literally no reason to hack the core on a production site. If WordPress really doesn’t achieve what you need it to, then it’s the wrong solution to the problem you’re trying to solve. (But we’ve also built some really advanced stuff in WordPress so that’s not always the case either.)
Moderator
Jan Dembowski
(@jdembowski)
Forum Moderator and Brute Squad
You can modify the core files. You can also hit your head on the desk if you want, though I’m pretty sure you don’t do that. 😉
There is never a case where modifying any file that ships with WordPress. Honest. There are miles of filters, actions and theme options that can get you almost anything you want to do.
Neither of your solutions work. The first solution will stop working because the part you are modifying will drift and in a few versions your hack won’t work.
The second solution won’t work either. Those files aren’t meant to be included that way. Using actions and filters will probably accomplish what you are trying to do.
Note: I’ll open a separate question related to the underlying problem I’m having with a particular core file.
Or you save time: what are you trying to accomplish?
OK, thank you for your replies.
If there is a filter or hook for the function I am trying to override, it is not entirely obvious as to how it should be done, because there are no actions or hooks added for the function within the file itself, and I’ve reviewed the entire list of filters, and there are none that pertain to this function specifically.
I think that if there is a hook to override a file or function, then unless it can be found within the file that contains the function you should expect people to try to override that file. Clearly these cases exist and so it seems that there should be a way to override the file. Not that I’m saying it is wise to do so…
Anyway, here is a link to the underlying problem I am trying to solve, but I think it is irrelevant to this conversation…
New Nine mentioned that:
anything that doesn’t have a hook could still be included in some way through custom PHP in your theme or a plugin.
Perhaps, this is what I am talking about. What is the recommended way of doing this?
We build our themes and plugins using PHP classes, but I’ll exclude that so as not to complicate the issue…
Let’s say you want to integrate the Mailchimp API so that visitors can sign up to your email newsletter through your site, but you don’t want to send them to the Mailchimp signup form and you don’t want to use a plugin. There are many ways to accomplish this, but as an example:
You download the Mailchimp PHP SDK and put that into a folder in your theme (let’s call that folder mailchimp). Now, your theme folder looks something like this:
footer.php
functions.php
header.php
index.php
style.css
mailchimp/
When someone clicks your “Subscribe” button, you want to capture that information, connect with Mailchimp via the SDK, and then continue loading your site after adding the user to your list. To do this, you need to include (for example) the init.php file in the mailchimp
directory when the form is submitted:
add_action( 'init', 'my_mailchimp_subscribe' );
function my_mailchimp_subscribe(){
// If the form was submitted with the EMAIL variable
// let's load the mailchimp file and add the user
if( $_POST && is_email( $_POST[ 'EMAIL' ] ) ){
// You're in a custom theme. If mailchimp is in a child theme
// you'd use get_stylesheet_directory() instead
require_once( get_template_directory() . '/mailchimp/init.php' );
// Mailchimp is now loaded and we can add the user
...
}
}
And that’s it. You can put whatever you want in your theme (or a plugin) and then include it when you need it. You could use WordPress hooks to determine when to include code and when not to so you don’t slow your site down, loading resources when they’re not needed.
OK, that seems like the kind of thing I was looking for. I still have some questions about that though: Why put the require_once inside a function? Is that to cause the resources to be loaded later?
Also, Is there a significant reason to use “require_once” instead of just “require” or “include” in a functions.php file?
I put the require_once
inside the function so it’s only called when the function is run, because I need it on demand at that time but I don’t need it to load, for example, when someone is just viewing the home page. Why slow the site down?
I prefer require_once
because it first checks if the file has been required and, if so, doesn’t bring it in again. I prefer require/require_once
over include/include_once
because require/require_once
will kill my script if it runs into an error vs. include/include_once
which just generates a warning.
During development, I want to write bug-free code. I’d rather my site/application die/end/freeze during development so I can debug it and get it right before I release it into production. Plus, I find it makes finding the error easier because if I require
something, hit save, reload, and my site crashes, I know what the problem is and I’m not banging my head against a wall later wondering why it’s not working when some function I’m trying to access doesn’t exist because it was never actually loaded in!
Thanks New Nine,
Good explanation. Topic resolved!
I just wanted to point out, to anyone else who happens to read this though, that wrapping the require_once statements in a function might not work in all situations. In the case which I referenced above (the underlying problem), my solution did not wrap the require statements in a function because wrapping it caused the file and function to be read after the one that was declared by a function in the parent theme, and that caused an fatal error where the function was being declared twice. I’m not exactly sure why the error didn’t occur when the new function was “required” first, outside the wrapping function, but not wrapping it was the only way I found to get it to work in my child theme… Weird…
One more note: “init” is a keyword that also has peculiar behavior. In one testcase, I found it to force the add_action to be called in the child theme <i>after</i> the same function was called in the parent theme. If that word is changed to ‘my_init’ the function is called before the parent theme function. Somewhat counter intuitive, that is…