Skip to main content

Structured Content for Joomla "Product Articles" with WidgetsBox

Posted in:

on by Marco Rensch

In this tutorial I take you on a journey that shows you step by step how you can generate structured content with Joomla! board means, with the help of CustomFields with the WidgetsBox. So let's have fun!

Disclaimer:

To be successful with this tutorial you need to use at least Joomla 3.7.x and the latest version of WidgetsBox. Furthermore, one or two cups of coffee won't be a bad thing either. Ah and by the way, all screenshots were made on Joomla 4 (Pre-Release) - but the handling on Joomla 3.x is identical. We do not give you any guarantee that you got a better SEO ranking when using the WidgetsBox functions described in this post. It is fully up to you to understand what you are doing and that this could also have a negative impact to your SEO ranking when you use the given options falsely.

In this tutorial we will create a new article category, a corresponding article field group and the necessary fields for the structured type "Product". A Joomla article here represents one product at a time. By using structured data created with customfields, WidgetsBox can automatically generate a structured data set which can then be used by search engines to display rich content search results.

Step 1 | The BASE structure

We'll start simple, for clarity we'll create a new category for our items, we'll call it "Products" in our example. Next, we navigate to the field groups (Content --> Field Groups) and create a new field group with the name "Products". Note: The names can be chosen completely freely.

So now we have an article category named "Products" and a field group named "Products".

Step 2 | Create the fields

Now we start to create the fields that will later contain our additional information for the given product. Namely, we need the following fields for our "Rich Content" structure:

  • Price
  • Currency
  • Brand
  • SKU1
  • MPN1
  • Valid Until
  • Stock Information2

As well as optional for the rating of the product, unless we use the Joomla! integrated rating:

  • Rating Value3
  • Rating Counter3
  1. At least one value should be defined for SKU or MPN so that the product can be correctly identified by search engines or others.
  2. If no stock information is specified, the module will automatically use the value for "inStock" available in the structured content.
  3. Fully optional

Price Field

The price field only has to contain the price as a number, for simplicity's sake I'll use a field of the type "Text" here. Let's switch to the field overview (Content --> Fields) and create a new field with the title "Price". As type we choose Text and as Filter we select "no". Finally, we select the field group "Products" in the right column, delete the entry "All" in the category and select "Products" here.

Default Fields Text list marked

Currency, Brand, SKU, MPN Field

We do the same for the fields Currency, Brand, SKU and MPN. As title we also simply use Currency, Brand, SKU and MPN. Of course, you can assign description texts where they are necessary from your point of view. These are then simply displayed in the backend when editing the article in the appropriate field.

After the fields have been created, your overview of the fields should look like this. Make sure that the category is entered correctly for each field, that the field is published and that the access level is set correctly so that the corresponding field can be used later.
Fields can be assigned to article categories, if a field is not assigned to a category it will never appear in the "Edit article mask". If "All" is selected as the category, it can quickly become very confusing later, when you may use more fields.

Default Fields Text list marked

Valid Until Field

The Valid Until field defines how long this product price / offer is valid. Since this must be a date or search engines expect this type in the correct date format, it is also recommended to use a field type of the type "Calendar".

Stock Information Field

For the Stock Information Field we do not use a field of the type Text but "List". We create a new field as usual using the button in the upper left corner. As title we use "Stock Information" and as fieldtype "List". We set the Multiple option to "No", because a product can only have one stock type, either we have it in stock or not...

In our case we have to make sure that we use correct field values. We define these in the options that we can store at the bottom of the field settings. Since we have to stick to the given scheme, we can only use the following options:

  • BackOrder
  • Discontinued
  • InStock
  • InStoreOnly
  • LimitedAvailability
  • OutOfStock
  • ...

All available "ItemAvailability" members can be found here: https://schema.org/ItemAvailability. For the moment the three options Discontinued, InStock and OutOfStock are sufficient. Just use the member you need according to the scheme link. We now simply have to make sure that the "Value" value corresponds to the schema name, the label can be freely chosen. I have decided for the following:

Default Fields Text list marked

Also for the Stock Information field we have to remember to set the category in the right column to "Products" and select the field group also "Products" so that this field will be loaded together with the others when we create / edit the article right away.

Step 3 | We create the products

To do this, we switch to the article overview (Content --> Articles) and create a new article using the button at the top left. The first thing we notice is that everything is the same. Our fields are not displayed. But if we first select the category for the article and set it to "Products", Joomla reloads the page briefly and we get a new tab "Products" at the top in which we can add our "additional" information to the article:

Default Fields Text list marked

The field group "Products" has now been added to the Joomla Article Editor as a separate tab. However, only if there are fields in it that have been selected for the corresponding article category.

Default Fields Text list marked

Above we can see how it looks like in my example. In the tab Products all fields are listed that we created before. We can now fill these with information.

Up to this point everything was still "Joomla Core" as they say. Now let's create some products and then see what we can do with them in the WidgetsBox. See you in a minute!

What to do when

Some fields are not displayed:
Take another look at the field settings, especially the right column for the fields that are not displayed. Is the field published? Is the field assigned to the category "Products"? Is the field assigned to the field group "Products"?

Some fields are not displayed in the "Products" tab but can be found in the Fields tab:
Check the options for the corresponding field, you will have forgotten to assign the field to the "Products" field group.

Step 4 | Configure WidgetsBox to create Structured Content

By default, this option is disabled, but with WidgetsBox 2.5 we have given you the option to automatically generate structured content for the articles that WidgetsBox displays. Let's finish the basics (there is a better tutorial in the manual --> First Steps). Open the configuration of a WidgetsBox instance and select the desired widget type. I'll use the Accordion because it's the fastest way. In the filter options we set a filter for the category "Products" so that our module only shows items of this category.

Next, we make sure that we publish the module on a position (so that it is displayed somewhere) and to be on the safe side, we check in the tab "Menu Assignement" that the module is published on all or the desired pages.

When we have done this, we should see our Accordion at the corresponding position, but there is still nothing to be seen of the Customfields:

Default Fields Text list marked

Please do not be put off by the design, the module is not styled and Joomla 4 is currently doing its worst... But what you can see is that I have created 3 products here which are all displayed.

However, we are concerned here with structured content - and this is what we configure now (finally). In the module settings we switch to the tab "Structured Content". When the option to "use" structured content is activated, further options will be available. In the first step we select the schema type of content for which WidgetsBox should generate the structure. Of course we select "Product" here in this tutorial but you could do a quick look how many / which fields are required for other types when changing the type here. For example the FAQ type does not need any further fields and works directly with the title and content of your articles.

We will find more or less fields (depending on the type) that we have to link with our custom fields. Some fields can also be skipped by using the "Not set" option. But be careful, there is an article in the manual for each supported schema type, it will tell you to decide which fields you can "skip". Ignoring the wrong data could lead to a devaluation by search engines, so be carefull.

Step 5 | Check structured content

Every time the module instance is loaded now, in addition to rendering the content, the module will also add a JSON script to the head of the page that contains the structured content.

The module now creates the structured content for you, faith is good control is better. You can check the head area in the source code of the page. There you will find a new script of type "application/ld+json". Or alternatively you can also check the URL on which the module is displayed directly by the checker. My example generated the following code:

[
    {
        "@context": "https://schema.org/",
        "@type": "Product",
        "creator": {
            "@type": "Person",
            "name": "Marco Rensch"
        },
        "name": "My First Product",
        "description": "My First Product description stays here.\u00a0My First Product description stays here. My First Product description stays here. My First Product description stays here. My First Product description stays here. My First Product description stays here. My First Product description stays here. My First Product description stays here. My First Product description stays here.\u00a0My First Product description stays here.",
        "sku": "MYPRDCT2313",
        "mpn": "1234567890",
        "brand": {
            "@type": "Brand",
            "name": "nx-productions"
        },
        "offers": {
            "@type": "Offer",
            "url": "http://j4beta.area59.ch//index.php?view=article&id=5:my-first-product&catid=10",
            "price": "22.50",
            "priceCurrency": "USD",
            "priceValidUntil": "2021-07-30T00:00:00+00:00",
            "availability": "https://schema.org/InStock"
        }
    },
    {
        "@context": "https://schema.org/",
        "@type": "Product",
        "creator": {
            "@type": "Person",
            "name": "Marco Rensch"
        },
        "name": "Somewhat used EarPods",
        "description": "This is my earpods article",
        "brand": {
            "@type": "Brand",
            "name": "Apple"
        },
        "offers": {
            "@type": "Offer",
            "url": "http://j4beta.area59.ch//index.php?view=article&id=6:somewhat-used-earpods&catid=10",
            "price": "5",
            "priceCurrency": "CHF",
            "priceValidUntil": "2021-07-29T00:00:00+00:00",
            "availability": "https://schema.org/InStock"
        }
    },
    {
        "@context": "https://schema.org/",
        "@type": "Product",
        "creator": {
            "@type": "Person",
            "name": "Marco Rensch"
        },
        "name": "Used Surface 3 Keyboard (blue)",
        "description": "Yep here is otherwise some text and so",
        "brand": {
            "@type": "Brand",
            "name": "Microsoft"
        },
        "offers": {
            "@type": "Offer",
            "url": "http://j4beta.area59.ch//index.php?view=article&id=7:used-surface-3-keyboard-blue&catid=10",
            "price": "13",
            "priceCurrency": "USD",
            "availability": "https://schema.org/InStock"
        }
    }
]

If I test this code now at https://search.google.com/test/rich-results I get to know if everything fits or not.

Default Fields Text list marked

Warnings should be checked and fixed if possible, in our case here I'm checking what's missing from the Surface Keyboard item...

  • Field "review" is missing (optional) --> WidgetsBox has actually no support to generate reviews for structured content
  • Field "sku" is missing (optional) --> I have not set an SKU for this item
  • Field "image" is missing (optional) --> I have not set an image for this article / not selected the correct field in module settings
  • Field "aggregateRating" is missing (optional) --> Rating is not used in this example
  • No global identifier specified (e.g. gtin, mpn, isbn) (optional) --> i have not set an SKU neither an MPN for this item
  • Field "priceValidUntil" is missing (optional) --> it looks like i have forgotten to set a valid until date for this product

WidgetsBox has some checks integrated to prevent invalid values, but unfortunately you can't check everything. If the WidgetsBox with activated structured content is visible on a publicly accessible website, you can simply enter the URL in the checker and check the status without having to copy the script manually.

The WidgetsBox also supports you as much as possible in debugging. For this purpose, the debug mode has been massively extended in version 2.5. If this is now activated (Module Settings --> Advanced --> Debug) you can, if you are logged in as administrator in the frontend, display additional information about the structured content that was generated. On the one hand the generated JSON itself and on the other hand you can find additional information in the browser console if an article was not used for the creation of the structured content.

 Default Fields Text list marked

And that's it again for today, done a lot, learned a lot and hopefully had a lot of fun!
See you next time!

Sincerely
Marco