With the sales channel product comparison you can export products to existing price portals. Furthermore you can create complete connections to new marketplaces. By using an export template that works with Twig variables, you can quickly make adjustments and create new exports.
For most portals, a link to the export file can be provided. Depending on the caching method, the file is regenerated each time it is called up and the portal always receives the most current data status. Alternatively, the file is renewed at regular intervals and the portal can fetch the file much faster.
In the general settings you first enter the name for your product comparison. If you would like to use the product comparison for a large price portal, you can also select one of the available templates here. The template will then be configured correctly for the portal in question.
Here you specify the sales channel (1) and storefront domain (2) to which your product comparison refers. You also specify which currency (3), language (4) and customer group (5) should be used for this product comparison.
In the product export section you specify how the output file of the product export should look like. First you specify a Filename (1).
As encoding (2) you can select UTF-8 or ISO-8859-1. Here you should inform yourself at the corresponding price portal, what is needed here.
As file format (3) you can choose a CSV file or a XML file. Also here you should inform yourself at the price portal, what is desired here.
You also specify whether or not you want to include the product variants (4) in the export and enter a generation interval (5). Set the interval (5) for the generation using the scheduler. The product comparison file is just regenerated automatically if the interval has expired and the option Generate via scheduler (6) is activated. You execute the scheduler by executing the command bin/console scheduled-task:run in your shop main directory.
You can use a dynamic product group (7) to define which items from your shop should be included in the product export. You can find out exactly how to create them here.
In the API Access section you can generate an API Access ID for this product comparison. For more information on how to use your own API accesses, please refer to our developer documentation.
In addition, the export URL for this specific product export is displayed here. This URL can be entered in the price portal.
If an error is displayed when calling up the export URL through the browser, check your dynamic product groups.
Add the conditions of the feed in the product group under "Catalogs > Dynamic product groups", e.g. "Sales price > 0" and " e.g. Price > 0".
Here you can temporarily deactivate the product comparison. The call of the product comparison URL and the API will then be temporarily inaccessible. You can also activate the maintenance mode here. The call is restricted and only available for selected IP addresses that are white listed.
If you delete the product comparison using this button, it will be irrevocably removed. You should only do this if the sales channel is no longer needed.
The template determines the structure of the product export file. The template is divided into a header line, a product line and a footer line.
If you use a template in the General tab, usually no adjustments are necessary here. The correct document templates for the respective comparison portals are already included in the templates.
The Test template button checks whether there are any syntax errors in the template. With Generate preview you can directly view the content of the created export file.
The header row differs depending on the selected format.
For a CSV file, the column descriptions are defined here, for example: id, manufacturer, model_no, name, category, price, etc.
In the case of an XML file, the entire file header is also located here, as well as the start tag, title, description, etc.
Here you define the template for the articles that are to be exported. The template is applied to each article using a loop. For CSV/TXT exports this results in one line per article. With an XML export, e.g. Google, each article is enclosed by a start and end tag. So it is possible to customize the exports, depending on structure and requirements. Note the more calculations are performed in the feed, the slower the generation will be!
The footer is only required for XML exports. This field contains the end tags that are opened in the header.
The product comparison is written in the PHP template engine TWIG. The standard already provides you with the most important information about your products. With the TWIG syntax you have the possibility to customise the template completely. You can find detailed documentation on which expressions and commands you can use here.
We have listed the most important commands that you can use in the product comparison here.
if- query:
With the if-query you can check whether a statement is true. This allows you to output the desired content only under certain conditions.
The start tag for an if-query contains if and a condition in a curly bracket and percent sign.
An if-query that checks whether a product is active would look like this:
{% if product.active %}
The condition is followed by the section that is to be output only if the condition is fulfilled, followed by a concluding endif tag, which is also enclosed in curly brackets and percent signs.
{% endif %}
In the following example, the product number is only output if the item is available.
{% if product.active %}
"{{ product.productNumber }}",{#- -#}
{% endif %}
elseif and else query:
The elseif query corresponds to another if query that is executed if the condition of the first if query is not fulfilled. The content behind an else tag is executed if the conditions of all previous if and elseif queries have not been fulfilled.
In the following example, the content 1 is output if the available stock is greater than 20. If it is not, but still greater than 10, content 2 is output. If the available stock is less than 10 and therefore both conditions are not fulfilled, content 3 is output.
{% if product.availableStock >20 %}
content
{% elseif product.availableStock > 10 %}
content 2
{% else %}
content 3
{% endif %}
set
With the set command, you can assign variables that you can then use. For example, with the following command you assign the price of a product to the variable price.
{% set price = product.calculatedPrice %}
You can then continue to work with the short variable instead of using branched resources.
"{{ price.unitPrice }}",{#- -#}
With the help of variables you can add information about the products and the product export to the template. The necessary variables for the respective export are already created in the templates.
For your own exports you can also add your own information with variables.
Each variable starts with product or productExport and can be extended with a dot, for example product.productNumber for the product number.
The variables can also be multi-level. For example, the variable for the product name is product.translated.name.
If you write a dot after a level, all available sublevels are displayed.
List of available Variables
Configuration variables | Description |
productExport.salesChannelDomain.url | URL of the Saleschannel |
context.salesChannel.name | Name of the Saleschannel |
Export settings | Description |
productExport.fileName | export filename |
productExport.accessKey | API - Access key |
productExport.encoding | Encoding standard |
productExport.fileFormat | File format |
productExport.includeVariants | Specifies whether variants are also exported |
productExport.salesChannel. ... | Data on the specified SalesChannel |
productExport.salesChannelDomain. ... | Data on the specified SalesChannel Domain |
Product settings (Only in the product row) | Description |
product.active | Product is activated |
product.productnumber | Product number |
product.translated.name | Product name |
seoUrl('frontend.detail.page', {'productId': product.id}) | Product-URL |
product.translated.description | Description |
product.deliveryTime | Delivery time |
product.restockTime | Time needed to restock the product in days |
product.minPurchase | Minimum purchase |
product.maxPurchase | Maximum purchase |
product.availableStock | Available stock |
product.manufacturerNumber | Manufacturer number |
product.ean | EAN |
product.manufacturer.translated.name | Manufacturer name |
product.cover.media.url | Product picture URL |
product.calculatedPrice.listPrice.price | List price |
product.categories.first.getBreadCrumb | Output of the categories |
product.stock | Quantity in stock |
product.available | Product is available |
product.deliveryTime | Product delivery time |
product.deliveryTimeID | Product delivery time ID |
product.isCloseout | Product is marked for clearance sale |
product.purchaseSteps | The steps in which the product can be bought |
product.referenceUnit | Product reference unit |
product.shippingFree | The product has free shipping |
product.markAsTopseller | Product is an top seller |
product.weight | Weight of the product |
product.width | Width of the product |
product.height | Height of the product |
product.length | Length of the product |
product.releaseDate | Product release date |
product.keywords | Product keywords |
product.description | Product description |
product.metaDescription | Product meta description |
product.metaTitle | Product mate title |
product.packUnit | product pack unit |
product.packUnitPlural | Product pack unit plural |
You also have the option of including custom fields in the template.
The technical name of the custom field is required for this. You can find this in the settings of the additional field.
The general structure for an custom field variable is as follows:
For a product custom field:
{{ product.translated.customFields.technical_name_of_the_custom_field }}
e.g.:
{{ product.translated.customFields.further_information }}
It is also possible to query custom fields of the product manufacturer.
{{ product.manufacturer.translated.customFields.technical_name_of_the_custom_field }}
e.g.:
{{ product.manufacturer.translated.customFields.manufacturer_information }}
It can be useful to include the query of the additional fields in an if-query, so that the output only occurs if the field is also filled.
This is possible, for example, as follows:
{% if product.translated.customFields.technical_name_of_the_custom_field is defined %}
{{ product.translated.customFields.technical_name_of_the_custom_field }}
{% endif %}
By adapting the template, properties can also be output and transferred. The product properties are located in the array product.properties. This can show you the properties.
{% for properties in product.properties %}
{{ properties.name }}
{% endfor %}
If you want to output a specific property group, you can limit and query it with an additional if query.
For example:
{% for properties in product.properties %}
{% if properties.group.name == "size" %}
{{ properties.name }}
{% endif %}
{% endfor %}
By using a condition that ends with an endif tag, you can display multiple image urls of a product. In the following query, five other image urls are output in addition to the cover image, if any are available. You can change the number of Urls to be output as you wish.
{%- if product.media|length > 1 -%}
"{%- for mediaAssociation in product.media|slice(0, 5) -%}
{{ mediaAssociation.media.url }}
{%- if not loop.last -%},{%- endif -%}
{%- endfor -%}"
{%- endif -%}{#- -#}
Errors may occur during the product comparison, these are explained here and how to solve them.
By default, some content such as product images are expected. For example, if you have selected Google Shopping (XML) as the template, the export may be canceled if the dynamic product group for the feed contains one or more items that do not have a product image. In such a case, you should make sure to assign a product image to all products.
Alternatively, you can edit the product line in the Template tab.
The product image URL is displayed using this entry:
<g:image_link>{{ product.cover.media.url }}</g:image_link>
This should be completely replaced by the following entry:
<g:image_link>
{% if product.cover.media.url is defined and product.cover.media.url is not null %}
{{ product.cover.media.url }}
{% endif %}
</g:image_link>
Thus, the first step in a product comparison is to check whether a product image is available. Only if one is available will it be included in the product comparison.
This example can also be applied to other variables.
If there are items in the selected Dynamic Product Group that are not assigned to a valid and available category, the following message may occur:
{"errors":[{"status":"400","code":"FRAMEWORK__STRING_TEMPLATE_RENDERING_FAILED",
"title":"Bad Request","detail":"Failed rendering string template using Twig:
Failed rendering string template using Twig: Impossible to access an attribute (\u0022getBreadCrumb\u0022)
on a null variable in \u0022420463b818562f32a1fd3ff62050d151\u0022 at line 6.",
"meta":{"parameters":
{"message":"Failed rendering string template using Twig: Impossible to access an attribute (\u0022getBreadCrumb\u0022) on a null variable in \u0022420463b818562f32a1fd3ff62050d151\u0022 at line 6."}
}}]}
By adjusting the template, you can check in advance whether a category is stored. So this message is bypassed.
To do this, you can edit the product line in the Template tab.
The category is displayed using this entry:
<g:product_type>{{ product.categories.first.getBreadCrumb|slice(1)|join(' > ')|raw|escape }}</g:product_type>
To check the category before comparing products, replace this entry with the following:
<g:product_type>
{% if product.categories.first.getBreadCrumb is defined and product.categories.first.getBreadCrumb is not null %}
{{ product.categories.first.getBreadCrumb|slice(1)|join(' > ')|raw|escape }}
{% endif %}
</g:product_type>
Thus, when comparing products, the system first checks whether a valid category exists. Only if a category exists is it included in the product comparison.
You can use a whitespace to remove unnecessary spaces or "whitespaces" on the left and right. To do this, you need to add a - at the beginning and end, as shown below.
Example with spaces:
{% for properties in product.properties %}
{% if properties.group.name == "brandname" %}
{{ properties.name }}
{% endif %}
{% endfor %}
Example without spaces:
{%- for properties in product.properties -%}
{%- if properties.group.name == "brandname" -%}
{{- properties.name -}}
{%- endif -%}
{%- endfor -%}
The Shopware templates for the product comparisons and the social shopping sales channels are delivered in a standard configuration. For some products or providers, additions are necessary. For frequently requested elements, we have collected the corresponding code snippets here.