Wordpress: how to create a template that is still available when you switch theme? - wordpress

I have a custom template for my portfolio page. However, after switching theme, it's gone because it is in my previous theme's folder.
Technically, I can copy that file into my new theme folder. However, I plan to change theme every two weeks and this becomes non-trivial. Is there a way to always have a bunch of common template files available to me no matter when and how often I switch theme? (In other words, I want to create template files that are not dependent on themes.)
Thanks!

There is, using template_redirect, which you would put in the functions.php file.
function uniquename_default_template() {
global $wpdb;
if(get_post_type() == 'posttype') : /* You could use is_single() instead of get_post_type() == '' or any type of conditional tag) */
include(TEMPLATEDIR . 'path/to/theme/file.php'); /* You could use TEMPLATEDIR to get a file from a template folder, or PLUGINDIR to get a file from the plugins directory - doesn't support HTTP requests */
exit; endif;
}
add_action('template_redirect', 'uniquename_default_template');
Hope it helps.

Related

Single Post Template Override for Custom Post Type

I've got kind of a unique scenario that I'm trying to nail down. I'm working on a new template for a custom post type that already exists. Basically, we're replacing the single-customposttype.php file with a new one. All of that is going swimmingly, except one thing - they have one post in that custom post type that they want to keep the OLD template on.
So there's a NEW single-customposttype.php file that will work as the default single template for that CPT.
But I need ID #93 to use the OLD single-customposttype.php template. I hoped just doing single-customposttype-93.php might do the trick, but it doesn't. What's the best way to apply the other template to only one post id?
Thanks in advance!
I deal with custom template loading all the time, it's really pretty simple! Really, all you need to do is hook into the template_include hook, and override the template based on whatever conditions you want.
That hook takes a single argument, the $template file to load. You can then use any conditionals you want and force a separate file to load instead.
add_filter( 'template_include', 'custom_template_include', 99 );
function custom_template_include( $template ){
// For ID 93, load in file by using it's PATH (not URL)
if( get_the_ID() === 93 ){
// Note the file name can be ANYTHING, the WP auto-template names don't matter here
$file = get_stylesheet_directory() . '/post-id-93-custom-template.php';
// It's generally good to see if the file exists before overriding the default
if( file_exists( $file ) )
$template = $file;
}
// ALWAYS return the $template, or *everything* will be blank.
return $template;
}
It's really that simple! Inside the custom PHP file, you have access to all of the WordPress functions and such as you would with a default template.
Generally you'll want to use the file_exists() function on the template, just to make sure it's found, otherwise you'll be passing along a file that doesn't exist, and that page will not load. By checking if it exists, it will still fall back to the old template if it's not found (deleted/renamed/moved, etc)
Also, you always need to have return $template at the end, otherwise anything that uses WordPress' template system will break.
I made a quick example on a demo site:
https://xhynk.com/content-mask/policies/cookie-policy/
https://xhynk.com/content-mask/policies/use-another-template/
The policies are a custom post type, and the cookie policy loads normally. The other one is modified with the same code as above (with the name/ID changed to match), and it's loading in a simple .php file with that content in it.

How to create a template if site is using Divi?

I am doing some work on a site and everything is made in Divi.
I just want to build out a few custom woocommerce templates for product page etc.. using code but when I add the templates to the theme folder it doesn't override the product page.
When I look in debug query it shows the et page builder template is being used instead of regular product template.
Their docs are all geared up for non-coders and only code related stuff is on making modules.
How do I just make a normal template override from a child theme?
You just have to make sure your path to the template files is correct. For instance, if you're trying to overwrite the single-product template, which is located at:
wp-content/plugins/woocommerce/templates/single-product.php
just copy it to:
wp-content/themes/{your-child-theme}/woocommerce/single-product.php
and make your changes there.
For any template files, just match the path minus the templates folder.
If you have any caching plugins installed, you may need to clear your cache before the changes show up.
To test it, I copied single-product.php and product-image.php and made the following changes.
And you can see the result here:
If that doesn't work for you, make sure your child theme is set up correctly.
Edit: Divi's Theme Builder, once activated, causes the site to no longer use page templates. So there is no way (short of rewriting the Theme Builder) to override it with your own template files.
However, you can customize the Divi modules that are used by the Theme Builder, although editing them is a bit more complicated.
The modules are found in:
wp-content/themes/Divi/includes/builder/module/
For example, I'll override the WooCommerce Title module.
wp-content/themes/Divi/includes/builder/module/woocommerce/Title.php
First, copy that file into your child theme and place it in a new folder:
wp-content/themes/Divi-child/custom-modules/Title.php
Next, add the following code your child theme's functions.php to replace the existing module:
function divi_child_theme_setup() {
if ( class_exists('ET_Builder_Module')) {
get_template_part( 'custom-modules/custom-title' );
$TE_ct = new Custom_ET_Builder_Module_Woocommerce_Title();
remove_shortcode( 'et_pb_wc_title' );
add_shortcode( 'et_pb_wc_title', array($TE_ct, '_shortcode_callback') );
}
}
add_action('wp', 'divi_child_theme_setup', 9999);
Call your variable ($TE_ct) and the module (Custom_ET_Builder_Module_Woocommerce_Title) whatever you want.
Finally, edit the module in your child theme. Make sure the class name matches what you used in functions.php.
...
class Custom_ET_Builder_Module_Woocommerce_Title extends ET_Builder_Module {
/**
* Initialize.
*/
public function init() {
echo "<h1>CUSTOMIZED!!</h1>";
$this->name = esc_html__( 'Woo Title', 'et_builder' );
$this->plural = esc_html__( 'Woo Titles', 'et_builder' );
$this->slug = 'et_pb_wc_title';
$this->vb_support = 'on';
...
Here, I've added a simple echo to show that the module is being overridden.
Result:

Changes on archive-product.php doesn't work

I'm trying to customize the standard woocommerce theme and so far that has worked well. I copied all template files from /plugins/woocommerce/templates to /mytheme/woocommerce and customized the files.
But when i'm change something in archive-product.php nothing happens? I even tried to customize this in the core files (/plugins/woocommerce/templates/archive-product.php) but i doesn't work.
I want to change the class of the h1 heading: <h1 class="page-title"><?php woocommerce_page_title(); ?></h1>.
So i looked up all woocommerce template files, the class page-title occurs only in this one file (to prevent editing the wrong file).
Edit:
In detail, i want to customize the theme used in this path: http://example.com/product-category/mycategory
I tried all the above solutions, to no avail. No matter what I did, the archive-product.php was not being used at all. Instead, most woocommerce pages were using page.php from my theme.
The solution for me was to add theme support... Which, it's been a while since I used woocommerce, so I completely forgot about that. But after adding the following line to my functions.php file, archive-product.php is now being used (/mytheme/woocommerce/archive-product.php) and I can update it, as I should be able to.
add_theme_support('woocommerce');
Seems this is STILL an issue in Woocommerce. For anyone landing here, the following solution was working for me as of version 2.1.6.
Apparently the problem is due to the function woocommerce_content() outputting the wrong page for archive content.
I used the following to get around it:
replace woocommerce_content() in woocommerce.php with:
if ( is_singular( 'product' ) ) {
woocommerce_content();
}else{
//For ANY product archive.
//Product taxonomy, product search or /shop landing
woocommerce_get_template( 'archive-product.php' );
}
Credit: found the solution here
Here's how I fixed mine:
Delete woocommerce.php in your theme folder.
Copy TEMPLATE folder in woocommerce plugin dir, paste it in your THEME folder, and rename it to woocommerce.
Open the folder you just renamed, go to shop folder, and edit wrapper-start.php and wrapper-end.php.
If you use the woocommerce.php method you cannot customize archive-product. You must use the hooks method
http://docs.woothemes.com/document/third-party-custom-theme-compatibility/
Please note: when creating woocommerce.php in your theme’s folder, you won’t be able to override the woocommerce/archive-product.php custom template as woocommerce.php has the priority over archive-product.php. This is intended to prevent display issues.
For others searching here, doublecheck the path. It is for example not /mytheme/woocommerce/templates/archive-product.php but only /mytheme/woocommerce/archive-product.php. I didn't have to apply #Talk nerdy to me's patch or any other to make it work.
you need to edit the file "taxonomy-product_cat.php" and add a conditional is_product_category( 'mycategory' ).
open your theme folder and add a new subfolder named "woocommerce" to it.
copy the files "archive-product.php" and "taxonomy-product_cat.php" from /plugins/woocommerce/templates to the woocommerce subfolder in your theme.
rename "archive-product.php" to "archive-mycategory.php" (or whatever you like, this will be the template file to the category).
open "taxonomy-product_cat.php" and wrap the wc_get_template( 'archive-product.php' ); with:
if (is_product_category( 'mycategory' )){
wc_get_template( 'archive-mycategory.php' );
} else {
wc_get_template( 'archive-product.php' );
}

Can my WordPress custom templates be in the plugin folder or only in the theme folder?

A WordPress theme I am developing has an integrated custom post type called "albums" which utilizes a few custom templates (archive-albums.php, content-albums.php, etc.). What I want to do is transfer this functionality, along with the template files, into a plugin for the sake of portability.
I transferred the CPT code from the functions.php with success, but when I try to move the template files from the theme folder to the plugin folder, things fall apart. I feel like it should be simple to somehow register the templates so WordPress knows to load them.
Can my WordPress custom templates be in plugin folder or only theme folder?
Things are falling apart because when you move those files, you're violating WP's native template hierarchy. You'll need to explicitly declare the location of those files. Using the archive as an example, you could add something like this to functions.php (to tell WP to look elsewhere):
add_filter('template_include', 'include_album_template', 1);
function include_album_template($template_path) {
if(get_post_type() == 'albums') {
if(!is_single()) {
$theme_file = 'path-to-your-plugin-directory';
$template_path = $theme_file;
}
}
return $template_path;
}
Obviously you'd use your own path, and I wrote this hastily so you might want to refactor.
I have the same issue. I'm already using add_filter ('template_include', ...) problem is that I need to specify a file to return, and in this case being it,index.php. This raises an issue with the theme not running entirely as if installed via themes folder, because what I need is to have WP selecting the appropriate file to render without any conditional logic from my part. So if it is a post it will select the single.php and so on. Another problem raised with this method is that in header.php the call get_header (); ignores the local file header.php and loads the default theme installed file instead.

Blog page with theme completely different from the main theme?

I have been trying to make my website on Wordpress. I am using Brave Zeenat as my primary and Grido as my blog theme.
I have read many tutorials in places, which discuss how to apply a customized flavour of the main theme on a static page, e.g. Blog. However, the main theme I am using does not appeal to me as a blog theme at all, so I wanted to do something entirely different, so I have tried two methods.
First, I tried to just create a page named Blog and force it to take a theme of my choice using the Page Theme plugin. That worked instantly, but the blog page is empty and would not accept articles of certain categories by default like this.
Second, I tried to not use any plugin at all, and use a custom PHP file instead, which sets some loops and calls a theme. This file blog.php had to be in the main theme directory, otherwise it would not be applicable as a template from the page settings in Wordpress dash.
So I put it with my main theme, but call to load the other theme, like this:
<?php
/*
Template Name: Blog
*/
$paged = get_query_var('paged');
query_posts('cat=0&paged='.$paged);
global $more;
$more = 0;
load_template(WP_CONTENT_DIR . '/themes/grido_v1.0.1/index.php');
?>
Eventually I only want to see category no.9, but for now, I left it as 0, which should display all categories. But when I run this with Page Theme plugin disabled, I get this error: Fatal error: Call to undefined function themify_get() in /var/sites/v/visualdeceptions.info/public_html/wp-content/themes/grido_v1.0.1/index.php on line 10.
Now, although this is a themify error, I am sure if I try to use other premium themes as well, I will encounter very similar errors, because I have only set a custom php file, and no style, header, footer, etc. But I am not sure how to do it.
Try to add getheader() and getfooter() in the code
<?php
/*
Template Name: Blog
*/
get_header(); //HERE
$paged = get_query_var('paged');
query_posts('cat=0&paged='.$paged);
global $more;
$more = 0;
load_template(WP_CONTENT_DIR . '/themes/grido_v1.0.1/index.php');
get_footer(); //HERE
?>

Resources