Tạo mẫu tùy chỉnh trong plugin WordPress

Khả năng gán các mẫu trang khác nhau cho các trang là một tính năng tuyệt vời mà WordPress có. Nhưng nếu bạn là nhà phát triển plugin và bạn không có quyền truy cập vào chủ đề thì rất khó để thêm mẫu trang cho trang web. Bởi vì chúng tôi biết rằng chúng tôi có thể tạo các mẫu trang trong chính các tệp chủ đề

Trong bài viết này, bạn sẽ tìm hiểu cách bạn có thể thêm các mẫu trang từ plugin và ở phần sau của bài viết này, có một đoạn mã thưởng khác liên quan đến tính năng này

Thêm mẫu trang từ plugin

Để bắt đầu phát triển, trước tiên, chúng tôi sẽ tạo một plugin mới và thêm các mã bên dưới

add_filter( 'theme_page_templates', 'pt_add_page_template_to_dropdown' );

Với mã này, chúng tôi có thể lọc danh sách mẫu trang cho chủ đề. Để thêm mẫu trang, trước tiên chúng ta cần tạo tệp mẫu và đặt tệp đó trong thư mục mẫu trong thư mục plugin. Bây giờ hãy tạo hàm với đường dẫn tệp cho tệp mẫu.

/**
* Add page templates.
*
* @param  array  $templates  The list of page templates
*
* @return array  $templates  The modified list of page templates
*/
function sf_add_page_template_to_dropdown( $templates )
{
   $templates[plugin_dir_path( __FILE__ ) . 'templates/page-template.php'] = __( 'Page Template From Plugin', 'text-domain' );

   return $templates;
}

Tạo mẫu tùy chỉnh trong plugin WordPress

Sau khi thêm các mã này, chúng ta có thể thấy một mẫu trang mới đang hiển thị trong danh sách thả xuống mẫu. Bây giờ nếu chúng tôi xuất bản trang với mẫu mới được tạo này được chọn, thì chúng tôi có thể thấy nó đang hiển thị mẫu mặc định từ chủ đề

Bây giờ, chúng tôi phải lưu thông tin mẫu này sau khi xuất bản/cập nhật trang. Để thực hiện việc này, hãy thêm đoạn mã này vào tệp plugin

add_filter( 'template_include', 'pt_change_page_template', 99 );

Móc bộ lọc này được thực thi trước khi WordPress bao gồm tệp mẫu, do đó, điều này có thể được sử dụng để ghi đè hành vi mẫu mặc định của WordPress. Chúng ta sẽ làm chính xác điều đó trong hàm, đây là mã hàm

/**
 * Change the page template to the selected template on the dropdown
 * 
 * @param $template
 *
 * @return mixed
 */
function pt_change_page_template($template)
{
    if (is_page()) {
        $meta = get_post_meta(get_the_ID());

        if (!empty($meta['_wp_page_template'][0]) && $meta['_wp_page_template'][0] != $template) {
            $template = $meta['_wp_page_template'][0];
        }
    }

    return $template;
}

Ở đây, chúng tôi đang trả lại đường dẫn của tệp mẫu mà chúng tôi đã thiết lập trước đó trong khi thêm mẫu trang vào danh sách thả xuống

Bây giờ sau khi thêm các mã này vào plugin của chúng tôi, chúng tôi có thể thấy mẫu được áp dụng thông qua plugin đúng cách và tệp mẫu này nằm ở thư mục mẫu trong thư mục plugin của chúng tôi

THƯỞNG. Xóa kiểu chủ đề gốc khỏi trang mẫu tùy chỉnh

Có nhiều trường hợp bạn cần sử dụng wp_headwp_footer function in your template file to get benefits of other plugins. In this case style of the current theme will also apply to your template and this may cause CSS confliction. To avoid any kind of CSS design confliction we may need to remove theme CSS file from our page.

add_action('wp_enqueue_scripts', 'pt_remove_style' );

function pt_remove_style()
{
    // Change this "my-page" with your page slug
    if (is_page('my-page')) {
        $theme = wp_get_theme();

        $parent_style = $theme->stylesheet . '-style'; 

        wp_dequeue_style($parent_style);
        wp_deregister_style($parent_style);
        wp_deregister_style($parent_style . '-css');
    }
}

Mã này sẽ lấy thông tin của chủ đề đang hoạt động và từ đó, chúng tôi sẽ lấy thông tin biểu định kiểu và xóa nó cho trang

Bạn đã bao giờ muốn tạo các mẫu trang của riêng mình nhưng không có quyền truy cập vào chính chủ đề đó chưa? . Rất may, giải pháp khá đơn giản. Tôi sẽ nhanh chóng đưa bạn qua một vài dòng mã mà bạn sẽ cần để tự động tạo Mẫu trang WordPress trực tiếp thông qua PHP

Cảm hứng cho bài viết này và thiên tài đằng sau giải pháp mã đến từ Tom McFarlin. Tôi đang sử dụng phiên bản đã chỉnh sửa của mã gốc của anh ấy, bạn có thể tìm thấy phiên bản này trên GitHub của anh ấy. Tôi đã giữ bình luận của anh ấy trong (cũng như thêm một số bình luận của riêng tôi) vì tôi thấy nó rất hữu ích trong việc giải thích những gì đang diễn ra – bản thân tôi không thể nói điều đó tốt hơn nữa

Bạn có thể tìm thấy toàn bộ mã và một plugin ví dụ ở cuối bài đăng này

Chúng ta bắt đầu chứ?

Mật mã

Chúng tôi sẽ tạo chức năng PHP của chúng tôi bằng cách sử dụng Lớp PHP. Đối với những người chưa thành thạo về Lớp PHP, Lớp được định nghĩa là một đối tượng chứa tập hợp các hàm và biến đang hoạt động cùng nhau. Kiểm tra PHP. net Giới thiệu để biết thêm chi tiết về cú pháp và lý thuyết

Trình bao bọc của chúng tôi sẽ chỉ cần 3 biến

  1. Sên plugin. Điều này chỉ đơn giản được sử dụng như một mã định danh duy nhất cho plugin
  2. Trường hợp lớp. Vì chúng tôi đang thêm một phiên bản của lớp này vào phần đầu của WordPress, tốt hơn hết chúng tôi nên lưu trữ nó
  3. Mảng mẫu. Như bạn có thể đoán, đây là một mảng chứa tên mẫu và tiêu đề

Đây là mã

class PageTemplater {

		/**
         * A Unique Identifier
         */
		 protected $plugin_slug;

        /**
         * A reference to an instance of this class.
         */
        private static $instance;

        /**
         * The array of templates that this plugin tracks.
         */
        protected $templates;

Nhận phiên bản lớp

Như tôi đã nói trước đây, chúng ta sẽ thêm một thể hiện của lớp vào tiêu đề WordPress bằng cách sử dụng hàm add_filter(). Do đó, chúng tôi sẽ cần một phương thức sẽ trả về (hoặc tạo) trường hợp này cho chúng tôi

Đối với điều này, chúng ta sẽ cần một phương thức đơn giản, được gọi là ‘get_instance’. Kiểm tra nó ra dưới đây;

/**
 * Returns an instance of this class. 
 */
public static function get_instance() {

	if( null == self::$instance ) {
		self::$instance = new PageTemplater();
	} 

	return self::$instance;

}

Đây sẽ là phương thức được gọi khi lớp của chúng ta được thêm vào đầu WordPress bằng cách sử dụng ‘add_action()’

Bộ lọc WordPress

Bây giờ chúng tôi đã sắp xếp phương thức 'get_instance', chúng tôi cần sắp xếp điều gì sẽ xảy ra khi nó thực sự được khởi tạo

Chúng tôi sẽ sử dụng chức năng add_filter() sẵn có của WordPress để thêm một phiên bản của lớp của chúng tôi vào các điểm chính dọc theo dòng thời gian khởi tạo WordPress. Sử dụng phương pháp này, chúng tôi sẽ chèn dữ liệu của các mẫu trang của chúng tôi vào các vị trí có liên quan, chẳng hạn như cho WordPress biết tệp nào sẽ sử dụng làm mẫu khi trang được gọi và tiêu đề sẽ hiển thị trên menu thả xuống trên Trình chỉnh sửa trang

Đối với điều này, chúng ta cần sử dụng phương thức '__construct' (phương thức này sẽ được chạy khi lớp được khởi tạo)

/**
 * Initializes the plugin by setting filters and administration functions.
 */
private function __construct() {

	$this->templates = array();

	// Add a filter to the attributes metabox to inject template into the cache.
	if ( version_compare( floatval( get_bloginfo( 'version' ) ), '4.7', '<' ) ) {

		// 4.6 and older
		add_filter(
			'page_attributes_dropdown_pages_args',
			array( $this, 'register_project_templates' )
		);

	} else {

		// Add a filter to the wp 4.7 version attributes metabox
		add_filter(
			'theme_page_templates', array( $this, 'add_new_template' )
		);

	}

	// Add a filter to the save post to inject out template into the page cache
	add_filter(
		'wp_insert_post_data', 
		array( $this, 'register_project_templates' ) 
	);

	// Add a filter to the template include to determine if the page has our 
	// template assigned and return it's path
	add_filter(
		'template_include', 
		array( $this, 'view_project_template') 
	);

	// Add your templates to this array.
	$this->templates = array(
		'goodtobebad-template.php' => 'It\'s Good to Be Bad',
	);

}

Có 4 điều khác nhau đang diễn ra ở đây (bỏ qua ‘ $this->templates = array();’, chỉ đang chuẩn bị biến để sử dụng);

  1. Dòng 9 – 13. Bộ lọc này đang thêm 'register_project_templates' vào hook 'page_attributes_dropdown_pages_args'. Điều này đang điền vào bộ đệm WordPress bằng các mẫu mới của chúng tôi, 'lừa' WordPress tin rằng các tệp mẫu trang thực sự tồn tại trong thư mục mẫu. Điều này thêm các mẫu trang vào danh sách thả xuống trên hộp meta thuộc tính trang trong trình chỉnh sửa trang
  2. Dòng 16 – 20. Ở đây, về cơ bản, chúng tôi đang thực hiện giống như khối mã trước đó, ngoại trừ lần này chúng tôi cũng đang thêm mẫu trang của mình (nếu được chọn) vào dữ liệu bài đăng đã lưu
  3. Dòng 23 – 28. Bộ lọc này đang thêm 'template_include' vào hook 'view_project_template'. Đây là một chức năng rất quan trọng; . WordPress sẽ sử dụng đường dẫn được cung cấp bởi điều này để hiển thị trang cuối cùng
  4. Dòng 31 – 34. Điều này tuy đơn giản nhưng lại rất quan trọng. Đây là nơi bạn chỉ định các mẫu trang mà bạn muốn thêm vào và đường dẫn liên quan đến tệp chứa tệp mẫu trang ( ví dụ:. 'thứ gì đó. php’ ). Tôi đã bao gồm một ví dụ (sẽ được sử dụng trong plugin ví dụ). Kiểm tra dưới đây cho một ví dụ chung
________số 8_______

(Ăn, Ngủ,) Mã, Lặp lại khi cần thiết

register_project_templates()

Tôi đã đề cập đến phương pháp này trước đây;

Về cơ bản, mục đích của phương pháp này là thao tác với bộ đệm của WordPress, chèn dữ liệu liên quan về các mẫu trang của chúng tôi vào đúng vị trí. Hãy xem mã trước và tôi sẽ nói với bạn về nó sau

public function register_project_templates( $atts ) {

	// Create the key used for the themes cache
	$cache_key = 'page_templates-' . md5( get_theme_root() . '/' . get_stylesheet() );

	// Retrieve the cache list. 
	// If it doesn't exist, or it's empty prepare an array
	$templates = wp_get_theme()->get_page_templates();
	if ( empty( $templates ) ) {
		$templates = array();
	} 

	// New cache, therefore remove the old one
	wp_cache_delete( $cache_key , 'themes');

	// Now add our template to the list of templates by merging our templates
	// with the existing templates array from the cache.
	$templates = array_merge( $templates, $this->templates );

	// Add the modified cache to allow WordPress to pick it up for listing
	// available templates
	wp_cache_add( $cache_key, $templates, 'themes', 1800 );

	return $atts;

}

Ngay sau đó. Dòng 4 là nơi đầu tiên để tìm. Như bạn có thể đoán, chúng tôi đang tạo một 'khóa bộ đệm'. Điều này sẽ được sử dụng làm mã định danh duy nhất cho dữ liệu mẫu trang của chúng tôi. Sử dụng hàm md5() chỉ cần tạo một mã định danh chuỗi duy nhất để tránh mọi xung đột

Tiếp theo, trên dòng 8, chúng tôi đang tìm kiếm và truy xuất bộ đệm mẫu trang (nếu nó đã tồn tại). điều này sẽ trả về một loạt các đường dẫn và tiêu đề. Trên các dòng 9-11, chúng tôi kiểm tra xem có bất kỳ đầu ra nào từ truy vấn bộ đệm không. Nếu có, tuyệt vời. Nếu không, hãy tạo một mảng cục bộ để chứa dữ liệu mà chúng ta sẽ hợp nhất vào bộ đệm

Bước tiếp theo là rất quan trọng. Trên dòng 14, chúng tôi xóa bộ đệm mẫu trang hiện có. Đừng lo lắng, không có dữ liệu nào bị mất – nó được lưu trữ trong biến $templates

Ở dòng 18, chúng tôi hợp nhất bộ đệm mẫu trang hiện có với các mục nhập mới của chúng tôi và ở dòng 22, chúng tôi chèn lại toàn bộ bộ đệm mẫu trang vào hệ thống của WordPress

Đơn giản

view_project_template ()

Bây giờ chúng tôi đang sử dụng phương pháp cuối cùng của mình;

/**
 * Checks if the template is assigned to the page
 */
public function view_project_template( $template ) {
	
	// Get global post
	global $post;

	// Return template if post is empty
	if ( ! $post ) {
		return $template;
	}

	// Return default template if we don't have a custom one defined
	if ( !isset( $this->templates[get_post_meta( 
		$post->ID, '_wp_page_template', true 
	)] ) ) {
		return $template;
	} 

	$file = plugin_dir_path(__FILE__). get_post_meta( 
		$post->ID, '_wp_page_template', true
	);

	// Just to be safe, we check if the file exist first
	if ( file_exists( $file ) ) {
		return $file;
	} else {
		echo $file;
	}

	// Return template
	return $template;

}

Được rồi, phương thức này sẽ kiểm tra đối với biến $post toàn cầu (dòng 6). Nó kiểm tra xem một mẫu trang ( ‘_wp_page_template’ ) đã được đặt cho bài đăng chưa (nghĩa là nó phải là một trang). Nếu không, thì đừng bận tâm – không phải trang không thể có mẫu trang

Dòng 16 chỉ định vị trí của tệp mẫu trang. Như tôi đã trình bày ở trên, nó sẽ kiểm tra tệp mẫu trang được chỉ định trong thư mục gốc của plugin của bạn. (Điều này có thể dễ dàng thay đổi; xem bên dưới. )

// Just changing the page template path
// WordPress will now look for page templates in the subfolder 'templates',
// instead of the root
$file = plugin_dir_path(__FILE__). 'templates/' .get_post_meta( 
	$post->ID, '_wp_page_template', true 
);

Sau đó, trên các dòng 21 – 24, chúng tôi chỉ cần xác thực một chút để kiểm tra xem tệp có thực sự tồn tại hay không. Nếu có, tuyệt vời. Nếu không, trời ơi… Rất có thể bạn sẽ nhận được thông báo lỗi PHP nếu WordPress không thể tìm thấy tệp mẫu hoặc thậm chí là một màn hình trống. Nếu bất kỳ triệu chứng nào trong số này nghe có vẻ quen thuộc, chỉ cần kiểm tra đường dẫn tệp mẫu bằng cách in biến $file ra màn hình

Nếu bạn dự định sử dụng mã này cho mục đích thương mại (bạn có thể tự do thực hiện điều này - phiên bản mã của tôi không có giấy phép, do đó bạn có thể tự do thực hiện tùy ý), tôi thực sự khuyên bạn nên đầu tư một chút thời gian vào việc xử lý lỗi để đạt hiệu quả tối đa

Vậy thôi đo. Khi lớp của chúng tôi đã hoàn thành, chỉ còn một việc phải làm – thêm nó vào đầu WordPress

add_action( 'plugins_loaded', array( 'PageTemplater', 'get_instance' ) );

Xin chúc mừng nếu bạn đã vượt qua. Tôi hy vọng bạn thấy những gì tôi nói hữu ích và bạn sẽ được hưởng lợi từ nó trong tương lai