Joomla 4+ system plugin that automatically generates JSON-LD structured data (schema.org) for e-shops running VirtueMart.
| Joomla | VirtueMart | PHP | Current version |
|---|---|---|---|
| 4.x, 5.x, 6.x | 4.x | 8.1+ | 1.0.0 |
1. Requirements
- Joomla 4.x, 5.x, or 6.x
- VirtueMart 4.x (optional – the plugin works without it, but Product and Breadcrumb schemas require VM)
- PHP 8.1 or newer
- MySQL 5.7+ / MariaDB 10.3+
2. Installation
Obtaining the Installation Package
Download the ZIP file plg_system_semavmstructureddata.zip from SemaHub.
Installation Steps
- Log in to the Joomla administration panel.
- Navigate to System > Install > Extensions.
- Upload the
plg_system_semavmstructureddata.zipfile. - Joomla installs the system plugin
plg_system_semavmstructureddata.
Upgrade: Same procedure as installation. Joomla uses
method="upgrade"and preserves all existing settings.
3. Enabling the Plugin
After installation, the plugin must be manually enabled:
- System > Manage > Plugins
- Search for
semavmstructureddataorStructuredData. - Click the plugin name and set Status = Enabled.
- Alternatively: click the red icon directly in the Status column.
Once enabled, JSON-LD structured data is immediately injected into the
<head>of all frontend pages.
4. Organization Settings
The “Organization” fieldset defines company details used in the Organization schema (displayed on all pages).
| Parameter | Default | Description |
|---|---|---|
| Organization Name | (empty) | Legal company name. |
| Alternate Name | (empty) | Brand name or trade name. Also used as the WebSite name. |
| Website URL | (empty) | Full URL of the website (including https://). |
| Logo Path | (empty) | Relative path to the logo image (e.g. images/logo.svg). |
| Phone – Customer Service | (empty) | Customer service phone number. |
| Phone – Technical Support | (empty) | Technical support phone number. |
| Street Address | (empty) | Street and house number. |
| City | (empty) | City name. |
| Postal Code | (empty) | ZIP / postal code. |
| Country Code | (empty) | ISO 3166-1 alpha-2 country code (e.g. CZ, SK, DE). |
| Tax ID | (empty) | Company tax identification number (VAT ID). |
| (empty) | Contact email address. | |
| Area Served | (empty) | Country or region served (e.g. CZ). |
| Available Language | (empty) | Language of the website (e.g. Czech, English). |
Recommendation: Fill in all organization details. Search engines use this data to display enhanced company information in search results (Knowledge Panel).
5. Shipping Settings
The “Shipping” fieldset configures shipping details used in the Product schema’s ShippingDetails.
| Parameter | Default | Description |
|---|---|---|
| Currency | CZK | Currency code (ISO 4217). |
| Free Shipping Threshold | 2500 | Order amount above which shipping is free. |
| Shipping Price | 99 | Shipping cost for orders below the threshold. |
| Shipping Country | CZ | Country code for shipping destination. |
| Handling Time Min (days) | 0 | Minimum order processing time. |
| Handling Time Max (days) | 1 | Maximum order processing time. |
| Transit Time Min (days) | 1 | Minimum delivery time. |
| Transit Time Max (days) | 3 | Maximum delivery time. |
The plugin automatically calculates shipping cost per product: if the product price is above the threshold, shipping is
0; otherwise, the configured shipping price is used.
6. Return Policy Settings
The “Return Policy” fieldset configures return details used in the Product schema’s MerchantReturnPolicy.
| Parameter | Default | Description |
|---|---|---|
| Return Window (days) | 14 | Number of days the customer can return goods. |
| Return Policy Country | CZ | Country code for the return policy. |
| Return Method | Return by Mail | How goods can be returned (ReturnByMail or ReturnInStore). |
| Return Fees | Customer Responsibility | Who pays for return shipping (ReturnFeesCustomerResponsibility or FreeReturn). |
7. Features (Schema Toggles)
The “Features” fieldset lets you enable or disable individual schema types.
| Parameter | Default | Description |
|---|---|---|
| Enable Organization Schema | Yes | Organization schema on all pages. |
| Enable WebSite Schema | Yes | WebSite schema on the homepage only. |
| Enable SearchAction | No | SearchAction within the WebSite schema (enables sitelinks searchbox in Google). |
| Search URL Pattern | /vyhledavani?searchword={search_term_string} | URL template for the search action. Must contain {search_term_string}. |
| Enable Product Schema | Yes | Product schema on VirtueMart product detail pages. |
| Enable BreadcrumbList Schema | Yes | BreadcrumbList schema on VirtueMart product detail pages. |
| Home Breadcrumb Label | Home | Text for the first breadcrumb item (home page). |
| Placeholder Image Path | images/stories/virtuemart/product/noimage.jpg | Fallback image when a product has no image. |
8. How the Plugin Works
- The plugin listens to the
onAfterRenderevent – it runs after the entire page has been rendered. - It checks that the request is a frontend HTML page (not admin, not AJAX, not feed).
- Homepage detection: Compares the active menu item ID with the default menu item ID.
- Product detection: Checks for
option=com_virtuemart,view=productdetails, and a validvirtuemart_product_id. - Based on the configuration, it builds the appropriate JSON-LD schemas.
- The JSON-LD
<script>blocks are injected before the closing</head>tag usingstr_replace.
VirtueMart Availability
If VirtueMart is not installed or its classes are not available, the plugin gracefully skips Product and Breadcrumb schemas. Organization and WebSite schemas work independently.
9. Generated Schema Types
Organization
- Where: All frontend pages (when enabled).
- Contains: Company name, alternate name, URL, logo, contact points (customer service and technical support phones), postal address, tax ID, email, area served, available language.
WebSite
- Where: Homepage only (when enabled).
- Contains: Website name (uses alternate name), URL. Optionally includes a
SearchActionfor the sitelinks searchbox.
Product
- Where: VirtueMart product detail pages (when enabled and VM is available).
- Contains:
- Product name, description, SKU, images
- Offer: Price, currency, availability (InStock / OutOfStock), seller (organization URL)
- ShippingDetails: Shipping rate (free or paid based on threshold), destination country, handling and transit times
- MerchantReturnPolicy: Return window, country, method, fees
- Brand: Manufacturer name (with database fallback)
BreadcrumbList
- Where: VirtueMart product detail pages (together with Product, when enabled).
- Contains: Home > Category (if available) > Product name.
10. Validation
After enabling the plugin, validate the generated structured data using:
- Google Rich Results Test: https://search.google.com/test/rich-results
- Schema.org Validator: https://validator.schema.org/
How to Check
- Open your website in a browser.
- View page source (Ctrl+U) and search for
application/ld+json. - You should see JSON-LD blocks before the
</head>tag. - Copy the JSON-LD content and paste it into the validators above.
11. Uninstallation
- Navigate to System > Manage > Extensions.
- Search for
semavmstructureddata. - Select and uninstall.
All plugin files are removed. There are no database tables to clean up – the plugin only reads data, it does not create any tables.
12. Troubleshooting
JSON-LD Not Appearing in Page Source
- Verify the plugin is enabled (Status = Enabled).
- Check that you are viewing the frontend (not admin).
- Verify the relevant schema is enabled in the Features tab.
- Check the page source (Ctrl+U) and search for
ld+json.
Product Schema Not Appearing
- Verify VirtueMart is installed and functioning.
- Confirm you are on a product detail page (
view=productdetails). - Check that the product has a valid
virtuemart_product_id. - Ensure “Enable Product Schema” is set to Yes in plugin settings.
WebSite Schema Not Appearing
- The WebSite schema only appears on the homepage.
- Verify the current page is the default menu item.
- Ensure “Enable WebSite Schema” is set to Yes.
Incorrect Product Data
- Price shows 0.00: The product may not have a
salesPriceorpriceWithTaxset in VirtueMart. - No product image: The plugin falls back to the placeholder image. Upload product images in VirtueMart.
- Missing manufacturer: The plugin tries
$product->mf_namefirst, then falls back to a direct database query. Ensure the manufacturer is assigned to the product in VirtueMart. - Wrong availability: Stock is calculated as
product_in_stock - product_ordered. Verify stock levels in VirtueMart.
Google Search Console Errors
- Validate using the Rich Results Test first.
- Common issues: missing required fields (ensure all Organization parameters are filled in), invalid image URLs (check logo and product image paths).
Security
- XSS prevention: All JSON-LD output uses
JSON_HEX_TAGflag, which encodes<and>to prevent script injection. - Input filtering: Request parameters are read using
getCmd()andgetInt(). - SQL safety: All IDs are cast to
(int), column names usequoteName(), and the VirtueMart language table suffix is validated with a regex. - User data: Product names, descriptions, and category names are passed through
strip_tags().