Как я могу добавить опцию в список шаблонов страниц из плагина?

10

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

Что я конкретно пытаюсь сделать, это добавить опцию в список доступных шаблонов страниц при редактировании страницы, а не использовать какой-либо другой метод, такой какif( is_page( 'page-slug' ) ) { /* etc */ }

Есть ли глобальная переменная, которую я могу изменить, чтобы сделать это?

Редактировать:

В настоящее время я использую этот код, основываясь на ссылке, которую мне дал @ m0r7if3r в комментарии, проблема в том, что он будет запускать эту функцию при просмотре страницы, но не при редактировании страницы (для заполнения раскрывающегося списка шаблонами страниц) :

class JW_SiteGrader {

    private static $instance;

    private function __construct() {


        add_action( 'template_redirect', array( &$this, 'sitegrader_template_redirect' ), 20 );

    }

    public static function getInstance() {

        // Return the class data in a Singleton fashion
        if (self::$instance == null)
            self::$instance = new JW_SiteGrader();
        return self::$instance;

    }

    public function sitegrader_template_redirect() {

        add_filter( 'page_template', array( &$this, 'sitegrader_page_template' ), 10, 1 );

    }

    public function locate_plugin_template( $template_names, $load = false, $require_once = true ) {

        if ( !is_array( $template_names ) )
            return '';

        $located = '';

        $this_plugin_dir = WP_PLUGIN_DIR . '/' . str_replace( basename( __FILE__ ), '', plugin_basename( __FILE__ ) );

        foreach ( $template_names as $template_name ) {

            if ( !$template_name )
                continue;

            if ( file_exists( STYLESHEETPATH . '/' . $template_name ) ) {

                $located = STYLESHEETPATH . '/' . $template_name;
                break;

            } else if ( file_exists( TEMPLATEPATH . '/' . $template_name ) ) {

                $located = TEMPLATEPATH . '/' . $template_name;
                break;

            } else if ( file_exists( $this_plugin_dir .  $template_name ) ) {

                $located =  $this_plugin_dir . $template_name;
                break;

            }

        }

        if ( $load && '' != $located )
            load_template( $located, $require_once );

        return $located;
    }

    public function sitegrader_page_template( $template ) {

        $object = get_queried_object();

        if ( 'page' == $object->post_type ) {

            // New 
            $templates[] = "page-sitegrader.php";
            // Like in core
            $templates[] = "page-{$object->post_type}.php";
            $templates[] = "page.php";

            return locate_template( $templates );  

        }

        // return apply_filters('page_template', $template);
        return $template;
    }

}

Изменить 2:

Похоже, что эта функциональность будет выпущена в будущем обновлении, я прочитал немало билетов об этом, и было некоторое обсуждение, но никакого реального ответа (в надежде на 3.4). Здесь будут перечислены URL-адреса trac tickets.

Изменить 3:

Приведенный выше код работает, НО, единственная проблема, с которой я столкнулся на данный момент, заключается в том, что при редактировании / добавлении новой страницы нет шаблона, добавляемого в раскрывающийся список. Я пробую несколько вещей и скоро обновлю свой вопрос.

Джаред
источник
2
Пытались ли вы что - то вроде этого ?
mor7ifer
@ m0r7if3r (Если вы попробуете это, пожалуйста, оставьте сообщение, как это получилось - спасибо!)
kaiser
@kaiser Я попробовал код, который он рекомендовал, единственная недостающая ссылка - получить мета-поле, чтобы добавить шаблон в выпадающий список (насколько я знаю!).
Джаред
@Jared Посмотрите на этот ответ от меня на похожий вопрос и связанные с ним билеты в нижней части. Рекламируйте свой код) Если он не отображается на каждой странице, значит, вы используете неправильные хуки для запуска экземпляра. Какие крючки вы используете?
Кайзер
@kaiser Я использую page_templateхук, код выше в моем редактировании - то, что используется в настоящее время. Нужно ли использовать template_redirectкрючок, а затем добавить page_templateтуда фильтр?
Джаред

Ответы:

4

Фильтры? Кто-нибудь?

Там нет фильтра, чтобы помочь: page_template_dropdown($template);используется для построения выпадающего списка, и он не фильтруется.

Пробирается в массив шаблонов?

Для создания выпадающего содержимого используется основной мета-блок get_page_templates(). Изнутри функция выглядит следующим образом:

$themes = get_themes();
$theme = get_current_theme();
$templates = $themes[$theme]['Template Files'];

Но при просмотре get_themes();тогда швов не будет возможности перехватить список шаблонов. Более того, у нас проблема в том, что нет возможности получить шаблон из-за пределов каталога тем…

... Подделка темы!

Теория и ее недостатки…

Вы можете использовать register_theme_directory()для добавления дополнительного каталога тем, где вы можете разместить шаблоны. Так что проще всего было бы зарегистрировать свой плагин как папку с темами:

// Register during init hook:
register_theme_directory( plugin_dir_path( __FILE__ ).'templates' );

Примечание: это где я не уверен, будет ли это работать .

Во время активации плагина: Затем вы должны поместить style.css.phpфайл в вашу templatesпапку. Это позволит вам добавить переменные в ваш файл. Эта переменная будет родительской темой. И родительская тема должна быть просто активной в данный момент. Затем обновите вашу активную тему для вашего плагина.

Недостаток № 2: Об интерфейсе »Внешний вид« UI… Возможно, добавьте примечание, что эта «Тема» не предназначена для использования в качестве актуальной Темы. Я оставляю остальную часть материала «Избегайте активации этой темы» на ваше воображение. Во всяком случае: это должно работать.

Недостаток № 2: Этот трюк успешно избегает дочерних тем. Вам разрешено иметь одну родительскую тему. Ничего больше.

кайзер
источник
Итак, я предполагаю, что нет никакого реального способа использовать пользовательские шаблоны страниц из какой-либо неактивной темы, правильно? Я мог бы зарегистрировать каталог тем, но шаблоны не доступны для использования, если эта тема не активна.
Джаред
1
На самом деле, нет. Это просто не должно быть и, следовательно, отсутствие ядра. Вы пробовали ссылку на ипстену выше? Я уже пытался пойти по этому пути, но закончил в тупик - с другим решением. Лучше всего следить за билетами, вставлять и связывать их, где бы вы ни находились. : /
Кайзер
2

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

Я надеюсь, что они выпустят то, что вы намеревались сделать, в следующем выпуске ядра.

Адам
источник
1
У меня был такой метод, который работал раньше, но у меня было много проблем, когда я пробовал его, потому что, когда пользователь переключал темы, он не удалял файл шаблона и если бы он копировал свою активную тему и помещал ее на другой сайт , они рискуют загрузить пользовательский файл шаблона, который не будет работать. Я знаю, что есть несколько обходных путей, но я действительно хочу, чтобы это было автоматически . +1 за предложение, хотя.
Джаред
1
Привет Джаред, я тоже был обеспокоен той же проблемой. Единственное решение, которое я мог бы подумать о дальнейшем расширении этого альтернативного метода, - это чтобы плагин при его активации получал имя текущей темы, а затем, если пользователь деактивирует / переключает темы, вы можете удалить файл шаблона из этой темы и перезаписать его на вновь активированную. тема. Взгляните на эту ссылку, где он создал свои собственные хуки активации / деактивации для проверки тем. С небольшим дополнительным кодом я чувствую, что это выполнимо.
Адам
Абсолютно, я думаю, что это может работать. Я попробую и опубликую результаты в моем вопросе. Спасибо за ссылку, это помогает!
Джаред
1

Я просмотрел источник, и довольно шокирующе, я не вижу способа сделать это! Я предложил бы добавить второй мета-блок с выпадающим списком переопределения темы / второй темы. Затем подключите этот фильтр:

# wp-includes/theme.php line 751 in 3.3.1:
return apply_filters( "{$type}_template", locate_template( $templates ) );

вернуть файл темы, если он был переопределен. Конечно, вы можете добавить add_filter только в том случае, если вам нужен пост.

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

Я также предложил бы добавить trac-билет, запрашивающий эту функцию (если его там еще нет).

Мэтью Бойнс
источник
1
согласен с предложением этого для trac.
helgatheviking
Кажется, он уже в трассе: core.trac.wordpress.org/ticket/15803
Джаред,
1
Я только что исследовал это для другого вопроса о шаблонах одного типа . Вы можете найти билеты Trac в конце ответа. Будем надеяться на 3.4.
Кайзер
1

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

gruvii
источник
Не могли бы вы показать полный код? В настоящее время это только грубая концепция. Спасибо.
Кайзер
1

Посмотрите на ловушку theme_page_templates, используемую get_page_templatesфункцией, фильтр добавлен с 3.9, обновлен в 4.4:

apply_filters( 'theme_page_templates', $page_templates, $this, $post );
Уильям Гу
источник
более подробно объяснил здесь: wordpress.stackexchange.com/a/255820/75495
cjbj
-2

Результат поиска с DuckDuckGo, который добавил шаблон страницы WordPress, нашел ответ для меня на странице wpmu.org под названием Учебное пособие по шаблонам пользовательских страниц WordPress .

По сути, в каталоге темы, wp-content / themes / your-theme , скопируйте существующий шаблон страницы в новое имя php-файла по вашему выбору. Отредактируйте новый файл, следя за тем, чтобы изменить волшебное значение свойства «Имя шаблона:» в комментарии вверху файла.

Это было все, что было с этим. Возможно, это особенность, которая ставит вопрос позже. Я использую WP 3.5 с темой nine_eleven.

Также возможно, что есть более чистые способы расширения темы. Такие изменения могут быть перезаписаны обновлениями темы. Моя вина.

Дуглас Ловелл
источник
Мне нужно решение, чтобы добавить шаблон в выпадающий список из плагина, а не темы. :(
Джаред