Добавить настройки в пользовательский тип сообщения

У меня есть настраиваемый тип сообщений, называемый Портфолио. Он связан с тремя обычными таксономиями. Все это прекрасно работает.

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

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

Я добавил только один параметр ( header_text ), пока не смогу найти проблему с сохранением.

Я полагаю, что $option_group , вероятно, проблема.

Если я var_dump($_POST) я получаю:

 array (size=6) 'option_page' => string 'edit.php?post_type=rushhour_projects&page=projects_archive' (length=58) 'action' => string 'update' (length=6) '_wpnonce' => string '23c70a3029' (length=10) '_wp_http_referer' => string '/wp-admin/edit.php?post_type=rushhour_projects&page=projects_archive' (length=68) 'rushhour_projects_archive' => array (size=1) 'header_text' => string 'asdf' (length=4) 'submit' => string 'Save Changes' (length=12) 

Вот пользовательская регистрация типа записи:

 if ( ! function_exists('rushhour_post_type_projects') ) : // Add Portfolio Projects to WordPress add_action( 'init', 'rushhour_post_type_projects', 0 ); // Register Portfolio Projects Custom Post Type function rushhour_post_type_projects() { $labels = array( 'name' => _x( 'Portfolio', 'Post Type General Name', 'rushhour' ), 'singular_name' => _x( 'Project', 'Post Type Singular Name', 'rushhour' ), 'menu_name' => __( 'Portfolio Projects', 'rushhour' ), 'name_admin_bar' => __( 'Portfolio Project', 'rushhour' ), 'archives' => __( 'Portfolio Archives', 'rushhour' ), 'parent_item_colon' => __( 'Parent Project:', 'rushhour' ), 'all_items' => __( 'All Projects', 'rushhour' ), 'add_new_item' => __( 'Add New Project', 'rushhour' ), 'add_new' => __( 'Add New', 'rushhour' ), 'new_item' => __( 'New Project', 'rushhour' ), 'edit_item' => __( 'Edit Project', 'rushhour' ), 'update_item' => __( 'Update Project', 'rushhour' ), 'view_item' => __( 'View Project', 'rushhour' ), 'search_items' => __( 'Search Projects', 'rushhour' ), 'not_found' => __( 'Not found', 'rushhour' ), 'not_found_in_trash' => __( 'Not found in Trash', 'rushhour' ), 'featured_image' => __( 'Featured Image', 'rushhour' ), 'set_featured_image' => __( 'Set featured image', 'rushhour' ), 'remove_featured_image' => __( 'Remove featured image', 'rushhour' ), 'use_featured_image' => __( 'Use as featured image', 'rushhour' ), 'insert_into_item' => __( 'Insert into project', 'rushhour' ), 'uploaded_to_this_item' => __( 'Uploaded to this project', 'rushhour' ), 'items_list' => __( 'Projects list', 'rushhour' ), 'items_list_navigation' => __( 'Projects list navigation', 'rushhour' ), 'filter_items_list' => __( 'Filter projects list', 'rushhour' ), ); $rewrite = array( 'slug' => 'portfolio', 'with_front' => true, 'pages' => true, 'feeds' => true, ); $args = array( 'label' => __( 'Project', 'rushhour' ), 'description' => __( 'Portfolio projects for Global VDC.', 'rushhour' ), 'labels' => $labels, 'supports' => array( 'title', 'editor', 'excerpt', 'thumbnail', 'revisions', ), 'taxonomies' => array( 'rushhour_clients', 'rushhour_locations', 'rushhour_project_type' ), 'hierarchical' => false, 'public' => true, 'show_ui' => true, 'show_in_menu' => true, 'menu_position' => 5, 'menu_icon' => 'dashicons-portfolio', 'show_in_admin_bar' => true, 'show_in_nav_menus' => true, 'can_export' => true, 'has_archive' => 'portfolio', 'exclude_from_search' => false, 'publicly_queryable' => true, 'rewrite' => $rewrite, 'capability_type' => 'page', ); register_post_type( 'rushhour_projects', $args ); } endif; 

Затем у меня есть функция для настройки страницы подменю администратора.

 if ( ! function_exists('rushhour_projects_admin_page') ) : add_action( 'admin_menu' , 'rushhour_projects_admin_page' ); /** * Generate sub menu page for settings * * @uses rushhour_projects_options_display() */ function rushhour_projects_admin_page() { add_submenu_page( 'edit.php?post_type=rushhour_projects', __('Portfolio Projects Options', 'rushhour'), __('Portfolio Options', 'rushhour'), 'manage_options', 'projects_archive', 'rushhour_projects_options_display'); } endif; 

Таким образом, эти два элемента работают без проблем.

Проблема, я думаю, где-то в функциях ниже для регистрации и сохранения настроек:

 if ( ! function_exists('rushhour_projects_options_display') ) : /** * Display the form on the Rush Hour Projects Settings sub menu page. * * Used by 'rushhour_projects_admin_page'. */ function rushhour_projects_options_display() { // Create a header in the default WordPress 'wrap' container echo '<div class="wrap">'; settings_errors(); echo '<form method="post" action="">'; var_dump( get_option('rushhour_projects_archive') ); settings_fields( 'edit.php?post_type=rushhour_projects&page=projects_archive' ); do_settings_sections( 'edit.php?post_type=rushhour_projects&page=projects_archive' ); submit_button(); echo '</form></div><!-- .wrap -->'; } endif; add_action( 'admin_init', 'rushhour_projects_settings' ); /** * Register settings and add settings sections and fields to the admin page. */ function rushhour_projects_settings() { if ( false == get_option( 'rushhour_projects_archive' ) ) add_option( 'rushhour_projects_archive' ); add_settings_section( 'projects_archive_header', // Section $id __('Portfolio Project Archive Page Settings', 'rushhour'), 'rushhour_project_settings_section_title', // Callback 'edit.php?post_type=rushhour_projects&page=projects_archive' // Settings Page Slug ); add_settings_field( 'header_text', // Field $id __('Header Text', 'rushhour'), // Setting $title 'projects_archive_header_text_callback', 'edit.php?post_type=rushhour_projects&page=projects_archive', // Settings Page Slug 'projects_archive_header', // Section $id array('Text to display in the archive header.') ); register_setting( 'edit.php?post_type=rushhour_projects&page=projects_archive', // $option_group 'rushhour_projects_archive', // $option_name 'rushhour_projects_archive_save_options' ); } /** * Callback for settings section. * * Commented out until settings are working. * * @param array $args Gets the $id, $title and $callback. */ function rushhour_project_settings_section_title( $args ) { // printf( '<h2>%s</h2>', apply_filters( 'the_title', $args['title'] ) ); } /** * Settings fields callbacks. */ function projects_archive_header_text_callback($args) { $options = get_option('rushhour_projects_archive'); printf( '<input class="widefat" id="header_text" name="rushhour_projects_archive[header_text]" type="textarea" value="%1$s" />', $options ); } /** * Save options. */ function rushhour_projects_archive_save_options() { if ( isset( $_POST['rushhour_projects_archive[header_text]'] ) ) { update_option( 'rushhour_projects_archive', $_POST['rushhour_projects_archive[header_text]'] ); } } 

Solutions Collecting From Web of "Добавить настройки в пользовательский тип сообщения"

Хорошо, поэтому я досадил, что он не работает, и решил просто переписать его. Я не уверен, какое решение было, но я подозреваю две вещи: неправильная конечная точка для формы (должна быть options.php ) и неправильная $option_group и $option_name (они, вероятно, не были правильно сопоставлены).

Для потомков я оставлю свою переписку здесь и, надеюсь, это поможет другим. Несколько отличий между этой и предыдущей версиями.

  1. Это теперь находится в собственном файле, поэтому вы не увидите зарегистрированный пользовательский тип записи.
  2. Я использовал объект для страницы в примере 2 из кода WordPress .
  3. Я добавил второй вариант для загрузчика мультимедиа, используя этот учебник , который я обновил для использования wp_localize_script() чтобы внедрить объект JSON для получения некоторых данных PHP.

     public function __construct() { add_action( 'admin_menu', array( $this, 'add_submenu_page_to_post_type' ) ); add_action( 'admin_init', array( $this, 'sub_menu_page_init' ) ); add_action( 'admin_init', array( $this, 'media_selector_scripts' ) ); } /** * Add sub menu page to the custom post type */ public function add_submenu_page_to_post_type() { add_submenu_page( 'edit.php?post_type=rushhour_projects', __('Portfolio Projects Options', 'rushhour'), __('Portfolio Options', 'rushhour'), 'manage_options', 'projects_archive', array($this, 'rushhour_projects_options_display')); } /** * Options page callback */ public function rushhour_projects_options_display() { $this->options = get_option( 'rushhour_projects_archive' ); wp_enqueue_media(); echo '<div class="wrap">'; printf( '<h1>%s</h1>', __('Portfolio Options', 'rushhour' ) ); echo '<form method="post" action="options.php">'; settings_fields( 'projects_archive' ); do_settings_sections( 'projects-archive-page' ); submit_button(); echo '</form></div>'; } /** * Register and add settings */ public function sub_menu_page_init() { register_setting( 'projects_archive', // Option group 'rushhour_projects_archive', // Option name array( $this, 'sanitize' ) // Sanitize ); add_settings_section( 'header_settings_section', // ID __('Header Settings', 'rushhour'), // Title array( $this, 'print_section_info' ), // Callback 'projects-archive-page' // Page ); add_settings_field( 'archive_description', // ID __('Archive Description', 'rushhour'), // Title array( $this, 'archive_description_callback' ), // Callback 'projects-archive-page', // Page 'header_settings_section' // Section ); add_settings_field( 'image_attachment_id', __('Header Background Image', 'rushhour'), array( $this, 'header_bg_image_callback' ), 'projects-archive-page', 'header_settings_section' ); } /** * Sanitize each setting field as needed * * @param array $input Contains all settings fields as array keys */ public function sanitize( $input ) { $new_input = array(); if( isset( $input['archive_description'] ) ) $new_input['archive_description'] = sanitize_text_field( $input['archive_description'] ); if( isset( $input['image_attachment_id'] ) ) $new_input['image_attachment_id'] = absint( $input['image_attachment_id'] ); return $new_input; } /** * Print the Section text */ public function print_section_info() { print 'Select options for the archive page header.'; } /** * Get the settings option array and print one of its values */ public function archive_description_callback() { printf( '<input type="text" id="archive_description" name="rushhour_projects_archive[archive_description]" value="%s" />', isset( $this->options['archive_description'] ) ? esc_attr( $this->options['archive_description']) : '' ); } /** * Get the settings option array and print one of its values */ public function header_bg_image_callback() { $attachment_id = $this->options['image_attachment_id']; // Image Preview printf('<div class="image-preview-wrapper"><img id="image-preview" src="%s" ></div>', wp_get_attachment_url( $attachment_id ) ); // Image Upload Button printf( '<input id="upload_image_button" type="button" class="button" value="%s" />', __( 'Upload image', 'rushhour' ) ); // Hidden field containing the value of the image attachment id printf( '<input type="hidden" name="rushhour_projects_archive[image_attachment_id]" id="image_attachment_id" value="%s">', $attachment_id ); } public function media_selector_scripts() { $my_saved_attachment_post_id = get_option( 'media_selector_attachment_id', 0 ); wp_register_script( 'sub_menu_media_selector_scripts', get_template_directory_uri() . '/admin/js/media-selector.js', array('jquery'), false, true ); $selector_data = array( 'attachment_id' => get_option( 'media_selector_attachment_id', 0 ) ); wp_localize_script( 'sub_menu_media_selector_scripts', 'selector_data', $selector_data ); wp_enqueue_script( 'sub_menu_media_selector_scripts' ); } 

    }

Затем просто вызовите объект, если is_admin() истинно:

 if ( is_admin() ) $my_settings_page = new RushHourProjectArchivesAdminPage(); 

Это должно сделать трюк. + Изменить

 function rushhour_projects_archive_save_options() { if ( isset( $_POST['rushhour_projects_archive[header_text]'] ) ) { update_option( 'rushhour_projects_archive', $_POST['rushhour_projects_archive[header_text]'] ); } } 

в

 function rushhour_projects_archive_save_options() { if ( isset( $_POST['rushhour_projects_archive']['header_text'] ) ) { update_option( 'rushhour_projects_archive', $_POST['rushhour_projects_archive']['header_text'] ); } }