Best Practices For Prompting CodeWP

By James LePage, CodeWP Founder
November 25, 2022

CodeWP is an AI Code Generator for WordPress. In this article, we'll be taking a look at how to prompt CodeWP for the best generations possible.

Prompting any generative AI is more of an art than a science, and this fact rings true with CodeWP. It's important to be descriptive, clear, but also simple with your prompts, while tailoring them to your desired outputs.

The concepts covered in this article can be applied to any of the modes that CodeWP has, but are primarily tailored towards the general WordPress PHP mode (set by default when you load the generator). However, a caveat that should be noted: our modes are ever improving, evolving, and changing. Over time, more basic prompts may yield the same results as more explicit and descriptive prompts, simply due to the nature of Machine Learning and Artificial Intelligence. To help expedite this, be sure to rate all of your generations!

Also, you can completely ignore everything in this article and try out your own methods. The underlying AI for CodeWP is massive and different approaches may yield great results for individual situations.

Before Prompting

Before you enter your prompt, think about what you're actually trying to do.

It's important not to stuff to much into a single prompt. Instead of asking for a snippet that makes a new post type of user_profile with 12 custom fields being filled out, and elevating the user to the editor role, and sending an email and etc..., break each objective into a single request. Then you can tie it all together by prompting:

Run the functions "cwpai_new_post, cwp_ai_upgrade_user, cwpai_update_profile, etc..." when any user registers.

Remember, this tool is designed to make you Code Snippets, not plugins and software 😃.

Prompts With Desired Outputs


Generating complex queries for WordPress is easy with CodeWP AI.

Prompt:// Get all posts published by users with the role of editor, with the post type of post page or snippet, with the tags of "tag_one" OR "tag_two", with the category of "category_good", that have been published in the past 3 months, but modified in the past 20 days, and then order by the modified date.

$args = array( 'author' => array( 'role' => 'editor' ), 'post_type' => array( 'post', 'page', 'snippet' ), 'tag' => array( 'tag_one', 'tag_two' ), 'category_name' => 'category_good', 'date_query' => array( array( 'after' => '3 months ago', 'before' => '20 days ago', 'inclusive' => true, ), ), 'orderby' => 'modified', 'order' => 'DESC', ); $query = new WP_Query( $args ); Generation ID:cmpl-6GcJLl1KFBV1lnzIHUwUf1BT5XEog

You can see that the CodeWP AI can chew through this prompt pretty easily. For those that need to create complex queries all the time, this can be a massive time saver. Let's break down this prompt:

  • Get all posts
  • published by users with the role of editor
  • with the post type of post page or snippet
  • [...]
  • and then order by the modified date

Each query parameter is separated by commas. At the end of the prompt, we have a period. Tags and categories are wrapped in quotations. For queries, doing it all in one sentence typically works best. The final "command" (for this it's "order by the modified date"), should start with "then".

Now, for queries, we can actually go for multiple steps in one prompt (contrary to what was mentioned in the section above) if we want to take the data and output it some way.

Prompt:// Get all posts published by users with the role of editor, with the post type of post page or snippet, with the tags of "tag_one" OR "tag_two", with the category of "category_good", that have been published in the past 3 months, but modified in the past 20 days, and then order by the modified date, then return the first 5 words of all queried post titles in a comma separated list.

$args = array( 'role' => 'editor', 'post_type' => array('post', 'page', 'snippet'), 'tag' => array('tag_one', 'tag_two'), 'category_name' => 'category_good', 'date_query' => array( array( 'after' => '3 months ago', 'column' => 'post_modified', 'before' => '20 days ago' ) ), 'orderby' => 'post_modified', 'order' => 'DESC' ); $query = new WP_User_Query( $args ); $users = $query->get_results(); if ( ! empty( $users ) ) { foreach ( $users as $user ) { $user_info = get_userdata($user->ID); $user_posts = get_posts(array('author' => $user->ID)); foreach ($user_posts as $user_post) { $post_title = $user_post->post_title; $post_title_words = explode(' ', $post_title); $post_title_first_five_words = implode(', ', array_slice($post_title_words, 0, 5)); echo $post_title_first_five_words; } } } Generation ID:cmpl-6GcKgn6S8sXEijFNVnH5BDiWh36le

We can even make this a shortcode:

Prompt:// A shortcode called "post_output" that gets all posts published by users with the role of editor, with the post type of post page or snippet, with the tags of "tag_one" OR "tag_two", with the category of "category_good", that have been published in the past 3 months, but modified in the past 20 days, ordered by the modified date, and shows them as a HTML list.

add_shortcode("post_output", "post_output"); function post_output() { $args = [ "role" => "editor", "post_type" => ["post", "page", "snippet"], "tag" => ["tag_one", "tag_two"], "category_name" => "category_good", "date_query" => [ [ "after" => "3 months ago", "before" => "20 days ago", "inclusive" => true, ], ], "orderby" => "modified", "order" => "DESC", ]; $query = new WP_Query($args); if ($query->have_posts()) { $output = ""; while ($query->have_posts()) { $query->the_post(); $output .= "" . get_the_title() . ""; } $output .= ""; } wp_reset_postdata(); return $output; }Generation ID:cmpl-6GcjfuJx879pfisOWcK9Blzwrea2i

Notice that this prompt is one continuous flow of logic - that's important! Also, we've changed around some of the language; a shortcode THAT [query command] and THEN [does something with the data].


As you can see above, you can also prompt for shortcodes. The best way to do this is to follow this template: A shortcode (called [name]) THAT does something and THEN outputs something. Here's an example:

Prompt:// A shortcode called "total donations" that gets the total dollar amount of sales for WooCommerce products with the category of donation and displays it.

function total_donations_shortcode() { $args = array( 'post_type' => 'product', 'product_cat' => 'donation', 'posts_per_page' => -1 ); $loop = new WP_Query( $args ); $total = 0; if ( $loop->have_posts() ) { while ( $loop->have_posts() ) : $loop->the_post(); global $product; $total += $product->get_price(); endwhile; } wp_reset_postdata(); return $total; } add_shortcode( 'total_donations', 'total_donations_shortcode' ); Generation ID:cmpl-6GcodWqxp8CzlgWUL8zCpU5vIEOQC

We can also prompt for arguments/parameters, like so:

Prompt:// A shortcode that accepts a comma separated list of post ids, and shows the first 10 words of each post's excerpts, hyperlinked to the post, in a html list using.

function show_excerpts_shortcode( $atts ) { $a = shortcode_atts( array( 'ids' => '', ), $atts ); $ids = explode(',', $a['ids']); $output = '<ul>'; foreach ($ids as $id) { $excerpt = get_the_excerpt($id); $excerpt = strip_tags($excerpt); $excerpt = substr($excerpt, 0, 10); $output .= '<li><a href="' . get_permalink($id) . '">' . $excerpt . '...</a></li>'; } $output .= '</ul>'; return $output; } add_shortcode( 'show_excerpts', 'show_excerpts_shortcode' );Generation ID:cmpl-6GcsolgIsA9FMcFvXNirXfNwOPGi5

General WordPress Things

We can also generate basic things like post types:

Prompt:// register a custom post type for "locations", and add custom fields for "address", "website" and "hours" to that post type.

//Register the custom post type "locations" function locations_init() { $labels = array( 'name' => _x( 'Locations', 'post type general name', 'your-plugin-textdomain' ), 'singular_name' => _x( 'Location', 'post type singular name', 'your-plugin-textdomain' ), 'menu_name' => _x( 'Locations', 'admin menu', 'your-plugin-textdomain' ), 'name_admin_bar' => _x( 'Location', 'add new on admin bar', 'your-plugin-textdomain' ), 'add_new' => _x( 'Add New', 'location', 'your-plugin-textdomain' ), 'add_new_item' => __( 'Add New Location', 'your-plugin-textdomain' ), 'new_item' => __( 'New Location', 'your-plugin-textdomain' ), 'edit_item' => __( 'Edit Location', 'your-plugin-textdomain' ), 'view_item' => __( 'View Location', 'your-plugin-textdomain' ), 'all_items' => __( 'All Locations', 'your-plugin-textdomain' ), 'search_items' => __( 'Search Locations', 'your-plugin-textdomain' ), 'parent_item_colon' => __( 'Parent Locations:', 'your-plugin-textdomain' ), 'not_found' => __( 'No locations found.', 'your-plugin-textdomain' ), 'not_found_in_trash' => __( 'No locations found in Trash.', 'your-plugin-textdomain' ) ); $args = array( 'labels' => $labels, 'public' => true, 'publicly_queryable' => true, 'show_ui' => true, 'show_in_menu' => true, 'query_var' => true, 'rewrite' => array( 'slug' => 'location' ), 'capability_type' => 'post', 'has_archive' => true, 'hierarchical' => false, 'menu_position' => null, 'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' ) ); register_post_type( 'location', $args ); } add_action( 'init', 'locations_init' ); //Add custom fields to the custom post type "locations" function locations_meta_box() { add_meta_box( 'locations_meta_box', 'Location Details', 'locations_meta_box_callback', 'location', 'normal', 'high' ); } add_action( 'add_meta_boxes', 'locations_meta_box' ); function locations_meta_box_callback( $post ) { $values = get_post_custom( $post->ID ); $address = isset( $values['address'] ) ? esc_attr( $values['address'][0] ) : ''; $website = isset( $values['website'] ) ? esc_attr( $values['website'][0] ) : ''; $hours = isset( $values['hours'] ) ? esc_attr( $values['hours'][0] ) : ''; wp_nonce_field( 'locations_meta_box_nonce', 'meta_box_nonce' ); ?> <p> <label for="address">Address</label> <input type="text" name="address" id="address" value="<?php echo $address; ?>" /> </p> <p> <label for="website">Website</label> <input type="text" name="website" id="website" value="<?php echo $website; ?>" /> </p> <p> <label for="hours">Hours</label> <input type="text" name="hours" id="hours" value="<?php echo $hours; ?>" /> </p> <?php } function locations_meta_box_save( $post_id ) { // Bail if we're doing an auto save if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return; // if our nonce isn't there, or we can't verify it, bail if( !isset( $_POST['meta_box_nonce'] ) || !wp_verify_nonce( $_POST['meta_box_nonce'], 'locations_meta_box_nonce' ) ) return; // if our current user can't edit this post, bail if( !current_user_can( 'edit_post' ) ) return; // now we can actually save the data $allowed = array( 'a' => array( // on allow a tags 'href' => array() // and those anchors can only have href attribute ) ); // Probably a good idea to make sure your data is set if( isset( $_POST['address'] ) ) update_post_meta( $post_id, 'address', wp_kses( $_POST['address'], $allowed ) ); if( isset( $_POST['website'] ) ) update_post_meta( $post_id, 'website', wp_kses( $_POST['website'], $allowed ) ); if( isset( $_POST['hours'] ) ) update_post_meta( $post_id, 'hours', wp_kses( $_POST['hours'], $allowed ) ); } add_action( 'save_post', 'locations_meta_box_save' ); Generation ID:cmpl-6Gcz0ZuLRZnZ6HgiiDScZuGiV4jDd

You can see that we can merge multiple common things into one prompt, and CodeWP will handle it well.


Prompt:// Register a taxonomy called "Area" and add it to the post type "location"

add_action( 'init', 'create_area_taxonomy', 0 ); function create_area_taxonomy() { $labels = array( 'name' => _x( 'Areas', 'taxonomy general name' ), 'singular_name' => _x( 'Area', 'taxonomy singular name' ), 'search_items' => __( 'Search Areas' ), 'all_items' => __( 'All Areas' ), 'parent_item' => __( 'Parent Area' ), 'parent_item_colon' => __( 'Parent Area:' ), 'edit_item' => __( 'Edit Area' ), 'update_item' => __( 'Update Area' ), 'add_new_item' => __( 'Add New Area' ), 'new_item_name' => __( 'New Area Name' ), 'menu_name' => __( 'Area' ), ); $args = array( 'hierarchical' => true, 'labels' => $labels, 'show_ui' => true, 'show_admin_column' => true, 'query_var' => true, 'rewrite' => array( 'slug' => 'area' ), ); register_taxonomy( 'area', array( 'location' ), $args ); } Generation ID:cmpl-6Gd3P9uszK3tCSMNlrFDe7iqgrTCa

Simple and easy. Also, no need to manually create all of the labels!

Custom fields:

Prompt:// Add 2 meta fields called "Editor" and "Favorites" to posts

add_action( 'add_meta_boxes', 'add_custom_meta_box' ); function add_custom_meta_box() { add_meta_box( 'custom_meta_box', 'Editor', 'custom_meta_box_callback', 'post', 'normal', 'high' ); add_meta_box( 'custom_meta_box', 'Favorites', 'custom_meta_box_callback', 'post', 'normal', 'high' ); } function custom_meta_box_callback( $post ) { $value = get_post_meta( $post->ID, '_custom_meta_box_key', true ); echo '<label for="custom_meta_box_field">Description for this field</label>'; echo '<input type="text" id="custom_meta_box_field" name="custom_meta_box_field" value="' . esc_attr( $value ) . '" size="25" />'; } add_action( 'save_post', 'custom_meta_box_save' ); function custom_meta_box_save( $post_id ) { if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return; if ( ! isset( $_POST['custom_meta_box_nonce'] ) || ! wp_verify_nonce( $_POST['custom_meta_box_nonce'], '_custom_meta_box_nonce' ) ) return; if ( ! current_user_can( 'edit_post', $post_id ) ) return; if ( isset( $_POST['custom_meta_box_field'] ) ) update_post_meta( $post_id, '_custom_meta_box_key', esc_attr( $_POST['custom_meta_box_field'] ) ); } Generation ID:cmpl-6Gd2PcXnSBtYofyXrm9uPDCiLDmeN

Typically this will include code to add meta boxes as well.

Custom user roles:

Prompt:// Add a new user role called "members"

add_role('members', 'Members', array( 'read' => true, // True allows that capability 'edit_posts' => true, 'delete_posts' => false, // Use false to explicitly deny )); Generation ID:cmpl-6GczzWiqqQ2gdEQa9Wot9xAt24c6K

Adding/Doing Things

The general WordPress model won't be accurate for most plugins, so it can't really be prompted to do something like "when a user registers, add them to Mailerlite and send a Slack message to the channel XXXXX". However, it will do things like:

Prompt:// change the user role to Editor if they have published over 5 articles

add_action('init', 'my_role_change'); function my_role_change() { global $wpdb; $user_id = get_current_user_id(); $count = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts WHERE post_author = $user_id AND post_status = 'publish' AND post_type = 'post'"); if ($count > 5) { $user = new WP_User($user_id); $user->set_role('editor'); } } Generation ID:cmpl-6Gd8cL3Y2PhUfhzcd4e6qvXPlqRyy

When it comes to WordPress-core specific things, the sky is your limit.

Prompt:// Require users to enter a referral code called "codewp_invite" when registering and if code isn't entered, or is not "codewp_invite", show a message "beep beep boop boop: not allowed".

add_action('register_form','show_first_name_field'); function show_first_name_field() { ?> <p> <label>Referral Code<br/> <input id="codewp_invite" type="text" tabindex="20" size="25" value="<?php echo esc_attr(stripslashes($_POST['codewp_invite'])); ?>" name="codewp_invite" /> </label> </p> <?php } add_filter('registration_errors', 'registration_errors_validation', 10,3); function registration_errors_validation($reg_errors, $sanitized_user_login, $user_email) { global $whitelist_options; if ( !isset( $_POST['codewp_invite'] ) || !in_array( $_POST['codewp_invite'], $whitelist_options ) ) { return new WP_Error( 'codewp_invite', '<strong>ERROR</strong>: beep beep boop boop: not allowed.' ); } return $reg_errors; } add_action( 'user_register', 'user_register_save_codewp_invite' ); function user_register_save_codewp_invite( $user_id ) { if ( isset( $_POST['codewp_invite'] ) ) { update_user_meta( $user_id, 'codewp_invite', $_POST['codewp_invite'] ); } } Generation ID:cmpl-6GdBhYeq77O3uqrizcwzGusT8djia

When You're Not Sure

Iterate on your prompts. If:

Prompt:// Require users to enter a referral code

Doesn't work, try:

Prompt:// Require users to enter a referral code called "codewp_invite"

And if that doesn't work, add on:

Prompt:// Require users to enter a referral code called "codewp_invite" when registering and if code isn't entered, or is not "codewp_invite", show a message...

You get the idea.

Just remember, when iterating, be sure to downvote the ones that you don't like, and upvote the ones that you do.

You can also use the Inverted Pyramid approach, which is used by salespeople to help iterate the prompt.


We hope that this article helps you create better prompts, and in turn, better generations when using CodeWP. It should also give you a good overview of the capabilities that the general WordPress PHP mode has, as well as some ideas of what you can use CodeWP AI to generate for your WordPress Projects.

Snippets In This Tutorial Were Generated With CodeWP
PHP, JS or jQuery
AI models trained for WordPress & popular plugins
Unlimited generations
100% free trial
Start For Free