I run a multi website setup where there is only one store and store view per website.
In this scenario the store switcher won't work, so I'd like to implement a website switcher instead.
I'd like to use this [article][1] to implement it,
Based on Daniels solution below, I did the following.
Created a module
/app/code/{vendor}/{module}/ViewModel/StoreSwitchModel.php
With the following code
<?php
namespace [Vendor]\{Module}\ViewModel;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Locale\TranslatedLists;
use Magento\Framework\Url\EncoderInterface;
use Magento\Framework\UrlInterface;
use Magento\Store\Api\Data\StoreInterface;
use Magento\Store\Model\ResourceModel\Website\Collection as WebsiteCollection;
use Magento\Store\Model\ResourceModel\Website\CollectionFactory as WebsiteCollectionFactory;
use Magento\Store\Model\ScopeInterface;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Store\ViewModel\SwitcherUrlProvider;
class StoreSwitchModel extends SwitcherUrlProvider
{
const LOCALE_CONFIG_PATH = 'general/locale/code';
const DEFAULT_COUNTRY_CONFIG_PATH = 'general/country/default';
private $websiteCollectionFactory;
private $scopeConfig;
private $translatedLists;
private $storeManager;
public function __construct(
EncoderInterface $encoder,
StoreManagerInterface $storeManager,
UrlInterface $urlBuilder,
WebsiteCollectionFactory $websiteCollectionFactory,
ScopeConfigInterface $scopeConfig,
TranslatedLists $translatedLists
) {
parent::__construct($encoder, $storeManager, $urlBuilder);
$this->websiteCollectionFactory = $websiteCollectionFactory;
$this->scopeConfig = $scopeConfig;
$this->translatedLists = $translatedLists;
$this->storeManager = $storeManager;
}
public function getWebsite()
{
return $this->storeManager->getWebsite();
}
public function getWebsites(): WebsiteCollection
{
return $this->websiteCollectionFactory->create();
}
public function getStoreLocale(StoreInterface $store): string
{
$locale = $this->scopeConfig->getValue(self::LOCALE_CONFIG_PATH, ScopeInterface::SCOPE_STORE, $store->getId());
return $locale;
}
public function getStoreCountryCode(StoreInterface $store): string
{
return $this->scopeConfig->getValue(
self::DEFAULT_COUNTRY_CONFIG_PATH,
ScopeInterface::SCOPE_STORE,
$store->getId()
);
}
}
Created the following file at
/app/code/{vendor}/{module}/etc/frontend/di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\Store\ViewModel\SwitcherUrlProvider" type="[Vendor]\{Module}\ViewModel\StoreSwitchModel" />
</config>
And updated the child_theme languages.phtml at
{vendor}/{child_theme}/Magento_Store/templates/switch/languages.phtml
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
// @codingStandardsIgnoreFile
/** @var \Magento\Store\Block\Switcher $block */
?>
<?php
/** @var \Magento\Store\Block\Switcher $block */
$viewModel = $block->getData('view_model');
$websites = $viewModel->getWebsites();
$websiteid = $viewModel->getWebsite()->getWebsiteId();
?>
<div class="switcher store switcher-store" id="switcher-store">
<strong class="label switcher-label"><span><?php echo __('Select Store') ?></span></strong>
<div class="actions dropdown options switcher-options">
<?php foreach ($websites as $website): ?>
<?php if ($websiteid == $website->getId()): ?>
<div class="action toggle switcher-trigger"
role="button"
tabindex="0"
data-mage-init='{"dropdown":{}}'
data-toggle="dropdown"
data-trigger-keypress-button="true"
id="switcher-store-trigger">
<strong>
<span><?php echo $block->escapeHtml($website->getName()) ?></span>
</strong>
</div>
<?php endif; ?>
<?php endforeach; ?>
<ul class="dropdown switcher-dropdown" data-target="dropdown">
<?php foreach ($websites as $website): ?>
<?php if (!($websiteid == $website->getId())): ?>
<li class="switcher-option view">
<a href='<?php echo $website->getDefaultStore()->getBaseUrl() ?>'>
<?php echo $block->escapeHtml($website->getName()) ?>
</a>
</li>
<?php endif; ?>
<?php endforeach; ?>
</ul>
</div>
</div>
This shows the website switcher instead of a store switcher.
$websiteid = $viewModel->getWebsite()->getWebsiteId();
do you have any websites in the collection$websites
?var_dump($websites)
to see it's contents.