Custom Page Templates comes with a single default template for all page templates you create.

Default Custom Page Template

if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly

if ( cptemplates_template()->render_template() ) {
  get_header();
  cptemplates_template_content();
  get_footer();
}

Here is what it does exactly line by line:

if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly

Prevents accessing template file directly.

if ( cptemplates_template()->render_template() ) {
...
}
  • Checks if template has been applied to the current request.
  • Checks if custom template file has been applied for this page template and renders it if the file exists.
  • Otherwise, processes code inside if statement. E.g. renders default template.
get_header();

Displays header. Factually, processes header.php from child or parent theme.

cptemplates_template_content();

Displays custom page template created with Visual Composer in WP Admin.

get_footer();

Displays footer. Factually, processes footer.php from child or parent theme.

Overwriting Default Template

The plugin is using locate_template() function to locate custom default template in theme. Default template file name is cptemplate.php. It means that you can overwrite default template from plugin in your parent or child theme by adding cptemplate.php file under theme root folder.

Additionally, plugin looks for specific template by request type. E.g. cptemplate-{request_type}.php which takes priority over cptemplate.php. For example, default template for the frontpage would be cptemplate-front.php and default template for search page would be cptemplate-search.php.

You can read more about request types here.

Custom Location

It is possible to adjust a set of the templates the plugin looks for as well as specifying custom directory by adding a filter function for cptemplates/custom_template_files. Here is a sample code for it:

add_filter( 'cptemplates/custom_template_files', function( $templates, $template ) {
  $templates = array_map( function( $template_file ) {
    return sprintf( 'custom_folder_path/%s', $template_file );
  }, $templates );
  
  return $templates;
}, 10, 2 );

Template File

It is possible to choose specific template file you want to render your custom page template you create in admin with. On page template edit screen there is a meta box "Template File" in right sidebar where you can pick a template file you want to use for this particular page template.

Registering Template Files in Parent or Child Theme

As a theme developer you may want to offer your customers to choose from pre-built templates you ship with your theme. For example, you may want to offer Default Page template that implements all theme features like hero image, custom footer and has all content wrappers set or Blank Page template to allow customers creating absolutely custom layout with Visual Composer.

Custom Page Templates has a very simple process for registering custom template files. The simplest way is to add files to your theme root or 1 level subfolder. The plugin automatically scans files in these folders using standard WP functions, just like WP does for registering standard page templates.

It is also possible to add files somewhere deeper in your theme to the custom location where you want them to reside, e.g. under /inc/integrations/custom-page-templates/. In this case you'll need to create a filter function for cptemplates/post_templates hook to supply custom paths to the files.

Option 1: Automatically scan whole folder

add_filter( 'cptemplates/post_templates', function( $post_templates ) {
  $theme_path = trailingslashit( get_template_directory() );
  $files = glob( $theme_path . 'inc/integrations/custom-page-templates/*.php' );
  $relative_file_paths = array_map( function( $file ) use ( $theme_path ) {
    return str_replace( $theme_path, '', $file );
  }, $files );

  return cptemplates_admin_template_file()->get_post_templates_from_files( array_combine( $relative_file_paths, $files ), $post_templates );
} );

If you want to grab files from a child theme, then replace get_template_directory() with get_stylesheet_directory(), so the final code will be:

add_filter( 'cptemplates/post_templates', function( $post_templates ) {
  $theme_path = trailingslashit( get_stylesheet_directory() );
  $files = glob( $theme_path . 'inc/integrations/custom-page-templates/*.php' );
  $relative_file_paths = array_map( function( $file ) use ( $theme_path ) {
    return str_replace( $theme_path, '', $file );
  }, $files );

  return cptemplates_admin_template_file()->get_post_templates_from_files( array_combine( $relative_file_paths, $files ), $post_templates );
} );

Option 2: Manually specify each file

add_filter( 'cptemplates/post_templates', function( $post_templates ) {
  $post_templates[ 'Common' ][ 'inc/integrations/custom-page-templates/default-page.php' ] = "Default Page";
  $post_templates[ 'Common' ][ 'inc/integrations/custom-page-templates/blank-page.php' ] = "Blank Page";
  $post_templates[ 'Product' ][ 'inc/integrations/custom-page-templates/default-product.php' ] = "Default Product";
  return $post_templates;
} );

Note that file paths must be relative to the parent or child theme root.

Creating Template Files

Template file for custom page template is the same as template file for standard WP pages, except of the 2 difference below:

1) Special PHP Comment

Just like standard page templates must have a PHP comment on top of the file, you need to add similar comments to your template file as well. For example:

/**
 * CPT Name: Blank Page
 * CPT Type: Common
 */
  • CPT Name is a nice template title that will appear in admin
  • CPT Type is a template file group this file goes under

2) Special Template Content Rendering Function

Custom Page Templates has a special function cptemplates_template_content() for rendering template content.

Note: It is required to use this function in order to make everything work nicely without conflicts. If you'll attempt to display custom page content differently, you may end up breaking layout, Visual Composer fronteditor and shortcodes functionality.

Generally speaking, you should just use cptemplates_template_content() function instead of standard WP function  the_content() and everything else remains the same as you would create standard page template.

Sample Template File

<?php
/**
 * CPT Name: Default Page
 * CPT Type: Sample
 */
get_header(); ?>
<div class="wrap">
  <div id="primary" class="content-area">
    <main id="main" class="site-main" role="main">

      <?php
      while ( have_posts() ) : the_post();

        cptemplates_template_content(); // Usually you would use the_content() function here

        // If comments are open or we have at least one comment, load up the comment template.
        if ( comments_open() || get_comments_number() ) :
          comments_template();
        endif;

      endwhile; // End of the loop.
      ?>

    </main>
  </div>
</div>
<?php get_footer();

Custom Content Rendering Function

If your theme has custom functions for rendering page's content, then you pass this function (or closure function) to the cptemplates_template_content().

For example, BeTheme is using mfn_builder_print( get_the_ID() ); to render page's content with all that complex routine, instead of standard the_content() function. To handle this case, you'll need to write the following code:

cptemplates_template_content( function() {
  mfn_builder_print( get_the_ID() );  // Content Builder & WordPress Editor Content
});

Note: custom rendering function must utilize the_content() function to render main content in order to apply page template.

Creating Compatible Template File from Existing Page Template

Let's say you have a page template in your theme root folder called my-nice-page-template.php and you want to create template file with the same structure and functionality around the template content.

  1. Make a copy of your file my-nice-page-template.php and give it some recognizable name. Let's say, cpt-nice-page-template.php
  2. Add PHP comments at the top of the file. For example, CPT Name: Nice Page Template and CPT Type: Page.
  3. Replace the_content(); function with cptemplates_template_content();

That's it. Now you have a fully compatible template file.

Recent Posts