Як створити віртуальну сторінку в WordPress

Привіт:) У цьому пості покажу, як програмно створити віртуальну сторінку WordPress, якої не існує в базі даних (а тому й у середовищі ВордПрес). Під час публікації запису або сторінки ВордПрес всі її дані записуються у базу даних. Але можна зробити так, щоб сторінка існувала (тобто відкривалася за своєю URL-адресою), але в середовищі WP її не було. Часто такий хід використовують плагіни для створення, наприклад, форм авторизації та реєстрації. Також зручно розробникам тем і плагінів, щоб генерувати на ходу потрібні сторінки.

Спосіб 1

Віртуальна сторінка з власним контентом.

/**
 * Створення віртуальних сторінок
 */

if ( ! class_exists( 'mpVirtualPage' ) ) {
	class mpVirtualPage {
 
		private $slug = null;
		private $title = null;
		private $content = null;
		private $author = null;
		private $date = null;
		private $type = null;
        private $dategmt = null;
	 
		public function __construct( $args ) {
			if ( ! isset( $args['slug'] ) )
				throw new Exception( 'відсутній ярлик для віртуальної сторінки' );
	 
			$this->slug = $args['slug'];
			$this->title = isset( $args['title'] ) ? $args['title'] : '';
			$this->content = isset( $args['content'] ) ? $args['content'] : '';
			$this->author = isset( $args['author'] ) ? $args['author'] : 1;
			$this->date = isset( $args['date'] ) ? $args['date'] : current_time( 'mysql' );
			$this->dategmt = isset( $args['date'] ) ? $args['date'] : current_time( 'mysql', 1 );
			$this->type = isset( $args['type'] ) ? $args['type'] : 'page';
	 
			add_filter( 'the_posts', array( &$this, 'virtualPage' ) );
		}
	 
		public function virtualPage( $posts ) {
			global $wp, $wp_query;
	 
			if ( count( $posts ) == 0 &&
				( strcasecmp( $wp->request, $this->slug ) == 0 || 
				$wp->query_vars['page_id'] == $this->slug ) ) {
	 
				$post = new stdClass;
	 
				$post->ID = -111;
				$post->post_author = $this->author;
				$post->post_date = $this->date;
				$post->post_date_gmt = $this->dategmt;
				$post->post_content = $this->content;
				$post->post_title = $this->title;
				$post->post_excerpt = '';
				$post->post_status = 'publish';
				$post->comment_status = 'closed';
				$post->ping_status = 'closed';
				$post->post_password = '';
				$post->post_name = $this->slug;
				$post->to_ping = '';
				$post->pinged = '';
				$post->modified = $post->post_date;
				$post->modified_gmt = $post->post_date_gmt;
				$post->post_content_filtered = '';
				$post->post_parent = 0;
				$post->guid = get_home_url( '/' . $this->slug );
				$post->menu_order = 0;
				$post->post_type = $this->type;
				$post->post_mime_type = '';
				$post->comment_count = 0;
	 
				$posts = array( $post );
	 
				$wp_query->is_page = true;
				$wp_query->is_singular = true;
				$wp_query->is_home = false;
				$wp_query->is_archive = false;
				$wp_query->is_category = false;
				unset( $wp_query->query['error'] );
				$wp_query->query_vars['error'] = '';
				$wp_query->is_404 = false;
			}
	 
			return ( $posts );
		}
	}
}

function mp_create_virtual_page() {
    $url = trim( parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH ), '/' );
	
	$pages = [
		[
			'url'   => 'petrov-virtual-page-1',
			'slug'  => 'petrov-virtual-page-1',
			'title'	=> 'Це віртуальна сторінка 1',
			'content' => "Контент віртуальної сторінки 1 <br> Рядок 2",
            'author' => 1,
            //'date' => '14:01:2017:15:30:25',
            'type' => 'post',
		],
		[
			'url'   => 'petrov-virtual-page-2',
			'slug'  => 'petrov-virtual-page-2',
			'title'	=> 'Це віртуальна сторінка 2',
			'content' => "Контент віртуальної сторінки 2 <br> Рядок 2",
            'author' => 1,
            //'date' => '14:01:2017:15:30:25',
            'type' => 'post',
		],
		[
			'url'   => 'petrov-virtual-page-3',
			'slug'  => 'petrov-virtual-page-3',
			'title'	=> 'Це віртуальна сторінка 3',
			'content' => "Контент віртуальної сторінки <br> Рядок 2",
            'author' => 1,
            //'date' => '14:01:2017:15:30:25',
            'type' => 'post',
		],
		
	];
	
	// перебір першого масиву з ел. 0,1,2...
	foreach ( $pages as $page ) {
		if ( $url == $page['url'] ) {
			$pg = new mpVirtualPage( $page );
		}
	}

}
add_action( 'init', 'mp_create_virtual_page' );

У коді створюються 3 пости типу Запис з URL-адресами та слагами petrov-virtual-page-1, petrov-virtual-page-2, petrov-virtual-page-3 відповідно.

Спосіб 2

У цьому випадку для створеної віртуальної сторінки буде підставлятися окремий файл-шаблон із контентом.

Нехай потрібно створити сторінку за адресою https://site.com/petrov-virtual-page/.

add_filter( 'generate_rewrite_rules', function ( $wp_rewrite ) {
    $wp_rewrite->rules = array_merge(
        ['petrov-virtual-page/?$' => 'index.php?custom=1'],
        $wp_rewrite->rules
    );
});
add_filter( 'query_vars', function( $query_vars ) {
    $query_vars[] = 'custom';
    return $query_vars;
});
add_action( 'template_redirect', function() {
    $custom = intval( get_query_var( 'custom' ) );
    if ( $custom ) {
        include plugin_dir_path( __FILE__ ) . 'templates/template-content.php';
        die;
    }
});

У рядку include plugin_dir_path( __FILE__ ) . 'templates/custom.php' підставляється шаблон із контентом, який буде виводитися на сторінці. У файлі custom.php можете додати звичайний HTML-код або вивести дані через конструкції типу echo.

Оскільки будь-яка інформація про віртуальні сторінки для WordPress-середовища відсутня, вони не підтримуються СЕО-плагінами. А тому мета-теги за допомогою Yoast чи All In One SEO задати не вийде.
Віртуальні сторінки зручно використовувати, наприклад, для RSS-фідів або генерації інших XML-даних.

Михайло Петров
Михайло Петров

Мене звати Михайло. Я — WordPress-розробник. Створюю візитки, корпоративні сайти, блоги на WordPress.

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *