I am trying to unhook and modify an action from within my child themes functions.php file.
The WordPress plugin Sensei, adds this action in line 86 of this document.
https://github.com/Automattic/sensei/blob/master/includes/class-sensei-modules.php#L86
The action references a function further down the page that is responsible for outputting a dynamic header element.
/**
* Show the title modules on the single course template.
*
* Function is hooked into sensei_single_course_modules_before.
*
* #since 1.8.0
* #return void
*/
public function course_modules_title( ) {
if( sensei_module_has_lessons() ){
echo '<header><h2>' . __('Modules', 'woothemes-sensei') . '</h2></header>';
}
}
My goal here is to change the html currently output as 'Modules' to something else.
I have tried to the following in my child themes functions.php file but neither seem to be working.
remove_action( 'sensei_single_course_modules_before', array( 'Sensei_Core_Modules', 'course_modules_title' ), 20);
remove_action( 'sensei_single_course_modules_before', array( 'Sensei()->Sensei_Core_Modules', 'course_modules_title' ), 20);
The issue is, I do not know how to determine which initial parameter, to add to the array to call the correct class. Because I am accessing it externally I cannot use $this like it is being used in the core file.
In order to remove the action you have to find the instance of the class. This is an assumption since I don't have access to the source code of Sensei but big chance there is one since most WordPress plug-ins use this method.
When you find the instance name you can load it using global $senseiInstance - replace this with the actual name of the variable.
Then you can remove the action using for example this code:
remove_action( 'sensei_single_course_modules_before', array( $senseiInstance, 'course_modules_title' ), 20);
More information can be found in for example this article: https://www.sitepoint.com/digging-deeper-wordpress-hooks-filters.
Hope this helps you out!
Related
There is not a specific answer for this exact issue so i am going to try this.
So in the parent theme of a wordpress website there is a php file named helpers-icons.php. The exact path for this file is /wp-content/themes/parent/inc/helpers/helpers-icons.php, and the content of that file is
function get_flatsome_icon($name, $size = null) {
if($size) $size = 'style="font-size:'.$size.';"';
return '<i class="'.$name.'" '.$size.'></i>';
}
This file is then inlcuded in functions.php of that parent theme.
Now i want to override a function inside and being more specific, just this line of code
return '<i class="'.$name.'" '.$size.'></i>'; to return '<span class="'.$name.'" '.$size.'></span>';
how could i do that on child theme without messing with the php files of parent?
Thanks in advance
EDIT
EDIT 2
EDIT - Different Approach
You can copy the file /inc/helpers/helpers-icons.php into your child theme (keep the folder structure - e.g. /child-theme/inc/helpers/helpers-icons.php). That way it will be called instead of the original file and you can change the function there.
(Original Answer) Removing Functions From Hooks:
You’ll need to de-hook the parent function and hook your child theme function instead by using remove_action() and remove_filter().
The one you use will depend on whether the function is attached to an action hook or filter hook in the parent theme.
To remove a function, use:
remove_action( 'init', 'parent_function' );
However, this won’t work on its own, you will need to attach this function to a hook which will fire after the hook which the parent theme function is attached to. This is because you can’t remove the action before it’s been fired.
function child_remove_parent_function() {
remove_action( 'init', 'parent_function', [priority level] );
}
add_action( 'wp_loaded', 'child_remove_parent_function' );
NOTE: If the parent_function() was loaded using a priority level, you have to unloaded by stating the same level as well. That’s why [priority level] is in square brackets.
As you may imagine, wp-loaded is a hook that comes after init, so remove_action() can really remove the parent_function() that was loaded to init.
Now you’re free to write whatever new function you’d like.
function child_function() {
// your function
}
add_action( 'init', 'child_function' );
Source and further reading: https://obsessive-coffee-disorder.com/how-to-override-parent-theme-functions-in-wordpress/
I searched everywhere and could not find.
Now you are my only hope, please help.
Custom page template for global use , don't showing up in wordpress template dropdown when i create custom floder for the template parts.
My-theme/global_template.php WORK
My-theme/template-parts/global_template.php WORK
My-theme/template-parts/archive/global_template.php DON'T WORK
How can I make folders that inside template-parts that contain templates to appear in page attributes->template?
Here the code inside global_template.php
As you see there is no test template..
Your problem is the depth the function thats get the templates have 1 depth. so you must put the files in the theme root or first sub-folder
The core functions get_post_templates() call get_files() with depth 1 and it pass it on to the function scandir() that scan the directories.
You can add more templates manually like this replace the {$post_type} in the add_filter with the post type that you want to add the templates to. for example page.
/**
* #param array $post_templates Array of page templates.
* Keys are filenames, values are translated names.
*/
function extend_post_type_templates($post_templates, $this, $post, $post_type) {
$post_templates['template-parts/archive/global_template.php'] = 'Name for this';
return $post_templates;
}
add_filter( 'theme_{$post_type}_templates', 'extend_post_type_templates', 10, 4 );
I'm trying to extend the customer endpoint in woocommerce api to include some customfields I've created in my functions.php.
But I can't understand how to do it.
I have copied the class-wc-rest-customers-controller.php from the woocommerce plugin (woocommerce/includes/api/) to my woocommerce-folder in my theme as you should do with woocommerce files when you want to edit them.
This is how my class-wc-rest-customers-controller.php looks like:
https://www.pastebucket.com/561405
My plan now was to edit this copy of the file to include my custom_fields I've added in functions.php. But I can't solve this part.
This is the code from my functions.php that I added my custom fields with:
https://www.pastebucket.com/561406
It feels like it is in the function at line 475 in class-wc-rest-customers-controller.php, but I'm not sure.
So I'm wondering where and how should I add my custom fields to this class-wc-rest-customers-controller.php or I'm all wrong about this?
The file overrides apply AFAIK for templates only. In this case you are trying to override a class, which is different.
As you wrote, it's not a good idea to make your changes directly to the file inside WooCommerce directory. In fact, I wouldn't recommend changing the native endpoint at all, except through actions & filters.
One good, re-usable and future-proof way to change the behavior of a WC REST API endpoint would be to create your own endpoint which simply extends the Woocommerce controller class, and overrides the methods which need to be customized. Preferably, try not to override the entire method, but include the call to the parent method in your custom method.
Example solution: (haven't tested this particular one, but made a very similar one recently)
wp-content/plugins/
woocommerce/
your-plugin/
includes/
class-your-plugin.php
your-plugin.php
your-plugin.php
<?php
defined( 'ABSPATH' ) || exit;
add_action('rest_api_init', function(){
require_once __DIR__ . '/includes/class-your-plugin.php';
$controller = new Your_Custom_Class();
$controller->register_routes();
} );
includes/class-your-plugin.php
<?php
defined( 'ABSPATH' ) || exit;
/**
* Class Your_Custom_Class
*/
class Your_Custom_Class extends WC_REST_Customers_Controller {
/**
* Endpoint namespace.
* Use the wc- prefix to make use of WooCommerce authentication for third-parties.
* #see /wp-content/plugins/woocommerce/includes/api/class-wc-rest-authentication.php:63
*
* #var string
*/
protected $namespace = 'wc-your-route/v1';
public function register_routes() {
register_rest_route(
$this->namespace,
'/' . $this->rest_base . '/your-custom-route',
array(
array(
'methods' => WP_REST_Server::EDITABLE,
'callback' => array( $this, 'your_customized_function' ),
'permission_callback' => array( $this, 'get_items_permissions_check' ),
'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
),
'schema' => array( $this, 'get_item_schema' ),
)
);
}
/**
* Your custom function
*/
protected function your_customized_function( $arg1, $arg2) {
/*******************************
// IMPLEMENT CUSTOM CODE HERE
*******************************/
parent::the_name_of_the_original_function( $arg1, $arg2 );
/*******************************
// IMPLEMENT CUSTOM CODE HERE
*******************************/
}
This way you can freely extend the API for your own needs, take advantage of all current and future features of the WC API, and preserve the native API... well.. native.
While this should be a clean and "correct" solution, I would not recommend going for this path without a solid understanding of PHP classes and inheritance, as well as a good IDE to work with.
So it seems I managed to solve it.
I couldn't overwrite the class-wc-rest-customers-controller.php by copying it to my-theme-folder/woccomerce/includes/api/
So instead I just overwrote it and kept a backup of the original. But I now also need to keep an backup of of the class-wc-rest-customers-controller.php file I overwrote with.
This isn't the correct way of doing it, but this was the only way I could sole my problem.
UPDATE: Seems like I cannot update these values through the api. So this was not a solution at all.
I have a plugin that uses apply_filters like this:
$additional_fields = apply_filters('attachment_meta_add_fields', $additional_fields);
In my theme's functions.php, I do:
function addAttachmentMeta($additionalFields) {
return $addtionalFields;
}
add_filter( 'attachment_meta_add_fields', 'addAttachmentMeta', 1, 1 );
But the function addAttachmentMeta never runs.
How can I alter my apply or add filter statements to make it so that addAttachmentMeta gets called?
Edit:
This is a custom plugin that I wrote based off tutorials on how to add additional attachment meta fields. The whole source is here: http://pastebin.com/7NcjDsK5. As I mentioned in the comments, I know this is running and working because I can add additional fields in this plugin file, but not by using the filters because the filter doesn't get added.
I can see var_dumps before and after the apply_filters statement, but the function I've pointed to with add_filter never gets called.
According to the order WordPress' core loads, function.php gets called after all plugins are loaded and executed.
You need to make sure the apply_filters() in your plugin runs AFTER your add_filter() is called. Otherwise at the point where your filters are 'applied', add_filter() simply hasn't been called yet.
What you could do is use a hook to make that part of your plugin run after functions.php has loaded. You could use the add_action('after_setup_theme', 'function_name') hook.
Wrap the last three lines of your plugin file inside a function and execute it after functions.php runs.
function addAttachmentMeta() {
$additional_fields = array();
$additional_fields = apply_filters('attachment_meta_add_fields', $additional_fields);
$am = new Attachment_Meta( $additional_fields );
}
add_action('after_setup_theme', 'addAttachmentMeta');
The standard template for a node in Drupal is node.tpl.php
It's possible to call a different template for a content-type, like 'newsitem'. You will call it like this : node-newsitem.tpl.php.
I was wondering if there's a way to call a specific Node ID? node-34.tpl.php does not work.
Thanks
For Drupal 7 use this template name (34 - is node ID):
node--34.tpl.php
And don't forget to clear your cache! More information on drupal.org
In your theme's template.php put the following at the top of theme_preprocess_node():
$vars['template_files'][] = 'node-'. $vars['node']->nid;
So if your theme is called "myTheme", you might have the following:
function myTheme_preprocess_node(&$vars){
$vars['template_files'][] = 'node-'. $vars['node']->nid;
}
I have this working as we speak. In Drupal 6, my front page is node 5. It uses
page-node-5.tpl.php
If it's not loading, consider clearing cache's or rebuilding your theme registry.
That naming convention will work, just not by default. Assuming this is Drupal 6, try adding the following code to your theme's template.php:
/**
* Override or insert variables into the node templates.
*
* #param $vars
* An array of variables to pass to the theme template.
* #param $hook
* The name of the template being rendered ("node" in this case.)
*/
function yourthemename_preprocess_node(&$vars, $hook) {
$node = $vars['node'];
$vars['template_file'] = 'node-'. $node->nid;
}
Make sure you don't try to redeclare yourthemename_preprocess_node()--that is, if it already exists in your theme's template.php, just add the $node and $vars['template_file'] lines to it.