I am really a Drupal developer but got asked to do a bit of Wordpress work and need a little help.
I am running WP3.8.x
We are using a purchased Auction Theme and I wish to extend it's functionality by adding another payment gateway.
Here is what I have:
The Auction theme registers a new admin menu
add_action('admin_menu', 'AuctionTheme_admin_main_menu_scr');
Then registers the sub page
function AuctionTheme_admin_main_menu_scr()
{
add_submenu_page(
"AT_menu_",
__('Payment Gateways','AuctionTheme'),
AuctionTheme_disp_spcl_cst_pic('gateway_icon.png') . __('Payment Gateways','AuctionTheme'), $capability, 'AT_pay_gate_', 'AuctionTheme_payment_gateways'
);
do_action('AuctionTheme_new_page_admin_menu');
}
And finally the payment config page is created.
function AuctionTheme_payment_gateways()
{
echo 'The Markup';
do_action('AuctionTheme_payment_methods_action');
if(isset($_POST['AuctionTheme_save1'])) {
update_option('AuctionTheme_paypal_enable', trim($_POST['AuctionTheme_paypal_enable']));
}
}
Obviously I removed some code as it's not relevant to my question.
So we have our own child theme called mytheme. I thought I could just add a new action?
So in mytheme function file added
add_action('AuctionTheme_payment_gateways', 'mytheme_payment_gateways');
function mytheme_payment_gateways () {
echo 'Test';
}
I don't see test in the page …. should? Or how do I go about adding?
In order for your add_action to work, you must have a do_action that calls the same tag.
So, for example, you have:
add_action('AuctionTheme_payment_gateways', 'mytheme_payment_gateways');
Which means that somewhere in your code (parent or child theme) you must have the following:
do_action('AuctionTheme_payment_gateways');
So, based on the code you have, I suspect you want to add it here:
function AuctionTheme_payment_gateways()
{
echo 'The Markup';
do_action('AuctionTheme_payment_methods_action');
if(isset($_POST['AuctionTheme_save1'])) {
update_option('AuctionTheme_paypal_enable', trim($_POST['AuctionTheme_paypal_enable']));
}
// Add below do_action
do_action('AuctionTheme_payment_gateways');
}
Of course that's just a guess based on your code - you may need to add the do_action somewhere else, but hopefully this explanation gets you pointed in the right direction.
Related
I have this in my index.php file. It adds the home banner image in WordPress. I know that it is mostly generated in WordPress customizer, but I need to add an anchor tag in this section. I can't find it anywhere in the file structure.
<?php do_action('cleanblog_index_top'); ?>
I'm not able to find where cleanblog_index_top leads to. Any help would be great. Thank you!
I stumbled on this old one while looking up the docs for do_action(). The answers are brutal so I decided to provide a better answer in case anyone else stumbles here.
If a WordPress theme has something like do_action( 'example_action_hook_tag' ) somewhere in one of the template files (such as index.php, page.php or whatever) the purpose is to provide theme or plugin authors with a way to write their own custom function that they can then "hook" onto the action with the function add_action().
WordPress would then call this function any time and anywhere do_action( 'example_action_hook_tag' ) is called.
The creators of commercial themes will often litter their template files with hooks declared with do_action() to make it easier for their customers to customize their themes via functions.php or by writing a site-specific plugin.
It looks to me that this is the likely scenario that is impacting the OP. This also explains why the OP was unsuccessful in finding where this "leads to".
It would only "lead somewhere" if the OP wrote a function in the theme/child-theme functions.php or in a plugin and added the line do_action( 'cleanblog_index_top', 'name_of_ops_function' ) to hook their function onto the cleanblog_index_top. WordPress would then call their function when do_action( 'cleanblog_index_top' ) was called in index.php.
From the name of the OP's hook, cleanblog_index_top, it sounds like the theme author intended to provide a way for others to inject output at the top of the index page template.
Suppose the OP wanted <h1>Hello World</h1> to appear there.
In functions.php of a theme/child-theme the OP could add a function that echo's this out:
function op_customization() {
echo '<h1>Hello World</h1>';
}
And hook their function onto cleanblog_index_top:
add_action( 'cleanblog_index_top', 'op_customization' );
Cheers!
You should never edit the index.php file directly, for the same reason you should never edit core Wordpress files directly - the next time WP pushes an update, your changes will be overwritten (and that assumes you don't break anything). Never edit plugin files directly, same reason.
You need to look in your theme, you should only make changes to the functions.php and style.css files in your theme - unless you create a child theme and that is a topic you should Google.
I have a function in my theme functions.php file which returns a value:
function my_theme_function() {
return "100";
}
Anywhere in my theme templates I can simply do this...
echo my_theme_function()
...and I see the number 100 on the page. That's cool.
But in my plugin I would have expected to be able do also get access to this function by echoing my_theme_function() but instead I get a 'call to undefined function' error.
The strangest part is I'm certain this was working a couple of days ago, but I've not touched the code since. I suspect some WordPress shenanigans, but I don't know why or how to get around this.
The reason you may take this result can be the order in which the theme and the plugins are loaded.
For example, your plugin can get loaded before the theme, and obviously, in this case, the function it is not available in your plugin source code.
The solution to this issue are the WordPress Hooks. I don't know what is your plugin code style, but you can bootstrap your plugin in the init hook or even better in the after_setup_theme.
So for example, let's say, you need your plugin should run once your theme is loaded by the WordPress. You can use the following code to do so:
function my_theme_is_loaded() {
// Bootstrap your plugin here
// OR
// try to run your function this way:
if ( function_exists( 'my_theme_function' ) ) {
my_theme_function();
}
}
// You can also try replace the `after_setup_theme` with the
// `init`. I guess it could work in both ways, but whilw your
// plugin rely on the theme code, the following is best option.
add_action( 'after_setup_theme', 'my_theme_is_loaded' );
What the above code does, is like you say to your plugin, wait until the theme is totally loaded, and then try to run my plugin code that rely on the theme code.
And of course, I suggest either wrap your theme function in a plugin function like that:
// This way, your plugin will continue running even if you remove
// your theme, or by mistake your rename the function in the theme
// or even if you totally decide to remove the function at all in the
// side of the theme.
function function_from_theme() {
if ( function_exists( 'my_theme_function' ) ) {
return my_theme_function();
} else {
return 0; // Or a value that is suitable with what you need in your plugin.
}
}
This is going to protect your site against theme de-activation or theme change. In this cases, you are going to have a plugin looking for a function in your theme, and while you change the theme or deactivate your theme, your plugin will break your site.
I'm using a plugin which adds a submenu item to an admin menu like so:
add_submenu_page( 'propertyhive', 'Property Hive Settings', 'Settings', 'manage_options', 'ph-settings', 'callback_fn' );
Due to it stating manage_options it only appears for administrators. I need to show it for editors. Here's what I've tried in my theme's functions.php file:
add_action( 'admin_menu', 'custom_settings_menu', 99 );
function custom_settings_menu()
{
// Remove the submenu item first
remove_submenu_page( 'propertyhive', 'ph-settings' );
// Add it again but with different role (manage_propertyhive)
// This role does exist as other submenu items ue it
add_submenu_page( 'propertyhive', 'Property Hive Settings', 'Settings', 'manage_propertyhive', 'ph-settings', 'my_theme_callback_fn' );
}
Although this does show the submenu item correctly, I get the following error:
Sorry, you are not allowed to access this page.
Can anyone see anything obvious or have any inclinations as to what might cause this?
Note: The manage_propertyhive capability definitely does exist
I believe this is happening because 'manage_propertyhive' is not a defined capability, therefore nobody will have access to that menu. You can either use one of the predefined wordpress capabilities which you can find here or you can define your own custom capability such as 'manage_propertyhive', by following the instructions here.
Hope this helps!
1) Are you sure the add_submenu_page() function from the Plugin is copied correctly? add_submenu_page() accepts only 6 parameters - in your question it has 7 paramters with propertyhive being the capability and manage_options being the menu_slug (which is perplexing)
https://developer.wordpress.org/reference/functions/add_submenu_page/
2) I guess that administrators as well as editors got the capability manage_propertyhive ? If not make sure.
3) In your sample code the callback function for the new propertyhive submenu page is my_theme_callback_fn - did you insert the correct callback function here?
4) The fact that you add the submenu page to editors does not necessarily mean they can access that page - did you check the Plugin for further capability checks? Maybe in the code of the callback function or in some other function of the Plugin capabilities are checked again and editors are missing some capability.
This must do the trick
function add_theme_caps() {
$role = get_role( 'editor' );
$caps = (array)$role->capabilities;
if(!array_key_exists('manage_propertyhive', $caps)) {
$role->add_cap( 'manage_propertyhive' );
}
}
add_action( 'admin_init', 'add_theme_caps');
Assuming you've set up the capability right, perhaps the parent page is not allowing access to submenu page, make sure user is able to access parent page...
This is the function that checks if user can access the page... If it returns false the error is displayed...
https://github.com/WordPress/WordPress/blob/4.6.1/wp-admin/includes/plugin.php#L1697-L1763
Besides checking several other things, it also checks if parent page is accessible by the user.
If that doesn't work, I'd suggest you to go to this file on you local install, and var_dump all vars that are checked before returning false, this is how we devs debug the errors... ;)
Make sure to restore the file to original file ( I just update the WordPress again, that restores all core files to their original state )...
Hope that helps.
I'm trying to allow my page to receive query variable but to rewrite it to nice permalink. So I wanted this
example.com/wordpress-page/random
So I don't want random to be a subpage or something like that, since it's coming from outside service. In order to do this, I've added this code to my functions.php
function add_my_var($public_query_vars) {
$public_query_vars[] = 'my_var';
return $public_query_vars;
}
add_filter('query_vars', 'add_my_var');
function do_rewrite() {
add_rewrite_rule('wordpress-page/([^/]+)/?$', 'index.php?name=wordpress-page&my_var=$matches[1]','top');
}
add_action('init', 'do_rewrite');
When I go to example.com/wordpress-page I get my page, but when I go to example.com/wordpress-page/random I get 404 page.
I have flushed rewrite rules by saving permalinks in wp-admin panel.
Where did I go wrong?
I found I needed to call the flush_rewrite_rules() function. That was done in addition to the query_vars action hook and add_rewrite_rule() function you already demonstrated above.
In my case I chose to put it in my theme's functions.php using the switch_theme action hook and deactivated/reactivated my theme. But you can probably put it elsewhere as long as it get's called once at some point (so probably not 'init')
add_action('switch_theme', 'mytheme_setup_options');
function mytheme_setup_options () {
flush_rewrite_rules();
}
I am working on a wordpress site and would like to clarify a basic concept that is definitely very important, and this is how to customize/extend a wordpress hook (at least that's what I think I want to do!)
As the real world example, I am setting up a wp-ecommerce site. When a user adds an item to the cart, I would like to do one or two more things than the original function does. Looking through the source, I find:
/wp-content/plugins/wp-e-commerce/wpsc-includes/ajax.functions.php
with the function:
function wpsc_add_to_cart()
I know I could simply edit the code right here, but obviously that is the completely wrong way to go about it as when the plugin is updated, I will lose changes. What is the correct way to extend a function that is part of a plugin, or wordpress for that matter?
Endless thanks in advance.
You can use the wordpress action hooks to resolve the code loss while plugin upgrade.
You can remove the function which is in plugin file by using remove_action hook and do your own code by adding add_action in your function.php file. So that you can customize your plugin code from theme's function.php.
Here are the examples to explain.I hope it will help.
http://codex.wordpress.org/Plugin_API
http://themeshaper.com/2009/05/03/filters-wordpress-child-themes/
I use a little supressed notice function (it lives in my child themes function.php page), for plugins that get irritating eg: please setup twitter account to use , this kind of warning is not useful at certain stages and sometimes just do not care for it.
function supressed_notices_active(){
echo '<div class="error"><p>Supressed Notices are active</p></div>';
}
if(function_exists('the_plugin_custom_function_call')){
remove_action('the_plugin_custom_function_call' );
add_action('admin_notices','supressed_notices_active');
}else{
function test_message_from_me(){
echo '<h1>show</h1>';
}
add_action('admin_notices','test_message_from_me');
}
So I create the supressed notice function to at least create a warning, so i remember.
Check if the target function exists with the function_exists($target_function) hook
then remove this action from running with the remove_action($tag,$target_function) hook
then just add your custom function with the add_action($tag,$target_function) hook (do not need to have a separate function this could just be a closure)
then else if the function does not exist either still run a new action or leave this section, it can be useful for testing to just add anything so you atleast get some feed back.
What you could try... Copy the function within the plugin file,
paste it into your themes functions.php file,
ie:
function wpsc_add_to_cart() {
global $wpdb, $wpsc_cart;
// default values etc..etc..
// new code here?
}
the only thing with this is, if the plugin is updated and that funciton is renamed or removed, changed or something you could start to run into trouble...
could you not ask the plugin developer to possibly add your requirements to it,
possibly for a small fee? but if your using it as your main shopping cart, then chances are, that small investment could be a good thing.
Marty