The key here (which I misunderstood/overlooked) is that for the FieldsHelper::getFields method, to also return the value & rawvalue of the custom fields, the $item has to be a content item object.
I was only passing the id of the category, instead of an object of that category, that's why I didn't get the field's value.
Just for clarity, I post here ...
For getting custom fields and values for Joomla articles, you can use the following code:
JLoader::register('FieldsHelper', JPATH_ADMINISTRATOR . '/components/com_fields/helpers/fields.php'); //load fields helper
$customFieldnames = FieldsHelper::getFields('com_content.article', $artile_id, true); // get custom field names by article id
Your approach will still work, but you just need to pass a contact object as the second parameter to your call
$fields = FieldsHelper::getFields(...);
Unfortunately afaik there is no API around contact the way there is around user, so it's a bit more complex to get it.
I got it by doing a database query (as in Selecting data using JDatabase) to find the #...
You don't necessary need it.
I think it may be a bit of a performance factor and also UI cluttering if you have custom fields enabled but not used. For core, it was decided to make it opt-in.
In my own extension, I have no parameter for it.
Create an override of com_fields/layouts/fields/render.php. Find this line:
$content = FieldsHelper::render($context, 'field.' . $layout, array('field' => $field));
Change it to also pass the item to field layout:
$content = FieldsHelper::render($context, 'field.' . $layout, array('field' => $field, 'item' => $item));
The item with its fields is ...
It's unknown what exactly is your $fields variable, what values it contains (how it has been produced), where you use this code and generally your question lacks context.
However, note that when a field is unpublished - then it's not included in the $jcfields array of the article object, for which the field has been assigned as a custom one.
Now, given the ...
Here is the solution I came up with for my question:
$programs = $fields['programs']->rawvalue;
$class = $fields['programs']->params->get('render_class');
$items = json_decode($programs, true);
<?php $i = 0; foreach($items as $program): ?>
<div class="program <?php echo $class; ?>">
I presume you're in a template override of com_content. In which case your $this will point to an instance of a view class, eg. ContentViewArticle or something.
PHP does allow you to declare functions at runtime within objects but $this won't be in scope so you have to pass in a handle of the object. So you can do the following: