Mẫu bài đăng tùy chỉnh từ thư mục Plugin?


57

Tôi muốn cung cấp loại bài đăng tùy chỉnh của tôi dưới dạng Plugin để mọi người có thể sử dụng nó mà không cần chạm vào thư mục chủ đề của họ. Nhưng các mẫu bài đăng tùy chỉnh - chẳng hạn như tập tin phim đơn - nằm trong thư mục chủ đề. Có cách nào để WP kiểm tra một tệp phim.php trong thư mục của plugin không? Nối một chức năng vào Phân cấp Filer ? Hoặc get_template_directory (); ?

Câu trả lời:


90

Bạn có thể sử dụng single_templatemóc lọc.

/* Filter the single_template with our custom function*/
add_filter('single_template', 'my_custom_template');

function my_custom_template($single) {

    global $post;

    /* Checks for single template by post type */
    if ( $post->post_type == 'POST TYPE NAME' ) {
        if ( file_exists( PLUGIN_PATH . '/Custom_File.php' ) ) {
            return PLUGIN_PATH . '/Custom_File.php';
        }
    }

    return $single;

}

Đó là câu trả lời tuyệt vời. Hãy chia sẻ là tôi có thể nhận được tất cả các hook có sẵn như single_template không.
Gowri

6
@gowri Bộ lọc được gọi bởi get_query_template()hàm. Đó là một hook biến, vì vậy phần đầu tiên {$type}_templatethay đổi tùy thuộc vào tham số nào được truyền cho hàm đó. Xem wp-gồm / template.php để biết một số cái phổ biến
shea

Hướng dẫn này bao gồm các hook single_template với lời giải thích tốt. Khi bạn hiểu các móc nối, nhận xét của @ shea gợi ý cách tiếp cận đơn giản hơn câu trả lời của @ BaiNET, sử dụng add_filter( 'single-movies_template', 'my_custom_template' );như trong hướng dẫn được liên kết. (Câu hỏi này được đóng lại cho câu trả lời mới, vì vậy tôi không thể tự thêm câu hỏi.)
Greg Perham

2
Bạn có thể thay thế PLUGIN_PATHbằng plugin_dir_path( __FILE__ )và sau đó xóa dấu gạch chéo đầu tiên khỏi tên tệp của bạn. Đường dẫn đầy đủ sẽ trông giống như thế này:return plugin_dir_path( __FILE__ ) . 'Custom_File.php';
Frits

1
PLUGIN_PATH ném một lỗi, đây là một bài tuyệt vời mà cho thấy làm thế nào để làm điều này và nó làm việc cho tôi ra khỏi hộp: wpsites.net/free-tutorials/...
Nathan

22

Cập nhật câu trả lời

Phiên bản sạch hơn và ngắn hơn.

function load_movie_template( $template ) {
    global $post;

    if ( 'movie' === $post->post_type && locate_template( array( 'single-movie.php' ) ) !== $template ) {
        /*
         * This is a 'movie' post
         * AND a 'single movie template' is not found on
         * theme or child theme directories, so load it
         * from our plugin directory.
         */
        return plugin_dir_path( __FILE__ ) . 'single-movie.php';
    }

    return $template;
}

add_filter( 'single_template', 'load_movie_template' );

Câu trả lời cũ

Đã thêm kiểm tra cho một mẫu cụ thể loại bài đăng tùy chỉnh trong thư mục chủ đề vào câu trả lời @BraiNET.

function load_cpt_template($template) {
    global $post;

    // Is this a "my-custom-post-type" post?
    if ($post->post_type == "my-custom-post-type"){

        //Your plugin path 
        $plugin_path = plugin_dir_path( __FILE__ );

        // The name of custom post type single template
        $template_name = 'single-my-custom-post-type.php';

        // A specific single template for my custom post type exists in theme folder? Or it also doesn't exist in my plugin?
        if($template === get_stylesheet_directory() . '/' . $template_name
            || !file_exists($plugin_path . $template_name)) {

            //Then return "single.php" or "single-my-custom-post-type.php" from theme directory.
            return $template;
        }

        // If not, return my plugin custom post type template.
        return $plugin_path . $template_name;
    }

    //This is not my custom post type, do nothing with $template
    return $template;
}
add_filter('single_template', 'load_cpt_template');

Bây giờ bạn có thể cho phép người dùng plugin sao chép mẫu từ plugin của bạn sang chủ đề của họ để ghi đè lên nó.

Với ví dụ này, các mẫu phải nằm trong thư mục gốc của cả plugin và chủ đề.


1
Sử dụng locate_templatethay vì get_stylesheet_directoryâm thanh như tùy chọn sạch hơn đối với tôi (tìm thấy ở đây: code.tutsplus.com/tutorials/iêu ).
Felix

1
Câu trả lời cập nhật không hoạt động, câu trả lời được chấp nhận (hoặc câu trả lời cũ của bạn) hoạt động.
Edward

2
Bạn đã đúng, @Edward, đó là một bản cập nhật khủng khiếp. Tôi đã cập nhật nó một lần nữa với đề nghị của Felix. Ngoài ra lần này tôi đã kiểm tra mã trước khi đăng nó :)
campsjos

4

Tôi muốn chỉ ra rằng khi bạn đang sử dụng phương thức lọc cho việc này, điều cực kỳ quan trọng là ưu tiên bộ lọc như vậy:

add_filter('single_template', 'my_custom_template', 99);

Nếu bạn không làm điều này, đôi khi WP sẽ cố kiểm tra lại sau bộ lọc này. Đã kéo tóc tôi ra vì điều này trong khoảng 2 giờ.


0

Có một cách tốt hơn để làm điều đó mà tôi đang sử dụng cho các plugin của mình.

Như @campjos đề cập ở đây , thay vì kiểm tra sự tồn tại của tệp, bạn có thể kiểm tra xem locate_templatesẽ kiểm tra chủ đề bao trùm tệp mẫu. Đó là khá rõ ràng.

function my_plugin_templates() {
    if (is_singular('movie')) {
        if (file_exists($this->template_dir . 'single-movie.php')) {
            return $this->template_dir . 'single-movie.php';
        }
    }
}

Sử dụng template_includemóc lọc để tải mã trên.

add_filter('template_include' , 'my_plugin_templates');

0

nhờ trang này mà tôi đã có thể giải quyết câu hỏi tương tự cho tôi.

Để tham khảo, đây là những gì tôi đã kết thúc với:

function pluginName_myposttype_single_template($single_template) {
  $myposttype_template = PLUGIN_DIR . 'templates/single-myposttype.php';
  return get_post_type() === 'myposttype' && file_exists($myposttype_template) ? $myposttype_template : $single_template;
}
add_filter('single_template', 'pluginName_myposttype_single_template');

hook bộ lọc {$ type} _template không hoạt động với tôi

function pluginName_myposttype_single_template($single_template) {
  $myposttype_template = PLUGIN_DIR . 'templates/single-myposttype.php';

  if ( file_exists($myposttype_template) ) {
    $single_template = $myposttype_template;
  }
  return $single_template;
}
add_filter('single-myposttype_template', 'pluginName_myposttype_single_template');

-2

Trên đây là một câu trả lời tuyệt vời, nhưng việc kiểm tra var $ single cho phép mẫu ghi đè lên mẫu nếu một mẫu được cung cấp bởi chủ đề / chủ đề con.

/* Filter the single_template with our custom function*/
add_filter('single_template', 'your_cpt_custom_template');

function your_cpt_custom_template( $single ) {
    global $wp_query, $post;
    /* Checks for single template by post type */
    if ( !$single && $post->post_type == 'cpt' ) {
        if( file_exists( plugin_dir_path( __FILE__ ) . 'single-cpt.php' ) )
            return plugin_dir_path( __FILE__ ) . 'single-cpt.php';
    }
    return $single;
}

1
Điều này không kiểm tra nếu một cpt.php có trong một đứa trẻ hoặc chủ đề. Nó chỉ kiểm tra đối với single.php sẽ luôn có mặt trong bất kỳ chủ đề nào.
newpxsn

Đúng vậy, khi tôi viết bài này, tôi đang sử dụng một chủ đề thực sự trần trụi, phải có một cách tốt hơn!
DigitalDesignDj
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.