Xác định Mẫu trang tùy chỉnh mà không có tệp .php riêng


7

Có cách nào để xác định Mẫu trang từ một số chức năng / bộ lọc / hook, mà không có bất kỳ tệp .php nào chứa nhận xét ở đầu trang để khai báo Tên mẫu không?


Ví dụ, thay vì làm điều này:

some-custom-page-template.php

/**
* Template Name: Some Custom Page Template
*/

other-custom-page-template.php

/**
* Template Name: Another Custom Page Template
*/

Tôi tự hỏi nếu tôi có thể làm một cái gì đó như:

Hàm.php

wp_some_function_to_define_templates( 'Some Custom Page Template' );
wp_some_function_to_define_templates( 'Another Custom Page Template' );

EDIT : Tôi đang viết mộtchủ đề WP thử nghiệm phức tạp phức tạp - Đó là hướng đối tượng như WP cho phép, tôi có các lớp Trình điều khiển để quyết định hiển thị gì trong mỗi trang, các lớp DAO để lấy dữ liệu từ DB, Twig các mẫu để tạo các lượt xem, v.v.

Tôi đã truyền bá mã rất nhiều, rằng Mẫu trang của tôi đã trở thành một dòng mã nơi tôi gọi một số Trình điều khiển và để nó thực hiện công việc, để cuối cùng kết xuất một mẫu Twig. Vì vậy, tôi quyết định chuyển cuộc gọi đó đến Bộ điều khiển, vào bên trong template_includebộ lọc để tôi thậm chí không cần đặt bất kỳ mã nào trong Mẫu trang ...

Tôi có thể thoát khỏi Mẫu trang, nhưng tôi vẫn cần chúng để nhóm các trang bằng cách nào đó, để đặt một số nhóm Trường tùy chỉnh nâng cao cho chúng, v.v ...

Vì vậy, tôi đã kết thúc với khoảng 15 tệp PHP chỉ chứa một nhận xét ở trên cùng với một số Tên mẫu, đó chính xác là những gì tôi muốn tránh bằng cách xác định các mẫu đó từ một số chức năng ...

Tôi đang cố gắng để phát minh lại bánh xe ? Có thể theo một nghĩa nào đó, nhưng tôi nghĩ nó đang trở thành một chủ đề thực sự hay , rất dễ bảo trì và có thể sửa đổi ...


Đây có phải là cơ chế bạn đang theo dõi bằng cách sử dụng tên Mẫu trong Nhận xét? Và điều gì là sai với nó?
Pratik

@PratikJoshi, tôi đã chỉnh sửa câu hỏi của mình để đưa ra lời giải thích phù hợp nếu bạn muốn xem ...
MikO

Vì vậy, chức năng duy nhất cho các mẫu trang là điền vào hộp chọn mẫu ở mặt sau?
s_ha_dum

@s_ha_dum, về cơ bản là có, nhưng điều đó cho phép tôi nhóm các trang, vì vậy tôi có thể đặt các nhóm trường ACF cho tất cả chúng, sử dụng cùng một Trình điều khiển để xử lý dữ liệu của chúng (với một số tham số thu được từ tên trang), sử dụng cùng một mẫu Twig đối với họ, v.v ...
MikO

1
chức năng điền vào hộp meta mẫu trang không thể lọc được, nhưng vì bạn không thực sự sử dụng nó theo cách nó được dự định, tại sao không thêm hộp meta của riêng bạn và điền vào bất kỳ tùy chọn nào bạn muốn?
Milo

Câu trả lời:


6

WordPress đọc các mẫu từ các tiêu đề tệp, sau đó đặt chúng vào bộ đệm. sử dụng wp_cache_set()nad một khóa có nguồn gốc từ md5 có thư mục biểu định kiểu.

Vì vậy, chỉ cần ghi đè lên bộ đệm đó, chúng tôi có thể hiển thị các mẫu mà chúng tôi muốn. Để ghi đè bộ đệm đó, chúng ta cần gọi wp_cache_set()lại bằng cùng một phím.

Trước hết, hãy viết một hàm lấy các mẫu mà chúng ta muốn hiển thị. Có rất nhiều cách chúng ta có thể đặt mẫu: tùy chọn, tệp cấu hình, bộ lọc hoặc kết hợp chúng:

function get_custom_page_templates() {
  $templates = array();
  // maybe by options? --> $templates = get_option( 'custom_page_templates' );
  // maybe by conf file? --> $templates = include 'custom_page_templates.php';
  return apply_filters( 'custom_page_templates', $templates );
}

Sau đó, chúng tôi cần truy xuất các mẫu bên trong chỉnh sửa trang, ngay sau khi WordPress lưu bộ đệm. Ngoài ra, chúng tôi cần lấy lại chúng khi biểu mẫu chỉnh sửa được đăng để cho phép lưu.

Chúng ta có thể sử dụng 'edit_form_after_editor'hook cho phạm vi đầu tiên 'load-post.php''load-post.new'cho lần thứ hai:

add_action( 'edit_form_after_editor', 'custom_page_templates_init' );
add_action( 'load-post.php', 'custom_page_templates_init_post' );
add_action( 'load-post-new.php', 'custom_page_templates_init_post' );

function custom_page_templates_init() {
  remove_action( current_filter(), __FUNCTION__ );
  if ( is_admin() && get_current_screen()->post_type === 'page' ) {
    $templates = get_custom_page_templates(); // the function above
    if ( ! empty( $templates ) )  {
      set_custom_page_templates( $templates );
    }
  }
}

function custom_page_templates_init_post() {
  remove_action( current_filter(), __FUNCTION__ );
  $method = filter_input( INPUT_SERVER, 'REQUEST_METHOD', FILTER_SANITIZE_STRING );
  if ( empty( $method ) || strtoupper( $method ) !== 'POST' ) return;
  if ( get_current_screen()->post_type === 'page' ) {
    custom_page_templates_init();
  }
}

Điều cuối cùng chúng ta phải làm, viết set_custom_page_templates()hàm chỉnh sửa bộ đệm để bao gồm các mẫu của chúng tôi, đảm bảo hợp nhất bất kỳ mẫu nào được xác định bởi các tiêu đề tệp:

function set_custom_page_templates( $templates = array() ) {
  if ( ! is_array( $templates ) || empty( $templates ) ) return;
  $core = array_flip( (array) get_page_templates() ); // templates defined by file
  $data = array_filter( array_merge( $core, $templates ) );
  ksort( $data );
  $stylesheet = get_stylesheet();
  $hash = md5( get_theme_root( $stylesheet ) . '/' . $stylesheet );
  $persistently = apply_filters( 'wp_cache_themes_persistently', false, 'WP_Theme' );
  $exp = is_int( $persistently ) ? $persistently : 1800;
  wp_cache_set( 'page_templates-' . $hash, $data, 'themes', $exp );
}

Có mã này đang chạy, bạn có thể thiết lập các mẫu tùy chỉnh chỉ bằng cách sử dụng phương thức bạn đã sử dụng trong get_custom_page_templates()hàm, ở đây tôi sử dụng bộ lọc:

add_filter( 'custom_page_templates', function( $now_templates ) {

  $templates = array(
    'some-custom-page-template' => 'Some Custom Page Template',
    'another-custom-page-template' => 'Another Custom Page Template' ,
  );

  return array_merge( $now_templates, $templates );

} );

Và bạn đã hoàn thành.


Rực rỡ lừa! Rõ ràng là bạn đã tự ngâm mình trong ruột của WP :) Dù sao, tôi nghĩ rằng việc thêm quá nhiều công việc mỗi khi bạn muốn tải một trang có lẽ không phải là một ý tưởng hay ... Tôi nghĩ rằng tôi nên giữ lại tệp mẫu của tôi với một dòng mã, tôi sẽ chỉ đặt chúng vào thư mục con và quên chúng ... bạn không nghĩ vậy sao?
MikO

1
@MikO Không hẳn. Chức năng này hoạt động chủ yếu trên phụ trợ, trên frontend không làm gì cả. Hơn nữa, đọc một đĩa biểu mẫu tệp và phân tích tiêu đề bình luận của nó chậm hơn là chỉ cập nhật một mảng ... Kiểm tra, nó có số lượng mẫu cao và bạn sẽ thấy rằng quy trình làm việc của tệp khá chậm.
gmazzap

Điều này không làm việc cho tôi, có cách nào mới để làm việc này không?
mrmadhat

Tôi đã tạo một plugin dựa trên cái này để làm điều này.
chắc chắn là

2

Nếu tôi hiểu bạn, bạn có thể làm điều này với template_includehook. Ví dụ:

add_filter( 'template_include', 'phpless_template');
function phpless_template( $template ) {  
  get_header();
  // some php
  get_footer();
  die;
}

Thủ thuật hay, nhưng không phải là điều tôi đang tìm kiếm ... nếu bạn đợi một giây tôi sẽ viết EDIT trong câu hỏi của mình vì kịch bản hơi phức tạp
MikO

0

Tôi đề nghị với bạn một cách giải quyết đơn giản hơn:

  1. Trong tệp cấu hình / hàm / chỉ mục của bạn, xác định biến cấu hình $config_template = false;(*)
  2. Tạo một thư mục "bao gồm" (có thể bạn đã có)
  3. Đặt ở đó các tệp some-custom-page-template.php và Another-custom-page-template.php
  4. Trong các tệp này, chỉ cần gán một giá trị cho $ config_template và sau đó yêu cầu trang bạn đang sử dụng để hiển thị vòng lặp - ví dụ: $config_template = 'some-custom-page'; require( "../index.php" );
  5. Trong tệp này (index.php), bạn có thể muốn bạn muốn dựa trên giá trị của $ config_template

Sử dụng phương pháp này, bạn không ép buộc quy trình làm việc bình thường của WP (đây không bao giờ là một ý tưởng hay) nhưng bạn đang giữ cho dự án của mình đủ sạch sẽ.

(*) Có lẽ bạn đã sử dụng một số thuộc tính đối tượng để quản lý các cấu hình của mình. Bạn sẽ đặt biến $ config_template ở đó.

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.