The7 is one of the most popular and qualitative theme on themeforest. When using with Custom Page Templates plugin, you may need to add compatibility code to make it play together.

Template files

For better compatibility you can download this default template file and place it in theme's root (child theme's root is recommended) folder.

Compatibility Code

You may find that layout for some shortcodes is messed up when used in custom templates. To fix it, copy the code below to your theme's (child theme is recommended) functions.php file.

/*
  There are 2 style issues with Custom Page Templates and The7 theme:
  1) Custom styles that The7 theme saves in postmeta for the added shortcodes to content are not added to ,
    when custom template applied. Solution is to echo custom shortcode styles stored in template's postmeta when custom template
    were applied
  2) The7 creates unique classes for each shortcode by provided attributes (instead of generating unique ID on creation).
    Due to this, shortcodes that have Dynamic Values end with different class name after attributes were replaced,
    which doesn't match selectors in WP Head. Solution is to:
      a) Capture initial shortcode attributes before DSV apply for all shortcodes with Dynamic Values
      b) When shortcode is generated:
        - Generate fake shortcode with initial params
        - Get its initial unique CSS class (it will be same as echoed in )
        - Get newly generated CSS class by attributes after Dynamic Values were applied
        - Filter shortcode output to teplace newly generated CSS class with initial class, so selectors are matched
*/
class CptThe7Compatibility {
  protected static $instance;
  private $initial_atts = array();
  private $class_map = array();
  private $shortcodes = array();
  private $applied_template_post;

  public static function instance() {
    return self::$instance ? self::$instance : self::$instance = new self();
  }

  private function __construct() {
    add_action( 'cptemplates/cptemplate/before_template_content', array( $this, 'start' ) );
    add_action( 'cptemplates/cptemplate/after_template_content', array( $this, 'end' ) );
    add_action( 'cptemplates/template_applied', array( $this, 'template_applied' ) );
  }

  public function template_applied( $applied_template_post = null ) {
    $this->applied_template_post = $applied_template_post;
    add_action( 'wp_head', array( $this, 'print_custom_css' ), 9999 );
  }

  function print_custom_css() {
    if ( ! is_a( $this->applied_template_post, 'WP_Post' ) ) return;
    $inline_css = get_post_meta( $this->applied_template_post->ID, 'the7_shortcodes_inline_css', true );
    $inline_css = is_string( $inline_css ) ? trim( $inline_css ) : false;
    if ( ! $inline_css ) return;

    printf( '', $inline_css );
  }

  public function start() {
    add_filter( 'cptemplates/dynamic_shortcode_values/shortcode_atts', array( $this, 'capture_initial_shortcode_atts' ), 10, 4 ); // Before DSV
    add_action( 'the7_before_shortcode_output', array( $this, 'create_class_map' ), 10 ); // After DSV
    add_filter( 'do_shortcode_tag', array( $this, 'replace_shortcode_id' ), 10, 4 ); // After DSV
  }
  
  public function end() {
    remove_filter( 'cptemplates/dynamic_shortcode_values/shortcode_atts', array( $this, 'capture_initial_shortcode_atts' ), 10 ); // Before DSV
    remove_action( 'the7_before_shortcode_output', array( $this, 'create_class_map' ), 10 ); // After DSV
    remove_filter( 'do_shortcode_tag', array( $this, 'replace_shortcode_id' ), 10 ); // After DSV
  }

  public function replace_shortcode_id( $output, $tag, $atts, $m ) {
    // Process only those we're captured
    if ( ! in_array( $tag, $this->shortcodes ) ) return $output;

    // Replace new shortcode class with initial to match styles
    foreach ( $this->class_map as $initial_class => $new_class ) {
      $output = str_replace( $new_class, $initial_class, $output );
    }

    return $output;
  }

  public function capture_initial_shortcode_atts( $atts, $tag, $content ) {
    // Process only if dynamic values were specified
    $dynamic_values = isset( $atts[ 'cptdsv' ] ) ? trim( $atts[ 'cptdsv' ] ) : '';
    if ( ! $dynamic_values ) {
      return $atts;
    }

    // Do no process if has been hashed already
    if ( isset( $atts[ 'cpt_unique_id' ] ) ) {
      return $atts;
    }

    // Capture initial hash
    $unique_id = uniqid();
    $this->initial_atts = $atts;
    
    return $atts;
  }


  public function create_class_map( $dt_shortcode ) {
    if ( ! is_a( $dt_shortcode, 'DT_Shortcode_With_Inline_Css' ) ) return;

    // Capture new hash
    if ( ! $this->initial_atts ) return;
    $initial_atts = $this->initial_atts;

    // Need to generate shortcode with initial params to get unique class, which has been used to save styles in postmeta
    $shortcode_class = get_class( $dt_shortcode );
    $default_shortcoode = new $shortcode_class();

    global $wp_filter;
    // Must disable these filters as otherwise it break. Don't need it to run here anyways, since we're initializing shortcode just to get merged attributes
    $the7_before_shortcode_output = $wp_filter[ 'the7_before_shortcode_output' ];
    $the7_after_shortcode_output = $wp_filter[ 'the7_after_shortcode_output' ];
    unset( $wp_filter[ 'the7_before_shortcode_output' ] );
    unset( $wp_filter[ 'the7_after_shortcode_output' ] );

    // Must run shortcode to merge attributes with defaults as otherwise there is no chance to get them
    $default_shortcoode->shortcode( $this->initial_atts );

    // Restore filters
    $wp_filter[ 'the7_before_shortcode_output' ] = $the7_before_shortcode_output;
    $wp_filter[ 'the7_after_shortcode_output' ] = $the7_after_shortcode_output;
    $default_atts = $default_shortcoode->get_atts();

    // Map initial class to new class. This will be used to replace new class generated after DSV have been applied with initial class
    $default_class = $default_shortcoode->get_unique_class();
    $shortcode_class = $dt_shortcode->get_unique_class();
    $this->class_map[ $default_class ] = $shortcode_class;

    // Save tag name for faster processing later
    $this->shortcodes []= $dt_shortcode->get_tag();

    // Reset initial atts
    $this->initial_atts = false;
  }

}

CptThe7Compatibility::instance();

Recent Posts