In the previous episode Custom Fields - Episode 7 Part 1: one Custom Field to rule them all we presented the new Type of Custom Field introduced with Joomla4, namely the Subform.
In practice, we even built a full Carousel available for any Article using only 1 single Custom Field ?.
No extension was necessary, we only used the power of Joomla core. In particular only 1 feature was necessary: the Alternate Layout.
With other words, all it takes now for you to have the same Carousel is to copy-paste 1 file in the correct folder of your website ?.
A little Github repo gathering all these Alternate Layouts
To make this copy-paste even easier, we have created a Github repo gathering all those Alternate Layouts / Overrides:
Several advantages of that little Github repo:
- you have syntax highlighting
(the<code>
in the Magazine is indeed displayed only in black & white at the moment) - you can easily fork it to adapt the Alternate Layouts to your needs
- and last but not least you can make suggestions for improvement ?
Displaying the Carousel only on the Article View
See the detailed code on github.com/woluweb/Custom-Field-of-Type-Subform/blob/main/step2-my-carousel-article-view-only.php
By default (unless your template does not foresee it of course), Joomla displays the Custom Fields both
- on the Article View
- and on the Blog View
In many cases though, users don't necessarily want (all) the Custom Fields on the Blog View.
My easy workaround was sometimes to hide them with CSS (with a simple {display: none}).
This is good enough when the concerned Custom Fields are only Text or Numbers, but if they are Images or Videos or Maps for instance then for obvious performance reasons you don't want to load and then hide them.
So as we have seen in the previous episode, all it takes if you want to restrict in which View you want to display any Custom Field is to add the following 2 lines in your Alternate Layout / Override:
$view = $app->input->getCMD('view', '');
if ('article' !== $view) { return; }
which simply means that if the View is not an Article View then the rest of the code will be skipped (return;
)
As a reminder, we gave to the Carousel Container the following ID
$carouselContainerId = 'carousel-field'. $field->id;
meaning in practice that all Carousels would have the (same) following Container
<div id="carousel-field4">
where 4
is the ID of our Custom Field of Type Subform.
Displaying the Carousel also on the Blog View
To display the Carousel on all Views, all we have to do is to disable the following line which we had initially added to restrict the Carousel to the Article View (with other words, we add //
to transform the line into a comment)
// if ('article' !== $view) { return; }
If we display the Carousel (being our Custom Field of Type Subform) on a Blog View we will get several Carousels on the same page.
Still by definition each Carousel container should have a unique ID because otherwise we would have javascript issues (when a visitor click on a Next/Previous button, the javascript code should know to which Carousel.it applies).
So the question is: how to get a unique ID for each Carousel container, knowing that the Custom Field as such is totally agnostic of the Context (with other words, we don't have access to the Article ID to make it easily unique)?
Side note: a container ID should not start with a digit.
Here is a screenshot of what we will get:
Solution 1 - having a unique ID for the Custom Field by using simply the hash of its rawvalue
See the detailed code on github.com/woluweb/Custom-Field-of-Type-Subform/blob/main/step3-my-carousel-article-and-blog-views.php
This solution only requires current Alternate Layout: we create simply an MD5 hash based on the whole $rawvalue
.
So even 2 articles having almost the same carousel (same images for example but a little difference in the text or in the number of images) will have a different hash.
This is a pragmatic solution which should cover more than 99% of the cases.
So let's now give the Carousel Container the following ID
$carouselContainerId = 'carousel-field'. $field->id . '-'. md5($rawvalue, false);
In practice each Article would then have a unique Container similar to the following, both on the Article View and in the Blog View
<div id="carousel-field4-e714c3f5e913f8521b854c432145770b">
where e714c3f5e913f8521b854c432145770b
is the hash of the rawvalue of our Custom Field of Type Subform.
Solution 2 - having a unique ID for the Custom Field by getting the corresponding Article ID
See the detailed code on github.com/woluweb/Custom-Field-of-Type-Subform/blob/main/step4-my-carousel-article-and-blog-views-with-article-id.php
Oh, didn't we say that the Article ID was not available in our Alternate Layout? Yes indeed... but we manage here to find a clean way to make it available ?.
Next to our current Alternate Layout, we create an Override of
components/com_fields/layouts/fields/render.php
in
/templates/[template]/html/layouts/com_fields/fields
Like already explained in detail in the previous episode an Override can be done
- either manually (via FTP for example)
- or simply via Joomla's back-end
In that override we will change
$content = FieldsHelper::render($context, 'field.' . $layout, array('field' => $field));
into
$content = FieldsHelper::render($context, 'field.' . $layout, array('itemid' => $item->id, 'field' => $field));
With other words, in the "fields layout" we make the item ID (the article ID in this case) available in the "field layout".
Please find the adapted render.php file on https://github.com/woluweb/Custom-Field-of-Type-Subform/blob/main/render.php
So now we can define the Container ID as follows
$carouselContainerId = 'carousel-field'. $field->id . '-'. $displayData['itemid'];
In practice a given Article would then have the following Container, both on the Article View and in the Blog View
<div id="carousel-field4-41">
where 41
is the ID of the concerned Article.
Refactored Alternate Layout (for more advanced users)
If you want a refactored version of the code of Solution 1 which is probably easier to customize if you are a more advanced user, here it is:
github.com/woluweb/Custom-Field-of-Type-Subform/blob/main/step5-my-carousel.php
My conclusion & your challenge
Over the last 3 years I have written for the Joomla Community Magazine 9 articles about Custom Fields.
So by now I have probably told here everything I know about Custom Fields ?
At this stage what would make me suuuper happy would be to have a 10th and final article gathering as many examples as possible of Custom Fields in action.
So your challenge - if you accept it - is to share with the Community what you have already built with Custom Fields!
All you have to do is to send me (
- the link to the page where Custom Fields are used
- one or several screenshots (back-end and/or front-end)
- a few words/lines of description of what you have achieved, how, ...
- and if you wish you can also share the code of your Overrides / Alternate Layouts (for example via gist.github.com or github.com)
This would definitely give even more inspiration to all Joomla fans ?.
Thanks in advance!