對於我的項目,我需要針對不同設備的多個主題設計,但現在在一個頻道中,只能選擇一個主題。在Sylius的單個頻道上的多個主題的想法
例如, 如果我有在日本銷售的頻道「日本」,我想爲每個設備的多個主題:手機,平板電腦和PC。所以用戶會看到主題取決於他們的設備。
我需要一些關於使用單個通道爲不同設備創建多個主題/樣式的想法。
那麼,有什麼想法?
對於我的項目,我需要針對不同設備的多個主題設計,但現在在一個頻道中,只能選擇一個主題。在Sylius的單個頻道上的多個主題的想法
例如, 如果我有在日本銷售的頻道「日本」,我想爲每個設備的多個主題:手機,平板電腦和PC。所以用戶會看到主題取決於他們的設備。
我需要一些關於使用單個通道爲不同設備創建多個主題/樣式的想法。
那麼,有什麼想法?
好的,所以負責當前主題的服務是sylius.context.theme
服務。如果您使用Sylius full stack,則將使用ChannelBasedThemeContext
(請參閱:https://github.com/Sylius/SyliusCoreBundle/blob/master/Theme/ChannelBasedThemeContext.php)。正如您在源代碼中看到的那樣,它只是在當前頻道中找到您已通過主題themeName
屬性安裝的主題。知道這一點,我們可以通過實施ThemeContextInterface
來實現我們自己的目標。因爲在你的情況下,當主題japan_mobile
不存在時,你可能想回到默認行爲,我們將裝飾sylius.context.theme
服務,而不是替換它!
因此,讓我們通過創建Acme\AppBundle\Theme\DeviceBasedThemeContext
開始:
namespace Acme\AppBundle\Theme\DeviceBasedThemeContext;
use Sylius\Bundle\ThemeBundle\Context\ThemeContextInterface;
use Sylius\Bundle\ThemeBundle\Repository\ThemeRepositoryInterface;
use Sylius\Component\Channel\Context\ChannelContextInterface;
use Sylius\Component\Channel\Context\ChannelNotFoundException;
use Sylius\Component\Core\Model\ChannelInterface;
final class DeviceBasedThemeContext implements ThemeContextInterface
{
/**
* @var ThemeContextInterface
*/
private $decoratedThemeContext;
/**
* @var ChannelContextInterface
*/
private $channelContext;
/**
* @var ThemeRepositoryInterface
*/
private $themeRepository;
/**
* @param ThemeContextInterface $decoratedThemeContext
* @param ChannelContextInterface $channelContext
* @param ThemeRepositoryInterface $themeRepository
*/
public function __construct(
ThemeContextInterface decoratedThemeContext,
ChannelContextInterface $channelContext,
ThemeRepositoryInterface $themeRepository
) {
$this->decoratedThemeContext = $decoratedThemeContext;
$this->channelContext = $channelContext;
$this->themeRepository = $themeRepository;
}
/**
* {@inheritdoc}
*/
public function getTheme()
{
try {
/** @var ChannelInterface $channel */
$channel = $this->channelContext->getChannel();
$deviceThemeName = $channel->getThemeName().’_’.$this->getDeviceName();
// try to find a device specific version of this theme, if so, it will use that one
if ($theme = $this->themeRepository->findOneByName($deviceThemeName) {
return $theme;
}
// fallback to use the default theme resolving logic
return $this->decoratedThemeContext->getTheme();
} catch (ChannelNotFoundException $exception) {
return null;
} catch (\Exception $exception) {
return null;
}
}
private function getDeviceName()
{
// here you should return the proper device name
return ‘mobile’;
}
}
現在,我們有主題背景下完成,我們已經讓服務容器識別它,我們正在做的是通過裝飾現有sylius.theme.context
服務(又名ChannelBasedThemeContext
)。
所以在你services.xml
添加以下服務:
<service id="acme.context.theme.device_based" class="Acme\AppBundle\Theme\DeviceBasedThemeContext"
decorates=「sylius.theme.context」>
<argument type=「service」 id=「acme.context.theme.device_based.inner」/>
<argument type=「service」 id=「sylius.context.channel」/>
<argument type=「service」 id=「sylius.repository.theme」/>
</service>
而你完成!如果你清除緩存,現在應該首先加載japan_mobile
,如果它不存在,它將簡單加載japan
主題(假設當前頻道的主題名稱爲japan
)。
我希望這是一個足夠明確的指令,以幫助您順利進行,因爲注入可以檢測到適當設備名稱的服務並不難,我猜,但如果您無法弄清楚,請告訴我我也會通過實施這個來擴展它。