Aggiungere Impostazioni a un Custom Post Type
Ho un custom post type chiamato Portfolio. È associato a tre tassonomie personalizzate. Tutto funziona correttamente.
Per la pagina archivio, però, ho bisogno di aggiungere alcune impostazioni personalizzate. A causa di una limitazione nel progetto, non posso scrivere un plugin - tutti i cambiamenti devono essere fatti nel tema.
Ho fatto apparire la pagina del sottomenu delle impostazioni (abbastanza facile) seguendo questa guida, e le impostazioni appaiono nella pagina senza problemi. Il problema ora è che non vengono salvate.
Ho aggiunto solo un'impostazione (header_text
) finché non riesco a risolvere il problema del salvataggio.
Immagino che $option_group
sia probabilmente il problema.
Se faccio var_dump($_POST)
ottengo:
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)
Ecco la registrazione del custom post type:
if ( ! function_exists('rushhour_post_type_projects') ) :
// Aggiungi Portfolio Projects a WordPress
add_action( 'init', 'rushhour_post_type_projects', 0 );
// Registra il Custom Post Type Portfolio Projects
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;
Poi ho una funzione per impostare la pagina del sottomenu admin.
if ( ! function_exists('rushhour_projects_admin_page') ) :
add_action( 'admin_menu' , 'rushhour_projects_admin_page' );
/**
* Genera la pagina del sottomenu per le impostazioni
*
* @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;
Quindi i due elementi sopra funzionano senza problemi.
Il problema, penso, è da qualche parte nelle funzioni seguenti per la registrazione e il salvataggio delle impostazioni:
if ( ! function_exists('rushhour_projects_options_display') ) :
/**
* Visualizza il form nella pagina del sottomenu delle impostazioni di Rush Hour Projects.
*
* Usato da 'rushhour_projects_admin_page'.
*/
function rushhour_projects_options_display()
{
// Crea un header nel contenitore 'wrap' predefinito di WordPress
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' );
/**
* Registra le impostazioni e aggiunge sezioni e campi alla pagina admin.
*/
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 per la sezione delle impostazioni.
*
* Commentato finché le impostazioni non funzionano.
*
* @param array $args Ottiene $id, $title e $callback.
*/
function rushhour_project_settings_section_title( $args ) {
// printf( '<h2>%s</h2>', apply_filters( 'the_title', $args['title'] ) );
}
/**
* Callback per i campi delle impostazioni.
*/
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 );
}
/**
* Salva le opzioni.
*/
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]'] );
}
}
Ok, quindi mi sono irritato perché non funzionava e ho deciso di riscriverlo. Non sono sicuro quale fosse la soluzione, ma sospetto due cose: l'endpoint sbagliato per il form (dovrebbe essere options.php) e il $option_group
e $option_name
errati (probabilmente non corrispondevano correttamente).
Per i posteri, lascio qui la mia riscrittura e spero che aiuti altri. Alcune differenze tra questa e la versione precedente.
- Questo ora è in un file separato, quindi non vedrai il tipo di post personalizzato registrato.
- Ho usato un oggetto per la pagina seguendo l'esempio 2 del codex di WordPress.
- Ho aggiunto una seconda opzione per un selettore media utilizzando questo tutorial, che ho aggiornato per usare
wp_localize_script()
per iniettare un oggetto JSON e ottenere alcuni dati PHP.
<?php
class RushHourProjectArchivesAdminPage
{
/**
* Contiene i valori da utilizzare nei callback dei campi
*/
private $options;
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' ) );
}
/**
* Aggiunge una pagina di sottomenu al tipo di post personalizzato
*/
public function add_submenu_page_to_post_type()
{
add_submenu_page(
'edit.php?post_type=rushhour_projects',
__('Opzioni Portfolio Progetti', 'rushhour'),
__('Opzioni Portfolio', 'rushhour'),
'manage_options',
'projects_archive',
array($this, 'rushhour_projects_options_display'));
}
/**
* Callback della pagina delle opzioni
*/
public function rushhour_projects_options_display()
{
$this->options = get_option( 'rushhour_projects_archive' );
wp_enqueue_media();
echo '<div class="wrap">';
printf( '<h1>%s</h1>', __('Opzioni Portfolio', 'rushhour' ) );
echo '<form method="post" action="options.php">';
settings_fields( 'projects_archive' );
do_settings_sections( 'projects-archive-page' );
submit_button();
echo '</form></div>';
}
/**
* Registra e aggiunge le impostazioni
*/
public function sub_menu_page_init()
{
register_setting(
'projects_archive', // Gruppo opzioni
'rushhour_projects_archive', // Nome opzione
array( $this, 'sanitize' ) // Sanificazione
);
add_settings_section(
'header_settings_section', // ID
__('Impostazioni Intestazione', 'rushhour'), // Titolo
array( $this, 'print_section_info' ), // Callback
'projects-archive-page' // Pagina
);
add_settings_field(
'archive_description', // ID
__('Descrizione Archivio', 'rushhour'), // Titolo
array( $this, 'archive_description_callback' ), // Callback
'projects-archive-page', // Pagina
'header_settings_section' // Sezione
);
add_settings_field(
'image_attachment_id',
__('Immagine di Sfondo Intestazione', 'rushhour'),
array( $this, 'header_bg_image_callback' ),
'projects-archive-page',
'header_settings_section'
);
}
/**
* Sanifica ogni campo delle impostazioni come necessario
*
* @param array $input Contiene tutti i campi delle impostazioni come chiavi di array
*/
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;
}
/**
* Stampa il testo della sezione
*/
public function print_section_info()
{
print 'Seleziona le opzioni per l\'intestazione della pagina archivio.';
}
/**
* Ottiene l'array delle opzioni delle impostazioni e stampa uno dei suoi valori
*/
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']) : ''
);
}
/**
* Ottiene l'array delle opzioni delle impostazioni e stampa uno dei suoi valori
*/
public function header_bg_image_callback()
{
$attachment_id = $this->options['image_attachment_id'];
// Anteprima immagine
printf('<div class="image-preview-wrapper"><img id="image-preview" src="%s" alt="Anteprima immagine di sfondo" title="Anteprima immagine di sfondo"></div>', wp_get_attachment_url( $attachment_id ) );
// Pulsante di caricamento immagine
printf( '<input id="upload_image_button" type="button" class="button" value="%s" />',
__( 'Carica immagine', 'rushhour' ) );
// Campo nascosto contenente il valore dell'ID dell'allegato immagine
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' );
}
}
Quindi semplicemente chiama l'oggetto se is_admin()
è vero:
if ( is_admin() )
$my_settings_page = new RushHourProjectArchivesAdminPage();

Questo dovrebbe funzionare. Cambia
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]'] );
}
}
con
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'] );
}
}
