Aggiungere Impostazioni a un Custom Post Type

5 ago 2016, 12:10:18
Visualizzazioni: 15.3K
Voti: 3

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]'] );
    }
}
3
Commenti

Solo per commentare "Non so scrivere un plugin", non è un problema. Solitamente tutto ciò che potresti inserire in un plugin può essere inserito nel file functions.php del tema, se questo si adatta meglio alla tua situazione.

Andy Macaulay-Brook Andy Macaulay-Brook
5 ago 2016 12:12:50

Ciao Andy. Grazie per la tua risposta. Hai ragione, non è un problema, ma pensavo fosse un parametro degno di nota per chi risponde.

dotZak dotZak
5 ago 2016 12:14:25

Sì. Domanda molto completa e dettagliata. Al momento non posso rispondere personalmente, ma spero che il mio voto positivo ti attirerà l'attenzione di qualcuno.

Andy Macaulay-Brook Andy Macaulay-Brook
5 ago 2016 12:22:23
Tutte le risposte alla domanda 2
0

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.

  1. Questo ora è in un file separato, quindi non vedrai il tipo di post personalizzato registrato.
  2. Ho usato un oggetto per la pagina seguendo l'esempio 2 del codex di WordPress.
  3. 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();
8 ago 2016 12:04:47
2

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'] );
    }
}
5 ago 2016 13:23:10
Commenti

Oh. Certamente! Proverò e ti farò sapere come va. Grazie per questo.

dotZak dotZak
6 ago 2016 03:15:22

Questo non ha risolto il problema. È appena passato il weekend qui, quindi potrò esaminarlo stamattina e farti sapere se utilizzerò una versione migliorata della tua risposta o meno.

dotZak dotZak
8 ago 2016 04:18:02