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.
Related
In a plugin I'm working on, I'm trying to replace the OOTB customer-completed-order email with a template in the plugin
Constructor:
define( 'BKF_WC_EMAIL_PATH', plugin_dir_path( __FILE__ ) );
add_filter('wc_get_template', array($this, 'bkf_customer_completed_order_template'), PHP_INT_MAX, 5);
Function:
function bkf_customer_completed_order_template($template, $template_name, $args, $template_path, $default_path) {
if( $template_name == 'emails/customer-completed-order.php' ) {
$template = trailingslashit(BKF_WC_EMAIL_PATH) . 'templates/' . $template_name;
return $template;
}
}
note the template is still pulling the default woo one
Any thoughts/ideas are welcome!
Worked it out!
Instead of the method used in my original question, here's what worked for me:
I created a new class (similar to woocommerce/includes/emails/class-wc-email-customer-completed-order.php) - for demo purposes we'll call it My_Custom_Class
I then called like so in my constructor for the parent class I was working on:
add_action('woocommerce_email_classes', array( $this, 'bk_register_email' ), PHP_INT_MAX, 1 );
And added this function:
public function bk_register_email( $emails ) {
require_once 'emails/my-custom-class.php';
$emails['WC_Email_Customer_Completed_Order'] = new My_Custom_Class();
return $emails;
}
define( 'AMP_QUERY_VAR', apply_filters( 'amp_query_var', 'amp' ) );
add_rewrite_endpoint( AMP_QUERY_VAR, EP_PERMALINK );
add_filter( 'template_include', 'amp_page_template', 99 );
function amp_page_template( $template ) {
if( get_query_var( AMP_QUERY_VAR, false ) !== false ) {
if ( is_single() ) {
$template = get_template_directory() . '/amp-single.php';
}
}
return $template;
}
If you're looking to make your site AMP compatible without a plugin it would take a lot more work than the function referenced. Have you tried the official AMP plugin? I help out in the support forums if you want to post the question there, happy to help out from there.
Is that possible for overwriting a plugin templates via making a folder in theme file and copy the file in that folder and altering the content [both folder and file name have the same name as arranged in plugin ].
Generally we altering the woocommerce page templates by following these system .Woothemes has implemented something similar for their woocommerce plugin. You copy files from /wp-content/plugins/woocommerce <-->to<--> /wp-content/themes/yourthemes/woocommerce and WP automatically uses the files in the theme folder rather than the plugin folder. This way users can make customizations to their plugins without losing them to a plugin update..Is that possible for all plugin ?
If no , what code that make woocommerce plugin to change the style based on the file inside our theme folders woocoomerce folder ?
or What about CHILD PLUGIN concept ?
is there any possible way ?
Woocommerce checks first does file /wp-content/themes/yourthemes/woocommerce exists and reqire it. If not it require general template from /wp-content/plugins/woocommerce
Simple possible solution in your plugin, you can use.
function loadTemplate( $template_name ){
$plugin_path = plugin_dir_path(__FILE__);
$original_template = $plugin_path . "templates/" . $template_name . ".php";
$theme_path = get_template_directory();
$override_template = $theme_path . "/myplugin/" . $template_name . ".php";
if(file_exists($override_template)){
include( $override_template );
}
else{
include( $original_template );
}
}
And now you can use as you want your loadTemplate() function like so:
function load_teplate_after_content( $template_name ) {
loadTemplate( 'example' );
// Now it will check first for
// wp-content/themes/yourtheme/myplugin/example.php
// and load, if not exists it will load original template from
// /wp-content/plugins/myplugin/templates/example.php
}
add_filter( 'the_content', 'load_teplate_after_content' );
Of course remember to prefix your functions or put it in a Class. This is just simple example.
Not tested. May be some errors.
EDIT:
Just to answer all questions. Here is precisely how woocommerce is doing this
/**
* Get template part (for templates like the shop-loop).
*
* #access public
* #param mixed $slug
* #param string $name (default: '')
* #return void
*/
function wc_get_template_part( $slug, $name = '' ) {
$template = '';
// Look in yourtheme/slug-name.php and yourtheme/woocommerce/slug-name.php
if ( $name && ! WC_TEMPLATE_DEBUG_MODE ) {
$template = locate_template( array( "{$slug}-{$name}.php", WC()->template_path() . "{$slug}-{$name}.php" ) );
}
// Get default slug-name.php
if ( ! $template && $name && file_exists( WC()->plugin_path() . "/templates/{$slug}-{$name}.php" ) ) {
$template = WC()->plugin_path() . "/templates/{$slug}-{$name}.php";
}
// If template file doesn't exist, look in yourtheme/slug.php and yourtheme/woocommerce/slug.php
if ( ! $template && ! WC_TEMPLATE_DEBUG_MODE ) {
$template = locate_template( array( "{$slug}.php", WC()->template_path() . "{$slug}.php" ) );
}
// Allow 3rd party plugin filter template file from their plugin
if ( ( ! $template && WC_TEMPLATE_DEBUG_MODE ) || $template ) {
$template = apply_filters( 'wc_get_template_part', $template, $slug, $name );
}
if ( $template ) {
load_template( $template, false );
}
}
EDIT2:
Is that possible for all plugin
It's possible for all plugins which have this feature implemented.
or What about CHILD PLUGIN concept ?
There is no general answer. If plugin provide an API to its functionallities, you could create such child plugin. But depending directly on current plugin code is bad idea. When your parent plugin(1) is gonna change, your plugin will break if you are using function that has been removed or edited.
But as I said, if plugin provide consistent API, and it's enough to write such functionaliity, then yes. But not for all plugins. At least without editing plugins itself.
(1) There is no such thing like child plugin or parent plugin oficially.
I'm creating a plugin that needs to replace the_content of only two specific pages that it created upon activation.
Here is my code:
add_filter('the_content', 'emd_content');
function emd_content() {
if ( is_page('Member Directory') ) {
include dirname( __FILE__ ) . '/content-members.php';
}
elseif ( is_page('Contact Members') ) {
include dirname( __FILE__ ) . '/content-member-contact-form.php';
}
else {
the_content();
}
}
The code above gives me a 500 Internal Server Error for pages other than Member Directory and Contact Members, which both work properly.
If I remove else { the_content(); }, then the Member Directory and Contact Members work correctly, but all other pages don't display anything where the_content should be displayed.
I also tried wrapping the add_filter() within if(is_page('Member Directory') || is_page('Contact Members')) { }. the_content worked for other pages, but not for the two created by the plugin.
What is a better/proper way to replace the_content for these two pages using my plugin?
You must add parameter to your function. After this, you can $content, the_content() instead. Example:
function emd_content($content) {
if ( is_page('Member Directory') ) {
$content = include dirname( __FILE__ ) . '/content-members.php';
}
elseif ( is_page('Contact Members') ) {
$content = include dirname( __FILE__ ) . '/content-member-contact-form.php';
}
else {
$content = $content;
}
return $content;
}
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