Symfony 《西流士》中单频道多主题的思想
对于我的项目,我需要为不同的设备设计多个主题,但现在在一个频道中,我只能选择一个主题 比如说,, 如果我有一个在日本销售的频道“Japan”,我希望每个设备都有多个主题:手机、平板电脑和PC。因此,用户将看到主题取决于他们的设备 我需要一些关于使用单个通道为不同设备创建多个主题/样式的想法Symfony 《西流士》中单频道多主题的思想,symfony,themes,sylius,Symfony,Themes,Sylius,对于我的项目,我需要为不同的设备设计多个主题,但现在在一个频道中,我只能选择一个主题 比如说,, 如果我有一个在日本销售的频道“Japan”,我希望每个设备都有多个主题:手机、平板电脑和PC。因此,用户将看到主题取决于他们的设备 我需要一些关于使用单个通道为不同设备创建多个主题/样式的想法 有什么想法吗?好的,负责当前主题的服务是sylius.context.theme服务。如果使用Sylius full stack,则将使用ChannelBasedThemeContext(请参阅:)。正如您在
有什么想法吗?好的,负责当前主题的服务是
sylius.context.theme
服务。如果使用Sylius full stack,则将使用ChannelBasedThemeContext
(请参阅:)。正如您在其源代码中所看到的,它只是通过themethemeName
属性在当前频道上查找您安装的主题。知道了这一点,我们可以通过实现ThemeContextInterface
来实现自己的功能。因为在您的情况下,当主题japan\u 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\u mobile
,如果它不存在,它只会加载japan
主题(假设当前频道的主题名为japan
)
我希望这是一个足够清晰的说明,可以帮助您继续,因为注入一个能够检测到正确设备名称的服务并不难,我想,但如果您无法理解,请告诉我,我也将通过实现来扩展这一点