How to Build Your Own Custom WordPress Premium Theme Admin – Part 2

Part two of of this tutorial is here at last! If you have missed part 1 I would recommend you check it out before you read this tutorial.

Let’s Recap a bit on what we did in part 1

  1.  We created a custom admin menu with sub menu’s.
  2.  We created a menu with tabbed menu’s using jQuery UI.

Today we will create all form fields needed within our tabbed menu and we will save data in to option fields using ajax. Then in the end we will be calling the option fields within our theme to show data on the pages where needed.

Code were we create our form for general settings

// General Settings
function generalSettings() {

	$content =  '
<div class="wrap">
<h3>General Option Settings</h3>
<form action="" method="post" enctype="multipart/form-data">
' . settings_fields( 'ty-option-group' ) . '
<table class="form-table">
<tr valign="top">
<td width="150px"><strong>Logo URL: </strong></td>
<td><img style="width: 100px;" src="' . get_option('ty-logo-url'). '" alt="" /><input id="tylogofile" type="text" name="logofile" value="' . get_option('ty-logo-url'). '" size="36" /><input id="upload_image_logobutton" type="button" value="Upload Image" />
Enter an URL or upload an image for the logo.</td>
<tr valign="top">
<td><strong>Favicon URL: </strong></td>
<td><img style="width: 100px;" src="' . get_option('ty-favicon-url') . '" alt="" /><input id="tyfavicon" type="text" name="favicon" value="' . get_option('ty-favicon-url') . '" size="36" /><input id="upload_image_button_tyfavicon" type="button" value="Upload Image" />
Enter an URL or upload an image for the Favicon.</td>
<tr valign="top">
<td><strong>Google Analytics Code: </strong></td>
<td><input id="tyanalytics" type="text" name="ty-analytics" value="' . get_option('ty-analytics') . '" /></td>
<tr valign="top">
<td><strong>Custom CSS: </strong></td>
<td><textarea id="tycustomcss" name="ty-custom-css">' . get_option('ty-custom-css') . '</textarea></td>
<tr valign="top">
<td><strong>Footer Text: </strong></td>
<td><textarea id="tyfootertext" name="ty-footer-text">' . get_option('ty-footer-text') . '</textarea></td>
<tr valign="top">
<td><input id="button-general" class="button-primary" style="margin-top: 10px;" type="button" value="Save General" /></td>

 return $content;

Above we created the general settings form, it’s very simple as you can see.

Code to save the data for the general settings form

 * Save General Settings page on post.
 add_action('wp_ajax_my_action', 'add_general_settings'); //ajax callback
function add_general_settings(){

		if(get_option('ty-logo-url') == ""){
            update_option( 'ty-logo-url', 'http://' );


        if(get_option('ty-favicon-url') == ""){
            update_option( 'ty-favicon-url', 'http://' );


        if(get_option('ty-analytics') == ""){
            update_option( 'ty-analytics', 'Goolge Analytics Here...' );


        if(get_option('ty-custom-css') == ""){
            update_option( 'ty-custom-css', 'Custom CSS Here...' );


        if(get_option('ty-footer-text') == ""){
            update_option( 'ty-footer-text', 'Add your footer text here...' );


    if(! empty( $_POST )){

        $logourl = $_POST['ty_logofile'];
        $faviconurl = $_POST['ty_favicon'];
        $analytics = $_POST['ty_analytics'];
        $customcss = $_POST['ty_custom_css'];
        $footertxt = $_POST['ty_footer_text'];

        update_option( 'ty-logo-url', $logourl );
        update_option( 'ty-favicon-url', $faviconurl );
        update_option( 'ty-analytics', $analytics  );
        update_option( 'ty-custom-css', $customcss );
        update_option( 'ty-footer-text', $footertxt );

In the code we checked if the option values contain data already, if not then set the default values. Then we check if the form was posted, if it’s posted we save the data to their individual option fields. The upload buttons won’t work at this moment. As we need to add additional jquery code to handle uploads, I will show this further down.

Social settings Form and Code to save data

// Social Settings Page
function socialSettings(){

$social = '
<div id="social-settings">' . settings_fields( 'ty-option-group' ) . '
<h2>Social Settings</h2>
<div id="social-wrapper"><form action="" method="post" name="socialform"><label for="facebook">Facebook: </label><input id="facebook" type="text" name="facebook" value="' .  get_option('ty-facebook') . '" /><a href="' . get_option('ty-facebook') .'"><img src="' .get_bloginfo('template_url') .'/images/social/facebook.png" alt="facebook" /></a>

 <label for="twitter">Twitter: </label><input id="twitter" type="text" name="twitter" value="'. get_option('ty-twitter') .'" /><a href="' . get_option('ty-twitter') .'"><img src="'. get_bloginfo('template_url') .'/images/social/twitter.png" alt="twitter" /></a>

 <label for="linkedin">LinkedIn: </label><input id="linkedin" type="text" name="linkedin" value="' . get_option('ty-linkedin') .'" /><a href="' . get_option('ty-linkedin') .'"><img src="'. get_bloginfo('template_url') .'/images/social/linkedin.png" alt="linkedin" /></a>

 <label for="flickr">Flickr: </label><input id="flickr" type="text" name="flickr" value="'. get_option('ty-flickr') .'" /><a href="'. get_option('ty-flickr') .'"><img src="'. get_bloginfo('template_url') .'/images/social/flickr.png" alt="flickr" /></a>

 <label for="skype">Skype: </label><input id="skype" type="text" name="skype" value="'. get_option('ty-skype') .'" /><a href="'. get_option('ty-skype') .'"><img src="'. get_bloginfo('template_url') .'/images/social/skype.png" alt="skype" /></a>

 <input id="social-button" class="button-primary" style="margin-top: 10px;" type="button" value="Save Social" />

return $social;

// Save Social Settings Data
 add_action('wp_ajax_slider_my_action', 'saveSocialSettings'); //ajax callback
function saveSocialSettings() {
	// set default values
	if(get_option('ty-facebook') == ""){

		update_option( 'ty-facebook', 'Facebook URL...');


	if(get_option('ty-twitter') == ""){

		update_option('ty-twitter', 'Twitter URL...');


	if(get_option('ty-linkedin') == ''){

		update_option('ty-linkedin', 'Linkedin URL...');


	if(get_option('ty-flickr') == ''){

		update_option('ty-flickr', 'Flickr URL...');


	if(get_option('ty-skype') == ''){

		update_option('ty-skype', 'Skype URL...');


	// Save data to option fields
	if(! empty($_POST)){

		$facebook = $_POST['ty_facebook'];
		$twitter = $_POST['ty_twitter'];
		$linkedin = $_POST['ty_linkedin'];
		$flickr = $_POST['ty_flickr'];
		$skype = $_POST['ty_skype'];

		// save the form values to the option fields
		update_option( 'ty-facebook', $facebook);
		update_option( 'ty-twitter', $twitter);
		update_option( 'ty-linkedin', $linkedin);
		update_option( 'ty-flickr', $flickr);
		update_option( 'ty-skype', $skype);



Contact details form and code to save the info

function my_contact_settings() {
$contact = '
<div id="contact-settings">
<div class="wrap"><form action="" method="post">' . settings_fields( 'ty-option-group' ) . '
<h3>Contact Us Settings</h3>
<div id="email">Email:
<input id="ty-email" type="text" name="ty-contact_form_email" value="' . get_option('ty-contact-form-email') . '" /></div>
<div id="otherinfo">Other contact info:
<textarea id="ty-other-info" style="width: 200px;" name="contact_info">'. get_option('ty-contact-info') .'</textarea></div>
<div class="submit"><input id="contact-button" class="button-primary" type="button" value="Save" /></div>

return $contact;

// save contact details
add_action('wp_ajax_contact_my_action', 'saveContactSettings'); //ajax callback
function saveContactSettings() {

	if(get_option('ty-contact-form-email') == ''){
		update_option('ty-contact-form-email', 'Your email...');

	if(get_option('ty-contact-info') == ''){
		update_option('ty-contact-info', 'Add contact information here...');

	// Save data to option fields
	if(! empty($_POST)){
		$email = $_POST['ty_email'];
		$contactinfo = $_POST['ty_info'];
		update_option('ty-contact-form-email', $email);
		update_option('ty-contact-info', $contactinfo);



Next we have the most important part of this tutorial, we are going to use Ajax to save the data and we will be doing this the way WordPress requires us to do it.

The code

//Ajax code for admin menu
add_action( 'admin_head', 'ty_ajax_to_header' );
function ty_ajax_to_header() {
        <script type="text/javascript" >
        jQuery(document).ready(function() {
            jQuery('#button-general').click(function() {

				//this is the ajax for general settings
				//get field values
                var tylogo = jQuery('#tylogofile').val();
                var tyfavicon = jQuery('#tyfavicon').val();
                var tyanalytics = jQuery('#tyanalytics').val();
                var tycustomcss = jQuery('#tycustomcss').val();
                var tyfootertext = jQuery('#tyfootertext').val();
				//set data varialbel with values
                var data = {
                        action: 'my_action',
                        ty_logofile: tylogo,
                        ty_favicon: tyfavicon,
                        ty_analytics: tyanalytics,
                        ty_custom_css: tycustomcss,
                        ty_footer_text: tyfootertext,


                // since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
      , data, function(response) {
                       jQuery('#savemessage').html('General Settings Saved').hide(2000);

		jQuery('#social-button').click(function() {
            //this is the ajax for general settings
                var tyfacebook = jQuery('#facebook').val();
                var tytwitter = jQuery('#twitter').val();
                var tyflickr = jQuery('#flickr').val();
                var tylinkedin = jQuery('#linkedin').val();
                var tyskype = jQuery('#skype').val();
                var data = {
                        action: 'slider_my_action',
                        ty_facebook: tyfacebook,
                        ty_twitter: tytwitter,
                        ty_flickr: tyflickr,
                        ty_linkedin: tylinkedin,
                        ty_skype: tyskype

                // since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
      , data, function(response) {
                       jQuery('#savemessageslider').html('Social data saved!').hide(2000);

            //contact us settings
            jQuery('#contact-button').click(function() {
            //this is the ajax for general settings
                var tyemail = jQuery('#ty-email').val();
                var tyinfo = jQuery('#ty-other-info').val();

                var data = {
                        action: 'contact_my_action',
                        ty_email: tyemail,
                        ty_info: tyinfo


                // since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
      , data, function(response) {
                       jQuery('#savemessagecontact').html('Contact Saved').hide(2000);



Above I created the code to run the ajax, but before it would work we need to add the following lines
before each function that saves the data.

 add_action('wp_ajax_my_action', 'add_general_settings'); //ajax callback
 add_action('wp_ajax_slider_my_action', 'saveSocialSettings'); //ajax callback
 add_action('wp_ajax_contact_my_action', 'saveContactSettings'); //ajax callback

Now we need to get the upload buttons to work for the logo and favicon fields

I've created a separate JS file for the uploads to work but before we include it to the header we need to add some code for it to work before all of our functions.

               //This is for the media upload box
		wp_register_script('my-upload', get_bloginfo('template_url').'/js/my-script.js', array('jquery','media-upload','thickbox'));
		wp_enqueue_style('thickbox'); //thickbox styles css

The code above sets the media-upload script and thickbox scripts with css to the header and adds my custom JS script
called my-script.js to the header.

The code for my-script.js

jQuery(document).ready(function() {

jQuery(document).find("input[id^='upload_image_logobutton']").live('click', function(){
//var num ='-')[1];
 formfield = jQuery('#logofile"').attr('name');
 tb_show('', 'media-upload.php?type=image&TB_iframe=true');

 window.send_to_editor = function(html) {
 imgurl = jQuery('img',html).attr('src');

return false;

jQuery(document).find("input[id^='upload_image_button_tyfavicon']").live('click', function(){
//jQuery('#upload_image_button_zkrfavicon').click(function() {
 formfield = jQuery('#favicon').attr('name');
 tb_show('', 'media-upload.php?type=image&TB_iframe=true');

 window.send_to_editor = function(html) {
 imgurl = jQuery('img',html).attr('src');

 return false;


You can download this script here

You can download the completed tutorial code here, just copy the code to you functions file.

All that's left to do is to add the code which calls the data in to your theme

you can use the get_option('ty-logo-url'); part in your theme header for example and call the logo like this,

<img src="<?php get_option('ty-logo-url'); ?>" alt="logo" />

Hope you enjoyed part 2 of this tutorial? if you've missed part 1 make sure to check it out.

Please comment and let me know what you think. Comment & Win

Some Resources to help with this tutorial

WordPress Ajax

WordPress Options

Related Posts:

  • rss
  • email
  • rss
  • email
I'm a full time PHP developer and I just love all things web related. If you need help I'm your guy.

23 Responses to How to Build Your Own Custom WordPress Premium Theme Admin – Part 2

  1. Paresh says:

    Is the data saved in the wordpress database? i cant figure out where the options data is saved.

  2. Morné says:

    Hi Paresh,

    Yes it does get saved in the database in the wp_options table.

    Thanks for the comment. :)

  3. Karol says:

    It took me a while but I finally got this set up. This was a great tutorial that not many other people have touched on. I really appreciate all of your help too. One more question though, how would I add a drop down menu. ex. add a drop down menu with several options to general settings page.

  4. Karol says:

    I’ve been able to add the menu and get it working I just can’t figure out what to do with the jquery to get the selected option to stick. As soon as I reload my browser the form goes back to the top option. I can save the form and the option will change but the form goes back after that.

  5. Morné says:

    Hi Karol,

    Sorry for only getting back to you now, things are a bit hectic on this side. Unfortunately that is the nature of using jQuery.

    What I would suggest is that you use ajax to save data in your forms, it will look better and not reload the page causing it to go back to the first tab.

    If you need tips I can always write an tutorial on using ajax within your wordpress code.

  6. Morné says:

    Hi Karol,

    Ok the problem you are having is that it’s not showing the correct dropdown when you come back.

    Inside your option value you need to add some code. Here is just an example to help you. You can change it accordingly.

    <option value="blue.gif" >Your Option Value

    Hope that helps. So next time you load your page the correct option should show.

    Let me know if the code points you in the right direction. The code is not displaying correctly in the comments section. Contact me through my contact page then I can help you from there.

  7. qakbar says:

    Hi Morne,

    Wonderful tutorial like it…

    Can you please let me know if you will be adding a tutorial to change custom CSS for like font sizes and line heights etc.

    Maybe even some shortcodes.


  8. Morné says:

    Hi there,

    I will add this to my list of tutorials to do. So please join my newsletter and keep an eye out for the tutorial.


  9. qakbar says:


    Thank you for the reply.

    I was hoping you would be able to add like scroller to move up and down to change the sizes in the admin area that will update the font size.


  10. Morné says:


    No problem I’ve done something like this before. Will keep it in mind when doing a tutorial on this.

  11. Wow dude. Just WOW!

    One question though!
    I want to add a drop down but I can’t seem to get it to work.
    I can add the value to the database but when I refresh the page (or log out and in) it jumps back to the first value of the drop down.

    I have no idea how to fix this.

    Any help please?

    This is the code btw:


  12. Morné says:

    Hi Michel,

    Let me understand this first, do you want to add another dropdown option field dynamically?

    If so, it needs to be done via jQuery

    You could also serialize your data and store it in one option field instead of multiple option fields.

    Let me know if this is what you wanted I can try and write some code for you.

    I’m also doing a video series on this tutorial with some updated techniques. The first part is located here

    The rest will be available from tomorrow or Thursday.


  13. Hi Morné.

    This is not what I ment.
    I just need to add an drop down function to one of the tabs.

    The problem is that it doesn’t remember what a user filled in.
    In other words. If the page get’s loaded the dropdown should check with the database what value is stored in the database.

  14. Morné says:

    Hi Michel,

    This code should help you out.

    <option selected="" value="value1" >value1
    <option selected="" value="value2" >value2
    <option selected="" value="value3" >value3
    <option selected="" value="value4" >value4
    <option selected="" value="value5" >value5

    You need to check if the value is equal to the value in the database and then echo “selected” to set the users choice.

    Hope that was helpful?


    For some reason the code does not want to show correctly in the comments. Please contact me through my contact page and I will then reply to you with the code.

  15. Hi Morne,

    Still works like a charm. I’ve changed some formfield. They are now created dynamicly.
    I create a textfield every sunday for the next 12 times.

    The problem now is that I can create the forms dynamicly in PHP but I can’t save them with AJAX because I just don’t know how to do this.

    If you have some spare time could you please take a look at my script?

    If you like I send you the code in an e-mail.

  16. Morné says:

    Hi Michel,

    you can send me the code through my contact form. I’ve just realized that the forum has no place for people to register :( will fix that then you can post questions there in future.

  17. Hey Morné,

    I hope you have any spare time left to take a look at my earlier post?


  18. Morné says:

    Hi Michel,

    Sorry I’ve been really busy on freelance projects and this last 2 weeks I was sick and hospitalized.

    I will try and get back to you, really sorry about neglecting you a bit. Will try and have a look over this weekend.

    Chat soon.

  19. Daniele Pavinato says:

    Hi, great tutorial!
    I need to know how can i reload automatically the Settings page after saving…

    Any suggestion?

  20. Morné says:

    Hi Daniele,

    If I remember correctly we use ajax in this tutorial that is why it does not reload the page. What you could do is use the following with in your click event just add this part at the end .


    That should do it.

  21. Daniele Pavinato says:

    You’re right. Thanks

  22. Chella Durai says:

    Great tutorial, easy to understand… Thanks for sharing… :)

  23. nilesh says:

    Hi Morne Zeelie,

    Great Tutorial.

    I can’t save them with AJAX because I just don’t know how to do this.

    function showUser(str)
    if (str==””) {
    if (window.XMLHttpRequest) {
    // code for IE7+, Firefox, Chrome, Opera, Safari
    xmlhttp=new XMLHttpRequest();
    else { // code for IE6, IE5
    xmlhttp=new ActiveXObject(“Microsoft.XMLHTTP”);
    xmlhttp.onreadystatechange=function() {
    if (xmlhttp.readyState==4 && xmlhttp.status==200) {
    jQuery(document).ready(function() {
    dateFormat : ‘dd-mm-yy’

    <option value="highlight_new123?news" >News

    data not save.

    Please Help me how to save.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>