Skip to content

Commit

Permalink
OP-545: Twig templates for blocks and pages
Browse files Browse the repository at this point in the history
  • Loading branch information
jkindly committed Sep 19, 2024
1 parent 6344164 commit 1eb8aae
Show file tree
Hide file tree
Showing 30 changed files with 283 additions and 44 deletions.
2 changes: 1 addition & 1 deletion spec/Menu/ContentManagementMenuBuilderSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public function it_build_menu(
->addChild('templates', ['route' => 'sylius_cms_admin_template_index'])
->willReturn($cmsRootMenuItem)
;
$cmsRootMenuItem->setLabel('sylius_cms.ui.templates')->willReturn($cmsRootMenuItem);
$cmsRootMenuItem->setLabel('sylius_cms.ui.content_templates')->willReturn($cmsRootMenuItem);
$cmsRootMenuItem->setLabelAttribute('icon', 'clone')->shouldBeCalled();

$cmsRootMenuItem
Expand Down
10 changes: 7 additions & 3 deletions src/Controller/BlockController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use FOS\RestBundle\View\View;
use Sylius\Bundle\ResourceBundle\Controller\ResourceController;
use Sylius\CmsPlugin\Entity\BlockInterface;
use Sylius\CmsPlugin\Renderer\ContentElementRendererStrategyInterface;
use Sylius\CmsPlugin\Resolver\BlockResourceResolverInterface;
use Sylius\Component\Resource\ResourceActions;
use Symfony\Component\HttpFoundation\Request;
Expand Down Expand Up @@ -40,9 +41,7 @@ public function renderBlockAction(Request $request): Response
return $this->viewHandler->handle($configuration, View::create($block));
}

$template = $request->get('template') ?? self::BLOCK_TEMPLATE;

return $this->render($template, [
return $this->render($block->getTemplate() ?? self::BLOCK_TEMPLATE, [
'configuration' => $configuration,
'metadata' => $this->metadata,
'resource' => $block,
Expand Down Expand Up @@ -70,8 +69,13 @@ public function previewAction(Request $request): Response
return $this->viewHandler->handle($configuration, View::create($block));
}

/** @var ContentElementRendererStrategyInterface $contentElementRendererStrategy */
$contentElementRendererStrategy = $this->get('sylius_cms.content_element_renderer_strategy');

return $this->render($configuration->getTemplate(ResourceActions::CREATE . '.html'), [
'resource' => $block,
'template' => $block->getTemplate(),
'content' => $contentElementRendererStrategy->render($block),
$this->metadata->getName() => $block,
]);
}
Expand Down
40 changes: 40 additions & 0 deletions src/Controller/PageController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
use FOS\RestBundle\View\View;
use Sylius\Bundle\ResourceBundle\Controller\ResourceController;
use Sylius\CmsPlugin\Entity\PageInterface;
use Sylius\CmsPlugin\Repository\PageRepositoryInterface;
use Sylius\CmsPlugin\Resolver\PageResourceResolverInterface;
use Sylius\Component\Channel\Context\ChannelContextInterface;
use Sylius\Component\Locale\Context\LocaleContextInterface;
use Sylius\Component\Resource\ResourceActions;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
Expand All @@ -22,6 +25,42 @@ final class PageController extends ResourceController

public const FILTER = 'sylius_admin_product_original';

public const DEFAULT_TEMPLATE = '@SyliusCmsPlugin/Shop/Page/show.html.twig';

public function showAction(Request $request): Response
{
$configuration = $this->getRequestConfiguration($request);

$this->isGrantedOr403($configuration, ResourceActions::SHOW);

$slug = $request->attributes->get('slug');

/** @var PageRepositoryInterface $pageRepository */
$pageRepository = $this->get('sylius_cms.repository.page');

/** @var LocaleContextInterface $localeContext */
$localeContext = $this->get('sylius.context.locale');

/** @var ChannelContextInterface $channelContext */
$channelContext = $this->get('sylius.context.channel');

Assert::notNull($channelContext->getChannel()->getCode());

$page = $pageRepository->findOneEnabledBySlugAndChannelCode(
$slug,
$localeContext->getLocaleCode(),
$channelContext->getChannel()->getCode(),
);

if (null === $page) {
throw $this->createNotFoundException('Page not found');
}

return $this->render($page->getTemplate() ?? self::DEFAULT_TEMPLATE, [
'page' => $page,
]);
}

public function renderLinkAction(Request $request): Response
{
$configuration = $this->getRequestConfiguration($request);
Expand Down Expand Up @@ -78,6 +117,7 @@ public function previewAction(Request $request): Response
return $this->render($configuration->getTemplate(ResourceActions::CREATE . '.html'), [
'resource' => $page,
'preview' => true,
'template' => $page->getTemplate() ?? self::DEFAULT_TEMPLATE,
$this->metadata->getName() => $page,
]);
}
Expand Down
20 changes: 20 additions & 0 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public function getConfigTreeBuilder(): TreeBuilder
$rootNode = $treeBuilder->getRootNode();

$this->addResourcesSection($rootNode);
$this->addTemplatesSection($rootNode);

return $treeBuilder;
}
Expand Down Expand Up @@ -196,4 +197,23 @@ private function addResourcesSection(ArrayNodeDefinition $node): void
->end()
;
}

private function addTemplatesSection(ArrayNodeDefinition $node): void
{
$node
->children()
->arrayNode('templates')
->addDefaultsIfNotSet()
->children()
->arrayNode('pages')
->scalarPrototype()->end()
->end()
->arrayNode('blocks')
->scalarPrototype()->end()
->end()
->end()
->end()
->end()
;
}
}
5 changes: 5 additions & 0 deletions src/DependencyInjection/SyliusCmsExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ final class SyliusCmsExtension extends AbstractResourceExtension implements Prep

public function load(array $configs, ContainerBuilder $container): void
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);

$container->setParameter('sylius_cms.templates.pages', $config['templates']['pages']);
$container->setParameter('sylius_cms.templates.blocks', $config['templates']['blocks']);
}

public function prepend(ContainerBuilder $container): void
Expand Down
12 changes: 12 additions & 0 deletions src/Entity/Block.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ public function __construct()

protected ?string $name;

protected ?string $template = null;

public function getId(): ?int
{
return $this->id;
Expand All @@ -62,4 +64,14 @@ public function setName(?string $name): void
{
$this->name = $name;
}

public function getTemplate(): ?string
{
return $this->template;
}

public function setTemplate(?string $template): void
{
$this->template = $template;
}
}
4 changes: 4 additions & 0 deletions src/Entity/BlockInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,8 @@ public function setCode(?string $code): void;
public function getName(): ?string;

public function setName(?string $name): void;

public function getTemplate(): ?string;

public function setTemplate(?string $template): void;
}
12 changes: 12 additions & 0 deletions src/Entity/Page.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ class Page implements PageInterface

protected ?string $name = null;

protected ?string $template = null;

protected ?\DateTimeImmutable $publishAt;

public function __construct()
Expand Down Expand Up @@ -161,6 +163,16 @@ public function setName(?string $name): void
$this->name = $name;
}

public function getTemplate(): ?string
{
return $this->template;
}

public function setTemplate(?string $template): void
{
$this->template = $template;
}

public function getTitle(): ?string
{
/** @var PageTranslationInterface $pageTranslationInterface */
Expand Down
4 changes: 4 additions & 0 deletions src/Entity/PageInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ public function getName(): ?string;

public function setName(?string $name): void;

public function getTemplate(): ?string;

public function setTemplate(?string $template): void;

public function getTitle(): ?string;

public function setTitle(?string $title): void;
Expand Down
10 changes: 9 additions & 1 deletion src/Form/Type/BlockType.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType;
use Sylius\Bundle\TaxonomyBundle\Form\Type\TaxonAutocompleteChoiceType;
use Sylius\CmsPlugin\Entity\BlockInterface;
use Sylius\CmsPlugin\Provider\ResourceTemplateProviderInterface;
use Sylius\Component\Locale\Model\LocaleInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
Expand All @@ -23,6 +24,7 @@ final class BlockType extends AbstractResourceType

public function __construct(
private RepositoryInterface $localeRepository,
private ResourceTemplateProviderInterface $templateProvider,
string $dataClass,
array $validationGroups = [],
) {
Expand All @@ -48,6 +50,11 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
->add('name', TextType::class, [
'label' => 'sylius_cms.ui.name',
])
->add('templates', ChoiceType::class, [
'label' => 'sylius_cms.ui.template',
'choices' => $this->templateProvider->getBlockTemplates(),
'mapped' => false,
])
->add('collections', CollectionAutocompleteChoiceType::class, [
'label' => 'sylius_cms.ui.collections',
'multiple' => true,
Expand Down Expand Up @@ -90,7 +97,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
'multiple' => true,
'help' => 'sylius_cms.ui.display_for_taxons.help',
])
->add('template', TemplateBlockAutocompleteChoiceType::class, [
->add('contentTemplate', TemplateBlockAutocompleteChoiceType::class, [
'label' => false,
'mapped' => false,
])
Expand All @@ -105,6 +112,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
;

PageType::addContentElementLocaleListener($builder);
PageType::addTemplateListener($builder);
}

public function getBlockPrefix(): string
Expand Down
30 changes: 29 additions & 1 deletion src/Form/Type/PageType.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType;
use Sylius\Bundle\ResourceBundle\Form\Type\ResourceTranslationsType;
use Sylius\CmsPlugin\Form\Type\Translation\PageTranslationType;
use Sylius\CmsPlugin\Provider\ResourceTemplateProviderInterface;
use Sylius\Component\Locale\Model\LocaleInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
Expand All @@ -25,6 +26,7 @@ final class PageType extends AbstractResourceType

public function __construct(
private RepositoryInterface $localeRepository,
private ResourceTemplateProviderInterface $templateProvider,
string $dataClass,
array $validationGroups = [],
) {
Expand All @@ -47,6 +49,11 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
->add('name', TextType::class, [
'label' => 'sylius_cms.ui.name',
])
->add('templates', ChoiceType::class, [
'label' => 'sylius_cms.ui.template',
'choices' => $this->templateProvider->getPageTemplates(),
'mapped' => false,
])
->add('enabled', CheckboxType::class, [
'label' => 'sylius_cms.ui.enabled',
])
Expand Down Expand Up @@ -85,7 +92,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
'class' => 'content-elements-container',
],
])
->add('template', TemplatePageAutocompleteChoiceType::class, [
->add('contentTemplate', TemplatePageAutocompleteChoiceType::class, [
'label' => false,
'mapped' => false,
])
Expand All @@ -100,6 +107,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
;

self::addContentElementLocaleListener($builder);
self::addTemplateListener($builder);
}

public static function addContentElementLocaleListener(FormBuilderInterface $builder): void
Expand All @@ -120,6 +128,26 @@ public static function addContentElementLocaleListener(FormBuilderInterface $bui
});
}

public static function addTemplateListener(FormBuilderInterface $builder): void
{
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
$form = $event->getForm();
$data = $event->getData();
$template = $data['templates'] ?? null;

$entity = $form->getData();
$entity->setTemplate($template);
});

$builder->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event) {
$data = $event->getData();
$form = $event->getForm();
$template = $data->getTemplate();

$form->get('templates')->setData($template);
});
}

public function getBlockPrefix(): string
{
return 'sylius_cms_page';
Expand Down
2 changes: 1 addition & 1 deletion src/Menu/ContentManagementMenuBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public function buildMenu(MenuBuilderEvent $menuBuilderEvent): void
->addChild('templates', [
'route' => 'sylius_cms_admin_template_index',
])
->setLabel('sylius_cms.ui.templates')
->setLabel('sylius_cms.ui.content_templates')
->setLabelAttribute('icon', 'clone')
;

Expand Down
28 changes: 28 additions & 0 deletions src/Migrations/Version20240918091924.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Sylius\CmsPlugin\Migrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

final class Version20240918091924 extends AbstractMigration
{
public function getDescription(): string
{
return 'This migration adds a template column to the sylius_cms_block and sylius_cms_page table.';
}

public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE sylius_cms_block ADD template VARCHAR(250) DEFAULT NULL');
$this->addSql('ALTER TABLE sylius_cms_page ADD template VARCHAR(250) DEFAULT NULL');
}

public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE sylius_cms_block DROP template');
$this->addSql('ALTER TABLE sylius_cms_page DROP template');
}
}
Loading

0 comments on commit 1eb8aae

Please sign in to comment.