How to add custom fields to articles in Joomla! 3.x

08.20.2014
#6980A3

Update (10.17.2014): I built an example plugin & installer for Joomla! 3.x.

  • Install and enable plugin.
  • Open a new or existing article in your Joomla! admin. You should see a Custom Fields tab above the editor.

Download Here


Did you know you can add custom fields to Joomla! articles without modifying core files? And it's pretty simple.

Let me start by saying this isn't documented, so please use your discretion before implementing on production sites.

The Content Plugin

Here's a sample plugin that we use to add custom fields—zFields.

In this example let's suppose you created a category on your site to house all of the articles you have on the Los Angeles Dodgers.

Each article will have information about the team, which will be styled on the front-end the same. Instead of just sticking it in the article's text, you can create custom fields to make it easier to style on the front-end.

zFields Plugin Screenshot

Above is a screenshot of the added fields in an article. Below is the plugin that makes it all happen.

zfields.php

<?php
// no direct access
defined ( '_JEXEC' ) or die ( 'Restricted access' );
 
class plgContentZfields extends JPlugin {
 
        /**
         * Load the language file on instantiation.
         * Note this is only available in Joomla 3.1 and higher.
         * If you want to support 3.0 series you must override the constructor
         *
         * @var boolean
         * @since 3.1
         */
 
        protected $autoloadLanguage = true;
 
        function onContentPrepareForm($form, $data) {
        
                $app = JFactory::getApplication();
                $option = $app->input->get('option');
 
                switch($option) {
 
                    case 'com_content':
                        if ($app->isAdmin()) {
                                
                                //Hard-coded array of cateogry IDs. You could easily incorporate 
                                //a category field in the plugin XML to dynamically create this array
                                $selected_categories = array(43);
                                
                                JForm::addFormPath(__DIR__ . '/forms');
                                
                                //Show specific forms based on categories
                                if( is_array($data) && in_array($data['catid'], $selected_categories) ){
                                    
                                    $form->loadFile('dodgers', false);
                                    
                                }else{

                                    $form->loadFile('content', false);

                                }  
                                
                        }
                        return true;
 
                }

                return true;

        }
 
}
?>

zfields.xml

<?xml version="1.0" encoding="utf-8"?>
<extension version="2.5" type="plugin" group="content">
	<name>plg_content_zfields</name>
	<author>Joomla! Project</author>
	<creationDate>November 2010</creationDate>
	<copyright>Copyright (C) 2005 - 2014 Open Source Matters. All rights reserved.</copyright>
	<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
	<authorEmail>This email address is being protected from spambots. You need JavaScript enabled to view it.</authorEmail>
	<authorUrl>www.joomla.org</authorUrl>
	<version>2.5.0</version>
	<description>PLG_CONTENT_JOOMLA_XML_DESCRIPTION</description>

	<files>
		<filename plugin="zfields">zfields.php</filename>
		<filename>index.html</filename>
	</files>
	<languages>
		<language tag="en-GB">en-GB.plg_content_zfields.ini</language>
		<language tag="en-GB">en-GB.plg_content_zfields.sys.ini</language>
	</languages>
	<config>
		<fields name="params">
			<fieldset name="basic">
				<field name="check_categories"
					type="radio"
					default="1"
					description="PLG_CONTENT_JOOMLA_FIELD_CHECK_CATEGORIES_DESC"
					label="PLG_CONTENT_JOOMLA_FIELD_CHECK_CATEGORIES_LABEL">
					<option value="0">JNO</option>
					<option value="1">JYES</option>
				</field>

				<field name="email_new_fe"
					type="radio"
					default="1"
					description="PLG_CONTENT_JOOMLA_FIELD_EMAIL_NEW_FE_DESC"
					label="PLG_CONTENT_JOOMLA_FIELD_EMAIL_NEW_FE_LABEL">
					<option value="0">JNO</option>
					<option value="1">JYES</option>
				</field>
			</fieldset>
		</fields>
	</config>

</extension>

The above two files will create the content plugin, but you'll also need to create at least one XML file to generate the additional fields that'll show up in the article edit screen (using the above example, you'll need a dodgers.xml and content.xml file).

The following two files will go in the 'forms' directory of the content plugin.

dodgers.xml

<?xml version="1.0" encoding="UTF-8"?>
<form>
    <fields name="attribs" >
        <fieldset name="params" >

			<field name="overall_record"
			    type="text"
			    label="2013 Record"
			    />
			    
			<field name="home_record"
			    type="text"
			    label="Home Record"
			    />
			    
			<field name="road_record"
				type="text"
				label="Road Record"
				/>

        </fieldset>
    </fields>
</form>

content.xml

<?xml version="1.0" encoding="UTF-8"?>
<form>
    <fields name="attribs" >
        <fieldset name="params" >

			<field name="overall_record"
			    type="text"
			    label="2013 Record"
			    />
			    
			<field name="home_record"
			    type="text"
			    label="Home Record"
			    />
			    
			<field name="road_record"
				type="text"
				label="Road Record"
				/>

        </fieldset>
    </fields>
</form>

You'll immediately notice that the above files are identical. This is a quirk in the way things get saved—the article only uses content.xml to save and display the information, dodgers.xml is used to display the fields in the specific category.

Accessing the data

Here's how to access the data within a template override (for either a category item or article):

$attributes = json_decode($this->item->attribs);
echo $attributes->overall_record;
echo $attributes->home_record;
echo $attributes->road_record;

Wrap any of those up in a conditional statement and you're all set!

Here's a direct download to the files mentioned above. NOTE: this is not an installer, just the files.

Included files:

  • zfields
    • forms
      • content.xml
      • dodgers.xml
      • index.html
    • index.html
    • zfields.php
    • zfields.xml