I am making a plugin that shows a random joke on a custom 404 page via shortcode and it is basically near enough the same as the default hello dolly plugin, where the jokes are hardcoded into the script.

I want to be able to allow users to add their own jokes, maybe pulled from the database via custom post types, or just store it to a file which is pulled into the script (exploded or file_get_contents, i dont know)

I am new to wordpress plugin development, but i know a fair amount of php.

Heres the code i currently have to create an admin page

add_action('admin_menu', 'jokes_admin_add_page');
function jokes_admin_add_page() {
add_options_page('Jokes Page', 'Jokes Menu', 'manage_options', 'plugin', 'jokes_plugin_options_page');

 // display the admin options page
function jokes_plugin_options_page() {
<h2>My custom plugin</h2>
Options relating to the Custom Plugin.
<form action="options.php" method="post">
<?php settings_fields('plugin_options'); ?>
<?php do_settings_sections('plugin'); ?>

<input name="Submit" type="submit" value="<?php esc_attr_e('Save Changes'); ?>" />


Don't use settings api for this.

Register a custom post type, 'Joke' see register_post_type docs

add_action( 'init', function () {
  $labels = array(
    'name'  => 'Jokes',
    'singular_name' => 'Joke',
    'add_new' => 'Add New',
    'add_new_item' => 'Add New Joke',
    'new_item' => 'New Joke',
    'edit_item' => 'Edit Joke',
    'view_item' => 'View Joke',
    'all_items' => 'All Jokea',
    'search_items' => 'Search Jokes',
    'not_found' => 'No jokes found.',
    'not_found_in_trash' => 'No jokes found in Trash.',
  $args = array(
    'labels' => $labels,
    'public' => true,
    'publicly_queryable' => false,
    'show_ui' => true,
    'show_in_menu' => true,
    'show_in_nav_menus' => false,
    'query_var' => false,
    'rewrite' => false,
    'capability_type' => 'post',
    'has_archive' => false,
    'hierarchical' => false,
    'supports' => array( 'title', 'editor')
  register_post_type( 'joke', $args );

For each argument, please refer to documentation.

WordPress will add the administration menu for you.

Now your site users can create their own jokes.

At this point you can write a function that take a random joke an return the markup, I'll use get_posts for the scope:

function get_random_joke() {
  $args = array(
    'post_type' => 'joke', // be sure this is exactly 1st arg of register_post_type
    'posts_per_page' => 1, // one joke is enough
    'orderby' => 'rand' // randomly
  $jokes = get_posts( $args );
  if ( empty( $jokes ) ) return; // no jokes, nothing to do
  $joke = array_pop( $jokes ); // get posts always returns an array
  $out = '<div id="joke">';
  $out .= sprintf( '<h3>%s</h3>', apply_filters('the_title', $joke->post_title) );
  $out .= sprintf( '<p>%s</p>', apply_filters('the_content', $joke->post_content) );
  $out .= '<div>';
  return $out;

And can call this function from a shortcode:

add_shortcode( 'joke' , 'get_random_joke' );

Now you can isert in your posts/pages [joke] and a random joke will be shown (if there are some...)

However, if you are developing a plugin, is possible that in the theme the 404.php file does not contain any post or page, so where will you put that shortcode?

Probably you can write your own 404 template and use that instead of the theme one, just matter of a filter on 'template_include':

add_filter( 'template_include', function( $template ) {
  if ( is_404() ) $template = plugin_dir_path( __FILE__  ) . '404.php';
  return $template;
} );

Using this code, when there is a request that turns into a 404, WordPress will require the '404.php' inside your plugin folder, instead of the one in theme.

In this template you can make use of the get_random_joke() function to output the joke, just an example (highly derived form 2013 theme):

<?php get_header(); ?>
<div id="primary" class="content-area">
  <div id="content" class="site-content" role="main">
    <header class="page-header">
      <h1 class="page-title">Not found</h1>
    <div class="page-wrapper">
      <div class="page-content">
        <h2>This is somewhat embarrassing, isn&rsquo;t it?</h2>
        <p>It looks like nothing was found at this location. Maybe try a search?</p>
        <?php get_search_form(); ?>

        <?php echo get_random_joke(); ?>

<?php get_footer(); ?>
  • Right, that all works well, apart from the 'randomness' of the jokes, sometimes it takes the joke to change every few refreshes, but that isnt a big deal. – John Zon Apr 3 '14 at 12:24
  • 1
    'randomness' is handled by mysql RAND funcrtion, WordPress is not the culprit there. @JohnZon – gmazzap Apr 3 '14 at 12:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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