Carbon fields is a library for easy creation of custom(meta) fields in WordPress administration panel. It allows theme developer to associate meta-information with various entities in a WordPress site(such as posts, taxonomy terms, widgets and so on).
The main components of the library are:
Carbon Container is a group of custom fields and display options. Containers are displayed on different parts of the backend, according to their type and display options.
Containers have a title, which must be unique across the whole WordPress instance.
Carbon_Container::factory('custom_fields', 'Custom Data') ->show_on_post_type('page') ->add_fields(array( Carbon_Field::factory('map', 'location')->set_position(37.423156, -122.084917, 14), Carbon_Field::factory('choose_sidebar', 'custom_sidebar'), Carbon_Field::factory('image', 'Photo'), ));
To create a new Carbon Container, you just use the container factory methodCarbon_Container::factory($type, $title)
, where:
$type
custom_fields
and theme_options
)$title
Custom field containers are used to extend the post edit screens with additional fields. Field data is stored separately for each post as post meta (see add_post_meta).
Carbon_Container::factory('custom_fields', 'Post Properties') ->add_fields(array( Carbon_Field::factory('map', 'location')->set_position(37.423156, -122.084917, 14), Carbon_Field::factory('choose_sidebar', 'custom_sidebar'), ));
Custom fields containers are very flexible in terms of display options. You can select specific post type they show on, as well as category, format, parent, etc. A list of all options is displayed below:
->show_on_post_type('page')
You can also show a single container on multiple post types, as seen below:
->show_on_post_type(array('page', 'my_custom_post_type', 'post'))
Containers may be assigned to posts from specific categories or taxonomies:
->show_on_category($category_slug)
->show_on_taxonomy_term($term_slug, $taxonomy)
Show container on a specific page, identified by path:
->show_on_page($page_path)
Show container on all subpages of a specific page, identified by path:
->show_on_page_children($parent_page_path)
Containers may be assigned to pages using specific template:
->show_on_template($template_path)
The $template_path
is the name of the template file (or array of template file names), for example: "about_us.php"
You can also hide the continer from pages using specific template:
->hide_on_template($template_path)
->show_on_post_format($post_format)
To access field values you need to use the function carbon_get_post_meta($id, $name, $type = null)
, where:
$id
$name
$type
(optional)"complex"
.<!-- Simple field --> <p>Article was published in: <?php echo carbon_get_post_meta($article->ID, 'location'); ?></p> <!-- Complex field --> <?php $slides = carbon_get_post_meta($page->ID, 'slides', 'complex'); foreach ($slides as $slide) { echo $slide['image']; } ?>
You can also use carbon_get_the_post_meta($name, $type = null)
to access the values for the current post in The Loop.
<p>Article was published in: <?php echo carbon_get_the_post_meta('location'); ?></p> <?php $slides = carbon_get_the_post_meta('slides', 'complex'); ?>
Theme option containers are used to add pages with options in the back-end. Field data is stored as options.
By default, theme options containers automatically create main page in the admin area menu named "Theme Options". In most cases these default settings are sufficient, but if you need to change the title or the location of a page in the menu, read the "Multiple option pages" section below.
Carbon_Container::factory('theme_options', 'Theme Options') ->add_fields(array( Carbon_Field::factory('text', 'facebook_url'), Carbon_Field::factory('textarea', 'footer_text') ));
It is sometimes needed to create more than one option page. At other times you need to place different pages in different sections in the admin menu. For example, you might have extensive list of settings for the background that you would want to place on a separate Theme options page under Appearance.
To change the location of your Theme Options page, you use set_page_parent($parent)
, where:
$parent
$parent_slug
parameter of add_submenu_page. You can see all predefined page parents here.Below you see sample code for creating three theme option containers:
// Default options page Carbon_Container::factory('theme_options', 'Basic Options') ->add_fields(array( Carbon_Field::factory('header_scripts', 'header_script'), Carbon_Field::factory('footer_scripts', 'footer_script'), )); // Add second options page under 'Basic Options' Carbon_Container::factory('theme_options', 'Social Links') ->set_page_parent('Basic Options') // title of a top level Theme Options page ->add_fields(array( Carbon_Field::factory('text', 'facebook_link'), Carbon_Field::factory('text', 'twitter_link') )); // Add third options page under "Appearance" Carbon_Container::factory('theme_options', 'Customize Background') ->set_page_parent('themes.php') // indentificator of the "Appearance" admin section ->add_fields(array( Carbon_Field::factory('color', 'background_color'), Carbon_Field::factory('image', 'background_image') ));
For detailed information on managing admin pages, see Administration_Menus.
Every theme options container requires a level of permission, which by default is set to edit_themes
(read more about permissions: Roles & Capabilities).
You can change the permission required to view your options page using set_page_permissions($permission)
To retrieve field values from a theme options container, you need to use the function carbon_get_theme_option($name, $type = null)
, where:
$name
$type
(optional)"complex"
.<p>Copyright <?php echo carbon_get_theme_option('copyright'); ?></p> <p> Office locations: <?php $address_lines = carbon_get_theme_option('addresses', 'complex'); foreach ($address_lines as $line) { echo $line . '<br/>'; } ?> <p>
Term meta containers are used to extend the term edit screens with additional fields. Field data is stored separately for each term in a custom table ($wpdb->termmeta
).
Carbon_Container::factory('term_meta', 'Category Properties') ->add_fields(array( Carbon_Field::factory('color', 'title_color'), Carbon_Field::factory('image', 'thumb'), ));
By default the term meta containers are displayed on category
terms, but you can select specific taxonomies they show on using the method show_on_taxonomy($taxonomy)
, where:
$taxonomy
To access field values you need to use the function carbon_get_term_meta($term_d, $name, $type = null)
, where:
$term_d
$name
$type
(optional)"complex"
.<!-- Simple field --> <p>Editor of this category: <?php echo carbon_get_term_meta($category->ID, 'editor'); ?></p> <!-- Complex field --> <?php $authors = carbon_get_term_meta($category->ID, 'authors', 'complex'); foreach ($authors as $author) { echo $author['name']; } ?>
User meta containers add extra fields to the user edit screens. Field data is stored separately for each user as user meta (see add_user_meta).
Carbon_Container::factory('user_meta', 'Address') ->add_fields(array( Carbon_Field::factory('text', 'city_and_post', 'City and post code'), Carbon_Field::factory('text', 'street', 'Street Name'), ));
By default the user meta containers are displayed for all users of all roles, but you can select specific user roles they show on using the method show_on_user_role($role)
, where:
$role
To access field values you need to use the function carbon_get_user_meta($user_d, $name, $type = null)
, where:
$user_d
$name
$type
(optional)"complex"
.<!-- Simple field --> <?php $author = get_the_author(); ?> <p>Author address: <?php echo carbon_get_user_meta($author->ID, 'street'); ?></p> <!-- Complex field --> <?php $phone_numbers = carbon_get_user_meta($author->ID, 'phone_numbers', 'complex'); foreach ($phone_numbers as $phone) { echo $phone['country_code'] . '-' . $phone['number']; } ?>
Widget containers are used to create custom widgets for your theme. Each widget is defined as a PHP class. Widget classes must extend the Carbon_Widget
class and must have at least two methods - constructor and front_end
method.
The constructor must be named after the class and it must call the method setup($name, $description, $fields, $classname)
, where:
$name
$description
$fields
$classname
The front_end($args, $instance)
method is responsible for rendering your widget in the front-end. Here you have access to all values saved for the fields you defined in the constructor via the $instance
parameter.
After you define your class, it is important that you register your new widget during the widgets_init
action.
class ThemeWidgetExample extends Carbon_Widget { // Register widget function. Must have the same name as the class function __construct() { $this->setup('Theme Widget - Example', 'Displays a block with title/text', array( Carbon_Field::factory('text', 'title', 'Title')->set_default_value('Hello World!'), Carbon_Field::factory('textarea', 'content', 'Content')->set_default_value('Lorem Ipsum dolor sit amet') )); } // Called when rendering the widget in the front-end function front_end($args, $instance) { echo $args['before_title'] . $instance['title'] . $args['after_title']; echo '<p>' . $instance['content'] . '</p>'; } } function load_widgets() { register_widget('ThemeWidgetExample'); } add_action('widgets_init', 'load_widgets');
Fields are the building block of every container.
New field are created using the factory method Carbon_Field::factory($type, $name, $label=null)
, where:
$type
text
will create field of class Carbon_Field_Text
. For a complete list of field types, see Types.$name
bgcolor
becomes _bgcolor
). For more information why, see here$label
(optional)$name
The factory greatly simplifies the field creation process, since it returns the field object itself and you don't need to assign it to a variable. The fields API supports method chaining (as seen in the example below).
// Create image field with name "customer_photo" and label "Photo" Carbon_Field::factory('image', 'customer_photo', 'Photo'); // Here the title is automatically set to "Custom Sidebar" Carbon_Field::factory('choose_sidebar', 'custom_sidebar'); // Method chaining Carbon_Field::factory('select', 'color')->addOptions(array('red', 'blue', 'green'))->help_text('Pick a color');
All field types originate from a single class named Carbon_Field
and inherit the following basic features:
You can assign a default value for each field in every container. The default value is used when there is currently no value for the particular field in the database. This is the case for example, when you add a new post, or you add a new theme options field to existing container.
To assign a default value, you use Carbon_Field::factory(...)->set_default_value($default_value)
You can mark any field as required, in which case the user will need to fill it out before submitting. To set a field as required, you use Carbon_Field::factory(...)->set_required(true)
Help text is used as a hint to the user, who will use the field. It is usually rendered under the field and contains more information about what it should contain - requirements, examples, links, etc. HTML tags are allowed.
You add help text using Carbon_Field::factory(...)->help_text($text)
text
The text field is the simplest and most generic field. It renders a text input field.
Carbon_Field::factory('text', 'subtitle')
textarea
Multiline text input with HTML allowed
Carbon_Field::factory('textarea', 'meta_description')Setup methods
set_height($height = 170)
Carbon_Field::factory("textarea", "related_urls", "Related Links")->set_height(250);
rich_text
This field renders the built-in WordPress tinyMCE editor.
Carbon_Field::factory("rich_text", "sidenote", "Sidenote Content");
date
Renders a date picker using jQuery UI. The value is stored in YYYY-MM-DD
format.
Carbon_Field::factory("date", "event_start_date", "Start");
color
Renders color picker using Farbtastic. Colors are represented with six hexadecimal digits prefixed with #
(e.g. white is #FFFFFF
)
Carbon_Field::factory("color", "box_background", "Background Color");
checkbox
The checkbox field create a single tick-able option with a label next to it.
set_option_value($value)
Carbon_Field::factory("checkbox", "show_content", "Show content") ->set_option_value('yes');
select
Creates a select box with pre-defined options.
add_options($options)
Carbon_Field::factory("select", "content_align", "Text alignment")->add_options(array( 'left' => 'Left', 'center' => 'Center', 'right' => 'Right', ));
radio
Similar to the Select field, but instead of in a select box, options are rendered as a set of radio buttons.
add_options($options)
Carbon_Field::factory("radio", "subtitle_styling", "Subtitle text style")->add_options(array( 'em' => 'Italic', 'strong' => 'Bold', 'del' => 'Strike', ));
set
The set field creates a list of tick-able options. This field enables to select multiple options. The value is retrieved as array containing the ticked options.
add_options($options)
Carbon_Field::factory("set", "product_features", "Features")->add_options(array( 'bluetooth' => 'Bluetooth', 'gps' => 'GPS navigation', 'nfc' => 'Near field communication', ));
relationship
This field allows to select multiple posts, pages or custom post types. Useful for creating links between different posts.
set_post_type($post_type)
set_max($max)
-1
(no limit).Carbon_Field::factory("relationship", "publications", "Publications")->set_post_type('publication'); Carbon_Field::factory("relationship", "artworks", "Artworks")->set_post_type(array('painting', 'sculpture'));
file
Renders a text input with URL and file upload button. The built-in WordPress file handling interface is used.
Carbon_Field::factory("file", "price_list", "Price list (PDF)");
image
Renders a text input with URL and image upload button. The built-in WordPress file handling interface is used.
Supported image formats are: jpg, jpeg, gif, png and bmp
Carbon_Field::factory("image", "employee_photo", "Photo");
attachment
Renders a button to choose file (attachment) from the Media library. Instead of the URL, the field saves the attachment's ID. This allows you to retrieve additional information such as titles, descriptions, captions and different thumbnail sizes.
Carbon_Field::factory("attachment", "relateD_file", "Related File");
map
Creates a Google-powered map. The location is represented as longitude and latitude and is saved in three times in the database - one row for the latitude (with name $field_name . '_lat'
), one row for the longitude (with name $field_name . '_lng'
) and one row as a single string ($latitude . ',' . $longitude
with name $field_name
)
set_position($lat, $lng, $zoom)
$lat
and $lng
and the default zoom level to $zoom
(zoom 0
corresponds to a map of the Earth fully zoomed out).Carbon_Field::factory("map", "company_location", "Location")->help_text('drag and drop the pin on the map to select location');
map_with_address
Map
field with additional field for address search.
Carbon_Field::factory("map_with_address", "company_location", "Location")
separator
Creates visual separator between adjacent fields. Has aesthetic function only, no data is saved.
Carbon_Field::factory("separator", "style_options", "Style");
choose_sidebar
Adds a drop-down field that lists existing sidebars and provides the ability to add new sidebars to the site.
disable_add_new()
set_sidebar_options($sidebar_options)
array( 'before_widget' => '<li id="%1$s" class="widget %2$s">', 'after_widget' => '</li>', 'before_title' => '<h2 class="widgettitle">', 'after_title' => '</h2>', )
The example below shows how to create a Choose Sidebar field with custom sidebar options and help text:
Carbon_Field::factory("choose_sidebar", "custom_sidebar", "Sidebar") ->help_text('Select which sidebar to show in this page, or click "Add New" to create a new one') ->set_sidebar_options(array( 'before_widget' => '<div id="%1$s" class="widget %2$s">', 'after_widget' => '</div>', 'before_title' => '<h3 class="widgettitle">', 'after_title' => '<div class="cl"> </div></h3>', ));
header_scripts
Applicable to Theme Options container only. Displays a text area, the contents of which will be automatically printed in the <head>
of each page. Useful for printing user-defined javascript, as well as styles, meta tags, etc.
Carbon_Field::factory("header_scripts", "header_script");
footer_scripts
Applicable to Theme Options container only. Displays a text area, the contents of which will be automatically printed before the closing </body>
of each page (during wp_footer()
). Useful for printing Google Analytics code, or user-defined javascript.
Carbon_Field::factory("footer_scripts", "footer_script");
html
Render custom HTML markup
set_html($html)
$html
.Carbon_Field::factory("html", "information_text")->set_html('<h2>Lorem ipsum</h2> <p>Quisque mattis ligula eget placerat volutpat. Praesent tincidunt ultricies tempor.</p>');
Complex fields act as containers to which you can add multiple groups of fields. It is represented as a table, where each row is a field group. The user is able to add infinite rows of each group. This allows to repeat a set of fields multiple times creating customizable and sortable lists. This is useful when creating image galleries, lists of data or advanced content and layout elements.
Carbon_Field::factory('complex', 'slide')->add_fields(array( Carbon_Field::factory('text', 'title'), Carbon_Field::factory('image', 'photo'), )),
The example above shows how to make a slide show. We crated a single complex field named slide
, to which we attached one group of fields that represents a single slide - title
and photo
. The user will be able to add multiple rows of title and photo, thus creating a list of slides for the slide show.
A more advanced usage of the complex field is shown below:
Carbon_Field::factory('complex', 'media_item') ->add_fields('photograph', array( Carbon_Field::factory('image', 'image'), Carbon_Field::factory('text', 'caption'), )) ->add_fields('movie', array( Carbon_Field::factory('file', 'video'), Carbon_Field::factory('text', 'title'), Carbon_Field::factory('text', 'length'), )),
Here we have to create a list of media items, lets say for an art exhibition. There are two types of items - photos (defined by an image
and a caption
) and movies (having a title
, length
and the video
file itself). Since items have different properties, we need to define separate group for each one. Groups also must have a name, by which they will be recognized later - photograph
and movie
.
As you can see, depending on their usage, complex fields can either contain a single unnamed group or multiple named groups.
To add a single group of fields you use add_fields($fields)
, where:
$fields
add_fields(array( Carbon_Field::factory('text', 'name'), Carbon_Field::factory('text', 'job_title'), )),
To add multiple groups of fields you use add_fields($name, $fields)
, where:
$name
$fields
Carbon_Field::factory('complex', 'job') ->add_fields('driver', array( Carbon_Field::factory('text', 'name'), Carbon_Field::factory('text', 'drivers_license_id'), )) ->add_fields('teacher', array( Carbon_Field::factory('image', 'name'), Carbon_Field::factory('image', 'years_of_experience'), )),
Each call to add_fields($name, $fields)
creates a new group and adds it to the complex field.
You can also give each group a label different from their name using add_fields($name, $label, $fields)
.
All data stored in a complex field is returned as a two-dimensional array with the following format:
array ( 0 => array ( '_type' => 'photograph', 'caption' => 'Lorem Ipsum', 'image' => 'http://example.com/wp-content/uploads/2012/12/Jellyfish.jpg', ), 1 => array ( '_type' => 'movie', 'length' => '1:56', 'title' => 'Dolor sit amet', 'video' => 'http://example.com/wp-content/uploads/2012/12/video_new.mp4', ), 2 => array ( '_type' => 'photograph', 'caption' => 'Consectetur adipiscing elit', 'image' => 'http://example.com/wp-content/uploads/2012/12/Koala.jpg', ), )
Each item represents the values stored by a single group. The name of the group is stored in element with key _type
. When the complex field contains one group only, it's type will be an empty string - ""
.
Complex field values are retrieved using either carbon_get_post_meta
or carbon_get_theme_option
(depending on the container it is added to) and passing the string "complex"
as $type
argument (see Types).
Complex fields can be nested. The following will define a container that creates multiple slides and allows positioning of multiple text fragments on each slide:
Carbon_Container::factory('custom_fields', 'Slider Data') ->show_on_post_type('post') ->add_fields(array( Carbon_Field::factory('complex', 'slides')->add_fields(array( Carbon_Field::factory('image', 'image'), Carbon_Field::factory('complex', 'slide_fragments')->add_fields(array( Carbon_Field::factory('text', 'fragment_text'), Carbon_Field::factory('select', 'fragment_position')->add_options(array('Top Left', 'Top Right', "Bottom Left", "Bottom Right")), )) )), ));
Values are retrieved as usual using either carbon_get_post_meta
or carbon_get_theme_option
. The format of the returned data is a multi-dimensional array, as follows:
array ( 0 => array ( 'photo' => 'http://example.com/lorem.jpg', 'people_on_photo' => array ( 0 => array ( 'name' => 'John', ), 1 => array ( 'name' => 'Karen', ), ) ), 1 => array ( 'photo' => 'http://example.com/ipsum.jpg', 'people_on_photo' => array ( 0 => array ( 'name' => 'Paul', ), 1 => array ( 'name' => 'Kasper', ), 2 => array ( 'name' => 'Julie', ), ) ), )
You can constrain the number of rows in a complex field using the following two functions:
add_fields
add_fields
method.
set_layout($layout = table | list)
Carbon_Field_Complex::LAYOUT_LIST
(default) - lists groups as rows and their fields as a columns.Carbon_Field_Complex::LAYOUT_TABLE
- lists groups as rows. Each field in the group is displayed in a new line with the label on the left and the user control on the right.set_min($min)
-1
(no limit).
set_max($max)
-1
(no limit).
setup_labels($labels)
$employees_labels = array( 'plural_name'=>'Employees', 'singular_name'=>'Employee', ); Carbon_Field::factory('complex', 'employee_data') ->setup_labels($employees_labels) ->set_layout(Carbon_Field_Complex::LAYOUT_TABLE) ->add_fields(array( Carbon_Field::factory('text', 'name')->help_text('Name of employee'), Carbon_Field::factory('text', 'position')->help_text('Position title'), Carbon_Field::factory('image', 'image'), Carbon_Field::factory('rich_text', 'description'), ))
Complex field values are saved in the database in multiple rows - a row per field per group. To be able to distinguish which value for field is, a special format of the keys (meta_key
or option_name
) is adopted:
{complex_field_name}_{group_name}-{field_name}_{number}
, where
Carbon_Field::factory()
add_fields()
, or ""
if only one group is present.Carbon_Field::factory()
NB! When in a Custom Fields container, the name of the complex field is prefixed with an underscore, but the name of the field (field_name
) is not. Thus, the key format becomes: _{complex_field_name}_{group_name}-{field_name}_{number}