Category Archives: Uncategorized

Adding Custom Field to WordPress Quick Edit UI for Custom Post Type

Adding a custom field to the WordPress Quick Edit screen for a custom post type was a rather tricky task, so I wanted to be sure to share my solution with my readers in case any of you have a difficult time with it as well.

Let's get our hands dirty shall we?

There are six basic high level steps to adding a field to quick edit which are:

  1. Add a new column to the posts screen for the post type - I thought this was not necessary at first, but I assure you that it is 100% required for the new field to work within the quick edit UI. Therefore if this turns you off, you can surely find a way to hide the field from view if you don't want it to show up on the posts admin screen.
  2. Fill the column you added in the previous item with data - While this step isn't actually required for the field to work in the quick edit screen, it is needed if you wish for the column to have relevant data in it. However, if you wish to hide the column as I suggested could be done, then you may surely skip this step. I don't recommend skipping it however.
  3. Add HTML code to the Quick Edit User Interface - this will be accomplished, as you'll soon see below, with WordPress's quick_edit_custom_box action hook and your custom HTML for your custom field.
  4. Save the new custom field's value that you've added to the Quick Edit UI - This can be easily achieved by making use of the WordPress save_post action hook as you will discover below.
  5. Add some JavaScript code in the admin page's footer to update your custom fields value within Quick Edit UI - this is where it gets a little tricky for some. I'll explain as best I can below, but suffice it to say for now that you have to update the input field you created in the quick edit menu with JavaScript that's generated with PHP code using WordPress's admin_footer hook. I have seen some alterations of this in other posts online where people use JQuery, but I tend to find that using JQuery is often more likely to lead to plugin conflicts if you are not very careful, so I prefer to use plain JavaScript whenever possible.
  6. Finally you'll need to link your JavaScript function from the previous step to the Quick Edit link for each post using a JavaScript OnClick event - this is done with the elusive WordPress filter named post_row_actions that allows you to change the context of the Quick Edit link itself with some PHP magic.

Now that the high level steps have been explained in very little detail to give you an idea of what we'll be doing in this tutorial, I will demonstrate each step with a working code example that you can use to paste into your own Plugin or Theme files as needed. If you don't know where to paste the code, then frankly, this tutorial may not be for you, so I won't go into that part in detail since this tutorial is really meant for plugin developers and all of them surely know where to place the code I'll be showing below.

Step 1 - Add a new column to the posts screen for the post type

Step 1 is by far the easiest step with very little code. All we need to accomplish here is to add a column to the Custom Post Type admin screen. Here is the simple PHP code:


//Add groomer Column to dogs CPT:
add_filter('manage_dogs_posts_columns', 'dogs_groomer_post_column');
function dogs_groomer_post_column($columns) {
    $columns['groomer'] = 'groomer';
    return $columns;
}//end dogs_groomer_post_column PHP function


Not a lot you need to do to the above code but change the custom post type name and the field name to your own CPT and Custom Field Name, so search and replace "dogs" with the name of your Custom Post Type. Then search and replace "groomer" with your custom field name. Your now done with step 1! Don't worry, they will get harder!

Step 2 - Fill the column you added in the previous item with data

Now all we have to do in step 2 is fill our column from step 1 with relevant data. In our case, the name of the groomer for each dog in the dogs custom post type. Here's the PHP code:


//Add content to new groomer Column in wp-admin for dogs cpt:
add_action('manage_posts_custom_column', 'render_groomer_column_for_dogs', 10, 2);
function render_groomer_column_for_dogs($column_name, $id) {
    switch($column_name) {
    case 'groomer':
        // show groomer
        $groomer_val = get_post_meta( $id, '_groomer', TRUE);
        if($groomer_val == '')$groomer_val = 'None';
        echo $groomer_val;              
}//end render_groomer_column_for_dogs PHP Function


Again, all you have to do to make this code your own is replace "dogs" with the name of your custom post type and replace "groomer" with the name of your custom field and be sure to get the ones with the underscore in front of them too! I like to put underscores in front of field names when saving them to the database. That's all for step 2! Another easy one! Okay on to step 3.

Step 3 - Add HTML code to the Quick Edit User Interface

In step 3 we have to add a PHP function using the quick_edit_custom_box WordPress hook that adds HTML content to the Quick Edit User Interface. Here's the PHP code:


//add groomer to quick edit screen:
add_action('quick_edit_custom_box',  'CCRM_add_groomer_to_quick_edit', 10, 2);
function CCRM_add_groomer_to_quick_edit($column_name, $post_type) {
    if($column_name != 'groomer') return;
    <fieldset class="inline-edit-col-left">
    <div class="inline-edit-col">
        <input type="hidden" name="groomer_noncename" id="groomer_noncename" value="" />
<label for="groomer_status"><?php _e('groomer: ', 'dogs'); ?><select name="groomer_status" id="groomer_status">
    <option>-Pick one-</option>
    <option>Ted Dogly</option>
    <option>Teresa Lassie</option>
    <option>Megan Dame</option>
    <option>Star Wolfe</option>
    <option>Joan Smith</option>
    <option>Dober Mann</option>
}//end CCRM_add_groomer_to_quick_edit PHP function


Again to make the above code your own, you'll want to replace all occurrences of dogs and groomer with your own names as in the previous two steps. Another option you may wish to change in the above code will be the input type. Here we have decided to use a select input to create a drop-down of possible groomer names to assign to each dog. You may prefer to use a text field, checkbox or even a textarea here, you can use any form element you want to collect your custom field's data. Simply change the above code to fit your individual needs and your done with step 3!

Step 4 - Save the new custom field's value that you've added to the Quick Edit UI

In step 4, we save the new custom field value to the WordPress database when it is edited from the Quick Edit dialog. As with all the previous steps, change the names of dog and groomer according to your own post type and field name respectively. In the below code we use the common "save_post" WordPress hook to detect when a new field value is submitted and save it with the following PHP code:


//save groomer for quick edit screen:
add_action('save_post', 'save_groomer_quick_edit_data');
function save_groomer_quick_edit_data($post_id) {
    $post = get_post($post_id);
    //verify if this is an auto save routine. If it is our form has not been submitted, so we dont want to do anything:
        return $post_id;    
    //Check permissions
    if('dogs' == $post->post_type){
        if(!current_user_can('edit_page', $post_id ))
            return $post_id;
    //OK, we're authenticated: we need to find and save the data
    if(isset($_POST['groomer_status']) && ($post->post_type != 'revision')) {
        $groomer = esc_attr($_POST['groomer_status']);
        if ($groomer)
            update_post_meta($post_id, '_groomer', $groomer);     
            delete_post_meta($post_id, '_groomer');     
    return $groomer;  
}//End save_groomer_quick_edit_data PHP function


The above code is fairly straight forward, so simply change dogs and groomer text as with previous steps and move on to step 5 below.

step 5 - Add some JavaScript code in the admin page's footer to update your custom fields value within Quick Edit UI

Here is where it gets a little tricky! There's no simple PHP code to update the Quick Edit UI with the latest updated field value, so we have to generate some JavaScript with the following PHP code. We'll use the admin_footer WordPress hook to inject JS code into the footer of the admin page like so:


//add JS to footer that updates quick edit dropdown:
add_action('admin_footer', 'groomer_quick_edit_JS');
function groomer_quick_edit_JS() {
    global $current_screen;
    if(($current_screen->id != 'edit-dogs') || ($current_screen->post_type != 'dogs')) return;
    <script type="text/javascript">
    function replace_quick_edit_link(widgetSet, nonce) {
        //revert Quick Edit menu so that it refreshes properly
        var widgetInput = document.getElementById('groomer_status');
        var nonceInput = document.getElementById('groomer_noncename');
        nonceInput.value = nonce;
        //check option selected
        for(i = 0; i < widgetInput.options.length; i++) {
            if(widgetInput.options[i].value == widgetSet) {
                widgetInput.options[i].setAttribute("selected", "selected");
    }//End replace_quick_edit_link JavaScript Function
}//End groomer_quick_edit_JS PHP function


Now the above code maybe a little complicated for some, especially those of you who want to use a different type of form field rather than use the drop-down select like in our code. Where you see the section of code that has the comment "//check option selected" before it is where you'll need to make significant code changes if you use anything other than a select field in your own code. Also be sure to also change all occurrences of dog and groomer as in each of the previous steps.

Step 6 - Link your JavaScript function from step 5 to the Quick Edit link for each post using a JavaScript OnClick event

Next due to the fact that it's impossible to update the option updated in the quick edit UI, we use the following PHP and JS magic to make it happen with the help of the WordPress post_row_actions filter hook:


//code to modify quick edit link with on-click event:
add_filter('post_row_actions', 'groomer_expand_quick_edit_link', 10, 2);
function groomer_expand_quick_edit_link($actions, $post) {
    global $current_screen;
    if (($current_screen->id != 'edit-dogs') || ($current_screen->post_type != 'dogs')) return $actions;
    $nonce = wp_create_nonce('groomer'.$post->ID);
    $groomer_val = get_post_meta($post->ID, '_groomer', TRUE);
    $actions['inline hide-if-no-js'] = '<a href="#" class="editinline" title="';
    $actions['inline hide-if-no-js'] .= esc_attr(__( 'Edit this item inline' ) ) . '" ';
    $actions['inline hide-if-no-js'] .= " onclick=\"replace_quick_edit_link('{$groomer_val}', '{$nonce}')\">";
    $actions['inline hide-if-no-js'] .= __( 'Quick&nbsp;Edit' );
    $actions['inline hide-if-no-js'] .= '</a>';
    return $actions;    
}//end groomer_expand_quick_edit_link PHP function


Changing each occurrence of dogs and groomer in the above code should be sufficient in most cases to make it your own. Good luck!

Going a Step Further with Bulk Edit Ability Too!

Okay, this technically makes it seven steps instead of six, but I added this as an afterthought because it is so easy to add the bulk edit feature to the above code. All you have to do in order to make the same custom field from the above code show up in the bulk edit screen or UI, is add one line of code! Therefore I thought it wise to add it here.  Here is how:

If you look above at step 3, the first line of PHP code is the quick edit hook which looks like this:

add_action('quick_edit_custom_box',  'CCRM_add_groomer_to_quick_edit', 10, 2);

All you have to do to also make the same field show up in the bulk edit screen too is add the following code that contains the bulk_edit_custom_box hook in place of the quick_edit_custom_box hook in the above line of code like this:

add_action('bulk_edit_custom_box',  'CCRM_add_groomer_to_quick_edit', 10, 2);

That's it! you can add the above l line directly before or after the quick_edit_custom_box hook as in step 3 above. Now if you select all posts from the custom post type screen and then in the "bulk actions" dropdown, select "edit" and you can edit the new custom field value for all of your posts at one time! Yes, we saved the simple step for last! Enjoy your new bulk and quick editor plugin!


In conclusion, you'll want to incorporate the above code examples into your own plugin for best results. I have created such a plugin for anyone who needs it. Please feel free to contact me by email at if you would like the plugin.

How to Figure Out Relative Humidity with PHP

Today, I had to calculate relative humidity using PHP and I have documented my findings below:

First, let's just use an example situation where we have a temperature of 60.1 and a dew point of 42.7, both in Fahrenheit, so...:

dew point in Fahrenheit: 42.7

temperature in Fahrenheit: 60.1

1) The first step is to convert to Celsius using the following formulas


Formulas explained:
Tc=air temperature in degrees Celsius, Tf=air temperature in degrees Fahrenheit

Tdc=dewpoint temperature in degrees Celsius

Tdf=dewpoint temperature in degrees Fahrenheit

Notice: If your temperature and dewpoint are in degrees Celsius, you can skip step 1 and proceed to step 2.

answer for equations:
Temp in Celsius: 15.61

0.5555555555555556 * 28.1 = 15.61111111111111

dewpoint in Celsius: 5.94
0.5555555555555556 *  10.7 = 5.944444444444444

2) calculate saturation vapor pressure(Es) and actual vapor pressure(E) in millibars:
NOTE: first line is the equation and the subsequent lines represent one step solved at a time:
Es=61.1 ** (7.5*15.61/(237.7+15.61))
Es=61.1 ** (117.075/253.31)
Es = 61.1**0.4621807271722395
Es = 6.6907349413770067935260257174923

E=61.1 ** (7.5*5.94/(237.7+5.94))
E=61.1 ** (44.55/243.64)
E=61.1 ** 0.1828517484813659497619438515843
E = 2.1211957981192776150462474985589

3)  Once you have the saturation vapor pressure and actual vapor pressure, relative humidity(RH) can be computed by dividing the actual vapor pressure by the saturation vapor pressure and then multiplying by 100 to convert the quantity to a percent:
RH =(E/Es)*100
RH =(2.1211957981192776150462474985589/6.6907349413770067935260257174923)*100
RH = 0.31703479762758596814611114744566 * 100
RH = 31.703479762758596814611114744566%
SO... Humidity is 31.7%

And note here that ** means to the power of. I figured I'de clue anyone in that is as ignorant is I was when I had to figure it out.

Enabling Multiple Domain Names and Sites on Apache2 Server

Today I set up a new server and I am documenting exactly how to set up multiple domain names, sub domains and websites on a new Apache2 Server. I am using Ubuntu, but I believe these directions are similar for any Linux Apache2 web server.

Pointing your domain or sub-domain

It is a good practice to point your domain name or sub-domain first, before you set it up on your server which I'll cover afterwards below, so let's go ahead and point our domain. Whether you are using a new domain name or a sub-domain on one of your existing domain names, the process is similar for pointing the domain name or sub domain name to your server IP address. You will need to go to your domain management console and create a Type "A" record. This will normally be done in your DNS provider's advanced DNS settings or zone file settings. Use the following settings to create two new records:

  • Name: if there is a name field, enter the domain name or sub-domain name(most require you to follow the domain with a "." so for my sub domain I entered "".
  • Type: "A" for both records.
  • Hostname field: enter "www" in the first record and "@" in the second.
  • Destination IPv4 address(sometimes just called Address): Use your server's IP address for both records.
  • TTL: use "14400" for both records.

That should be enough information for you to figure out how to create your two host records on just about any platform, but if your platform differs, ask your provider for assistance or google the providers name followed by DNS instructions or "How to point a name with Provider Name". You are creating two similar records, one for WWW and one for @. That way visitors of your site can access with either or just The Hostname of @ makes the record for the domain without "www" in front of it. If your provider's DNS settings do not include the Host or Hostname field where we put either www or @, then you probably need to create two records with different names instead. For example, name one record "" and name the other "". If you're using a sub domain then name one "" and the other "" You don't really need a www record for sub domains usually, but you can use one if you want, it won't hurt anything and might help some users find your site.

Steps to adding  a second domain name to your server

Here I am going to explain how I set up a sub domain as as second domain name pointing to a second website on my Linux/Apache2 web server:

Note: My first site was already set up in var/www/html. Most people prefer to set up multiple websites under the var/www directory, but to keep things simple, I'm going to use the var/www/html folder and not var/www. It really makes no difference. It's just a preference.

  1. Create your directory structure for your new website that will reside on your new domain or sub-domain. I'm creating a sub domain like, but these directions are the same as if I were using just instead. First, create the directory /var/www/html/ Then create /var/www/html/ and /var/www/html/ If you are logged into FileZilla as root, you can create these from there, otherwise log in with putty and create them using the sudo command.
  2. Create your log files. Simple make two empty files named access.log and error.log and upload them to the logs folder you created in step one above.
  3. Create a VHOSTS file named after the domain or sub-domain followed by .conf, so in my case, I'd name my file THen copy and paste the  content below under the heading "VHOSTS Example File Contents" into it then change all instances of my sub-domain name with your own domain or sub domain and upload that file to /etc/apache2/sites-available.
  4. Next, use the a2ensite tool from the Linux command line to finalize the new site with the following command(replace with your domain or sub-domain):  sudo a2ensite
  5. Reset apache2 with: sudo service apache2 restart

VHOSTS Example File Contents

<Directory /var/www/html/>
    Require all granted
<VirtualHost *:80>

    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html/

    ErrorLog /var/www/html/
    CustomLog /var/www/html/ combined

Automating the process of setting up domain names and sub domains

If you have to do this often or alter DNS records often and create lots of virtual hosts, you should probably look into automating the process. I provide such a service and have done so for several of my clients. What I do is create a simple user interface in a secure admin web page on your own server where you can simply enter the domain name or sub domain name into a form field and press GO and it does all the above work for you! A real time saver if you have to do this more than once in a great while! IF you are interested in this service, contact me, Ian L. of for a fast, free quote by email or Skype. My email is and my Skype name is ianlin11. Or use the contact link on this site.


That is how you do it!

Find and Replace All Occurrences of a File on Linux Server from Command Line

Today I was given the challenge of providing a client with a command line command that would allow my client to replace all occurrences of any file named this-file.php with a new file with the same name that resides in the server's root directory. Here is how I accomplished the challenge with a single line command from the Linux command prompt:

find . -name "this-file.php" -print -exec cp this-file.php {} \;

What we have there is basically two commands in one. First is the command to find all occurrences of this-file.php on the server and display the results. I have it displaying results so you can verify what files were replaced in the end. So, the command to just find all files named this-file.php and list them is:

find . -name "this-file.php" -print

Type the above command at your Linux command prompt and you'll get a list of paths found to files with the name this-file.php.  However, it should be noted that the above command is the command to use if you are in the base directory of your server, otherwise you will want to specify the root directory. In the above command, the '.' (period) means to search in current directory. So if you're not in the curent directory, use something more appropriate such as a / instead of a . so it forces it to search all directories above and including /. Try this:

find / -iname "this-file.php"

That is a safer command than the first because it doesn't matter what directory you call it from. Notice we also didn't use the -print parameter at the end this time. It is actually moot because it will print the results anyway. It was included in the first example to explain it's use in the find and replace command, but is not needed when find is used by itself.

The second part of the challenge was to replace all those files listed with a new version of the file stored in the root directory. Therefore, before we go any further, we need to change into the root directory or whatever directory you will use to store the new file that will be used to replace all of the other files with. So change directories with the cd command like this:

cd /

That changes you into the root directory where you can go ahead and upload your new file if you haven't done so already.

Next is the command to copy this-file.php and overwrite the old version of the file. As long as you use the same file name, this works out-of-the-box with Linux. The simple command to copy a file from the root directory to a website's sub-directory might look something like this:

cp this-file.php /var/www/

Combining two Linux Commands into One Line

The final part of our challenge is to combine the two commands we have learned above into one simple command to find and replace all occurrence of the file named this-file.php with a new version of it stored in the root directory that has the same file name. Here are the two commands combined:

find . -name "this-file.php" -print -exec cp this-file.php {} \;

Notice the find command which ends with -print looks the same. Then the find command is followed by -exec and then the cp command. Finally the combined command ends with {} \;. That last part has two functions. The brackets, {}, are used to replace what is found by the find command each time it finds something. The \; part lets Linux know the command is done and it can stop. Please note that for this to work the way it is written here, you must change directories into the directory that contains the new file in which will replace all instances of the file with the same name elsewhere on your server. So, be sure to execute the combined command only after changing into the correct directory which contains your new file!



How to add Custom Admin Meta Boxes to a WordPress Custom Post Type

I decided to write this detailed tutorial on how to add custom field meta boxes to the WordPress admin mostly because I couldn't find a decent description of how to do it anywhere online. Hopefully this will help others having trouble trying to learn how to add admin meta boxes with custom fields for a custom post type in WordPress. It is an essential step to learning WordPress plugin development.

Let's dive in and learn some code because I believe that is the quickest and easiest way to learn this advanced WordPress method. I say it is an advanced subject because it is a little complex for beginners. If you are not sure how to start your own plugin yet in WordPress, then this topic may be too advanced for you. You should at least learn how to make a very basic WordPress plugin first, so feel free to read one of my more basic WordPress plugin tutorials first.

First of all, I'll show you how to add a single meta box with a single field in it. It is also important to know that you can have more than one field inside a single meta box. It is equally important to know that you can have more than one meta box. Each meta box can have one or more fields in them. It just depends on your individual needs. Below is the basic code for how to add a custom post type with a custom field inside of an admin meta box. I'll also include a basic plugin heading so you may follow along and create a working example to work from:

Adding a Custom Post Type to WordPress Plugin

 * Plugin Name: Jafty Metabox Example Plugin
 * Plugin URI:
 * Description: A Plugin that adds metaboxes to your WordPress blog or site.
 * Version: 1.0
 * Author: Ian L. of
 * Author URI:
 * License: GPL2

 //Add new Custom Post Type named videos:
add_action('init', 'create_video_posttype');
function create_video_posttype(){
            'labels' => array(
            'name' => __('Videos'),
            'singular_name' => __('Video')
        'public' => true,
        'has_archive' => true,
        'rewrite' => array('slug' => 'video'),
}//end create_video_posttype function


Okay, now start a .php file and add the above code in green to the start of it. Name the file "jafty-metabox-example-plugin.php" and save it. Please NOTE: it is important to go into wp-admin/settings/permalinks and re-save those settings after activating a plugin with a custom post type or after adding a custom post type to a plugin. If you do not do this, the custom post type posts will not show up on the front end of your blog.

At this point, you should be able to upload the jafty-metabox-example-plugin.php file to your WordPress site's plugins folder and activate it. If it works, you'll see a new "Video" option in the left navigation menu of wp-admin as in the following photo:


Add a Metabox with a Custom Field to your CPT

Now here is the code to add to the end of the file you started above(just before the closing PHP tag) that will add a meta-box with a custom field inside of it to your plugin. It adds a field to the wp-admin edit screen for the videos CPT(custom post type):

//Add custom admin Meta Boxes:
add_action('add_meta_boxes', 'add_ians_metaboxes');
function add_ians_metaboxes(){
//add meta box for Video type and description:
add_meta_box('meta_box_html_id', 'Video Details', 'video_details_function', 'videos', 'normal', 'high');

//##################### Video Details Metabox: ################
function video_details_function() {
global $post;  
//Noncename needed to verify where the data originated
echo '<input type="hidden" name="eventmeta_noncename" id="eventmeta_noncename" value="' .
wp_create_nonce(plugin_basename(__FILE__)) . '" />';

//Get video description data if its already been entered
$video_desc = get_post_meta($post->ID, '_video_desc', true);
//Start video Description text field HTML:
Video Description:
<input type="text" name="video_desc" value="<?php echo $video_desc; ?>" class="widefat" />
}//end video_details_function

Save the "jafty-metabox-example-plugin.php" file and update it on your site and click on the "Video" link in wp-admin and then click on "Add New" to see the add/edit screen for your new CPT. You will notice your  custom meta-box with the heading of "Video Details". You will also notice the meta-box contains a custom field named "Video Description". You can see both near the bottom of the photo below:


Saving Custom Field Data

Your not quite done however. While the code above will display the metaboxes, it does not save the data as I soon discovered. To save the data, you'll need to add this code directly after your video_details callback function:

//hook into save_post to save the meta box data:
add_action ('save_post', 'save_video_desc');

function save_video_desc($post_id) {
//verify the metadata is set
     if (isset( $_POST['video_desc'])) {
     //save the metadata
     update_post_meta ($post_id, '_video_desc', strip_tags($_POST['video_desc']));


 Adding Multiple Meta-Boxes and Custom Fields

Next I'll show you what our final plugin file would look like if we were to add another custom field to our meta-box and then another meta-box with yet another custom field inside of it. This way you can see how more than one meta-box is added and also how to add more than one field inside of a single meta-box. Here is the complete plugin code containing a total of two meta-boxes and three total custom fields:

* Plugin Name: Jafty Metabox Example Plugin
* Plugin URI:
* Description: A Plugin that adds metaboxes to your WordPress blog or site.
* Version: 1.0
* Author: Ian L. of
* Author URI:
* License: GPL2

//Add new Custom Post Type named videos:
add_action('init', 'create_video_posttype');
function create_video_posttype(){
'labels' => array(
'name' => __('Videos'),
'singular_name' => __('Video')
'public' => true,
'has_archive' => true,
'rewrite' => array('slug' => 'video'),
}//end create_video_posttype function

//Add custom admin Meta Boxes:
add_action('add_meta_boxes', 'add_ians_metaboxes');
function add_ians_metaboxes(){
//add the first meta box for Video type and description:
add_meta_box('meta_box_html_id', 'Video Details', 'video_details_function', 'videos', 'normal', 'high');
//add a second meta box for Video Rating
add_meta_box('meta_box_html_id2', 'Video Rating', 'video_rating_function', 'videos', 'normal', 'high');
//################## Video Details Metabox: ####################
function video_details_function() {
global $post;

//Noncename needed to verify where the data originated
echo '<input type="hidden" name="eventmeta_noncename" id="eventmeta_noncename" value="' .
wp_create_nonce(plugin_basename(__FILE__)) . '" />';

//Get the video type  if its already been entered
$video_type = get_post_meta($post->ID, '_video_type', true);
// Get the video description if its already been entered
$video_desc = get_post_meta($post->ID, '_video_desc', true);

//Start type select field HTML:
Video Type: <select name="video_type">
<option value="DVD"<?php if($video_type=="DVD")echo " selected";?>>DVD<option>
<option value="Blueray"<?php if($video_type=="Blueray")echo " selected";?>>Blueray<option>
</select><br />
// Start video description field HTML:
Video Description:
<input type="text" name="_location" value="<?php echo $video_desc; ?>" class="widefat" />
}//end video_details_function
//##################### Video Rating Metabox: ###################
function video_rating_function() {
global $post;

//Noncename needed to verify where the data originated
echo '<input type="hidden" name="eventmeta_noncename" id="eventmeta_noncename" value="' .
wp_create_nonce(plugin_basename(__FILE__)) . '" />';

//Get the start_month data if its already been entered
$video_rating = get_post_meta($post->ID, '_video_rating', true);

//Start type select field HTML:
Video Type: <select name="_video_rating">
<option value="R"<?php if($video_rating=="R")echo " selected";?>>R<option>
<option value="PG"<?php if($video_rating=="PG")echo " selected";?>>PG<option>
</select><br />
}//end video_rating_function

//add your save data hook and function to save all fields here:

//hook into save_post to save the meta box data:
add_action ('save_post', 'save_video_data');

function save_video_data($post_id) {
//verify the metadata is set
     if (isset( $_POST['video_desc'])) {
     //save the metadata
     update_post_meta ($post_id, '_video_type', strip_tags($_POST['video_type']));

    update_post_meta ($post_id, '_video_desc', strip_tags($_POST['video_desc']));

    update_post_meta ($post_id, '_video_rating, strip_tags($_POST['video_rating']));

That's it! Save the above code in a PHP file and name it the same name as before and allow it to overwrite the original plugin file if you were following along and it will add another meta-box and a couple more custom fields to your custom post type. Now you should have enough information to be able to make your own custom admin meta-boxes and fields for your next WordPress plugin or theme. Here is an image of the two meta-boxes from when I tested the above code myself:



Now you should know more than enough to make your own plugin or custom theme with its own admin meta-boxes and custom fields for any custom post types you may have. It is important to know that you can also use any other type of form element in the above examples. Feel free to experiment and use textareas, radio buttons, checkboxes etc in your own code.


Finding Immediate Secrets Of website worth value

worth of your websiteTips on How to Estimate Your Opening Balance Sheet, Determine Fixed Assets & Liabilities & Configure Equity, Net Profit, Liabilities & Capital

If you are reading this post, then you know the need for Internet marketing. Internet marketing can get more visitors to your site, raise your customers and increase your brand products and services. The Web is dynamic; new approaches to web design, creating engagement and marketing are always being refined. Unless you are keeping tabs on the complete ecosystem, you happen to be certain to will lose out on ways and opportunities had to make your online efforts profitable. Fortunately, you won't need to do it yourself.

Regaining and building your self-worth and self-esteem can be a critical ingredient to healing and growing out of your divorce experience. The word “worth” means “good or important enough to justify something” or “usefulness or importance.” Do you consider yourself merit using a life that you simply love and relationships you cherish, during the aftermath of divorce?

"We want to make sure the lessons are clear, substantive, practical, understanding that the youth can easily use it inside their lives, so our youth can understand their true worth," stated Margaret DePena, Executive Director of VOTCDC. "This conference is intended to address real issues, real concerns and offer sensible guidance to arrange youth for today's challenges."

Ideally, a specialist SEO company seeks industry specific directories to submit your website of client that's aside from the general directories such as Yahoo Directory, the Open Directory Project,, etc. However, a true approach is to use organic SEO which means evolving client's website worth calculator into something that holds actual value to the client's prospects. Organic SEO is much more beneficial in the long term than the artificial methodology of trying to garner incoming links that your concerned website worth calculator doesn't truly deserve.

When selling business outcomes, which two choices are key points/ factors in connection with what the customer desires to achieve should be considered? (Choose two.) A.What the business priorities and methods are. B.What the Critical Set of Factors and Key Performance Indicators are. C.What the mindset of Stakepower clients is. D.What the business priorities and goals are. E.What the Critical Success Factors and Key Performance Indicators are. Answer: D E

These Bing AdWords tutorials will help you create your AdWords account, pick the best key words, compose effective advertising content, and track and optimize the performance of the ads. Begin training now to help make the much of your advertisement budget and optimize your AdWords promoting goals.

As an example, with all the Bing PPC keyword breakthrough device, typically you'd have to review your pay-per simply click keyword list manually, export your chosen keywords into a spreadsheet, review the info, and then regulate how to proceed. With WordStream, it is possible to import lists of key words from Bing's keyword tool with one click, and get actionable suggested statements on how to use your keyword information. WordStream offer suggestions for keyword groups (which can then be turned into Bing PPC ad groups) that will help you build powerful text advertisements and to optimize your Google adwords lynda.Com PPC campaigns.

Finally, pay per click advertising cannot measure. In the event that you get more traffic, you spend more income in almost direct proportion compared to that traffic - your expense per simply click remains constant, plus overall cost increases. Compare that to find motor optimization , where you invest a set amount of time and/or money to obtain an improved ranking, along with your expense per click falls while you draw more traffic.

Key Takeaway: A/B evaluation isn't just for specialists. If you would like get the most from your AdWords promotions remember to test things such as ad content, bid cost, and landing pages. Check out the article The Practical Science of A/B Testing your AdWords Beginners Guide for a step-by-step guide on how best to begin with A/B screening.

WordStream's keyword administration system integrates keyword research with Bing AdWords pay-per-click marketing content authoring tools. This is certainly a strong combination that empowers you to make informed marketing choices and take action together with your information. Information is worthless if you do not can act onto it, and WordStream allows you to see your data plainly and work out smart decisions in managing your campaign.

Handling your online promotional initiatives can be an occasion consuming procedure. You will need to continuously monitor and improve your bids and keywords to ensure you stay within your budget while reaching the most readily useful ROI. Save yourself money and time using our PPC software to eliminate the hassle of running a PPC campaign. Our sophisticated putting in a bid algorithm will perform a selection of automatic tasks from setting automatic bids to producing comprehensive reports that visibly display your ROI so you can easily monitor the success of your campaign.

servidores low costAmong their duties are to provide internet connectivity in a data center. Web hosts provide space on a server that they own or lease them out to clients. Co-location is also provided if you want servers to be located on your data center.

Business Business News
Business Comment
Business Analysis & Features
Market News
Market Epic
Market Heatmaps
Market Screener
Business Directory
ES Business Connections
Create a business profile

You may get plenty of downtime, and you'll have ads that are not yours. To get going along with your first site that was very, consider a free hosting business. All things considered, your preliminary site will be the one which can coach you on classes - not make you a lot of gains.

2) Bandwidth and disk space: Every website has different requirements for bandwidth and disk space; before you decide on a webhosting company, you'll need to take yours into account. If your site will host large files (especially video content and other particularly large files), then you'll need to have plenty of disk space to allow for this.

You will be able to see a cost comparison and be able to make your decision based on other people's comments and experiences with those select companies. You can sign up at a lower level and a cheaper price, and the host company, if it is a good one, will let you know when you need more space and bandwidth. Where do I find the best one? You can find the best webhosting company by looking at a review page that compares different hosting companies.

It is your duty to determine your business needs, and know which type of web hosting service best fits your needs. Web hosting services are diverse and varied. It is best to know the reputation of a webhost before you employ their services.

Business Business News
Business Comment
Business Analysis & Features
Market News
Market Epic
Market Heatmaps
Market Screener
Business Directory
ES Business Connections
Create a business profile

This is a necessity as no business would like to be caught in the situation where clients are unable to download information or access the company's website because the bandwidth allocated is exceeded. Nowadays there are tons of webhosting providers providing unlimited bandwidths and unlimited web space. Firstly an ecommerce webhosting should have adequate bandwidth. There are also dedicated servers, VPS solutions too.

So, you may not exactly want to upload your secret drug formula worth millions of dollars on a free web hosting account. The data you want to have on the free web hosting account should ideally be that which you don't care much about, or don't mind losing. It's not exactly very secure. You don't want your data to be put to unintended uses. Efficacy of your data. When you use a free web hosting service, you can't have a great degree of confidence in the efficacy of your data on the free web hosting account.

In fact, these issues without limit sufficient bandwidth, the meaning is clear. So it will be good that next time you're shopping for web hosting services, to remember not only the bandwidth offered by the range of their eyes. When it comes to choosing the web hosting plan, so much to be concerned not only the bandwidth. Server CPU, RAM and the database connection used to transfer files as large as the capacity of bandwidth. Monitor customer feedback server stability, server availability, server load and the use of server resources at a time much about himself.

Before embarking on a search for a WebHostingHub, it is important to set the business goals and objectives. A number of factors need to be considered when selecting a host otherwise you will end up wasting your money and lagging your business behind. Knowing the purpose of the business and its target audience will enable you to identify the measures that should be given emphasis. Once you have determined your business needs, you will be able to know what to expect from the host.

com is a popular website that provides reviews of popular webhosting providers and this gives potential new customers good insight in to what they can expect. You should also read some of the individual reviews, which will provide you valuable insight in to the workings, attitude of the web hosting company towards their clients. If you go a simple google search on 'godaddy reviews' you will find several users of godaddy who have written bad things about them. Godaddy for example has an overall ranking of 3 out of 5.

x300 overflow: visible! skyscraper height:auto! important; /* Collapsing Skyscraper fix */ . important;padding:0px! hide-comment-buttons #singleCommentHeader . skyscraper height:600px! important; 'Biggest cyber-attack in history' slows down internet worldwide after quarrel between web-hosting company and anti-spam group - Home News - UK - The Independent Monday 27 April 2015 hide-comment-buttons #loginButtonContainer display: none; /* Expandable MPU fix */ #side .

If you loved this post and you would like to obtain additional facts concerning servers portugal kindly check out the web site.

You Can Now Contribute Web Development Content

Jafty Interactive Web Development has decided to start accepting user contributed blog posts! You can now submit any post that is related to out blog theme of web development and it will be published after admin moderation. As long as it is on topic and I think it improves the quality of my blog, it will probably be published. Some topics I would like to encourage users to submit posts about include:

  • PHP
  • JavaScript
  • HTML
  • XML
  • CSS
  • Search Engine Optimization/SEO
  • Freelancing as a web developer
  • Freelance writing
  • working from home
  • Laravel
  • WordPress
  • C Languages
  • Java
  • Ruby on rails
  • MySQL Database
  • SQL
  • PHP and MySQL
  • Remote server administration
  • Linux Command Line
  • Linux and Windows Servers
  • MAC and web development
  • PC vs MAC
  • Mobile Development
  • Mobile website optimization
  • PERL
  • AJAX
  • Adwords
  • CURL
  • Graphics
  • anything else related to web development!

That's just a list to fuel your mind. Feel free to submit any related topic. I will accept anything related to web development. I'm looking forward to some great blog posts! - Ian L.

Click Here to Sign Up and Begin Writing!


Troy Warren of LetsTalkBusinessRadio.Com is Scamming for Free online Work

Note: see latest updates at end of this post! Hilarious!

I get so sick of people taking advantage of me online that today I added the "Scams" category to my blog. Troy Warren of LetsTalkBusinessRadio.Com is the client that has motivated me to put up this unfortunate category when he neglected to pay for services rendered by myself. I want to expose people like Troy Warren so it doesn't happen to someone else. If this post prevents one person from working for him and getting ripped off, I'll be glad I posted it. The amount he burned me for was not that much, which makes it a worse scam in many ways because if he was willing to stab me in the back over less than $200, think how quick he would be not to pay someone on a larger job. I don't know this person, Troy, from anywhere but from the client who referred him to me, but he acted like he was a big shot marketer who had plenty of money which caused me to let my guard down a little with him, but regardless, this is just one of many examples of why freelance workers online should always get at least a percentage of their payment up front EVERY TIME. I started out doing a small test project with Troy and accepted a small amount of money upfront before starting. Again I was careful as always with this client, but in the end, he still got me. It is really sad that we have to live in a world with people like Troy that we can never let our guard down in front of, but that seems to be the case. The best advice I can give freelance workers who conduct business over the internet, is to collect as much money up front as possible. I normally won't take on a new client without collecting at least 33% upfront and I try to get half. That way, if I do get ripped of, the sting is a little less than if I were to get taken for the entire project cost. Anyway, this will be the first of many posts on that exposes scammers like Troy to the online world. I may post some of the people that have scammed me in the past here as well if I can find their information. I will post all of Troys info below that I have to help others avoid working for this untrustworthy online predator. I also encourage others to post about people who have scammed them by not paying for services rendered. Let it be known that Troy never had a problem with the work that I did that he mentioned and we had a long conversation over the phone in which I was clear about what I was going to do and what I would charge him, so there was no excuse for him to justify withholding my payment. In fact he kept saying that he would pay it for 3 or 4 weeks in a row and failed to every time even though the agreement we had stated that he would pay on the first Friday after starting the work. I both started and finished before the first Friday and that Friday and every Friday after that, he had a new excuse for why my invoice was not paid. Now, I've heard of bad luck, but if you have time to make up so many excuses, you surely have time to log into PayPal and make the payment! I said this to Troy and he blamed it on his "Bookkeeper" I've never dealt with his bookkeeper before, so I don't know why he thought to blame it on a probably fictional bookkeeper, but that was the gist of most of the excuses. When I asked why he didn't just log into PayPal himself, he kept silent avoiding that question. More to come folks!

If anyone else would like to expose a scammer such as Troy Warren, I have now opened up my site to contributors and any creditable scam report will be published. Simply use the Contribute link in the main nav of this site and sign up to become a blogger and you're in!

Latest Updates

So today is March 18th of 2018,  just over two years after I posted this. I was going through my emails today and found a "Cease and Desist" order supposedly from Trow Warren's attorney or from's attorney. From what I understand about a cease and desist order is that, as long as I have been completely truthful, there isn't much they can do to me. So, I am not going to be intimidated by this cease and desist order and I sent the supposed attorney, Ched Desire an email back. I'll post that email here for your reading pleasure:

Ched Desire,

My statement is not false and I will stand by it 100% and will NOT remove it. I believe that I have not broken any laws in telling the world that this person has not paid me because it is all true. Since it's been up about half a dozen other people have contacted me telling me how Troy has also not paid them for work, so you should consider working for an honest client rather than whatever Troy W. is. Tell him if he doesn't want such comments on the internet then he should pay for the work he hires unsuspecting online workers like myself to do. Thanks for reminding me about him though, I think I'll post some more truths about him online now that he's back on my mind. When my family suffers because he scammed me out of a week's pay check, I feel I have the right to tell anyone who is listening about it!
In fact, has he paid you? Good luck. You'll need it. Also I see you sent this to my service provider, who quite quickly dismissed it, but it seems that you are the one accusing me of doing something that I have not done, I must therefore request that you cease and desist as well.
...Also, how am I supposed to believe that a person like Troy Warren, who scammed me out of a meager few days of pay, can afford to pursue a law suite against me? Wouldn't it be less expensive for him to have simply paid me for my work? Anyway, this just fires me up again about the issue. I have every right in the world to post on my blog regarding the theft of my services by Troy Warren. He can keep his little couple hundred dollars he refused to pay me for the services I provided him because the only thing I hope to accomplish now is to keep him from taking advantage of other hard working online service providers and it seems that my post is accomplishing that, so I have no intentions of ever removing it, nor should I ever. The fact that he does this under a company name simply makes that company look bad.
I do appreciate the reminder to update my posts though. Maybe I'll start a whole new website in Troy's honor! That would be great!
I'm sorry, I'm not the kind of person you can take advantage of and quietly goes away like nothing happened. I will make sure as many people as I can reach out to will hear about this, especially now that he has made this week and futile attempt to intimidate me with legal nonsense.

Good day,

Ian L. Jafty Interactive Web Design
-------------------------------------------------------end emails----------------------------------------------
So, I sort of doubt the Ched Desire person even exists, but if he does, I feel sorry for him for even being associated with Troy Warren. I personally do not think that Troy is above faking this whole cease and desist letter, so I decided to have a little fun with it. If anyone would like to read it, send me a comment and I'll post a link to the pdf.

Making a Mobile App from a WordPress Site

To be competitive in the online market, we all know you need to have a regular website as well as a mobile  website or at least a regular website that is mobile-friendly. Well, these days, that's not enough any longer. You also need to have an app!

The App Era

Why do I need an app when I already have a mobile friendly website?

If you are wondering why you should also have an app, here are some of the more important reasons why you should have an app that features your website in addition to the site itself:

  • We now live in the "era of the apps" or the "app era" as I call it. There are millions of people that use apps everyday but rarely go to their browser to look something up, so by having an app, you expand your viewing audience greatly to a fresh market segment that you would otherwise have no exposure to.
  • Promotion of your website online and in an app store - By making an app out of your already existing mobile website, you can offer it for free in the Google Play Store, Apple/ITunes' App Store and various download locations online.
  • Convenient - since you already have the website made, it's easy to wrap it a native mobile app wrapper with a little know how or you can hire someone to do it for a lot less then the cost of creating a complete app from scratch. Work

Does anyone know if work online editing text is legit? I got an offer to edit email texts for $5 per kb and figure it is probably a scam. Can anyone confirm doing this work and actually being paid? They want you to work for 30 days before paying, so I am skeptical. Also, from Googling it, I can see that others are suspicious, but no one has confirmed it either way. I guess it's a common scam to get people to edit text first and then later they try to get you involved in Paypal and/or credit card scams. I'm waiting for that offer which of course I would not do, but if it was real, it would be nice. Usually when something online seems too good to be true, it is just that, too good to be true and therefore false. I'm interested to hear other's comments though.

From what I've heard, the scam, if it is a scam, goes like this:

1) they hire you to do some simple task like editing emails for a good amount of money($5 per kb) so that means you can make like $60 per hour, if you can type reasonably well, so that's a small red flat right there. This is as far as I've gotten so far. I have edited two emails so far and it took about an hour and I am supposed to be paid $75 for the work, but not for 30 days(red flag no. 2).

2) Then, they will ask you to work as a representative.

3) They will ask you to allow them to transfer money to your paypal account to handle transactions for them for one reason or another saying they can't due to some Paypal issue that they have. HUGE RED FLAG!!!

So, if they try to get me past step one, they will fail, but from what I've heard, others have done this, but with different companies. I've yet to confirm that is doing this scam or if someone claiming to be them is doing it or if it is in fact a scam at all. I suspect it is, but I have not been propositioned yet to do anything other than edit emails, so I will update this blog post if that does or does not indeed happen.

The reason this would be such a huge red flag is because supposedly, is owned by Ebay now. Ebay in turn owns Paypal. So, why would they have any issues with Paypal? They wouldn't. Period! So, while I am 80% sure at the moment that this is a scam, I have not yet confirmed it because I have not been asked to do anything other than correct emails. I suspect I will be asked though...

Update  05/10/2015

After attempting to inquire from my contact named Andrea Nelson, supposedly from, I have come to the conclusion that this is in fact a scam.  I simply stated to her that the work she is having me do is similar to a common scam and could she either, provide me with a verifiable contact phone number to a representative at that would confirm my employment, or, pay me for the first two tasks I had performed. I gave the second option because I know from my experience working online that a legit job will never mind making a small payment to prove they are trustworthy and a scammer will never pay you a dime. The amount I requested was only for $75 and the amount of work they had asked me to do before receiving a pay check would of totaled over $1000, so it was not too much to ask. I normally collect 33% of all jobs I do through without any problem at all, so it is a very good indication of a scam if they are not even willing to pay a fraction of that to prove they are for real. I concluded that this was a scam after she didn't reply for the first time within 24 hours. I'll document anything else that happens here, but I suspect it will be all things I have done to attempt to collect the debt as I don't expect to hear from them for some time.

So far I have only told them that I plan to exercise my right to collect the amount due to me for services rendered within 24 hours after being dismissed from a job according to a little known U.S. law. I sent her a bill via Paypal to the email she has been using to correspond with me to date.

I don't expect her to pay. I expect to have to take further action, which I will just to make a point. I advise anyone that is scammed online to take action in order to help eliminate this inhumane practice.

Please comment on this post if you have experience with or a similar scam... Document it at least! It saves others from getting taken advantage of.


How to Make Xampp Live

This guide explains what you need to do in order to set your XAMPP server on either Windows, Mac or Linux go onto the internet so others can access it online.

I'm writing this tutorial because I could find no easy to follow instructions on how to configure a XAMPP web server to work over the internet live and not just with localhost on your local computer.

How to Setup XAMPP to work Live on the Internet

  1. First we are basically assuming that you have already had XAMPP set up and running on your localhost for local development and that you just need to change it to go live online. If that is not the case and you still need to install XAMPP, go to this site and install it before continuing: Then continue to the next step after you have it working on http://localhost.
  2. Next, go to your router settings admin page and set up port forwarding to the machine that you installed XAMPP on. Usually you can access your router admin by going to and logging in. If you have a netgear router, you can also use as well as to access your router's admin area. I'll include the basic steps for a netgear router here and they should be similar enough for you to figure this out on most other routers, but if you have difficulty, you may need to consult your router's documentation or support to get the exact process for setting up port forwarding. Here are the steps to set up port forwarding on Netgear Routers:
  • Navigate to  in your browser and login using the username and password you set up for your router. If you didn't set it up, the Netgear defaults usually use username "admin" and password "password" so try that before trying to reset the password or calling support if you don't know your username and/or password.
  • Find the local IP address for the computer that has your XAMPP web server installed on it.  As long as you can access the internet from the computer with XAMPP installed on it, you can find the IP address in the Netgear admin by clicking on the "Attached Devices" link in the left navigation bar of the router admin page.
  • Once on the "Attached Devices" page, you should be able to locate your web server computer by it's name or mac address. Write down the IP address for your records and to use in the next steps of this tutorial.
  • Next, to back to your router admin's left navigation menu and click on the link that reads "Port Forwarding / Port Triggering". Then enter the IP address from the previous step into the "Server IP Address" field.
  • Then click the "Service Name" dropdown and select HTTP. After that, click the "Add" button to add the service with your web server's IP address and you are done!

That's pretty much all there is to it as long as your XAMPP was previously working on your localhost. Now go to and make a note of the IP address it gives you because this should be the IP address of your new web server now if everything is working like it should. Go to your browser and type in that IP address and you should now see the same things that you used to see by typing "localhost" into your browser's address bar.

WARNING! This guide doesn't take security into consideration at all. It is meant as a temporary solution to show someone your server online for a brief period of time and then it should be taken offline unless you go through all the necessary steps to tighten the server's security. Then you could keep it online as long as you wish, but security would need to be an entire tutorial by itself. Google it for more information or read how to lock down your server in the XAMPP docs. Good Luck and enjoy your new web server!

How to Pay with a Credit Card through PayPal

A lot if people seem to have a difficult time paying with a credit card when using the PayPal payment gateway in WooCommerce sites. I have wrote this simple tutorial on how to pay with a credit card on my site,, even if you do have a PayPal account but prefer to pay with a credit card. Here are the simple steps to make a credit card payment:

  1.  Go to the product page you wish to purchase. For example: Go to
  2.  Click the "Add to Cart" button.
  3.  In the page's top navigation bar, click on "Checkout".
  4.  To pay with a credit card or with PayPal, fill out all the information on the Checkout page and click the button at the bottom of the page that reads "Proceed to PayPal".
  5.  The PayPal page will look like the following image. If you want to pay with a credit card instead of with PayPal, click the link I have circled in red in the image below.


Please note that on my website,, you DO NOT have to have an account to make a payment, simply go to my shop and select a payment option that equals the amount you wish to pay me.

Subroutines – The Functions of Perl

I used to be foremost a PHP developer. Later, I became a Perl developer. The transition was NOT easy to minimize my experience, but it was tolerable and very interesting. If you love to learn new things, Perl is a great learning experience. I entitled this tutorial "Subroutines, the Functions of Perl" because being a PHP developer first, I was familiar with functions and Perl subroutines act very much like PHP functions. That's just a simple quick way to explain the essence of subroutines to those of you that may know a bit of PHP or even JavaScript or other similar languages that use functions instead.

Perl Subroutine Code Example

As I said, a subroutine is like a function, which is an object and so is a subroutine. It is a way to group together code inside curly brackets and to be able to reuse it later by calling the subroutine similar to the way you would call a function in JavaScript or PHP. Here's an example of a very simple Perl subroutine:

#!/usr/bin/env perl
use strict;
use warnings;
    sub mysubroutine{
    print "This is result of the mysubroutine subroutine...\n";
#Call mysubroutine:

To execute the above code:

  1. save it to a file named
  2. use ftp to upload it to a folder on your server
  3. cd to that directory and type "perl" at your server command prompt.

Here is the result of running the script:



Crash Course on WordPress Plugin Development

Ever wanted to learn how to make a WordPress plugin quickly? Then this crash course on WordPress plugin development should be what you are looking for. In this article, I will demonstrate how to make a simple WordPress plugin in less than 30 minutes.

Plugin Files

First you need to organize your plugin's file structure. A WordPress plugin can either be one single PHP file or many types of files in one directory, but if many, it must still include the main PHP file that defines the plugin. For our first, simple WordPress plugin, we will make a single PHP file plugin to keep it simple.


For this simple plugin, we will name Your Plugin and the PHP file named in traditional plugin format, will be your_plugin.php just for this tutorial. If you were creating an actual plugin that you were going to market, then you would want to check to be sure you have a unique name, but worry about that after you learn the basics;-) Here is the basic content that every plugin's main .php file should start with:

 * Plugin Name: Jafty Plugin
 * Plugin URI:
 * Description: A brief description of how to create a Plugin.
 * Version: 1.0
 * Author: Ian L. of
 * Author URI:
 * License: GPL2

Make sure above file is saved using UTF-8 encoding.

To continue from here and create a plugin that actually does something, follow the below link and finish up a simple plugin:

WordPress Plugin Development – Part 1 Tables



Commands for SED, Unix Stream Editor

What is SED?

"SED" stands for Stream EDitor. SED is a non-interactive editor useful from the Unix command line or for cron jobs I have found. Instead of altering a file interactively with a word processor, the user sends a script of editing instructions to SED along with the name of a file to edit. The text to be edited may also come as output from a pipe. SED works like a filter deleting, inserting and changing characters, words, and lines of text. It is capable of small changes and very complex changes to a file or text. Sed is often used as a find-and-replace tool.

Example SED Commands

Here is collection of one line scripts for SED (Unix stream editor) originally compiled by Eric Pement. I included this in my blog because I have found it a useful edition to my server admin category. SED can be used to do some pretty neat things such as using SED with a cron job to make regular changes to a CSS or .txt file or even HTML!


# double space a file
sed G

# double space a file which already has blank lines in it. Output file
# should contain no more than one blank line between lines of text.
sed '/^$/d;G'

# triple space a file
sed 'G;G'

# undo double-spacing (assumes even-numbered lines are always blank)
sed 'n;d'

# insert a blank line above every line which matches "regex"
sed '/regex/{x;p;x;}'

# insert a blank line below every line which matches "regex"
sed '/regex/G'

# insert a blank line above and below every line which matches "regex"
sed '/regex/{x;p;x;G;}'


# number each line of a file (simple left alignment). Using a tab (see
# note on '\t' at end of file) instead of space will preserve margins.
sed = filename | sed 'N;s/\n/\t/'

# number each line of a file (number on left, right-aligned)
sed = filename | sed 'N; s/^/ /; s/ *\(.\{6,\}\)\n/\1 /'

# number each line of file, but only print numbers if line is not blank
sed '/./=' filename | sed '/./N; s/\n/ /'

# count lines (emulates "wc -l")
sed -n '$='


Find and Replace

Find and replace "foo" with "bar" on each line
sed 's/foo/bar/' # replaces only 1st instance in a line
sed 's/foo/bar/4' # replaces only 4th instance in a line
sed 's/foo/bar/g' # replaces ALL instances in a line
sed 's/\(.*\)foo\(.*foo\)/\1bar\2/' # replace the next-to-last case
sed 's/\(.*\)foo/\1bar/' # replace only the last case

Substitute "foo" with "bar" ONLY for lines which contain "baz"
sed '/baz/s/foo/bar/g'

Substitute "foo" with "bar" EXCEPT for lines which contain "baz"
sed '/baz/!s/foo/bar/g'

Change "scarlet" or "ruby" or "puce" to "red"
sed 's/scarlet/red/g;s/ruby/red/g;s/puce/red/g' # most seds
gsed 's/scarlet\|ruby\|puce/red/g' # GNU sed only

UNIX ENVIRONMENT: convert DOS newlines (CR/LF) to Unix format
sed 's/.$//' # assumes that all lines end with CR/LF
sed 's/^M$//' # in bash/tcsh, press Ctrl-V then Ctrl-M
sed 's/\x0D$//' # works on ssed, gsed 3.02.80 or higher

UNIX ENVIRONMENT: convert Unix newlines (LF) to DOS format
sed "s/$/`echo -e \\\r`/" # command line under ksh
sed 's/$'"/`echo \\\r`/" # command line under bash
sed "s/$/`echo \\\r`/" # command line under zsh
sed 's/$/\r/' # gsed 3.02.80 or higher

DOS ENVIRONMENT: convert Unix newlines (LF) to DOS format
sed "s/$//" # method 1
sed -n p # method 2

DOS ENVIRONMENT: convert DOS newlines (CR/LF) to Unix format
# Can only be done with UnxUtils sed, version 4.0.7 or higher. The
# UnxUtils version can be identified by the custom "--text" switch
# which appears when you use the "--help" switch. Otherwise, changing
# DOS newlines to Unix newlines cannot be done with sed in a DOS
# environment. Use "tr" instead.
sed "s/\r//" infile >outfile # UnxUtils sed v4.0.7 or higher
tr -d \r outfile # GNU tr version 1.22 or higher

Delete leading whitespace (spaces, tabs) from front of each line
# aligns all text flush left
sed 's/^[ \t]*//' # see note on '\t' at end of file

Delete trailing whitespace (spaces, tabs) from end of each line
sed 's/[ \t]*$//' # see note on '\t' at end of file

Delete BOTH leading and trailing whitespace from each line
sed 's/^[ \t]*//;s/[ \t]*$//'

Insert 5 blank spaces at beginning of each line (make page offset)
sed 's/^/ /'

Align all text flush right on a 79-column width
sed -e :a -e 's/^.\{1,78\}$/ &/;ta' # set at 78 plus 1 space

Center all text in the middle of 79-column width. In method 1,
# spaces at the beginning of the line are significant, and trailing
# spaces are appended at the end of the line. In method 2, spaces at
# the beginning of the line are discarded in centering the line, and
# no trailing spaces appear at the end of lines.
sed -e :a -e 's/^.\{1,77\}$/ & /;ta' # method 1
sed -e :a -e 's/^.\{1,77\}$/ &/;ta' -e 's/\( *\)\1/\1/' # method 2

Reverse order of lines (emulates "tac")
# bug/feature in HHsed v1.5 causes blank lines to be deleted
sed '1!G;h;$!d' # method 1
sed -n '1!G;h;$p' # method 2

Reverse each character on the line (emulates "rev")
sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//'

Join pairs of lines side-by-side (like "paste")
sed '$!N;s/\n/ /'

If a line ends with a backslash, append the next line to it
sed -e :a -e '/\\$/N; s/\\\n//; ta'

If a line begins with an equal sign, append it to the previous line
# and replace the "=" with a single space
sed -e :a -e '$!N;s/\n=/ /;ta' -e 'P;D'

Add commas to numeric strings, changing "1234567" to "1,234,567"
gsed ':a;s/\B[0-9]\{3\}\>/,&/;ta' # GNU sed
sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta' # other seds

Add commas to numbers with decimal points and minus signs (GNU sed)
gsed -r ':a;s/(^|[^0-9.])([0-9]+)([0-9]{3})/\1\2,\3/g;ta'

Add a blank line every 5 lines (after lines 5, 10, 15, 20, etc.)
gsed '0~5G' # GNU sed only
sed 'n;n;n;n;G;' # other seds


Print first 10 lines of file (emulates behavior of "head")
sed 10q

Print first line of file (emulates "head -1")
sed q

Print the last 10 lines of a file (emulates "tail")
sed -e :a -e '$q;N;11,$D;ba'

Print the last 2 lines of a file (emulates "tail -2")
sed '$!N;$!D'

Print the last line of a file (emulates "tail -1")
sed '$!d' # method 1
sed -n '$p' # method 2

Print the next-to-the-last line of a file
sed -e '$!{h;d;}' -e x # for 1-line files, print blank line
sed -e '1{$q;}' -e '$!{h;d;}' -e x # for 1-line files, print the line
sed -e '1{$d;}' -e '$!{h;d;}' -e x # for 1-line files, print nothing

Print only lines which match regular expression (emulates "grep")
sed -n '/regexp/p' # method 1
sed '/regexp/!d' # method 2

Print only lines which do NOT match regexp (emulates "grep -v")
sed -n '/regexp/!p' # method 1, corresponds to above
sed '/regexp/d' # method 2, simpler syntax

Print the line immediately before a regexp, but not the line containing the regexp
sed -n '/regexp/{g;1!p;};h'

Print the line immediately after a regexp, but not the line containing the regexp
sed -n '/regexp/{n;p;}'

Print 1 line of context before and after regexp, with line number indicating where the regexp occurred (similar to "grep -A1 -B1")
sed -n -e '/regexp/{=;x;1!p;g;$!N;p;D;}' -e h

grep for AAA and BBB and CCC (in any order)
sed '/AAA/!d; /BBB/!d; /CCC/!d'

grep for AAA and BBB and CCC (in that order)
sed '/AAA.*BBB.*CCC/!d'

grep for AAA or BBB or CCC (emulates "egrep")
sed -e '/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d # most seds
gsed '/AAA\|BBB\|CCC/!d' # GNU sed only

Print paragraph if it contains AAA (blank lines separate paragraphs)
# HHsed v1.5 must insert a 'G;' after 'x;' in the next 3 scripts below
sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;'

Print paragraph if it contains AAA and BBB and CCC (in any order)
sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;/BBB/!d;/CCC/!d'

Print paragraph if it contains AAA or BBB or CCC
sed -e '/./{H;$!d;}' -e 'x;/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d
gsed '/./{H;$!d;};x;/AAA\|BBB\|CCC/b;d' # GNU sed only

Print only lines of 65 characters or longer
sed -n '/^.\{65\}/p'

Print only lines of less than 65 characters
sed -n '/^.\{65\}/!p' # method 1, corresponds to above
sed '/^.\{65\}/d' # method 2, simpler syntax

Print section of file from regular expression to end of file
sed -n '/regexp/,$p'

Print section of file based on line numbers (lines 8-12, inclusive)
sed -n '8,12p' # method 1
sed '8,12!d' # method 2

Print line number 52
sed -n '52p' # method 1
sed '52!d' # method 2
sed '52q;d' # method 3, efficient on large files

Beginning at line 3, print every 7th line
gsed -n '3~7p' # GNU sed only
sed -n '3,${p;n;n;n;n;n;n;}' # other seds

Print section of file between two regular expressions (inclusive)
sed -n '/Iowa/,/Montana/p' # case sensitive


Print all of file EXCEPT section between 2 regular expressions
sed '/Iowa/,/Montana/d'

Delete duplicate, consecutive lines from a file (emulates "uniq")
# First line in a set of duplicate lines is kept, rest are deleted.
sed '$!N; /^\(.*\)\n\1$/!P; D'

Delete duplicate, nonconsecutive lines from a file. Beware not to overflow the buffer size of the hold space, or else use GNU sed
sed -n 'G; s/\n/&&/; /^\([ -~]*\n\).*\n\1/d; s/\n//; h; P'

Delete all lines except duplicate lines (emulates "uniq -d")
sed '$!N; s/^\(.*\)\n\1$/\1/; t; D'

Delete the first 10 lines of a file
sed '1,10d'

Delete the last line of a file
sed '$d'

Delete the last 2 lines of a file
sed 'N;$!P;$!D;$d'

Delete the last 10 lines of a file
sed -e :a -e '$d;N;2,10ba' -e 'P;D' # method 1
sed -n -e :a -e '1,10!{P;N;D;};N;ba' # method 2

Delete every 8th line
gsed '0~8d' # GNU sed only
sed 'n;n;n;n;n;n;n;d;' # other seds

Delete lines matching pattern
sed '/pattern/d'

Delete ALL blank lines from a file (same as "grep '.' ")
sed '/^$/d' # method 1
sed '/./!d' # method 2

Delete all CONSECUTIVE blank lines from file except the first. Also deletes all blank lines from top and end of file (emulates "cat -s")
sed '/./,/^$/!d' # method 1, allows 0 blanks at top, 1 at EOF
sed '/^$/N;/\n$/D' # method 2, allows 1 blank at top, 0 at EOF

Delete all CONSECUTIVE blank lines from file except the first 2
sed '/^$/N;/\n$/N;//D'

Delete all leading blank lines at top of file
sed '/./,$!d'

Delete all trailing blank lines at end of file
sed -e :a -e '/^\n*$/{$d;N;ba' -e '}' # works on all seds
sed -e :a -e '/^\n*$/N;/\n$/ba' # ditto, except for gsed 3.02.*

Delete the last line of each paragraph
sed -n '/^$/{p;h;};/./{x;/./p;}'


Remove nroff overstrikes (char, backspace) from man pages

(The 'echo' command may need an -e switch if you use Unix System V or bash shell)
sed "s/.`echo \\\b`//g" # double quotes required for Unix environment
sed 's/.^H//g' # in bash/tcsh, press Ctrl-V and then Ctrl-H
sed 's/.\x08//g' # hex expression for sed 1.5, GNU sed, ssed

Get Usenet/e-mail message header
sed '/^$/q' # deletes everything after first blank line

Get Usenet/e-mail message body
sed '1,/^$/d' # deletes everything up to first blank line

Get Subject header, but remove initial "Subject: " portion
sed '/^Subject: */!d; s///;q'

Get return address header
sed '/^Reply-To:/q; /^From:/h; /./d;g;q'

Parse out the address proper. Pulls out the e-mail address by itself
# from the 1-line return address header (see preceding script)
sed 's/ *(.*)//; s/>.*//; s/.*[:<] *//' # add a leading angle bracket and space to each line (quote a message) sed 's/^/> /'

Delete leading angle bracket & space from each line (unquote a message)
sed 's/^> //'

Remove most HTML tags (accommodates multiple-line tags)
sed -e :a -e 's/<[^>]*>//g;/zipup.bat
dir /b *.txt | sed "s/^\(.*\)\.TXT/pkzip -mo \1 \1.TXT/" >>zipup.bat


Sed takes one or more editing commands and applies all of
them, in sequence, to each line of input. After all the commands have
been applied to the first input line, that line is output and a second
input line is taken for processing, and the cycle repeats. The
preceding examples assume that input comes from the standard input
device (i.e, the console, normally this will be piped input). One or
more filenames can be appended to the command line if the input does
not come from stdin. Output is sent to stdout (the screen). Thus:

cat filename | sed '10q' # uses piped input
sed '10q' filename # same effect, avoids a useless "cat"
sed '10q' filename > newfile # redirects output to disk

For additional syntax instructions,  the manual ("man") pages on Unix systems may be helpful. Try "man sed", "man regexp", or the subsection on regular expressions in "man

QUOTING SYNTAX: The preceding examples use single quotes ('...')
instead of double quotes ("...") to enclose editing commands, since
sed is typically used on a Unix platform. Single quotes prevent the
Unix shell from intrepreting the dollar sign ($) and backquotes
(`...`), which are expanded by the shell if they are enclosed in
double quotes. Users of the "csh" shell and derivatives will also need
to quote the exclamation mark (!) with the backslash (i.e., \!) to
properly run the examples listed above, even within single quotes.
Versions of sed written for DOS invariably require double quotes
("...") instead of single quotes to enclose editing commands.

USE OF '\t' IN SED SCRIPTS: For clarity in documentation, we have used
the expression '\t' to indicate a tab character (0x09) in the scripts.
However, most versions of sed do not recognize the '\t' abbreviation,
so when typing these scripts from the command line, you should press
the TAB key instead. '\t' is supported as a regular expression
metacharacter in awk, perl, and HHsed, sedmod, and GNU sed v3.02.80.

VERSIONS OF SED: Versions of sed do differ, and some slight syntax
variation is to be expected. In particular, most do not support the
use of labels (:name) or branch instructions (b,t) within editing
commands, except at the end of those commands. We have used the syntax
which will be portable to most users of sed, even though the popular
GNU versions of sed allow a more succinct syntax. When the reader sees
a fairly long command such as this:

sed -e '/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d

It is heartening to know that GNU sed will let you reduce it to:

sed '/AAA/b;/BBB/b;/CCC/b;d' # or even
sed '/AAA\|BBB\|CCC/b;d'

In addition, remember that while many versions of sed accept a command
like "/one/ s/RE1/RE2/", some do NOT allow "/one/! s/RE1/RE2/", which
contains space before the 's'. Omit the space when typing the command.

OPTIMIZING FOR SPEED: If execution speed needs to be increased (due to
large input files or slow processors or hard disks), substitution will
be executed more quickly if the "find" expression is specified before
giving the "s/.../.../" instruction. Thus:

sed 's/foo/bar/g' filename # standard replace command
sed '/foo/ s/foo/bar/g' filename # executes more quickly
sed '/foo/ s//bar/g' filename # shorthand sed syntax

On line selection or deletion in which you only need to output lines
from the first part of the file, a "quit" command (q) in the script
will drastically reduce processing time for large files. Thus:

sed -n '45,50p' filename # print line nos. 45-50 of a file
sed -n '51q;45,50p' filename # same, but executes much faster

Building a Responsive Navigation Menu

In today's blog post, I'm going to demonstrate how to make a horizontal responsive navigation menu anywhere on your webpage. This tutorial also demonstrates how to make a completely responsive web site if you follow it through. Here is a link to the final product:

If you want a vertical responsive menu, you can adapt the code accordingly yourself. I am posting this here for reference because it seems like every time I have to do this for a responsive website, I have to relearn it. Now myself and anyone else that needs the technique can find it right here. Another appropriate title for this tutorial could have been how to make a responsive image map since that is what led me to doing this in the first place.

Using Divs Instead of Image Maps

While this tutorial is technically about doing a navigation menu, this exact same method can be used in place of image maps because, if you've tried to make a responsive page that has an image map in it, you know it doesn't work well.

Building a Responsive Nav

First, lets' build our HTML:

<link rel="stylesheet" type="text/css" href="mystyle.css">
<div id="page">
<div id="header-menu-overlay">
<img src="topnav0map.png" style="width:100%;"  border="0" alt="top navigation menu"/>
        <div><a href=""></a></div>

To follow along with the tutorial, copy and paste the above code into a new notepad document and save it as test.html. The first div includes an img tag in it as you can see above. Here is the actual image to give you a better idea of what I have done here. So "topnav0map.png" refers to the following image:


Again, if you're following along, right click on the above image and save it to the same directory as your test.html file. I put the image in a blue background here so you can see it because it is mostly white over a transparent layer done in Photoshop. The reason I use an image here is because it is responsive when you set the width to 100% and height to auto. This is about when I got the idea for an image map to link the items in the nav as you see them in the above image, but quickly found out that image maps do not resize well when changing either the page size or the zoom level when looking at the page live. therefore I used divs as they are more responsive when used properly with percentages as you'll see below when I get to the CSS part.

Responsive CSS Layout

The most important part is probably the responsive CSS code. Here is what I used:

margin:0 auto;

position: absolute;
top: 100px;
width: 100%;
min-height: 30px;
text-align: center;
z-index: 99999;
position: relative;

border: 1px solid brown;
margin:0 auto;

position: relative;
border: 1px solid red;
height: 33px;
display: block;
float: left;
z-index: 999;

.nav_item a{
width: 100%;
height: 100%;
position: relative;
display: block;

width: 7%;
margin-left: 9%;

width: 10%;
margin-left: 1%;

width: 10%;
margin-left: 1%;

width: 20%;
margin-left: 1%;

width: 19%;
margin-left: 1%;

width: 10%;
margin-left: 1%;

min-width: 225px;
margin:0 auto;

First, I used the "page" div as a page wrapper by setting a standard 900px width which you may adjust to your needs. I also set width to 100% which is very important for responsive designs, but also notice the max-width is set to 900px this is so your page won't go crazy-wide when you open a large browser window on a PC. If you want to always cover the width of the screen regardless, then you could remove this, but I recommend using a maximum width myself for most scenarios. Next I'll include a short description for each CSS declararation after "page" which I just explained:

  • header_menu_overlay - is used to position the overall navigation menu where you want. You'll see I decided to put it a hundred pixels from the top of the page, but you can put yours wherever you need it even at the bottom of the page for a footer menu if that's what you need. the header-menu-overlay div is the one that holds the image as well as the rest of navigation divs. Be sure to set the width only of the image in this div and set that width to 100% so it is responsive.
  • navwrap - is the div that wraps the other divs we will use for our links. we set it's position to relative and top to a negative number to force it on top of the image above it.
  • nav_item_wrap - wraps around the individual menu items and has a margin of "0 auto" so it centers the group of menu items to the rest of the page nicely.
  • nav_item - this class is set to all of the navigation item divs and is used to set their height, display and to float them left which is important for responsiveness.
  • nav_item a - is a style definition for the anchor/link tags inside of the nav_item div. Without this the links will not work. It sets the width and height to 100% of the containing element. You have to set "position: relative", width and height for this to work.
  • nav1 - nav6 - the next six CSS declarations are used to set each individual menu item's width and margin-left properties since they can all be different.

Add CSS Classes & Content to HTML:

Okay now we just need to add the classes above in the proper spots in our original HTML code and add some content for each page so that your new HTML page  looks like this:

<!DOCTYPE html>
<link rel="stylesheet" type="text/css" href="mystyle.css">
<div id="page">
<div id="header_menu_overlay">
<img src="topnav0map.png" style="width:100%;"  border="0" alt="top navigation menu"/>
<div class="navwrap">
<div class="nav_item_wrap">
<div class="nav_item nav1"><a href="#pg1"></a></div>
<div class="nav_item nav2"><a href="#pg2"></a></div>
<div class="nav_item nav3"><a href="#pg3"></a></div>
<div class="nav_item nav4"><a href="#pg4"></a></div>
<div class="nav_item nav5"><a href="#pg5"></a></div>
<div class="nav_item nav6"><a href="#pg6"></a></div>

<div class="pg"><a name="pg1">page 1</a>
<h1>Place all of your page 1 content here...</h1>

<div class="pg"><a name="pg2">page 2</a>
<h1>Place all of your page 2 content here...</h1>

<div class="pg"><a name="pg3">page 3</a>
<h1>Place all of your page 3 content here...</h1>

<div class="pg"><a name="pg4">page 4</a>
<h1>Place all of your page 4 content here...</h1>

<div class="pg"><a name="pg5">page 5</a>
<h1>Place all of your page 5 content here...</h1>

<div class="pg"><a name="pg6">page 6</a>
<h1>Place all of your page 6 content here...</h1>

Now you should be done and you have a completely responsive website in no time at all! You should go back and remove the borders from the navigation menu's CSS as those were just for demonstration.


So if you followed this tutorial, you should have learned quite a bit about responsive design. Not only should you be able to grasp how to develop a navigation menu from this article, but you should now be able to understand how to replace an inline image map with responsive divs and even how to make an entire responsive website using the techniques demonstrated here. Remember to use percentages instead of pixels for widths and even heights wherever you can and your design will be responsive and evenly laid out for all devices. Congratulations, you are now a responsive developer if you understood all of this. Good Luck!

View outcome of tutorial here: