Multilingual Product Feed
August 7, 2025 ยท AI Conversations
How to get product title and description based on it
0)
{
foreach ($products as $product) {
$productu = Product::getByID($product['pID']);
$page = Page::getByID($productu->getPageID());
if (!$page || $page->isError()) {
$this->logFeedStatus($db, $config['id'], 'error', "Missing or invalid page for product ID {$product['pID']} ({$product['pName']}). Page ID: {$pageID}");
continue;
}
$url = $page->getCollectionLink();
$imageUrl = '';
$image = $productu->getImageObj();
if (is_object($image)) {
$imageUrl = $image->getURL();
}
$brand = '';
if (is_numeric($product['pManufacturer'])) {
$manufacturer = $db->fetchAssociative("SELECT * FROM CommunityStoreManufacturer WHERE mID = ?", [$product['pManufacturer']]);
if (is_array($manufacturer)) {
$brand = $manufacturer['mName'];
}
}
// ๐จ Check for empty description and log it
if (empty(trim($product['pDesc']))) {
$errorMessage = sprintf(
"Missing description for product ID %d (%s). Skipped from feed.",
$product['pID'],
$product['pName']
);
$this->logFeedStatus($db, $config['id'], 'error', $errorMessage);
continue; // skip product
}
$item = $channel->addChild('item');
$item->addChild('g:id', $product['pID'], 'http://base.google.com/ns/1.0');
$item->addChild('title', htmlspecialchars($product['pName']));
$item->addChild('description', htmlspecialchars($product['pDesc']));
$item->addChild('link', htmlspecialchars($url));
$item->addChild('g:image_link', htmlspecialchars($imageUrl), 'http://base.google.com/ns/1.0');
$item->addChild('g:availability', 'in stock', 'http://base.google.com/ns/1.0');
$item->addChild('g:price', $product['pPrice'] . ' USD', 'http://base.google.com/ns/1.0');
$item->addChild('g:brand', htmlspecialchars($brand), 'http://base.google.com/ns/1.0');
$item->addChild('g:condition', 'new', 'http://base.google.com/ns/1.0');
$item->addChild('g:identifier_exists', 'false', 'http://base.google.com/ns/1.0');
}
$this->logFeedStatus($db, $config['id'], 'success');
return new Response($xml->asXML(), 200, ['Content-Type' => 'application/xml']);
}else{
$this->logFeedStatus($db, $config['id'], 'error', 'No matching product found');
return new Response("Error generating feed: No matching product found" , 200);
}
} catch (Exception $e) {
if (isset($db) && isset($config['id'])) {
$this->logFeedStatus($db, $config['id'], 'error', $e->getMessage());
}
return new Response("Error generating feed: " . $e->getMessage(), 500);
}
}
}
Concrete CMS handles multilingual content using **Multilingual Sections** and **translated page trees**. Here's how to correctly get the translated title and description:
—
### โ Step-by-step integration for multilingual support in your `generateXml` method:
#### ๐ Replace this line:
$item->addChild('title', htmlspecialchars($product['pName']));
$item->addChild('description', htmlspecialchars($product['pDesc']));
#### ๐ With this **multilingual-aware block**:
use ConcreteCoreMultilingualPageSectionSection;
...
$locale = Localization::activeLocale();
$section = Section::getByLocale($locale);
$translatedPage = ConcreteCoreMultilingualPageSectionSection::getTranslatedPage($page, $section);
if ($translatedPage && !$translatedPage->isError()) {
$title = $translatedPage->getCollectionName();
$description = $translatedPage->getCollectionDescription();
} else {
// fallback to original
$title = $page->getCollectionName();
$description = $page->getCollectionDescription();
}
Then use:
$item->addChild('title', htmlspecialchars($title));
$item->addChild('description', htmlspecialchars($description));
—
### ๐ Notes:
– `getCollectionName()` gets the page's title (from the Name field).
– `getCollectionDescription()` gets the page's meta description.
– If your product titles and descriptions are stored in **custom attributes or blocks**, you would need to get them using `$translatedPage->getAttribute('your_attribute_handle')`.
—
### โ
Optional: Switch locale manually
If you're generating feed for a **specific locale**, you can set it before fetching translated pages:
Localization::changeLocale('de_DE'); // or 'fr_FR', etc.
—
Let me know if you're using a **block or attribute** for product description, and Iโll give you the exact code to fetch translated versions of that content.