Customizing Joomla 4’s Smart Search Results Pages with Images, Custom Fields and a new Layout

by Marc Dechèvre

Woluweb

Marc

JoomlaDay DACH | 2022.09.24

JoomlaDay FR | 2022.05.21

JoomlaDay USA | 2022.04.23 9:00am EDT (13:00 UTC) - with new sections in the present presentation

“Joomla NXT” session by Techjoomla (India) | 2022.02.16 8:00 UTC

present slides https://slides.woluweb.be

1 Please contribute

Help improve this presentation

  • if you think of other tips & tricks
  • if any information can be more precise
  • if you know of any other resource
  • if you spot any typo
  • if you see any error

then please get back to me!

❤️💙🧡💚

2 The goal of this presentation

At this end of this session we will be able to have such a Smart Search Results Page where

  • Intro Image is displayed for each Article
  • a Custom Field is displayed using its Options
  • a Custom Field is displayed by forcing an Alternate Layout (in this case a carousel for a CF of Type Subform)
  • the Results are displayed as Cards (and not as a simple Unordered List)
  • within the Card, we even change the order of some elements and push the last element to the bottom

Screenshot of the default Smart Search Result Page:

result_before

Screenshot of our customized Smart Search Result Page:

result_after

3 Reminder - J4.1 new features

3.1 The big new features

The big announcements around J4.1 typically focus on the “big features” like

  • Task Scheduler
  • Child Templates
  • Accessibility Checker
  • Syntax Highlighting in TinyMCE
  • Inline Help

Sources:

3.2 Note the new path for the “template media folders”

If you either use

  • a custom CSS file
  • an Override or an Alternate Layout
    • either in your original Template
    • or within a Child Template

the following informatoin will interest you.

As you might know, with the introduction of Child Templates in J4.1 the path to the “template media folders” (css, images, js and scss) changes

  • from templates/cassiopeia/ in J4.0
  • to media/templates/site/cassiopeia/ in J4.1

for Cassiopeia (and similarly for all Templates which are or will be compatible with Child Templates).

Good to know: if you created for example a templates/cassiopeia/css/user.css in J4.0, once you update to J4.1 the file will be automagically moved to media/templates/site/cassiopeia/css/user.css.

So you don’t have to worry about this, Joomla (Dimitris Grammatikogiannis in the present case) got you covered 😉

3.3 More discrete features - but nonetheless super interesting

But there are also more discrete features… like Adding Images in the Smart Search Results Pages

See for example the section “Images in search results” of this nice overview of the new features of J4.1 made by Jeroen Moolenschot

We owe this new feature to Sakis Terzis aka Blue-Coder and I am very grateful to him!

4 Adding the Intro Image in the Smart Search Results Pages

Did you know that you can customize independently the Layout for Articles, Contacts etc in the Smart Search Results Pages (com_finder)?

See in the Official Documentation how to achieve this:

https://docs.joomla.org/Customising_the_Smart_Search_results_page

Note: most of my J3 websites were using com_search (classical search) and not com_finder (smart search) so I was not aware of it but the feature was already there in Joomla 3!

4.1 Requires an override in J4.0

On 17 December 2021, Sakis published a very interesting article about how to add Intro/Full Images to the Smart Search Results Pages:

https://blue-coder.com/help/blog/customizing-search-results

The ready-to-use default_article.php can be found on https://github.com/bluecoderr/default_article/blob/main/html/com_finder/search/default_article.php

4.2 Now out of the box with J4.1

Good news, Sakis made this a feature for J4.1. So there is now an option to display the Images natively in the Smart Search Results Pages, without even the need for an override

Source: https://twitter.com/thebluecoder/status/1472925846059032581 on 20 December 2021

See https://github.com/joomla/joomla-cms/pull/35612

Go to Components > Smart Search > [ any of the sub-menu items ] > Options button

There are 3 new Options:

  • Result Image (Hide | Show)
  • Image Class (whatever class you like. Try for example float-start if you are using Casssiopeia in order to have a “float left” on LTR and a “float right” on RTL)
  • Linked Image (No | Yes)

For a more detailed explanation, see this new blog post publised by Sakis on 18 February 2022: https://blue-coder.com/help/blog/showing-images-in-the-search-results-in-joomla-4-1-and-above

image_option

[ added on 2022.04.02 ]

PS: note that there was a bug introduced in Joomla 4.1.2 which is fixed in 4.1.3: https://github.com/joomla/joomla-cms/pull/37450

4.3 Getting even further with Responsive Images

[ added on 2022.04.04 ]

If you don’t know it already, get the following (free) plugin by Dimitris Grammatikogiannis: https://responsive-images.dgrammatiko.dev/

This plugin transforms content (or layout) images from this:

<img
  src="/images/test/34zckrf0l6i51.jpg"
  alt=""
>

…to this:

<picture class="responsive-image">
    <source
      type="image/avif"
      sizes="(max-width: 1920px) 100vw 1920px"
      srcset="/media/cached-resp-images/images/test/34zckrf0l6i51_480.avif?version=722e4d8793f156da1ad89b44ee0e30b8 480w, /media/cached-resp-images/images/test/34zckrf0l6i51_320.avif?version=722e4d8793f156da1ad89b44ee0e30b8 320w, /media/cached-resp-images/images/test/34zckrf0l6i51_200.avif?version=722e4d8793f156da1ad89b44ee0e30b8 200w">
    <source
      type="image/webp"
      sizes="(max-width: 1920px) 100vw 1920px"
      srcset="/media/cached-resp-images/images/test/34zckrf0l6i51_480.webp?version=722e4d8793f156da1ad89b44ee0e30b8 480w, /media/cached-resp-images/images/test/34zckrf0l6i51_320.webp?version=722e4d8793f156da1ad89b44ee0e30b8 320w, /media/cached-resp-images/images/test/34zckrf0l6i51_200.webp?version=722e4d8793f156da1ad89b44ee0e30b8 200w">
    <source
      type="image/jpeg"
      sizes="(max-width: 1920px) 100vw 1920px"
      srcset="/media/cached-resp-images/images/test/34zckrf0l6i51_480.jpg?version=722e4d8793f156da1ad89b44ee0e30b8 480w, /media/cached-resp-images/images/test/34zckrf0l6i51_320.jpg?version=722e4d8793f156da1ad89b44ee0e30b8 320w, /media/cached-resp-images/images/test/34zckrf0l6i51_200.jpg?version=722e4d8793f156da1ad89b44ee0e30b8 200w">
    <img
      loading="lazy"
      width="2381"
      height="1283"
      src="/media/cached-resp-images/images/test/34zckrf0l6i51_ 1920.jpg?version=722e4d8793f156da1ad89b44ee0e30b8"
      alt="">
  </picture>

And the good news is: since April 2022, this includes also automatically the Images of the Smart Search Result Page.

5 Sorting/Ordering in the Smart Search Results Pages

5.1 In the back-end

Go to the Menu Item of Type Smart Search > Advanced Tab

There you have the last 2 options being

  • Sort Field (Use Global | Relevance | Title | Date | List Price✱)
  • Sort Direction (Use Global | Descending | Ascending)

menu

 ✱: I have no clue of what List Price is. Apparently it has been there for ages in Smart Search. If you know why it should be kept or deleted just tell me 😃

Here is a first feedback by Philippe Combet:
  • This column does exist in the database but the value is always 0 (and not NULL, which is differnt). So if you sort by List Price it will have no sense since all values are 0 anyway.
  • Apparently this is in the Joomla code since J2.5. Maybe there was a reason back in the time, but it is most probably useless today and can only potentially harm performance.
  • This parameter is created when the table #finder_links (of the Indexer) is created. The file administrator/components/com_finder/src/Indexer/Result.php mentions it on line 47. It was some information used for the Meta information.
  • Every indexed content has this Option and it takes the value 0 in the corresponding table.
  • The file administrator_finder.mysql.sql creates that field on line 53.
  • This Option is used nowhere else in Joomla, except precisely in the backend in the Sorting options of Smartsearch where it is “possible” to sort on that value.

And here is a useful link found by Brian Teeman:

https://developer.joomla.org/joomlacode-archive/issue-29551.html

5.2 In the front-end

[ Note: unfortunately this feature is not merged yet ]

This feature by Sakis adds a user defined sorting/ordering capability to the front-end of the Smart Search Results Pages, by adding a sorting drop-down above the results.

See https://github.com/joomla/joomla-cms/pull/35993

frontend_sorting

6 Changing the Layout of the Smart Search Results Pages

6.1 How to have the image on the left and the rest on the right

[ added on 2022.03.26 & improved on 2022.04.13 ]

Let’s suppose you want to have the Image on the left and the rest (Link + Title + Description + Taxonomy) on the right as illustrated on this screenshot:

image_left

6.1.1 By making an Override of the view

Of course you could play with PHP and make an Override of the view.

But don’t forget that the (Smart) Search does return not only Articles but also

  • Categories
  • Contacts
  • Newsfeeds
  • Weblinks
  • (and the items of any compatible third-party extension)

For such a usecase the easiest way to change our Layout is simply to play with CSS.

We provide 2 ways to achieve that.

6.1.2 By using CSS - simply adding an Image Class

The fastest way to get such a result would be to add

  • the class float-start to the Image Class in the Smart Search Options. As a reminder: float-start is a class available in Cassiopeia, corresponding to float: left; when “LTR (Left To Right)” and to float: right; when “RTL (Right To Left)”
  • and maybe also another class to limit the width or the height

But this is not perfect: according to their heights some images might end up “higher” than the corresponding row in the results.

This is a typical “side-effect” of float: left;

In CSS the classical “fix” for this side-effect is to “clear” with an after pseudo-element.

Add the following to media/templates/site/cassiopeia/css/user.css:

/* Smart Search Results Pages - when using float-start as Image Class in Smart Search Options */
li.result__item:after {
    content: '';
    display: block;
    clear: both;
}

You could also add a bit of CSS in order to add a margin-right or define a max-width for the image:

li.result__item img.float-start {
    margin-right: 20px;
    max-width: 250px;
}

6.1.3 By using CSS - playing with CSS Grid

Add the following to media/templates/site/cassiopeia/css/user.css:

/* Smart Search Results Pages - when using CSS Grid */
@media (min-width: 768px) {
    li.result__item {
        display: grid;
        grid-template-columns: 250px 1fr;
        grid-template-areas:
            "search-img search-title"
            "search-img search-desc"
            "search-img search-tax";
    }
    .result__image {
        grid-area: search-img;
        margin-right: 20px;
    }
    .result__title {
        grid-area: search-title;
    }
    .result__description {
        grid-area: search-desc;
    }
    .result__taxonomy {
        grid-area: search-tax;
    }
}

Now as soon as the visitor’s screen is wider than 768px we have this 2 columns layout:

  • a first 250px column where we display the image
  • a second column taking the rest of the available width, showing
    • first the Link and Title
    • then the Description
    • then the Taxonomy (if enabled in the Options of Smart Search)

If the screen is smaller than 768px we get the regular layout, namely with the Image of each Result before its corresponding details.

Of course, you could even adapt the CSS to have exactly the Layout you want. For example if you wanted to have the Taxonomy on the full width instead of having it under the Title and Description, simply replace "search-img search-tax"; by "search-tax search-tax"; in the above example.

6.2 How to get a Cards layout

Let’s suppose you want to change the default Layout of the Smart Search Results Pages to have, say, Cards instead of an Unordered List (<ol><li>) (see screenshot at the beginning of this presentation).

Again the easiest way to change our Layout to get Cards is simply to play with CSS using for example

  • CSS Grid for the Result_s_ in order to have a nice dynamic grid where each Result is a Card
  • Flexbox inside each Result in order to easily
    • stack each element (Image, Title, Description, Taxonomy) of each Result vertically
    • be able to change the order of some elements if desired
    • be able to push some element(s) to the bottom of each Card

Add the following to media/templates/site/cassiopeia/css/user.css:

/* Smart Search Results Pages - change the look from a List to Cards */
ol#search-result-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); /* this is more dynamic than a basic repeat(3, 1fr); */
  grid-gap: 20px;
  margin-left: 0;
}
ol#search-result-list > li.result__item {
  background: white;
  display: flex;
  flex-direction: column;
  padding: 10px;
  border: 1px solid lightgray;
  box-shadow: 3px 3px 2px 1px rgb(0 0 0 / 20%);
  transition: 0.5s;
}
ol#search-result-list > li.result__item:hover {
  box-shadow: 3px 3px 2px 1px rgb(0 0 0 / 40%);
}
.result__item + .result__item {
  /* removing the default Cassiopeia style which adds a border + padding + margin on top of each result execept the first one */
  border-top: 0;
  margin-top: 0;
  padding-top: 0;
}

6.2.1 Switching Image and Title

Of course, if for example you want to switch the Image and the Title then you can simply play further with CSS Grid and/or flexbox, for example by adding

.result__image {
    order: -1;
}

since li.result__item already uses Flexbox in our example.

6.2.2 Pushing the Taxonomy to the bottom of each Card

If you want to push the Taxonomy to the bottom of each Card, simply add the following CSS (which will “grow” the Description therefore pushing the Taxonomy to the bottom of the Card)

.result__description {
    flex: 1;
    border-bottom: 1px lightgrey dotted;
    padding-bottom: 20px;
}
.result__taxonomy {
    color: lightgrey;
    font-size: smaller;
}

since li.result__item already uses Flexbox in our example.

Note: the only necessary CSS is of course the flex: 1;. All the rest is there just to make the whole thing look even nicer.

6.3 How to have any kind of layout thanks to an Override

If CSS is not enough for the changes you want to make, see Sakis’ blog:

https://blue-coder.com/help/blog

In particular see the following article explaining how to make an Override of the Result Search Page View (or see the next section of this presentation where we also make an override to add Custom Fields):

https://blue-coder.com/help/blog/customizing-search-results

[edit 2022 09 19 ] Today, Sakis published another similar post on his blog: https://blue-coder.com/help/blog/smart-search-and-jfilters-results-as-multi-column-grid

7 Adding Custom Fields in the Smart Search Results Pages

What about having also Custom Fields directly on the Smart Search Results Page?

7.1 Make an Override

As mentioned above, we follow the instructions explained in https://docs.joomla.org/Customising_the_Smart_Search_results_page

With other words, in practice:

  1. Copy the content of components/com_finder/tmpl/search/default_result.php
  2. Create a new file called /templates/[YOUR_TEMPLATE]/html/com_finder/search/default_article.php
    which will then override the Joomla default’s view in the Smart Search Results Pages but only for Articles
    and where [YOUR_TEMPLATE] is for example cassiopeia… or where it is the template of your Child Template, for example cassiopeia-woluweb
  3. Paste the content

Given the fact that we call this file default_article.php this override will trigger only for Articles.

Note: for a longer version with screenshots see https://blue-coder.com/help/blog/customizing-search-results

7.2 Adding Custom Fields

7.2.1 Making Custom Fields available in our override

By default Custom Fields are not loaded on the Smart Search Results Pages.

With the help of Alexandre ELISÉ (another “Super Joomler”) I could improve on Sakis’ tutorial to manage to add Custom Fields to the Smart Search Results Pages 🎉

At the beginning of our override /[template]/html/com_finder/search/default_article.php, right after defined('_JEXEC') or die; add

use \Joomla\Component\Fields\Administrator\Helper\FieldsHelper; // makes the FieldsHelper available in our override
$myCustomFields = FieldsHelper::getFields('com_content.article', $this->result, true); // creates a variable which will contain all CF of the current article. The True will allow us to render the value instead of the rawvalue
$myCustomFieldsById = \Joomla\Utilities\ArrayHelper::pivot($myCustomFields, 'id'); // we use a pivot on id so that we can easily use the id to access every CF by its ID

7.2.2 Displaying the Rawvalue of a Custom Field

Let’s suppose we have a Custom Field of Type URL having ID 10.

In the override simply paste the following line where you want to display the Custom Field (in my example, right after <li class="result__item">)

<p><?php echo $myCustomFieldsById[10]->rawvalue; ?></p>

Note: it the Custom Field in question does not apply to all articles then of course you should add an “if”. Example :

<?php if(isset($myCustomFieldsById[10]->rawvalue)) : ?>
    <p><?php echo $myCustomFieldsById[10]->rawvalue; ?></p>
<?php endif ?>

7.2.3 Displaying the Value of a Custom Field

Typically in Joomla

  • ->rawvalue displays the raw value of a CF, namely what is litteraly written in the database (in this case a simple url. In the case of a video, the url of the video)
  • ->value displays the value of a CF, namely the “rendering” (in this case, a real hyperlink with the url. In the case of a video, the real video player)

->value works automagically in an Article override for example

But in the context of Smart Search, this is not the case. With other words ->value just gives the same as ->rawvalue

How to overcome that? Simply by using the FieldsHelper:

<p><?php echo FieldsHelper::render('com_content.article', 'field.render', ['field' => $myCustomFieldsById[10]]); ?></p>

Not only will the CF be rendered correctly but all he Options you have configured in the CF itself will trigger. Examples: - showing (or not) the label - render classes, value classes, …

More information about FieldsHelper: https://www.joomill-extensions.com/extensions/custom-fields-plugins/documentation/render-custom-fields-manually

7.2.4 Forcing an Alternate Layout when displaying the Value of a Custom Field

Now let’s suppose you have created and assigned an Alternate Layout to a Custom Field.

Then you will notice that the Alternate Layout is not triggered when using the line of code above.

Let’s take the example of our last presentation https://slides.woluweb.be/cf-subform/cf-subform.html where we created a Custom Field of Type Subform displaying

  • as “bullet points” (unordered list) by default
  • as a real carousel by creating and assigning an Alternate Layout

If you want to force an Alternate Layout (in this example london.php) for a CF then simply use the following code:

<p><?php echo FieldsHelper::render('com_content.article', 'field.london', ['field' => $myCustomFieldsById[4]]); ?></p>

See the result on the animated gif hereafter: even our Carousel is now directly displayed on the Smart Search Results Pages!


com_finder

7.2.5 Special case - only if you added a unique ID to a Custom Field Alternate Layout

When giving examples about Custom Field of Type Subform on https://slides.woluweb.be/cf-subform/cf-subform we showed several possible Alternate Layouts allowing to have several Carousels on the same page:

https://github.com/woluweb/Custom-Field-of-Type-Subform

Don’t use the “advanced” Alternate Layout which injects the Article ID from


/templates/cassiopeia/html/layouts/com_fields/fields/render.php
into
/templates/cassiopeia/html/layouts/com_fields/field/______.php
… bc the first file won’t be called here in the context of Smart Search so the Article ID would not be injected automatically in the Alternate Layout
https://github.com/woluweb/Custom-Field-of-Type-Subform/blob/main/step4-my-carousel-article-and-blog-views-with-article-id.php

You should rather use the following (or a fork of it), based on a hash of the rawvalue of the CF of Type Subform and do not require extra file(s)
https://github.com/woluweb/Custom-Field-of-Type-Subform/blob/main/step3-my-carousel-article-and-blog-views.php

8 Displaying Tags in the same view

By defaults Tags are not available neither in the Smart Search Results View.

Yannick Gaultier gives us the solution to make them available on https://www.facebook.com/groups/joomlanospam/posts/10158832276465997/?comment_id=10158834244510997

In practice it works the same way we added Custom Fields in default_article.php

  • for Custom Fields we have to call the FieldsHelper: use \Joomla\Component\Fields\Administrator\Helper\FieldsHelper;
  • for Tags we have to call the TagsHelper: use Joomla\CMS\Helper\TagsHelper;

Here is the full code for Tags in order to call them… and loop through them to also get the link:

use Joomla\CMS\Helper\TagsHelper;
use Joomla\CMS\Helper\RouteHelper;
$tagsHelper = new TagsHelper;
$routeHelper = new RouteHelper;
$tags = $tagsHelper->getItemTags(
$this->result->getElement('context'),
$this->result->id
);
foreach ($tags as $tag)
{
$tagRoute = $routeHelper->getRoute(
$tag->id,
'com_tags.tag'
);
$sefUrl = Route::_($tagRoute);
}

9 Displaying the article Full Text with its style instead of the trimmed introtext

By default, the Smart Search displays a trimmed introtext.

If instead you want to have the real article Full Text with its style, in default_article.php just replace

<?php echo $description; ?>

by

<?php echo $this->result->summary; ?>

10 What else is available in our override

If you want to see what is available in your override of default_article.php add the following line for example in the <li class="result__item"> line:

<pre><code><?php echo print_r($this->result, true); ?></code></pre>

11 The ultimate step - a Filtering solution in the Smart Search Results Pages

There are different Filter extensions in Joomla (see https://magazine.joomla.org/all-issues/august-2021/custom-fields-episode-6-make-more-with-extensions section “Filters and Custom Fields”).

But afaik there is only 1 filtering solution being integrated with the J4 Smart Search (which makes it very powerful): JFilters, developed by Sakis

JFilters allows to filter your content using

  • Custom Fields
  • Categories
  • Tags

It is also SEO-friendly.

jfilters

For more information, see

11.1 Create a template override only for JFilters

JFilters uses the Layout of the Smart Search.

As explained above, you can customize that view by creating for example /templates/[YOUR_TEMPLATE]/html/com_finder/search/default_article.php

But sometimes my might want to create a template override of a layout that will be used exclusively by JFilters and not by Smart Search.

If this is what you are looking you can create a template override, only for JFilters, under the folder: /templates/[YOUR_TEMPLATE]/html/com_jfilters/results/

Just use the layouts for the Smart Search /components/com_finder/tmpl/search/ under this folder.

11.2 Tips & tricks about JFilters

See regularly the new posts on https://blue-coder.com/help/blog.

Example of interesting news:

13 Thank you

The organizers of the different virtual and physical Joomla events for giving me the opportunity to share this presentation at their respective events

So many members of the Joomla Community for being #jPositive

YOU who showed interest in this presentation. And even more if you share any feedback/suggestion you might have

😉

14 Get in touch

https://slides.woluweb.be

Any suggestion about this presentation?
Please feel free to contact me. I’ll be happy to keep improving it 🙂

Marc Dechèvre | woluweb
+32 474 37 13 12 | +32 2 772 58 69

https://www.woluweb.be/contact