The time when WordPress was used mainly as a blog engine has passed and WordPress has become one of the most powerful Content Management Systems on the web because of using custom post fields.

Custom post types allows flexibility and give enormous power to WordPress. Usually, we use custom post types with built-in fields like excerpt, content editor, thumbnail etc.

But often, we need some special type of fields for dealing with customer wishes like date picker, relationships, file upload etc.

This is where Advanced Custom Fields plugin comes in.

Advanced custom post fields overview

The Advanced Custom Fields Plugin gives you the tools to create your own custom edit screens. It’s a must have for any WordPress developer. Custom post fields types include: Wysiwyg, text, textarea, image, file, select, checkbox, page link, post object, date picker, repeater …

Advanced Custom Fields Plugin provides a simple to use interface allowing you to create, edit, reorder and completely customize your edit screens.

With Advanced Custom Fields Plugin it is not only possible to create new fields, but to hide WordPress’s default fields as well.

Installing the plugin

Installation is the same as for any WordPress plugin

  1. Download Advanced Custom Fields plugin
  2. Upload ‘advanced-custom-fields’ to the ‘/wp-content/plugins/’ directory
  3. Activate the plugin through the ‘Plugins’ menu in WordPress
  4. You may be prompted for a Database Upgrade. This is necessary for ACF to function. Please backup your database and click the Upgrade button

Usage

Once the plugin is uploaded and activated, go to Settings and click on the Adv Custom Fields link and then “Add New”. You can then give a name to your new set of fields (for example “Columns”) and add as many types of custom fields as you want. Currently supported types are:

  • Text
  • Text area
  • WYSIWYG Editor
  • Image
  • File
  • Select
  • Checkbox
  • Radio Button
  • True / False
  • Page Link
  • Post Object
  • Relationship
  • Date Picker
  • Repeater (it costs $25)

Advanced Custom Fields interface is very intuitive and it is very simple to add custom fields groups and assign them to what ever you want. You can decide what Pages, Posts or Custom Post Types you want to have this new set of Custom Fields. For example, you could have all Pages, or all Posts, or only a specific page (for example Home), or all posts in a certain category:

Advanced Custom Fields options page

Advanced Custom Fields also lets you decide what other fields are available on the page. So you can remove the Content Editor, Slug, Author etc and control that and you new fields all from one place.

Advanced Custom Post Fields

Advanced Custom Fields API

Plugin also have a powerful API for dealing with your fields. For example, to display a field on the theme inside a loop:

[code lang=”php”]
<p><?php the_field(‘field_name’); ?></p>
[/code]

More about the API can be read on Plugin’s official documentation page.

Extending the plugin

Now, you may think that all this is enough. Well, for an average developer it should be. But, if you want to make some really cool types of fields, you can. That is the beauty of this powerful plugin.

I am going to show you how easy it is to make your own custom post field on a real life example. At the end of this tutorial, you can download custom post field type shown here.

The problem

Your customer wants to enter Events into WordPress and wants to select a location of the event by simply clicking on Google Map.

Making the Events custom post type

To make this work, we need a custom post type named Events in which our customer will enter data. First, let us see what data will be needed:

  • Title
  • Image
  • Description
  • Date
  • Time
  • Location – shown on Google Maps

Let’s begin by making this post type. Open your theme’s functions.php and enter this in:

[code lang=”php”]
function eventRegister()
{
$labels = array(
‘name’ => _x(‘Events’, ‘post type general name’),
‘singular_name’ => _x(‘Event’, ‘post type singular name’),
‘add_new’ => _x(‘Add New’, ‘portfolio item’),
‘add_new_item’ => __(‘Add New Event’),
‘edit_item’ => __(‘Edit Event’),
‘new_item’ => __(‘New Event’),
‘view_item’ => __(‘View Event’),
‘search_items’ => __(‘Search Events’),
‘not_found’ => __(‘Nothing found’),
‘not_found_in_trash’ => __(‘Nothing found in Trash’),
‘parent_item_colon’ => ”
);

$args = array(
‘labels’ => $labels,
‘public’ => true,
‘publicly_queryable’ => true,
‘show_ui’ => true,
‘query_var’ => true,
‘capability_type’ => ‘post’,
‘hierarchical’ => false,
‘menu_position’ => null,
‘supports’ => array(‘title’, ‘editor’, ‘thumbnail’),
‘rewrite’ => true,
‘show_in_nav_menus’ => true,
);

register_post_type(‘event’ , $args);
}

add_action(‘init’, ‘eventRegister’);
[/code]

Save functions.php and go to WordPress admin dashboard. You will see newly created Custom Post type in the left hand menu. Wow, that was easy.

Click on Add Event and you will see something similar to this:

Add events custom post type

You can enter title, description and thumbnail image. Now, open your Advanced Custom Fields under Settings and click Add new. We will add other fields into field group called Events and it should look like this:

Advanced custom fields - field group

If you go to Add Event page now, you should see that you can now pick an event date and enter a time.

Wow, that was really easy. Now comes the hard part.

Making our own custom field type

Author of this great plugin has made our lives easier and give us a Class template for making our own custom field types for ACF. Download it here, unpack it and place it inside your active theme. I prefer to create a fields folder in my theme’s root and put this template in it.

Now rename this file to location.php. Open it up in your editor and rename the class, the name variable and the title:

[code lang=”php”]
class Location_field extends acf_Field
{
function __construct($parent)
{
// do not delete!
parent::__construct($parent);

// set name / title
$this->name = ‘location’; // variable name (no spaces / special characters / etc)
$this->title = __("Location",’acf’); // field label (Displayed in edit screens)

} …
[/code]

Next, we must register this field so ACF plugin will know about it. Open your theme’s functions.php and enter this anywhere:

[code lang=”php”]
register_field(‘Location_field’, dirname(__FILE__) . ‘/fields/location.php’);
[/code]

This function will register our field in the ACF. It has 2 parameters, the first is our Class name and the second is the path to the Class file.

If you go to Advanced Custom Fields Settings, you should see Location in the drop down:

Location field in the drop down

Next thing we are going to do is create our Latitude and Longitude field that will be shown on edit screen and populated with values from Google Map.

For this, we will need create_field function inside our location.php file:

[code lang=”php”]
function create_field($field)
{
echo ‘<input type="text" value="’ . $field[‘value’] . ‘" id="’ . $field[‘name’] . ‘" class="’ . $field[‘class’] . ‘" name="’ . $field[‘name’] . ‘" />’;
echo ‘<div id="map"></div>’;
}
[/code]

Save this file and go add Location field to field group inside ACF settings and Update. Now, go to entering new Event and you will see our Location text field. Everything is working, field gets saved to database. Basically, we recreated the text field.

Adding Google Map

Next task is to add a Google Map and some Google Map API, so when the user clicks on the map, we will get the Latitude and Longitude of that point and fill our Location field with it.

For this use, we will use admin_head function, which is great for inserting CSS and JavaScript:

[code lang=”php”]
function admin_head()
{
?>
<style type="text/css">
#map {width: 100%; height: 500px; margin-top: 10px;}
</style>
<script src=’http://maps.googleapis.com/maps/api/js?sensor=false’ type=’text/javascript’></script>
<script type="text/javascript">
function load() {
var exists = 0, marker;
// get the lat and lng from our input field
var coords = jQuery(‘.location’).val();
// if input field is empty, default coords
if (coords === ”) {
lat = 45.77598686952638;
lng = 15.985933542251587;
} else {
// split the coords by ;
temp = coords.split(‘;’);
lat = parseFloat(temp[0]);
lng = parseFloat(temp[1]);
exists = 1;
}
// coordinates to latLng
var latlng = new google.maps.LatLng(lat, lng);
// map Options
var myOptions = {
zoom: 8,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
//draw a map
var map = new google.maps.Map(document.getElementById("map"), myOptions);

// if we had coords in input field, put a marker on that spot
if(exists == 1) {
marker = new google.maps.Marker({
position: map.getCenter(),
map: map,
draggable: true
});
}

// click event
google.maps.event.addListener(map, ‘click’, function(point) {
if (exists == 0) {
exists = 1;
// drawing the marker on the clicked spot
marker = new google.maps.Marker({
position: point.latLng,
map: map,
draggable: true
});
//put the coordinates to input field
jQuery(‘.location’).val(marker.getPosition().lat() + ‘;’ + marker.getPosition().lng());
// drag event for add screen
google.maps.event.addListener(marker, "dragend", function (mEvent) {
jQuery(‘.location’).val(mEvent.latLng.lat() + ‘;’ + mEvent.latLng.lng());
});
} else {
// only one marker on the map!
alert(‘Marker already on the map! Drag it to desired location.’);
}
});
//dragend event for update screen
if(exists === 1) {
google.maps.event.addListener(marker, "dragend", function (mEvent) {
jQuery(‘.location’).val(mEvent.latLng.lat() + ‘;’ + mEvent.latLng.lng());
});
}
}

jQuery(document).ready(function(){
load();
});
</script>

<?php
}
[/code]

There is plenty of comments above in the code, so everything is self explanatory.

When you go to add new Event, you will now see a Google Map below your Location field. When you click on a map, Lat and Long coordinates will be filled into your Location field. You can even drag a marker on a map to change the location! How cool is that?

Now, all we have to do is to show this Event in our theme, along with a Google Map.

Showing the location in the theme

Actually, it is very easy to show the coordinates we entered in our event in the theme. Advanced Custom Fields has a great API for that.

To use the coordinates, just enter this inside your WordPress loop:

[code lang=”php”]
the_field(‘location’);
[/code]

But, I want to show this coordinates in a map. So create a single-event.php file in your theme’s folder and enter something like this (this is just the content inside a single post loop for TwentyEleven Theme):

[code lang=”php”]
<div class="entry-content">
<?php the_content(); ?>
<p>Date of the event: <?php the_field(‘date’); ?> <?php the_field(‘time’); ?></p>
<div id="map" style="width: 500px; height: 350px;"></div>
<?php
$location = get_field(‘location’);
$temp = explode(‘;’, $location);
$lat = (float) $temp[0];
$lng = (float) $temp[1];
?>
<script src=’http://maps.googleapis.com/maps/api/js?sensor=false’ type=’text/javascript’></script>
<script type="text/javascript">
//<![CDATA[
function load() {
var lat = <?php echo $lat; ?>;
var lng = <?php echo $lng; ?>;
// coordinates to latLng
var latlng = new google.maps.LatLng(lat, lng);
// map Options
var myOptions = {
zoom: 9,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
//draw a map
var map = new google.maps.Map(document.getElementById("map"), myOptions);
var marker = new google.maps.Marker({
position: map.getCenter(),
map: map
});
}
// call the function
load();
//]]>
</script>
<?php wp_link_pages( array( ‘before’ => ‘<div class="page-link"><span>’ . __( ‘Pages:’, ‘twentyeleven’ ) . ‘</span>’, ‘after’ => ‘</div>’ ) ); ?>
</div><!– .entry-content –>
[/code]

Or, you can make a page with events and one map that will show all your events. What ever you want, is achievable now.

Conclusion

WordPress is a very powerful tool and stuff described above, makes it even more powerful. Your imagination is the limit.

Demo
Don’t hesitate to share your thoughts or ask a question below.