Suppose you want to create a custom article option in Joomla 4/5. In this example, I’m creating two fields -> “showspecialtext” and “specialtext”.
The “showspecialtext” field will be a boolean with a value of 0 or 1. If it it zero, nothing will happen on the single article page. If it’s 1, it will print out “specialtext” before the article. Then, the author of the article can select whether they want to enter specialtext or not.
Of course, this could be extended to implement many different features. In this short guide, I’ll show you how to create these fields and access them.
Creating Custom Fields
Joomla 4 and 5 support custom article fields. You can create them from the “Articles -> Fields” menu. You may optionally create field groups to put them in, too.
Create your custom field, set its type, and give it some values if applicable.
If you’re using this value internally, but don’t actually want to display it to guests on your website, be sure to change the “Automatic Display” option on the second tab so it doesn’t display the field value to your visitors on the front end.
Load The Field
Now, I have created an override of the article view in my template. This will allow me to customize what value(s) get loaded in the article view and how I want to use them. If you’re unfamiliar with layout overrides, please read the separate guide on that.
Create your layout override for a single article view if you have not done so. You can use the overrides manager to override com_content article if you want. The file should be at /templates/yourtemplate/html/com_content/article/default.php (or whatever you named your layout file).
As it stands, I don’t think there is a particularly easy way to add your custom fields programatically, like when your template is installed, other than running a custom SQL query when the template is installed. This should only be a concern if you are distributing the template to many people and want the feature to be available on many different sites, without the need for end users to manually add the custom fields. If you only intend on using your template on a particular website, it’s not a huge issue.
There are several ways to load the value of a field.
Loading By ID
This is the easiest way to load a specific field, if you already know its ID. This is not the same as the name. I’m talking about the numerical ID of the custom article field displayed in the rightmost column of the table in the article custom fields page.
If you want to use that ID to get the value of the field from within the com_content article layout, you can do so like this:
Within an article layout, you can access the properties of the article itself with $this->item. The custom fields are stored in the jcfields array.
So to access the value of the article’s custom field with an ID of 5, I would use this code:
$myvalue = $this->item->jcfields[5]->rawvalue;
Code language: PHP (php)
So just change the [5] index to whatever the index of the custom field you’re looking for.
Note that rawvalue gives you the actual “value” of the field selected. Depending on your field type, this is important. You can also access the “value” of the field, which is different from rawvalue. For example, if you’re using a radio field type, “value” returns the TEXT of the selected field, not the actual “value”. Return to my screenshot above. $this->item->jcfields[5]->rawvalue;
would return 1 if the first field was selected at the article level. $this->item->jcfields[5]->value;
would return “yas” if the user selected that option. So if I wanted to determine if the article’s custom field is set to be “yas” or “1”, the code would be…
//by value
if ($this->item->jcfields[1]->value === 'yas')
//by rawvalue
if ($this->item->jcfields[1]->rawvalue == '1')
Code language: PHP (php)
The text field containing the actual “specialtext” of my article is stored in the field with id 2, so in summary, I could check if the feature is switched on and print out the value by doing this:
<?php if ($showspecialtext == '1') : ?>
<div class="com-content-article__specialtext">
<?php echo $specialtext; ?>
</div>
<?php endif;?>
Code language: HTML, XML (xml)
By Name With Loop
If you want to make your code more generic so it’s not specific to a single website, you can try to find the value of the field by name. I don’t think Joomla provides a function to do this exact thing. So I’ve created a custom function to look into jcfields and get the value by name:
// Get custom article fields
global $customFields;
$customFields = $this->item->jcfields;
function getCustomFieldValue($fieldName){
global $customFields;
foreach ($customFields as $field) {
if ($field->name == $fieldName) {
return $field->rawvalue;
}
}
return null;
}
Code language: PHP (php)
With this function, you can get the rawvalue of any field by calling it. getCustomFieldValue('showspecialtext')
would return ‘1’.
This is probably fine if you’re just using a few fields on your site. However, it could impact performance if you’re running this command on dozens or hundreds of fields. There is one last option.
By Name With array_column
Another alternative to a foreach loop is to use PHP’s array_column function. The array_column function can retrieve specific columns from an array.
This achieves the same thing as above, but may be more efficient/fast, as it’s using an optimized built in PHP function.
// Get custom article fields
global $customFields;
$customFields = $this->item->jcfields;
function getCustomFieldValue($fieldName){
global $customFields;
$rawvalues = array_column($customFields, 'rawvalue', 'name');
return $rawvalues[$fieldName];
}
Code language: PHP (php)
You’d use it the same way as before.
Get Field Value By Name With SQL
We can create a custom query to look into the database and get the exact field we’re looking for. Functionally, it’s used the same way as the previous function. But this one finds the field’s value by looking at the fields and fields_values tables of the Joomla database.
This may be more efficient if you’re working with a site that has a large amount of custom article fields.
// Get custom article fields via sql query
global $itemid;
$itemid = $this->item->id;
function getCustomFieldValue($fieldName){
global $itemid;
$db = Factory::getContainer()->get('DatabaseDriver');
$query = $db->getQuery(true)
->select($db->quoteName('value'))
->from($db->quoteName('#__fields_values', 'fv'))
->join('INNER', $db->quoteName('#__fields', 'f') . ' ON (' . $db->quoteName('f.id') . ' = ' . $db->quoteName('fv.field_id') . ')')
->where($db->quoteName('fv.item_id') . ' = ' . $db->quote($itemid))
->where($db->quoteName('f.name') . ' = ' . $db->quote($fieldName));
$db->setQuery($query);
$result = $db->loadResult();
return $result;
}
Code language: PHP (php)
Other Considerations
I’ve seen other examples with developers using Joomla’s FieldsHelper instead of using the jcfields property to retrieve the values of all the fields. Effectively, this achieves the same thing as $customFields = $this->item->jcfields;
with more lines of code and an additional used class. So I don’t really think you need to do it this way, but it could be good to know.
use Joomla\Component\Fields\Administrator\Helper\FieldsHelper;
// rest of code
// above your getCustomFieldValue function...
global $customFields;
$customFields = FieldsHelper::getFields('com_content.article', $this->item, true);
Code language: PHP (php)
Summary
You can use Joomla’s custom fields with articles to provide individualized options for your template at a per-article level. You can access the values of the custom fields you create by numerical field index, by looping through the values of jcfields, or by running a custom SQL query. Depending on the speed of your database and server, one method may be more efficient than another. If you notice significant performance issues, I’d suggest trying a different method.
The only way to create a custom field upon your template’s installation is to run a custom query. Here are instructions on how to do that.