I have little problem how implement deleting data from database using row actions. I have my custom list which includes data from database table. List

 function column_name( $item ) {
    $delete_nonce = wp_create_nonce();
    $title = '<strong>' . $item['article_name'] . '</strong>';
    $actions = [
        'edit' => sprintf('<a href="?page=%s&id=%s">Edit</a>', 'edytuj-artykul', $item['article_id']),
        'delete' => sprintf('<a href="?page=%s&action=%s&article_id=%s&_wpnonce=%s">Delete</a>', esc_attr( $_REQUEST['page'] ), 'delete', absint($item['article_id']), $delete_nonce)
    return $title. $this->row_actions( $actions );

function delete_article($item){
    $article_id = $item['article_id'];
    global $wpdb;
     $table = 'wp_copywriter_articles';
     $wpdb->query("DELETE FROM $table WHERE article_id = %d", $article_id);

In the same file I added

add_action( 'admin_action_delete', 'delete_article' );

When I click Delete action, nothing happend. I got link http://localhost/wordpress/wp-admin/admin.php?page=Artykuly&action=delete&article_id=26&_wpnonce=60a01b82d7

but record is not deleted from database.

For testing, I added a specific ID number of article to the delete_article method in the SQL query but still not works, so this method is not used by WP, when I click delete button.

Someone can give me any tip what am I doing wrong, because I spent on this few few hours :)

Best Regards, Bartek



My mistake was put delete_article() method to my custom list class. When I put my method to functions.php, everything works! :)

2 Answers 2


The "admin_action_{$_REQUEST['action']}" hook does not pass any arguments. You would need to get the article_id from the $_REQUEST array. There are also a few other concerns such as:

  1. You're not assigning an action when you call wp_create_nonce().
  2. As Mafnah suggets in their ansewr, you should use $wpdb::delete() as a shortcut for using $wpdb::prepare().

Here's how you could rewrite this:

function column_name( $item ) {
    $delete_nonce = wp_create_nonce( 'delete_article' );
    $actions = [
        'delete' => add_query_arg( array(
            'action'        => 'delete',
            'article_id'    => $item['article_id'],
            '_wpnonce'      => $delete_nonce,
        ), admin_url( 'admin.php' ) ),
    /* Etc... */

function delete_article() {

    global $wpdb;

    // Ensure we can verify our nonce.
    if( ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'delete_article' ) ) {
        wp_die( esc_html__( 'Could not verify request. Please try again.' ) );

    // Ensure we have an article ID provided.
    } else if( ! isset( $_REQUEST['article_id'] ) ) {
        wp_die( esc_html__( 'Could not find provided article ID. Please try again.' ) );

    // Ensure we're able to delete the actual article.
    } else if( false === $wpdb->delete( 'wp_copywriter_articles', array( 'article_id' => $_REQUEST['article_id'] ) ) ) {
        wp_die( esc_html__( 'Could not delete the provided article. Please try again.' ) );

    // Redirect back to original page with 'success' $_GET
    wp_safe_redirect( add_query_arg( array(
        'page' => ( isset( $_REQUEST['page'] ) ) ? $_REQUEST['page'] : '404',
        'success' => 1,
    ), admin_url( 'admin.php' ) ) );

  • Hello @Howdy_McGee ! Thank you for your time. I included your corrections in my code but still delete articles do not work. I think wordpress do not use delete_article() method, because when I delete ! in first if so if( wp_verify_nonce( $_REQUEST['_wpnonce'], 'delete_article' ) ) { wp_die( esc_html__( 'Could not verify request. Please try again.' ) ); nothing change. I do not have any error. If you could spare a moment of your time on this topic, please take a look at my code. Perhaps you will notice what I did wrong. pastebin
    – BElluu
    Commented Sep 5, 2021 at 9:27
  • The admin_action_delete hook will only trigger if you're linking to admin.php?action=delete. I think the issue is the link itself.
    – Howdy_McGee
    Commented Sep 5, 2021 at 17:13
  • Hi @Howdy_McGee, thank you for your reply. I'm not sure I understand you but I tried change this link so I changed row action to ''delete' => sprintf('<a href="admin.php&action=%s&article_id=%s&_wpnonce=%s">Delete</a>' ,'delete', absint($item['article_id']), $delete_nonce) and my link look like localhost/wordpress/wp-admin/… When I press delete button I got error 404 and article is not deleted from database :( Sorry for the large amount of questions. The first steps in wordpress overwhelm me a bit.
    – BElluu
    Commented Sep 5, 2021 at 17:45
  • It needs to be a query string. admin.php is the end of the URL so & here is in valid syntax. It should read admin.php?action=delete where ? denotes the start of a query string.
    – Howdy_McGee
    Commented Sep 5, 2021 at 18:40
  • Thanks, I fixed syntax @Howdy_McGee . I think we are closer to do that, because when I press button delete now, I do not have any 404, but I have empty blank page. Article is not deleted in database yet ;/ I thinking about create custom hook for that operation but I do not know how to hook this to row action delete
    – BElluu
    Commented Sep 5, 2021 at 19:01

I think it's better to use the $wpdb->delete() function to remove a row.

$article_id = $item['article_id'];
$table = 'wp_copywriter_articles';
$wpdb->delete( $table, array( 'id' => $article_id ) );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.