Modifica dei post nel frontend utilizzando un modulo
Ho un tipo di post personalizzato con i metabox standard e alcuni campi personalizzati. Come posso modificare un post attraverso un modulo nel frontend?

Ecco una soluzione di base per aggiornare un post/pagina. Ho aggiunto una rapida demo di campi meta personalizzati. È piuttosto basilare, ma ti indirizzerà verso la modifica di post sul front-end senza plugin. Non è super flessibile, ma puoi aggiungere tutto ciò di cui hai bisogno.
Aggiungi questo codice nel tuo loop:
<form id="post" class="post-edit front-end-form" method="post" enctype="multipart/form-data">
<input type="hidden" name="post_id" value="<?php the_ID(); ?>" />
<?php wp_nonce_field( 'update_post_'. get_the_ID(), 'update_post_nonce' ); ?>
<p><label for="post_title">Titolo</label>
<input type="text" id="post_title" name="post_title" value="<?php echo $post->post_title; ?>" /></p>
<p><?php wp_editor( $post->post_content, 'postcontent' ); ?></p>
<p><label for="post_title">Test</label>
<?php $value = get_post_meta(get_the_ID(), 'edit_test', true); ?>
<input type="text" id="edit_test" name="edit_test" value="<?php echo $value; ?>" /></p>
<p><label for="post_title">Test 2</label>
<?php $value = get_post_meta(get_the_ID(), 'edit_test2', true); ?>
<input type="text" id="edit_test2" name="edit_test2" value="<?php echo $value; ?>" /></p>
<input type="submit" id="submit" value="Aggiorna" />
</form>
Poi aggiungi questo codice in cima alla pagina per elaborare il form:
if ( 'POST' == $_SERVER['REQUEST_METHOD'] && ! empty($_POST['post_id']) && ! empty($_POST['post_title']) && isset($_POST['update_post_nonce']) && isset($_POST['postcontent']) )
{
$post_id = $_POST['post_id'];
$post_type = get_post_type($post_id);
$capability = ( 'page' == $post_type ) ? 'edit_page' : 'edit_post';
if ( current_user_can($capability, $post_id) && wp_verify_nonce( $_POST['update_post_nonce'], 'update_post_'. $post_id ) )
{
$post = array(
'ID' => esc_sql($post_id),
'post_content' => esc_sql($_POST['postcontent']),
'post_title' => esc_sql($_POST['post_title'])
);
wp_update_post($post);
if ( isset($_POST['edit_test']) ) update_post_meta($post_id, 'edit_test', esc_sql($_POST['edit_test']) );
if ( isset($_POST['edit_test2']) ) update_post_meta($post_id, 'edit_test2', esc_sql($_POST['edit_test2']) );
}
else
{
wp_die("Non puoi farlo");
}
}

Ho aggiunto esc_sql(). Mi è venuto in mente che dovresti sempre eseguire l'escape dei dati inviati da un modulo pubblico (o semi-pubblico) come quello.

Utilizzo Advanced Custom Fields per modificare molti post direttamente dal front-end con meta box. ACF ti permette di creare molti campi avanzati per le meta box e li aggiunge automaticamente al pannello di modifica dei post nel back-end.
Ma esiste anche una funzione per il front-end.
Questo metodo è completamente gratuito. L'unico costo è se vuoi utilizzare uno dei loro add-on più complessi per tipi di campo come repeater, flexible o gallery. Che funzionano tutti perfettamente in questo contesto.
Il primo limite è che non include il titolo e la descrizione del post... ma questo può essere risolto abbastanza facilmente aggiungendo questo al tuo functions.php:
/**
* Deregistra gli stili admin nel front-end quando si usano i form ACF
*
* ACF assicura che gli stili admin siano accodati quando carica la sua testata, questo quasi sempre causa problemi con i form front-end e non è necessario per il nostro scopo
*/
add_action( 'wp_print_styles', 'custom_acf_deregister_styles', 100 );
function custom_acf_deregister_styles()
{
if (! is_admin() )
{
wp_deregister_style( 'wp-admin' );
}
}
/**
* Salva i campi ACF come post_content / post_title per la pubblicazione front-end
*/
add_action( 'acf/save_post', 'custom_acf_save_post' );
function custom_acf_save_post( $post_id )
{
if (! is_admin() && 'acf' != get_post_type( $post_id ) ) // Non eseguire se si stanno aggiungendo/aggiornando campi/gruppi di campi in wp-admin
{
$post_title = get_post_meta( $post_id, 'form_post_title', true );
$post_content = get_post_meta( $post_id, 'form_post_content', true );
$post = get_post($post_id);
if ( ($post_title && $post_title != $post->post_title) || ($post_content && $post_content != $post->post_content) )
{
$post_data = array(
'ID' => $post_id,
);
if ( $post_content ) $post_data['post_content'] = $post_content;
if ( $post_title ) $post_data['post_title'] = $post_title;
remove_action( 'acf/save_post', 'custom_acf_save_post' );
wp_update_post( $post_data );
add_action( 'acf/save_post', 'custom_acf_save_post' );
}
}
}
/**
* Carica il post_title esistente
*/
add_filter( 'acf/load_value/name=form_post_title', 'custom_acf_load_value_form_post_title', 10, 3 );
function custom_acf_load_value_form_post_title( $value, $post_id, $field )
{
$value = get_the_title($post_id);
return $value;
}
/**
* Carica il post_content esistente
*/
add_filter( 'acf/load_value/name=form_post_content', 'custom_acf_load_value_form_post_content', 10, 3 );
function custom_acf_load_value_form_post_content( $value, $post_id, $field )
{
$post = get_post($post_id);
$value = $post->post_content;
return $value;
}
/**
* Installa Add-ons (Questo aggiunge due gruppi di campi che puoi usare per modificare titolo e contenuto)
*
* Il seguente codice includerà tutti i 4 Add-Ons premium nel tuo tema.
* Per favore non tentare di includere un file che non esiste. Questo produrrà un errore.
*
* Tutti i campi devono essere inclusi durante l'azione 'acf/register_fields'.
* Altri tipi di Add-Ons (come la pagina delle opzioni) possono essere inclusi fuori da questa azione.
*
* Il seguente codice assume che tu abbia una cartella 'add-ons' dentro il tuo tema.
*
* IMPORTANTE
* Gli Add-Ons possono essere inclusi in un tema premium come descritto nei termini e condizioni.
* Tuttavia, NON devono essere inclusi in un plugin premium/gratuito.
* Per maggiori informazioni, leggi http://www.advancedcustomfields.com/terms-conditions/
*/
// Campi
add_action('acf/register_fields', 'my_register_fields');
/**
* Registra Gruppi di Campi
*
* La funzione register_field_group accetta 1 array che contiene i dati rilevanti per registrare un gruppo di campi
* Puoi modificare l'array come preferisci. Tuttavia, questo potrebbe risultare in errori se l'array non è compatibile con ACF
*/
if(function_exists("register_field_group"))
{
register_field_group(array (
'id' => 'acf_form-post-title',
'title' => 'Form Titolo Post',
'fields' => array (
array (
'key' => 'field_25',
'label' => 'Titolo',
'name' => 'form_post_title',
'type' => 'text',
'default_value' => '',
'formatting' => 'html',
),
),
'location' => array (
array (
array (
'param' => 'post_type',
'operator' => '==',
'value' => 'course',
'order_no' => 0,
'group_no' => 0,
),
),
),
'options' => array (
'position' => 'normal',
'layout' => 'no_box',
'hide_on_screen' => array (
),
),
'menu_order' => -2,
));
register_field_group(array (
'id' => 'acf_form-post-content',
'title' => 'Form Contenuto Post',
'fields' => array (
array (
'key' => 'field_13',
'label' => 'Contenuto',
'name' => 'form_post_content',
'type' => 'wysiwyg',
'default_value' => '',
'toolbar' => 'full',
'media_upload' => 'yes',
),
),
'location' => array (
array (
array (
'param' => 'post_type',
'operator' => '==',
'value' => 'course',
'order_no' => 0,
'group_no' => 0,
),
),
),
'options' => array (
'position' => 'normal',
'layout' => 'no_box',
'hide_on_screen' => array (
),
),
'menu_order' => -1,
));
}
Questo aggiungerà tutto il codice necessario per supportare un campo titolo e contenuto che può essere aggiunto ai form front-end in questo modo:
// Aggiungi questo sopra get_header()
// Questo carica stili/script, ma processa anche il form, quindi piuttosto importante
acf_form_head();
get_header();
// Dove 51 è l'id del gruppo di campi ACF delle meta box che voglio aggiungere
acf_form( array(
'field_groups' => array('acf_form-post-title', 'acf_form-post-content', 51)
) );
Utilizzo questo metodo nella maggior parte dei siti su cui lavoro ultimamente. Tendo a usare Gravity Forms per creare un post base e poi controllo tutto con ACF sia nel front-end che nel back-end. La cosa migliore è che gestisci tutto da un unico posto per entrambi. Vale la pena notare, comunque, che ACF può essere usato anche per creare un post. Non l'ho ancora usato, ma proverò nel mio prossimo progetto, in modo da poter creare con pieno accesso ai meta.
ACF è, personalmente, l'unico plugin senza cui non potrei vivere, con Gravity Forms come secondo classificato.

Grazie per il SUGGERIMENTO, ma stavo cercando una soluzione senza alcun plugin

Si può fare. È solo un argomento davvero complicato. Ho qualcosa chiamato "Catapost" che ti permette di aggiungere metabox ai post e poi creare form frontend per modificare titolo/contenuto del post con i metabox. È SIMILE a un plugin, ma è incluso nel tema invece, così può essere distribuito con i temi. È questo il tipo di cosa che stavi cercando?

Beh. Una soluzione flessibile è complessa... Se vuoi solo modificare un post base... Potrebbe non essere così difficile.

Ho aggiunto una soluzione molto semplice in un'altra risposta che spiega come farlo senza plugin. Non è molto flessibile, ma funziona bene per un utilizzo occasionale.

Se vuoi modificare un post esistente, prova il mio plugin Front-end Editor.
Se vuoi creare nuovi post, prova uno di questi:

Grazie Scribu. Il tuo plugin è fantastico, ma non soddisfa le mie esigenze. Sto cercando di modificare un post esistente con un form. Avevo fatto una domanda simile sulla modifica del profilo utente con un form nel frontend e ho ricevuto questa risposta: http://wordpress.stackexchange.com/questions/9775/how-to-edit-a-user-profile-on-the-front-end Funzionava perfettamente per me. Se esiste una soluzione simile per modificare i post te ne sarei davvero grato.

@nickfancis.me usa i commenti per questo tipo di cose - è proprio a quello che servono!

Il modo più semplice sarebbe utilizzare qualcosa come Ninja Forms con la seguente estensione a pagamento:
http://wpninjas.com/downloads/front-end-posting/
Potresti anche codificarlo da solo. Essenzialmente creerai un modulo e poi utilizzerai wp_insert_post()
per creare un post completo.
Un esempio di modulo:
<form action="" id="primaryPostForm" method="POST">
<fieldset>
<label for="postTitle"><?php _e('Titolo del Post:', 'framework') ?></label>
<input type="text" name="postTitle" id="postTitle" class="required" />
</fieldset>
<fieldset>
<label for="postContent"><?php _e('Contenuto del Post:', 'framework') ?></label>
<textarea name="postContent" id="postContent" rows="8" cols="30" class="required"></textarea>
</fieldset>
<fieldset>
<input type="hidden" name="submitted" id="submitted" value="true" />
<button type="submit"><?php _e('Aggiungi Post', 'framework') ?></button>
</fieldset>
e poi al momento dell'invio, lo elaboreresti in questo modo:
if ( isset( $_POST['submitted'] ) && isset( $_POST['post_nonce_field'] ) && wp_verify_nonce( $_POST['post_nonce_field'], 'post_nonce' ) ) {
if ( trim( $_POST['postTitle'] ) === '' ) {
$postTitleError = 'Inserisci un titolo.';
$hasError = true;
}
$post_information = array(
'post_title' => wp_strip_all_tags( $_POST['postTitle'] ),
'post_content' => $_POST['postContent'],
'post_type' => 'post',
'post_status' => 'pending'
);
wp_insert_post( $post_information );
}
Il codice completo e il tutorial provengono da: http://wp.tutsplus.com/tutorials/creative-coding/posting-via-the-front-end-inserting/
