WordPress Custom Image Field in 80 lines

You need nearly 80 lines to add a custom file field to post edit screen (and create screen). There are some situations where it’s necessary to have more than one post image, for example if you want to have a separate image of facebook sharing (og:image).

The examples i found online are a bit complicated and often do more than just adding an image field, so here is the minimal code to do just add the field and save the image-url to post-meta.

Adding the field to admin is still simple and done in bohuco_edit_post and bohuco_image functions. There are two actions used, one for edit and the other for creating new posts. The bohuco_image formats the html for the form field, for this example i made it very simple.

 
    function bohuco_edit_post($post_id) {
        add_meta_box('bohuco_customImage', 'Custom Image', 'bohuco_image', 'post', 'normal', 'high' );
    }
    add_action('load-post.php', 'bohuco_edit_post');
    add_action('load-post-new.php', 'bohuco_edit_post');
 
    function bohuco_image($post, $field) {
        wp_nonce_field(plugin_basename(__FILE__), '_wpnonce_bohuco');
 
        if (! $value = get_post_meta($post->ID, $field['id'], true)) {
            $value = '';
        }
 
        echo '<input type="file" name="'.$field['id'].'_upload" size="55" /><br />';
        if ($value) {
            echo '<img src="'.$value.'" />';
        }
    }

Saving happens in bohuco_save_post where first the upload is done with build-in wordpress function wp_handle_upload, after that the url of the uploaded image is saved to a meta field (add_post_meta or update_post_meta). The overrides array holds some configuration for wp_handle_upload, the test_form must be false because it checks if the default upload action is used.

 
    function bohuco_save_post($postId) {
 
        if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
            return $postId;
        }
 
        if(isset($_FILES['bohuco_customImage_upload']['name'])
            && ! empty($_FILES['bohuco_customImage_upload']['name'])) {
 
            if (! wp_verify_nonce($_REQUEST['_wpnonce_bohuco'], plugin_basename(__FILE__))) {
                die('Security check'); 
            }
 
            $overrides = array('test_form'=>false);
            $result = wp_handle_upload($_FILES['bohuco_customImage_upload'], $overrides);
 
            if(isset($result['error']) && ! empty($result['error'])) {
                echo '<div class="error">'.$result['error'].'</div>';
            } else {
                $imageFileLocation = $result['url'];
                if (! update_post_meta($postId, 'bohuco_customImage', $imageFileLocation)) {
                    add_post_meta($postId, 'bohuco_customImage', $imageFileLocation, true);
                }                
            }
        }
    }
    add_action('save_post', 'bohuco_save_post');

This all works only if you first change the editor form enctype to multipart/form-data as you can see in add_post_enctype function. It’s a hack but it works, maybe there is a better method to change the post form tag?

 
    function add_post_enctype() {
        echo "<script type='text/javascript'>
                  jQuery(document).ready(function(){
                      jQuery('#post').attr('enctype','multipart/form-data');
                  });
              </script>";
    }
    add_action('admin_head', 'add_post_enctype');

Here is the whole example as little plugin, it should also work if you put it in a functions.php of a theme. I build it in wordpress 3.8 but should also work in older versions.

/*
Plugin Name: Custom Image Field
Plugin URI: http://bohuco.net/blog
Version: 1.0.0
Author: @DerFichtl
*/
 
if (is_admin()) {
 
    /**
     * Modify form enctype to support uploads
     */
    function add_post_enctype() {
        echo "<script type='text/javascript'>
                  jQuery(document).ready(function(){
                      jQuery('#post').attr('enctype','multipart/form-data');
                  });
              </script>";
    }
    add_action('admin_head', 'add_post_enctype');
 
    /**
     * Add custom field to new post and edit post screen
     */
    function bohuco_edit_post($post_id) {
        add_meta_box('bohuco_customImage', 'Custom Image', 'bohuco_image', 'post', 'normal', 'high' );
    }
    add_action('load-post.php', 'bohuco_edit_post');
    add_action('load-post-new.php', 'bohuco_edit_post');
 
    /**
     * Format the field html and output image if present
     */
    function bohuco_image($post, $field) {
        wp_nonce_field(plugin_basename(__FILE__), '_wpnonce_bohuco');
 
        if (! $value = get_post_meta($post->ID, $field['id'], true)) {
            $value = '';
        }
 
        echo '<input type="file" name="'.$field['id'].'_upload" size="55" /><br />';
        if ($value) {
            echo '<img src="'.$value.'" />';
        }
    }
 
    /**
     * Do upload and save custom meta field 
     */
    function bohuco_save_post($postId) {
 
        if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
            return $postId;
        }
 
        if(isset($_FILES['bohuco_customImage_upload']['name'])
            && ! empty($_FILES['bohuco_customImage_upload']['name'])) {
 
            if (! wp_verify_nonce($_REQUEST['_wpnonce_bohuco'], plugin_basename(__FILE__))) {
                die('Security check'); 
            }
 
            $overrides = array('test_form'=>false);
            $result = wp_handle_upload($_FILES['bohuco_customImage_upload'], $overrides);
 
            if(isset($result['error']) && ! empty($result['error'])) {
                echo '<div class="error">'.$result['error'].'</div>';
            } else {
                $imageFileLocation = $result['url'];
                if (! update_post_meta($postId, 'bohuco_customImage', $imageFileLocation)) {
                    add_post_meta($postId, 'bohuco_customImage', $imageFileLocation, true);
                }                
            }
        }
    }
    add_action('save_post', 'bohuco_save_post');
}

Things to improve would be: 1. Check if the uploaded file is an image, example works with all files allowed by wordpress. 2. Create a thumbnail of the image. 3. The save function is called twice if a new post is saved.

New on GitHub: Game Engine for Text Games

My Waiting Game Engine (WGE) is an simple php-engine for online browser games where the main task is to wait.

For each second you wait you get some money (depends on your level) and with money you can do/buy things. You can then combine the things and do more and more actions. For each action you earn experience (or lost some if you do the wrong action). And so on, and so on. More infos on GitHub.

Test a waiting game:
http://bohuco.net/waiting-game-engine/

Source code on GitHub:
https://github.com/DerFichtl/waiting-game-engine

 

How to Licence Apple Fonts for Web Usage

… not so easy as first thought: Buy a “Web-Licence” or “Web-Font” and use it on your page … thats not possible with apple fonts.

If you want browsersafe use one of more than 300 adobe webfonts like myriad, garamond or juniper you have to do it via typekit or webink. Just this two vendors can sell web licences for apple fonts.

 

Both services are easy to use: Just select the fonts you want to use and then insert the provided snippet in your webpage. Typekit uses javascript to deliver the font, webink do it with css-tag. So i like the webink delivery version more.

<!-- html head -->
<link href="http://fnt.webink.com/wfs/webink.css/
    ?project=CD0700EA-B4D9-4AFA-A52E-1F3AB19287CF
    &fonts=73E6C83D-7F13-A8AE-4770-C315AE5061C3:f=MyriadPro-Regular" rel="stylesheet" type="text/css"/>
/* in css */
@import url("http://fnt.webink.com/wfs/webink.css/
    ?project=CD0700EA-B4D9-4AFA-A52E-1F3AB19287CF
    &amp;fonts=73E6C83D-7F13-A8AE-4770-C315AE5061C3:f=MyriadPro-Regular");

The pricing is based  on website usage … typekit on pageviews and webink on unique users. The prices goes from free to 120 USD per year for larger websites. More Infos you can find on the Adobe web fonts site.

New Bootstrap Version by Twitter

Today Twitter released a new version of their popular html/css boilerplate for webpages. A good time to introduce my favorite bootstrap features …

1. Icons, Icons, Icons

Bootstrap includes a fat icon sprite with 120 small icons from glyphicons.com. all have transparent background and are available in black and in white.

2. Inline Labels

Put some highlights in your texts with inline labels.

3. Real Button Porn

Buttons in different colors, with and without dropdown and in groups or lonely.

… and what is your favorite feature from twitter bootstrap?

WordPress Quicky: Exclude Categories

Another quicktipp for wordpress theme developers.

If you want to exclude one or more categories from a page (startpage, category-page), you can call the query_posts function with negative category-ids …

<?php query_posts($query_string . '&cat=-1,-2,-3'); ?>
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
    <!-- POST -->
<?php endwhile; endif; ?>

Google Ranking Checker Class in PHP

Important notice: Check google rankings become a very complicated task today. So many environment variables are important so that this simple ranking checker class don’t work any more. But there are some commercial tools that can still track your rankings like sistrix or seolytics.

The only goal for an SEO is a good or very good google ranking. To ensure this you have to monitor your rankings and compare it to the positions of your competitors. With the Google AJAX Search API and my little PHP Class you can easy build a Google Ranking Checker …

The class needs an Google API key for the AJAX Search API (get it here) … it’s just one field and a click and you can start. You can check multiple keywords for multiple domains or urls, just pass this two arrays to the check() method.

Continue reading Google Ranking Checker Class in PHP