Joomla

How to easily access to Custom Fields in Joomla

Published July 23rd, 2019

Important: The information in this article is over 12 months old, and may be out of date or no longer relevant.

But hey, you're here anyway, so give it a read see if it still applies to you.

Update August 2021:

Item Helper has evolved since this blog post, and is now a plugin that you can install for your own Joomla site.

You can download it and see all documentation at https://github.com/mitydigital/joomla-item-helper

Over the past few years, I’ve had to get more and more involved in developing Joomla websites. Joomla is such a powerful, flexible and user-friendly CMS to work with, but did find a few harder-than-they-need-to-be moments.

Michael, Mity Digital’s in-house Certified Joomla Administrator with over a decade of Joomla experience, introduced me to Custom Fields for a specific project – and the value it adds to the author is incredible – he’s written a blog post all about the benefits of Custom Fields for Joomla content authors.

The project relied on a rather large number of Custom Fields – and by using the combination of Field Groups and Categories has created an incredibly easy-to-manage editing experience for the site’s authors. By using Field Groups, Fields are more logically placed, and lists of Fields appear shorter (making it easier to read and process entire sections) – and the nerd in me loves it because the content of these Fields remains fully separate from the core Article content – meaning I can do what I need to with the content and not have to rely on accuracy of markup from the author. Massive bonus.

Within each Article, we are able to access our Custom Fields using the jcfields array on our $item, and Joomla provide in their documentation the option of simply iterating, or using the FieldsHelper.

The FieldsHelper method spits out markup in a set (and not-overridable) way – which isn’t good for the control freak in me – and the jcfields index is a numerically indexed array, so accessing a specific field is quite loopy (ha…).

The documentation does also point out how to access the fields by their name – but still relies on placing repeated code at the top of every override. If we have several overrides  and need to make one change to the logic of this processing, we need to update several files.

So the core idea and logic how to access fields (directly using jcfields, not the FieldsHelper) is spot on – but the repeated implementation in every override isn’t the best. The programmer in me says “nope, let’s make it better”. Well, not “better”, but centralised. Let’s write the code to make it easier to access Custom Fields once rather than in every override.

To help out managing Articles at the override level, I wrote a Helper class that we use in all of our Joomla sites now at Mity. This Helper still requires some code in every override, but the code is simply including that Helper, and running it. The smarts inside the helper – i.e. making it easier to access Custom Fields – is then written once, but can be used by any override. Much happier coder now.

The jcfields array is great – it as everything we could ever need. But that’s also an issue – it has everything – and still requires a bit of work to get actual selected values based on different field types. This is actually really great though – it means we have total control and full knowledge over the source Custom Field. But we do just need to make sure we know how to access the different properties of different Custom Field types.

Hello this centralised Helper, once again.

Simply put, this Helper accepts an $item (i.e. $this->item from an Article override, or $item from a Module override), and performs some processing on the items.

Rather than overriding the jcfields array (as the docs suggest), we are creating another named-index array for our processed fields. This processing is:

  • Giving is the name and label

  • Telling us the Field Group ID

  • Processing the Value to be a little more friendly

  • Saving the options, if the Field Type uses them

1foreach ($item->jcfields as $field)
2{
3 $item->jcfieldsnames[ $field->name ] = [
4 'name' => $field->name,
5 'value' => is_array($field->rawvalue) && count($field->rawvalue) == 1 ? $field->rawvalue[0] : $field->rawvalue,
6 'label' => $field->label,
7 'group' => $field->group_id,
8 'options' => $field->fieldparams->get('options')
9 ];
10}
Copied!

This means that our original untouched jcfields are always there – but we can just access our Custom Fields using a named-index array.

Given different Field Types behave in slightly different ways with their value, we have also had to extend this. Currently I have only done this for Checkboxes and JSON-based data (such as a Repeatable) – again, all with the aim of making it easier to access the Field data at the override level.

1if ($field->type == 'checkboxes')
2{
3 // create an array for our selected items
4 $selected = [];
5 
6 // loop through all of the options
7 foreach ($field->fieldparams->get('options') as $option)
8 {
9 // check if the selected value(s) has the current option
10 // if rawvalue is an array, there is 2 or more options - look inside the rawvalue as an array
11 // if rawvalue is a string, there's only one option - comparitor is as a string
12 if ((is_array($field->rawvalue) && in_array($option->value, $field->rawvalue)) || $field->rawvalue == $option->value)
13 {
14 $selected[] = array(
15 'name' => $option->name,
16 'value' => $option->value
17 );
18 }
19 }
20 
21 // update the value with the selected items
22 $item->jcfieldsnames[ $field->name ]['value'] = $selected;
23}
24else if (ItemHelper::isJSON($item->jcfieldsnames[ $field->name ]['value']))
25{
26 // the value is a JSON string - so decode it to be an associative array
27 $item->jcfieldsnames[ $field->name ]['value'] = json_decode($item->jcfieldsnames[ $field->name ]['value'], true);
28}
Copied!

Note that this helper is currently for Joomla 3 – Joomla 4 will be making some changes to repeatable fields – and the PR for this has not yet been committed as of alpha 9.

If you find this useful, you may want to extend the helper further to process additional Field Types too. This is a great starting point though.

Want the full source code? You can view it all at my Joomla Item Helper repository over at Github.

Now that we have the smarts, how do we use it?

In our override, we need to include the Helper. For these code samples, we’re in an Article override using $this->item to access our item contents.

1$app = JFactory::getApplication();
2$path = JPATH_THEMES . DIRECTORY_SEPARATOR . $app->getTemplate() . DIRECTORY_SEPARATOR . 'helpers' . DIRECTORY_SEPARATOR . 'ItemHelper.php';
3JLoader::register('ItemHelper', $path);
Copied!

Now that we have registered the class, let’s just call the processing method – I’ve called it processItem as that is what it is doing:

1ItemHelper::process($this->item)
Copied!

The code inside the processItem call is making changes to the input parameter – i.e. $this->item or $item – but because the function definition is accepting this variable by reference, it is simply updating our item – no need to save it back to our calling script.

With the processing complete, fields can easily be used just by calling our array with a named index:

1echo $this->item->jcfieldsnames['my-field-name']['value'];
Copied!

But that wasn’t enough for me… so I went one step further and added a few additional helper functions to make it really easy (and less array-ish) for use in the overrides. There are four helpers that allow easy retrieval of specific properties:

  • getFieldGroupId

  • getFieldLabel

  • getFieldOptions

  • getFieldValue

These accept the item, and the field you are looking for, and will return the property (or false if not found). Just something to make life a little easier. You can now call:

1echo ItemHelper::getFieldValue($this->item, 'my-field-name');
Copied!

This will return the value of the Custom Field named “my-field-name” for the item. Easy!

The total nerd in me does like this approach – i.e. a centralised helper, with handy (and helpful) processing taking place in one central piece of code, which can easily be used where needed – be that a component override or module override – and, better yet, only run if we actually need it. And better still – without touching any core Joomla files, so future 3.x updates should have no impact (if any) to our site’s behaviour.

Custom Fields are really awesome – and the way that Joomla have provided a powerful and flexible approach to structuring, implementing and accessing them is great. And this Helper just takes the repetitive coding out of the way, and puts the processing in one central place. Need to update the processing for a new Custom Field type? Awesome – we can now make one code change any ALL of our overrides can take advantage of the processing. Time saving at its best.

Want the full source code? Get yourself started with my Joomla Item Helper repository over at Github.

You may be interested in...