I have created a plug-in with an Admin Menu that displays a list of artists saved into the database in a custom table. This page is a "master" page and I am trying to figure out how to link the artist name to a "details" page all in the backend. From the codex and other books I have determined that the second level pages should be like the top level pages in that it will be a function that displays the content. I cannot figure out how do I "link" to that callback function.

I add the first level page with this:

add_submenu_page('ppmtalentexpo', 'TARSTE II', 'TARSTE II', 'administrator', 'tarste2submenu2', 'jwg_talentexpo_options2_page');

and diplay the first level with this:

function jwg_talentexpo_options2_page() {
    global $wpdb;

    $cnt = 0;
    $rows = $wpdb->get_results("SELECT * from ppm_tarste2_bands ORDER BY band_name");
    //echo '<pre>'; echo var_dump( $rows ); echo '</pre>';
    $retHTML = "<div class='wrap trkr'><h2><div id='icon-upload' class='icon32'></div> PPM Talent Expo Administrator -- TARSTE II</h2><br><br>";
    $retHTML .= "<table cellpadding='5' cellspacing='0' border='1' style='width:96%;margin:auto;'>";
    $retHTML .= "<tr><td colspan='4'>" . count($rows) . " registered.</td></tr>";
    for( $c = 0; $c<count($rows);$c++ ) :
        $retHTML .= "<tr>";
        $retHTML .= "<td><span style='font:bold 16px sans-serif;color:#F87114;'><a href='#'>" . $rows[$c]->band_name . "</a></span>";
        $retHTML .= "<br><b>Contact: " . $rows[$c]->band_contact_person . "</b></td>";
        $retHTML .= "<td><a href='mailto:" . $rows[$c]->band_email . "'>EMAIL</a>";
        if( $rows[$c]->band_url != '' && $rows[$c]->band_url != 'n/a' ){
            $retHTML .= " | <a target='_blank' href='" . $rows[$c]->band_url . "'>WEB</a></td>";
        } else {
            $retHTML .= "</td>";
        } // end if
        $retHTML .= "<td>" . formatPhone($rows[$c]->band_contact_phone) . "</td>";
        $retHTML .= "<td>";
        switch( (int) $rows[$c]->status ){
            case 1:
                $retHTML .= "Registered";
            case 2:
                $retHTML .= "Selected";
            case 3:
                $retHTML .= "Face-Off";
            case 4:
                $retHTML .= "Winner";
        } // end switch
        $retHTML .= "</td>";
        $retHTML .= "</tr>";
    $retHTML .= "</table>";
    $resHTML .= "</div>";
    echo $retHTML;
} // end function

So, within the for loop I am trying to link to the details page of each registered artist in the second $retHTML line with an anchor tag. My plan is to create a function to display the details of that artist. Again, what do I put in the anchor tag OR is there a better way to do what I am trying?

Thanks in advance for any guidance or help provided, Jon

1 Answer 1


The add_submenu_page function allows you to link to a callback function and its this callback function which handles the display of that pages content.

     $parent_slug, //The slug name for the parent menu i.e. ppmtalentexpo
     $callback_function //your callback i.e. jwg_talentexpo_options2_page

So far what you have appears right, assuming all your arguments are correct.

Instead of creating a custom table, you could probably get away with using a Custom Post Type to handle your "bands".

Then all details like,


...could be post_meta associated with your custom post type "bands".

This would make querying data so much easier for you with the built in WordPress API functions such as WP_Query and get_post_meta.

Because as it stands right now, you may very well be able to list all of the band names with,

$retHTML .= "<td><span style='font:bold 16px sans-serif;color:#F87114;'><a href='#'>" . $rows[$c]->band_name . "</a></span>";

But then question I must ask you is that, where does that $rows[$c]->band_name point to? No where. That's where.

Unless you are comfortable with building custom tables as well as the data to go along with it, then you're making life hard for yourself straight out the gate.

Instead you should take advantage of the inbuilt custom post types as well as the automatic URL/permalink handling that goes along with it.

  1. Does this make sense so far?
  2. Are you aware of custom post types?
  3. What is your purpose for this custom table instead of using custom post types?

Happy to help, but lets clarify these points first... Just so we're all on the same page.


Based on your additional comments, I can see where you were coming from now. While Laravel and CI are fine in external applications, introducing them into the WordPress environment (albeit entirely possible) is not recommended, unless you have a special use case where nothing else but that will do.

WordPress bakes in a lot of the functionality you are looking for, in fact, all of it, in an easy to use API that abstracts away much of the heavy lifting and prevents that need to re-invent the wheel.

So to kick you off, become acquainted with...

  • This is my first dance with WordPress -- I am a PHP developer using Laravel or CodeIgniter -- so I am just learning about doing it the WordPress way. I am helping out a friend and built his site in WordPress because he wanted a CMS and the ability to edit his own content.
    – jgravois
    Oct 23, 2012 at 12:42
  • I have been researching of late custom post types and taxonomies and do feel that this is the direction I should have gone in the first place. What I need to do now is figure out how to make that link that you noted goes nowhere load the form that was filled out by the user. With that in place, I will go back and put the entire Expos feature into a custom post type with a taxonomy for Artists and one for Street Teams.
    – jgravois
    Oct 23, 2012 at 12:42
  • To answer your 3rd question -- I built the site in CodeIgniter and then "ported" it to WordPress at my friend's request. In the original site, I had a registration form for artists wishing to participate in a certain Talent Expo. I imported the data table into WordPress and now need a way to let them see the info.
    – jgravois
    Oct 23, 2012 at 12:45

Your Answer

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

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