Пользовательские страницы с помощью плагина

22 сент. 2014 г., 19:30:17
Просмотры: 24K
Голосов: 21

Я разрабатываю плагин, в котором хотел бы включить пользовательские страницы. В моем случае такая страница должна содержать форму наподобие контактной формы (не буквально). Когда пользователь заполнит эту форму и отправит её, должен быть следующий шаг, требующий дополнительной информации. Допустим, первая страница с формой будет находиться по адресу www.domain.tld/custom-page/, а после успешной отправки формы пользователь должен быть перенаправлен на www.domain.tld/custom-page/second. Шаблон с HTML элементами и PHP кодом также должен быть пользовательским.

Я думаю, что часть проблемы можно решить с помощью пользовательских правил перезаписи URL, но остальные части мне пока неизвестны. Я действительно не знаю, с чего начать поиск и как правильно называется эта задача. Буду благодарен за любую помощь.

4
Комментарии

Вы хотите, чтобы эти страницы хранились в WordPress или были 'виртуальными'?

Welcher Welcher
22 сент. 2014 г. 19:47:31

Вам нужно будет использовать rewrite api. Это не должно быть слишком сложно. Убедитесь, что данные передаются на вторую страницу, и всё будет в порядке.

setterGetter setterGetter
22 сент. 2014 г. 20:15:42

@Welcher: Эти страницы не такие, как предлагает WordPress в панели управления. Они должны просто сохранять данные в базу данных, но это не проблема. @.setterGetter: У вас есть пример, как передать данные с первой страницы на вторую и где (action?) подключить PHP-файл, который отображает форму?

user1257255 user1257255
22 сент. 2014 г. 20:35:28

Вы рассматривали возможность использования одностраничной формы с несколькими слайдами (javascript и/или css) полей ввода?

birgire birgire
24 сент. 2014 г. 20:27:31
Все ответы на вопрос 3
10
74

При посещении фронтенд-страницы WordPress выполняет запрос к базе данных, и если вашей страницы там нет, этот запрос становится бесполезной тратой ресурсов.

К счастью, WordPress предоставляет способ обработки фронтенд-запросов по-своему. Это возможно благодаря фильтру 'do_parse_request'.

Возвращая false в этом хуке, вы можете остановить стандартную обработку запросов WordPress и реализовать собственный механизм.

В этой статье я хочу поделиться способом создания простого ООП-плагина для работы с виртуальными страницами, который будет удобен в использовании и повторном применении.

Что нам понадобится

  • Класс для объектов виртуальных страниц
  • Класс-контроллер, который будет анализировать запрос и, если он предназначен для виртуальной страницы, отображать её с использованием соответствующего шаблона
  • Класс для загрузки шаблонов
  • Основные файлы плагина для добавления хуков, которые обеспечат работоспособность всей системы

Интерфейсы

Прежде чем создавать классы, напишем интерфейсы для трёх перечисленных выше объектов.

Сначала интерфейс страницы (файл PageInterface.php):

<?php
namespace GM\VirtualPages;

interface PageInterface {

    function getUrl();

    function getTemplate();

    function getTitle();

    function setTitle( $title );

    function setContent( $content );

    function setTemplate( $template );

    /**
     * Получить объект WP_Post, созданный на основе виртуальной страницы
     *
     * @return \WP_Post
     */
    function asWpPost();
}

Большинство методов — это обычные геттеры и сеттеры, не требующие пояснений. Последний метод должен использоваться для получения объекта WP_Post из виртуальной страницы.

Интерфейс контроллера (файл ControllerInterface.php):

<?php
namespace GM\VirtualPages;

interface ControllerInterface {

    /**
     * Инициализация контроллера, запускает хук, позволяющий добавлять страницы
     */
    function init();

    /**
     * Регистрация объекта страницы в контроллере
     *
     * @param  \GM\VirtualPages\Page $page
     * @return \GM\VirtualPages\Page
     */
    function addPage( PageInterface $page );

    /**
     * Запускается на хуке 'do_parse_request'; если запрос предназначен для одной из зарегистрированных страниц,
     * настраивает глобальные переменные, запускает основные хуки, загружает шаблон страницы и завершает выполнение.
     *
     * @param boolean $bool Флаг, переданный хуком 'do_parse_request'
     * @param \WP $wp       Глобальный объект WP, переданный хуком 'do_parse_request'
     */  
    function dispatch( $bool, \WP $wp ); 
}

И интерфейс загрузчика шаблонов (файл TemplateLoaderInterface.php):

<?php
namespace GM\VirtualPages;

interface TemplateLoaderInterface {

    /**
     * Настройка загрузчика для объекта страницы
     *
     * @param \GM\VirtualPagesPageInterface $page соответствующая виртуальная страница
     */
    public function init( PageInterface $page );

    /**
     * Активирует стандартные и пользовательские хуки для фильтрации шаблонов,
     * затем загружает найденный шаблон.
     */
    public function load();
}

Комментарии phpDoc должны быть достаточно понятными для этих интерфейсов.

План работы

Теперь, когда у нас есть интерфейсы, и прежде чем писать конкретные классы, давайте рассмотрим наш рабочий процесс:

  • Сначала мы создаём экземпляр класса Controller (реализующего ControllerInterface) и внедряем (вероятно, через конструктор) экземпляр класса TemplateLoader (реализующего TemplateLoaderInterface)
  • На хуке init мы вызываем метод ControllerInterface::init() для настройки контроллера и запуска хука, который будет использоваться для добавления виртуальных страниц.
  • На хуке 'do_parse_request' мы вызовем ControllerInterface::dispatch(), где проверим все добавленные виртуальные страницы и, если URL одной из них совпадает с текущим запросом, отобразим её, предварительно установив все необходимые глобальные переменные ($wp_query, $post). Мы также используем класс TemplateLoader для загрузки нужного шаблона.

В процессе мы будем активировать некоторые стандартные хуки, такие как wp, template_redirect, template_include... чтобы сделать плагин более гибким и обеспечить совместимость с ядром и другими плагинами, или по крайней мере с их значительной частью.

Помимо этого рабочего процесса, нам также потребуется:

  • Очистка хуков и глобальных переменных после выполнения основного цикла для улучшения совместимости с ядром и сторонним кодом
  • Добавление фильтра на the_permalink, чтобы он возвращал правильный URL виртуальной страницы, когда это необходимо.

Конкретные классы

Теперь мы можем написать наши конкретные классы. Начнём с класса страницы (файл Page.php):

<?php
namespace GM\VirtualPages;

class Page implements PageInterface {

    private $url;
    private $title;
    private $content;
    private $template;
    private $wp_post;

    function __construct( $url, $title = 'Untitled', $template = 'page.php' ) {
        $this->url = filter_var( $url, FILTER_SANITIZE_URL );
        $this->setTitle( $title );
        $this->setTemplate( $template);
    }

    function getUrl() {
        return $this->url;
    }

    function getTemplate() {
        return $this->template;
    }

    function getTitle() {
        return $this->title;
    }

    function setTitle( $title ) {
        $this->title = filter_var( $title, FILTER_SANITIZE_STRING );
        return $this;
    }

    function setContent( $content ) {
        $this->content = $content;
        return $this;
    }

    function setTemplate( $template ) {
        $this->template = $template;
        return $this;
    }

    function asWpPost() {
        if ( is_null( $this->wp_post ) ) {
            $post = array(
                'ID'             => 0,
                'post_title'     => $this->title,
                'post_name'      => sanitize_title( $this->title ),
                'post_content'   => $this->content ? : '',
                'post_excerpt'   => '',
                'post_parent'    => 0,
                'menu_order'     => 0,
                'post_type'      => 'page',
                'post_status'    => 'publish',
                'comment_status' => 'closed',
                'ping_status'    => 'closed',
                'comment_count'  => 0,
                'post_password'  => '',
                'to_ping'        => '',
                'pinged'         => '',
                'guid'           => home_url( $this->getUrl() ),
                'post_date'      => current_time( 'mysql' ),
                'post_date_gmt'  => current_time( 'mysql', 1 ),
                'post_author'    => is_user_logged_in() ? get_current_user_id() : 0,
                'is_virtual'     => TRUE,
                'filter'         => 'raw'
            );
            $this->wp_post = new \WP_Post( (object) $post );
        }
        return $this->wp_post;
    }
}

Здесь просто реализован интерфейс, ничего более.

Теперь класс контроллера (файл Controller.php):

<?php
namespace GM\VirtualPages;

class Controller implements ControllerInterface {

    private $pages;
    private $loader;
    private $matched;

    function __construct( TemplateLoaderInterface $loader ) {
        $this->pages = new \SplObjectStorage;
        $this->loader = $loader;
    }

    function init() {
        do_action( 'gm_virtual_pages', $this ); 
    }

    function addPage( PageInterface $page ) {
        $this->pages->attach( $page );
        return $page;
    }

    function dispatch( $bool, \WP $wp ) {
        if ( $this->checkRequest() && $this->matched instanceof Page ) {
            $this->loader->init( $this->matched );
            $wp->virtual_page = $this->matched;
            do_action( 'parse_request', $wp );
            $this->setupQuery();
            do_action( 'wp', $wp );
            $this->loader->load();
            $this->handleExit();
        }
        return $bool;
    }

    private function checkRequest() {
        $this->pages->rewind();
        $path = trim( $this->getPathInfo(), '/' );
        while( $this->pages->valid() ) {
            if ( trim( $this->pages->current()->getUrl(), '/' ) === $path ) {
                $this->matched = $this->pages->current();
                return TRUE;
            }
            $this->pages->next();
        }
    }        

    private function getPathInfo() {
        $home_path = parse_url( home_url(), PHP_URL_PATH );
        return preg_replace( "#^/?{$home_path}/#", '/', esc_url( add_query_arg(array()) ) );
    }

    private function setupQuery() {
        global $wp_query;
        $wp_query->init();
        $wp_query->is_page       = TRUE;
        $wp_query->is_singular   = TRUE;
        $wp_query->is_home       = FALSE;
        $wp_query->found_posts   = 1;
        $wp_query->post_count    = 1;
        $wp_query->max_num_pages = 1;
        $posts = (array) apply_filters(
            'the_posts', array( $this->matched->asWpPost() ), $wp_query
        );
        $post = $posts[0];
        $wp_query->posts          = $posts;
        $wp_query->post           = $post;
        $wp_query->queried_object = $post;
        $GLOBALS['post']          = $post;
        $wp_query->virtual_page   = $post instanceof \WP_Post && isset( $post->is_virtual )
            ? $this->matched
            : NULL;
    }

    public function handleExit() {
        exit();
    }
}

По сути, класс создаёт объект SplObjectStorage, в котором хранятся все добавленные объекты страниц.

На хуке 'do_parse_request' класс контроллера перебирает это хранилище, чтобы найти совпадение текущего URL с одним из добавленных URL страниц.

Если совпадение найдено, класс делает именно то, что мы запланировали: активирует некоторые хуки, настраивает переменные и загружает шаблон через класс, реализующий TemplateLoaderInterface. После этого просто вызывает exit().

Теперь напишем последний класс:

<?php
namespace GM\VirtualPages;

class TemplateLoader implements TemplateLoaderInterface {

    public function init( PageInterface $page ) {
        $this->templates = wp_parse_args(
            array( 'page.php', 'index.php' ), (array) $page->getTemplate()
        );
    }

    public function load() {
        do_action( 'template_redirect' );
        $template = locate_template( array_filter( $this->templates ) );
        $filtered = apply_filters( 'template_include',
            apply_filters( 'virtual_page_template', $template )
        );
        if ( empty( $filtered ) || file_exists( $filtered ) ) {
            $template = $filtered;
        }
        if ( ! empty( $template ) && file_exists( $template ) ) {
            require_once $template;
        }
    }
}

Шаблоны, указанные для виртуальной страницы, объединяются в массив со стандартными page.php и index.php, перед загрузкой шаблона активируется хук 'template_redirect' для добавления гибкости и улучшения совместимости.

После этого найденный шаблон проходит через пользовательский фильтр 'virtual_page_template' и стандартный 'template_include': опять же для гибкости и совместимости.

Наконец, файл шаблона просто загружается.

Основной файл плагина

Теперь нам нужно написать файл с заголовками плагина и использовать его для добавления хуков, которые обеспечат работу нашего процесса:

<?php namespace GM\VirtualPages;

/*
  Plugin Name: GM Virtual Pages
 */

require_once 'PageInterface.php';
require_once 'ControllerInterface.php';
require_once 'TemplateLoaderInterface.php';
require_once 'Page.php';
require_once 'Controller.php';
require_once 'TemplateLoader.php';

$controller = new Controller ( new TemplateLoader );

add_action( 'init', array( $controller, 'init' ) );

add_filter( 'do_parse_request', array( $controller, 'dispatch' ), PHP_INT_MAX, 2 );

add_action( 'loop_end', function( \WP_Query $query ) {
    if ( isset( $query->virtual_page ) && ! empty( $query->virtual_page ) ) {
        $query->virtual_page = NULL;
    }
} );

add_filter( 'the_permalink', function( $plink ) {
    global $post, $wp_query;
    if (
        $wp_query->is_page && isset( $wp_query->virtual_page )
        && $wp_query->virtual_page instanceof Page
        && isset( $post->is_virtual ) && $post->is_virtual
    ) {
        $plink = home_url( $wp_query->virtual_page->getUrl() );
    }
    return $plink;
} );

В реальном файле мы, вероятно, добавим больше заголовков, таких как ссылки на плагин и автора, описание, лицензию и т.д.

Gist плагина

Итак, мы закончили работу над нашим плагином. Весь код можно найти в Gist здесь.

Добавление страниц

Плагин готов и работает, но мы ещё не добавили ни одной страницы.

Это можно сделать внутри самого плагина, в файле темы functions.php, в другом плагине и т.д.

Добавление страниц — это просто:

<?php
add_action( 'gm_virtual_pages', function( $controller ) {

    // первая страница
    $controller->addPage( new \GM\VirtualPages\Page( '/custom/page' ) )
        ->setTitle( 'Моя первая пользовательская страница' )
        ->setTemplate( 'custom-page-form.php' );

    // вторая страница
    $controller->addPage( new \GM\VirtualPages\Page( '/custom/page/deep' ) )
        ->setTitle( 'Моя вторая пользовательская страница' )
        ->setTemplate( 'custom-page-deep.php' );

} );

И так далее. Вы можете добавить все необходимые страницы, просто помните, что нужно использовать относительные URL для страниц.

Внутри файла шаблона вы можете использовать все стандартные теги WordPress, а также писать любой PHP и HTML код.

Глобальный объект post заполняется данными из нашей виртуальной страницы. Саму виртуальную страницу можно получить через переменную $wp_query->virtual_page.

Получить URL виртуальной страницы так же просто, как передать в home_url() тот же путь, который использовался при создании страницы:

$custom_page_url = home_url( '/custom/page' );

Обратите внимание, что в основном цикле загруженного шаблона the_permalink() будет возвращать корректную постоянную ссылку на виртуальную страницу.

Примечания о стилях и скриптах для виртуальных страниц

Вероятно, при добавлении виртуальных страниц также потребуется зарегистрировать пользовательские стили/скрипты и затем просто использовать wp_head() в пользовательских шаблонах.

Это очень просто, так как виртуальные страницы легко распознаются по переменной $wp_query->virtual_page, а отдельные виртуальные страницы можно различать по их URL.

Просто пример:

add_action( 'wp_enqueue_scripts', function() {

    global $wp_query;

    if (
        is_page()
        && isset( $wp_query->virtual_page )
        && $wp_query->virtual_page instanceof \GM\VirtualPages\PageInterface
    ) {

        $url = $wp_query->virtual_page->getUrl();

        switch ( $url ) {
            case '/custom/page' : 
                wp_enqueue_script( 'a_script', $a_script_url );
                wp_enqueue_style( 'a_style', $a_style_url );
                break;
            case '/custom/page/deep' : 
                wp_enqueue_script( 'another_script', $another_script_url );
                wp_enqueue_style( 'another_style', $another_style_url );
                break;
        }
    }

} );

Примечания для автора вопроса

Передача данных со страницы на страницу не связана напрямую с этими виртуальными страницами, это общая задача.

Однако, если у вас есть форма на первой странице и вы хотите передать данные с неё на вторую страницу, просто используйте URL второй страницы в свойстве action формы.

Например, в шаблоне первой страницы вы можете:

<form action="<?php echo home_url( '/custom/page/deep' ); ?>" method="POST">
    <input type="text" name="testme">
</form>

А затем в шаблоне второй страницы:

<?php $testme = filter_input( INPUT_POST, 'testme', FILTER_SANITIZE_STRING ); ?>
<h1>Значение Test-Me с другой страницы: <?php echo $testme; ?></h1>
25 сент. 2014 г. 04:10:03
Комментарии

Потрясающий развернутый ответ, который охватывает не только саму проблему, но и создание плагина в ООП-стиле и многое другое. Мой голос точно ваш, представьте себе - по одному за каждый уровень, который охватывает этот ответ.

Nicolai Grossherr Nicolai Grossherr
25 сент. 2014 г. 13:50:51

Очень изящное и простое решение. Проголосовал, расшарил в твиттере.

kaiser kaiser
25 сент. 2014 г. 16:23:08

Код в Controller немного неверен... checkRequest() получает информацию о пути из home_url(), который возвращает localhost/wordpress. После preg_replace и add_query_arg этот URL становится /wordpress/virtual-page. А после trim в checkRequest этот URL превращается в wordpress/virtual. Это бы работало, если бы wordpress был установлен в корневой папке домена. Не могли бы вы предоставить исправление для этой проблемы, потому что я не могу найти подходящую функцию, которая возвращала бы правильный URL. Спасибо за все! (Приму ответ, когда он станет идеальным :)

user1257255 user1257255
25 сент. 2014 г. 21:20:08

Поздравляю, отличный ответ, и мне приятно видеть такое количество работы в качестве бесплатного решения.

bueltge bueltge
25 сент. 2014 г. 22:11:19

@G.M.: В моем случае WordPress установлен в .../htdocs/wordpress/, и сайт доступен по http://localhost/wordpress/. home_url() возвращает http://localhost/wordpress, а add_query_arg(array()) возвращает /wordpress/virtual-page/. Когда мы сравниваем $path и обрезанный $this->pages->current()->getUrl() в checkRequest(), возникает проблема, потому что $path равен wordpress/virtual-page, а обрезанный URL страницы равен virtual-page.

user1257255 user1257255
26 сент. 2014 г. 19:13:02

Невероятно, но как, черт возьми, я написал ' вместо " в preg_replace. Ты прав, это была моя ошибка, прости за это. После решения первой проблемы я столкнулся с другой: Undefined property: WP_Query::$queried_object_id. Вероятно, она связана с Page.php, где мы устанавливаем атрибуты поста, или с setupQuery в Controller'е. У меня есть еще один вопрос по поводу 'post_author' в Page.php, где используется функция is_user_logged_in(). У меня сайт, где любой может зарегистрироваться и войти. Может ли это представлять угрозу безопасности? Обязательно ли использовать функцию is_user_logged_in() или можно установить значение по умолчанию 0?

user1257255 user1257255
26 сент. 2014 г. 20:16:51

Функция is_user_logged_in() не является проблемой безопасности: вы не предоставляете никаких возможностей авторизованным пользователям, и страница даже не существует в базе данных. Однако, установка значения всегда в 0 не вызовет проблем. Что касается ошибки, я много раз тестировал код в разных окружениях (Windows, Linux, PHP 5.4, 5.5)... с включенным WP debug и отладочными плагинами. Никаких проблем не было. Так что, либо вы изменили что-то в коде, либо проблема связана с конфликтом плагина/темы. В обоих случаях я не могу решить эту проблему и надеюсь, вы поймете, что я уже потратил слишком много времени на этот ответ. @user1257255

gmazzap gmazzap
26 сент. 2014 г. 20:31:26

Я понимаю. Огромное спасибо за такой развернутый ответ и за все остальное! :)

user1257255 user1257255
26 сент. 2014 г. 20:44:19

Привет @gmazzap, если я передаю параметр запроса, маршрут с addPage не работает

Marc Garcia Marc Garcia
10 окт. 2018 г. 11:49:09

Что делать, если я не хочу расширять шаблон фронтенда.

Кажется, что даже с null или '' он всё равно его расширяет.

Кроме того, он не читает содержимое моих .php файлов

bmatovu bmatovu
27 мая 2020 г. 12:45:43
Показать остальные 5 комментариев
0

Более простое решение — автоматически добавлять страницу, если она не существует. Мы можем использовать пользовательское мета-поле для проверки её наличия. Мы можем добавить обработчик в фильтр the_content, если текущий ID совпадает с ID страницы.

        $this->id = $this->settings['id'];
        add_action('init', function (){
            $page = get_posts([
                'meta_key' => 'my_frontend_id',
                'meta_value' => $this->id,
                'post_type' => 'page',
                'post_status' => 'any',
                'numberposts' => 1
            ])[0];
            if (is_null($page)){
                $pageId = wp_insert_post($this->settings);
                add_post_meta($pageId, 'my_frontend_id', $this->id, true);
            }
            else
                $pageId = $page->ID;
            
            add_filter('the_content', function ($content) use ($pageId){
                if (is_singular() && in_the_loop() && is_main_query() && get_the_ID() === $pageId){
                    ob_start();
                    $this->render();
                    return ob_get_clean();
                }
                return $content;
            }, 1);
        });

Однако здесь есть нюанс. Например, защита паролем не работает с таким подходом. Требуются дополнительные усилия, чтобы правильно защитить эти страницы от несанкционированного чтения или записи. В итоге я предпочёл использовать шорткоды вместо этого фильтра, хотя могу представить сценарии, где он может быть полезен.

21 мар. 2024 г. 16:06:09
2

Я однажды использовал решение, описанное здесь: http://scott.sherrillmix.com/blog/blogger/creating-a-better-fake-post-with-a-wordpress-plugin/

Фактически, когда я его использовал, я расширил решение так, чтобы можно было зарегистрировать более одной страницы за раз (остальной код примерно похож на решение, на которое я ссылаюсь в предыдущем абзаце).

Однако для работы этого решения необходимо, чтобы были разрешены красивые постоянные ссылки...

<?php

class FakePages {

    public function __construct() {
        add_filter( 'the_posts', array( $this, 'fake_pages' ) );
    }

    /**
     * Внутренне регистрирует страницы, которые мы хотим подделать. Ключ массива — это ярлык, по которому страница будет доступна во фронтенде
     * @return mixed
     */
    private static function get_fake_pages() {
        //http://example.com/fakepage1
        $fake_pages['fakepage1'] = array(
            'title'   => 'Фейковая страница 1',
            'content' => 'Это содержимое фейковой страницы 1'
        );
        //http://example.com/fakepage2
        $fake_pages['fakepage2'] = array(
            'title'   => 'Фейковая страница 2',
            'content' => 'Это содержимое фейковой страницы 2'
        );

        return $fake_pages;
    }

    /**
     * Подделывает результат выборки записей
     *
     * @param $posts
     *
     * @return array|null
     */
    public function fake_pages( $posts ) {
        global $wp, $wp_query;
        $fake_pages       = self::get_fake_pages();
        $fake_pages_slugs = array();
        foreach ( $fake_pages as $slug => $fp ) {
            $fake_pages_slugs[] = $slug;
        }
        if ( true === in_array( strtolower( $wp->request ), $fake_pages_slugs )
             || ( true === isset( $wp->query_vars['page_id'] )
                  && true === in_array( strtolower( $wp->query_vars['page_id'] ), $fake_pages_slugs )
            )
        ) {
            if ( true === in_array( strtolower( $wp->request ), $fake_pages_slugs ) ) {
                $fake_page = strtolower( $wp->request );
            } else {
                $fake_page = strtolower( $wp->query_vars['page_id'] );
            }
            $posts                  = null;
            $posts[]                = self::create_fake_page( $fake_page, $fake_pages[ $fake_page ] );
            $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;
            $wp_query->is_fake_page = true;
            $wp_query->fake_page    = $wp->request;
            //Более длинные структуры постоянных ссылок могут не совпадать с ярлыком фейковой записи и вызывать ошибку 404, поэтому мы перехватываем ошибку здесь
            unset( $wp_query->query["error"] );
            $wp_query->query_vars["error"] = "";
            $wp_query->is_404              = false;
        }

        return $posts;
    }

    /**
     * Создает виртуальную фейковую страницу
     *
     * @param $pagename
     * @param $page
     *
     * @return stdClass
     */
    private static function create_fake_page( $pagename, $page ) {
        $post                 = new stdClass;
        $post->post_author    = 1;
        $post->post_name      = $pagename;
        $post->guid           = get_bloginfo( 'wpurl' ) . '/' . $pagename;
        $post->post_title     = $page['title'];
        $post->post_content   = $page['content'];
        $post->ID             = - 1;
        $post->post_status    = 'static';
        $post->comment_status = 'closed';
        $post->ping_status    = 'closed';
        $post->comment_count  = 0;
        $post->post_date      = current_time( 'mysql' );
        $post->post_date_gmt  = current_time( 'mysql', 1 );

        return $post;
    }
}

new FakePages();
24 сент. 2014 г. 20:32:02
Комментарии

А как насчёт пользовательского шаблона, куда я могу поместить свою форму?

user1257255 user1257255
24 сент. 2014 г. 20:51:20

content в массиве при регистрации фейковой страницы отображается в теле страницы - он может содержать HTML, простой текст или даже шорткод.

david.binda david.binda
24 сент. 2014 г. 20:53:34