Is it possible to make WordPress look at plugin directory first and if the system finds that page, for example, page.php, archive.php, single.php... show layout from plugin files and don't look at theme files?
Absolutely! Take a look at the single_template and archive_template filters. They're relatively straight forward to use:
function get_custom_post_type_template($single_template) {
global $post;
if ($post->post_type == 'my_post_type') {
$single_template = dirname( __FILE__ ) . '/post-type-template.php';
}
return $single_template;
}
add_filter( 'single_template', 'get_custom_post_type_template' );
There's also This Section on effectively adding single-post_type.php to the Template Hierarchy, but I prefer a slightly modified version that is IMO easier to read:
add_filter( 'single_template', 'my_single_templates' );
function my_single_templates( $single_template ){
global $post;
$file = '/my/path/to/templates/dir/'. $post->post_type .'/single-'. $post->post_type .'php';
if( file_exists( $file ) )
$single_template = $file;
return $single_template;
}
Related
I try to override the woocommerce customer-completed-order.php template via a custom plugin I build.
The most handy is to include the custom email template in the plugin, so various customers dont need to copy the template to a child theme.
So far i have (based upon internet research):
function intercept_wc_template( $template, $template_name, $template_path ) {
if ( strpos($template_name,'customer-completed-order.php' ) ) {
$template = trailingslashit( plugin_dir_path( __FILE__ ) ) . 'template/woocommerce/customer-completed-order.php';
}
return $template;
}
add_filter('woocommerce_locate_template', 'intercept_wc_template', 20, 3);
I tried to change the priority, by changing the priority to 9 instead of 20. However, that doesnt seem to help either.
Any help would be appriciated,
Kind regards, Kees
You should try this one:
add_filter('woocommerce_locate_template', 'woo_customer_completed_order_template', 10, 4);
function woo_customer_completed_order_template($template, $template_name, $template_path)
{
if ('customer-completed-order.php' === basename($template)){
$template = trailingslashit(plugin_dir_path( __FILE__ )) . 'templates/woocommerce/customer-completed-order.php';
}
return $template;
}
Note: You can change/update if ('customer-completed-order.php' === basename($template)) , cundition accordingly.
If now working above function, you can echo $template, $template_name, $template_path and update if() condition accordingly.
it's working 100% on my side.
I have develop a custom template for woocommerce checkout page and added all templates that I need to change specifically order_review.php in plugin/woocommerce/checkout/order_review.php and on order page it works perfect.
From Order page I can remove some products or add products through ajax and here is my ajax code.
ob_start();
woocommerce_order_review();
$woocommerce_order_review = ob_get_clean();
$response = array(
'cart_total' => WC()->cart->total,
'cart_item_key' => $new_key,
'fragments' => apply_filters(
'woocommerce_update_order_review_fragments',
array(
'.woocommerce-checkout-review-order-table' => $woocommerce_order_review,
)
),
);
if ( ! empty( $data ) ) {
$response['cartflows_data'] = $data;
}
return $response;
And the woocommerce_order_review(); loads woocommerce default template instead of template from my plugin.
WooCommerce does not look in plugin folders for templates by default. You need to use the filter woocommerce_locate_template in your plugin to tell WooCommerce to look in your plugin folder for templates. The solution is outlined by SkyVerge in this blog post: https://www.skyverge.com/blog/override-woocommerce-template-file-within-a-plugin/
I am including the solution here in case the post is every removed for some reason:
function myplugin_plugin_path() {
// gets the absolute path to this plugin directory
return untrailingslashit( plugin_dir_path( __FILE__ ) );
}
add_filter( 'woocommerce_locate_template', 'myplugin_woocommerce_locate_template', 10, 3 );
function myplugin_woocommerce_locate_template( $template, $template_name, $template_path ) {
global $woocommerce;
$_template = $template;
if ( ! $template_path ) $template_path = $woocommerce->template_url;
$plugin_path = myplugin_plugin_path() . '/woocommerce/';
// Look within passed path within the theme - this is priority
$template = locate_template(
array(
$template_path . $template_name,
$template_name
)
);
// Modification: Get the template from this plugin, if it exists
if ( ! $template && file_exists( $plugin_path . $template_name ) )
$template = $plugin_path . $template_name;
// Use default template
if ( ! $template )
$template = $_template;
// Return what we found
return $template;
}
You have to override WooCommerce Template
woocommerce/templates/checkout/review-order.php and Put this file in your theme folder themes/yourthemename/woocommerce/checkout/review-order.php
I am trying to relocate the position of the output generated by a review plugin for wordpress. The plugin hooks into the end of "the_content". I have found the filter which works to remove the output:
remove_filter('the_content', array( EDD_Reviews::get_instance(), 'load_frontend'));
Now I am going crazy trying to relocate the output to a new location. I have created a custom hook in my theme file:
function reviews() {
do_action('reviews');
}
The above hook outputs just fine to custom location in the theme files when passed a simple function. However the tricky part is getting the reviews and review form to display. I tried adding it back with this:
add_action('reviews', array( EDD_Reviews::get_instance(), 'load_frontend'));
This did not work. The full function I am trying to call is below. Any body have any ideas how I may call this via my new hook? I am rather stuck.
public function load_frontend( $content ) {
global $post;
if ( $post && $post->post_type == 'download' && is_singular( 'download' ) && is_main_query() && ! post_password_required() ) {
ob_start();
edd_get_template_part( 'reviews' );
if ( get_option( 'thread_comments' ) ) {
edd_get_template_part( 'reviews-reply' );
}
$content .= ob_get_contents();
ob_end_clean();
}
return $content;
}
Many thanks in advance.
Ok mostly figured this out after studying classes. If anyone else is looking to do this then remove the hook as below:
remove_filter('the_content', array( EDD_Reviews::get_instance(), 'load_frontend'));
The following line will then render the reviews and form anywhere you like:
<?php echo EDD_Reviews()->load_frontend( '' ); ?>
I am using the following function to call a custom single post overriding the default one single.php
function call_different_single_post($single_template)
{
global $post;
$path = get_stylesheet_directory() . '/includes/templates' . '/';
$single_template = $path. 'single-1.php';
return $single_template;
}
add_filter('single_template', 'call_different_single_post');
It's calling the single-1.php template for the single posts.
Now I want to check this template conditionally so that I can call some other js files like
function call_cust_js_single(){
if( /*..this is single-1.php template..*/){
wp_register_script('cust-js', get_stylesheet_directory_uri() . 'custom.js', false, '1.0.0');
wp_enqueue_script('cust-js');
}
}
add_action('wp_enqueue_scripts', 'call_cust_js_single');
There's a post similar to this but it doesn't quite cover your request. Here's the link here
Here's the valuable code:
add_filter( 'template_include', 'var_template_include', 1000 );
function var_template_include( $t ){
$GLOBALS['current_theme_template'] = basename($t);
return $t;
}
function get_current_template( $echo = false ) {
if( !isset( $GLOBALS['current_theme_template'] ) )
return false;
if( $echo )
echo $GLOBALS['current_theme_template'];
else
return $GLOBALS['current_theme_template'];
}
Now you have the function get_current_template that will return the filename of the template file.
Now edit your header.php file, here's an example:
<?php if('single-1.php' == get_current_template())
{
//load your scripts here
} ?>
It's not as clean as what you were looking for but I think it will help you.
I'd like to make a landing page. If plugin detects some GET or POST requests it should override wordpress theme and show its own.
It would work somehow like that:
if (isset($_GET['action']) && $_GET['action'] == 'myPluginAction'){
/* do something to maintain action */
/* forbid template to display and show plugin's landing page*/
}
I'm familiar with WP Codex, but I don't remember if there is any function to do that. Of course, I googled it with no results.
Thanks for any ideas in advance.
You need the hook template_include. It doesn't seem documented in the Codex, but you can find more examples here in SO or in WordPress StackExchange
Plugin file
<?php
/**
* Plugin Name: Landing Page Custom Template
*/
add_filter( 'template_include', 'so_13997743_custom_template' );
function so_13997743_custom_template( $template )
{
if( isset( $_GET['mod']) && 'yes' == $_GET['mod'] )
$template = plugin_dir_path( __FILE__ ) . 'my-custom-page.php';
return $template;
}
Custom Template in Plugin folder
<?php
/**
* Custom Plugin Template
* File: my-custom-page.php
*
*/
echo get_bloginfo('name');
Result
Visiting any url of the site with ?mod=yes will render the plugin template file, e.g.: http://example.com/hello-world/?mod=yes.
you need to create a folder '/woocommerce/' inside your plugin directory, inside woocommerce you need to add a folder say, for email 'emails' and put the required template inside '/emails/' to override. just copy paste this code in the main.php of your plugin.
<?php
/**
* Plugin Name: Custom Plugin
*/
function myplugin_plugin_path() {
// gets the absolute path to this plugin directory
return untrailingslashit( plugin_dir_path( __FILE__ ) );
}
add_filter( 'woocommerce_locate_template', 'myplugin_woocommerce_locate_template', 10, 3 );
function myplugin_woocommerce_locate_template( $template, $template_name, $template_path ) {
global $woocommerce;
$_template = $template;
if ( ! $template_path ) $template_path = $woocommerce->template_url;
$plugin_path = myplugin_plugin_path() . '/woocommerce/';
// Look within passed path within the theme - this is priority
$template = locate_template(
array(
$template_path . $template_name, $template_name
)
);
// Modification: Get the template from this plugin, if it exists
if ( ! $template && file_exists( $plugin_path . $template_name ) )
$template = $plugin_path . $template_name;
// Use default template
if ( ! $template )
$template = $_template;
// Return what we found
return $template;
}
?>
for reference template override using plugin