From 7a05e3e5d839dcf3401fd8372b5b5c22b8e4e359 Mon Sep 17 00:00:00 2001 From: jkindly Date: Wed, 7 Aug 2024 14:56:19 +0200 Subject: [PATCH] OP-344: init --- src/Fixture/BlockFixture.php | 35 ++- src/Fixture/CollectionFixture.php | 10 +- src/Fixture/Factory/BlockFixtureFactory.php | 34 ++- .../Factory/CollectionFixtureFactory.php | 13 + src/Fixture/Factory/MediaFixtureFactory.php | 8 +- src/Fixture/Factory/PageFixtureFactory.php | 28 +- .../Factory/TemplateFixtureFactory.php | 51 ++++ src/Fixture/MediaFixture.php | 2 - src/Fixture/PageFixture.php | 44 ++- src/Fixture/TemplateFixture.php | 56 ++++ src/Resources/config/services/fixture.xml | 15 ++ src/Resources/views/Shop/Block/show.html.twig | 1 + .../views/Shop/Media/Show/image.html.twig | 12 +- src/Twig/Runtime/RenderBlockRuntime.php | 3 +- .../Resources/fixtures/homepage_logo.png | Bin 0 -> 20968 bytes .../packages/bitbag_sylius_cms_plugin.yaml | 250 ++++++++++++------ .../SyliusShopBundle/Homepage/index.html.twig | 47 +--- .../bundles/SyliusShopBundle/layout.html.twig | 8 +- 18 files changed, 437 insertions(+), 180 deletions(-) create mode 100755 src/Fixture/Factory/TemplateFixtureFactory.php create mode 100755 src/Fixture/TemplateFixture.php create mode 100644 tests/Application/Resources/fixtures/homepage_logo.png diff --git a/src/Fixture/BlockFixture.php b/src/Fixture/BlockFixture.php index 2613dcdf8..d26ad4019 100755 --- a/src/Fixture/BlockFixture.php +++ b/src/Fixture/BlockFixture.php @@ -38,11 +38,42 @@ protected function configureOptionsNode(ArrayNodeDefinition $optionsNode): void ->arrayPrototype() ->children() ->booleanNode('remove_existing')->defaultTrue()->end() - ->integerNode('number')->defaultNull()->end() - ->booleanNode('last_four_products')->defaultFalse()->end() + ->scalarNode('name')->end() ->booleanNode('enabled')->defaultTrue()->end() ->arrayNode('collections')->scalarPrototype()->end()->end() ->arrayNode('channels')->scalarPrototype()->end()->end() + ->arrayNode('locales')->scalarPrototype()->end()->end() + ->arrayNode('products')->scalarPrototype()->end()->end() + ->arrayNode('taxons')->scalarPrototype()->end()->end() + ->arrayNode('products_in_taxons')->scalarPrototype()->end()->end() + ->arrayNode('content_elements') + ->prototype('array') + ->children() + ->scalarNode('heading_type')->end() + ->scalarNode('heading')->end() + ->scalarNode('textarea')->end() + ->scalarNode('single_media')->end() + ->scalarNode('products_carousel_by_taxon')->end() + ->scalarNode('products_grid_by_taxon')->end() + ->arrayNode('multiple_media')->scalarPrototype()->end()->end() + ->arrayNode('products_grid') + ->children() + ->arrayNode('products')->scalarPrototype()->end()->end() + ->end() + ->end() + ->arrayNode('products_carousel') + ->children() + ->arrayNode('products')->scalarPrototype()->end()->end() + ->end() + ->end() + ->arrayNode('taxons_list') + ->children() + ->arrayNode('taxons')->scalarPrototype()->end()->end() + ->end() + ->end() + ->end() + ->end() + ->end() ->end() ->end() ->end() diff --git a/src/Fixture/CollectionFixture.php b/src/Fixture/CollectionFixture.php index ee07390de..88f963f27 100755 --- a/src/Fixture/CollectionFixture.php +++ b/src/Fixture/CollectionFixture.php @@ -38,13 +38,9 @@ protected function configureOptionsNode(ArrayNodeDefinition $optionsNode): void ->arrayPrototype() ->children() ->booleanNode('remove_existing')->defaultTrue()->end() - ->arrayNode('translations') - ->prototype('array') - ->children() - ->scalarNode('name')->defaultNull()->end() - ->end() - ->end() - ->end() + ->node('name', 'scalar')->end() + ->node('type', 'scalar')->end() + ->arrayNode('page_codes')->scalarPrototype()->end() ->end() ->end() ->end() diff --git a/src/Fixture/Factory/BlockFixtureFactory.php b/src/Fixture/Factory/BlockFixtureFactory.php index 157bf2627..d15a413ab 100755 --- a/src/Fixture/Factory/BlockFixtureFactory.php +++ b/src/Fixture/Factory/BlockFixtureFactory.php @@ -12,7 +12,12 @@ use BitBag\SyliusCmsPlugin\Assigner\ChannelsAssignerInterface; use BitBag\SyliusCmsPlugin\Assigner\CollectionsAssignerInterface; +use BitBag\SyliusCmsPlugin\Assigner\LocalesAssignerInterface; +use BitBag\SyliusCmsPlugin\Assigner\ProductsAssignerInterface; +use BitBag\SyliusCmsPlugin\Assigner\ProductsInTaxonsAssignerInterface; +use BitBag\SyliusCmsPlugin\Assigner\TaxonsAssignerInterface; use BitBag\SyliusCmsPlugin\Entity\BlockInterface; +use BitBag\SyliusCmsPlugin\Entity\ContentConfiguration; use BitBag\SyliusCmsPlugin\Repository\BlockRepositoryInterface; use Sylius\Component\Resource\Factory\FactoryInterface; @@ -23,6 +28,10 @@ public function __construct( private BlockRepositoryInterface $blockRepository, private CollectionsAssignerInterface $collectionsAssigner, private ChannelsAssignerInterface $channelAssigner, + private LocalesAssignerInterface $localesAssigner, + private ProductsAssignerInterface $productsAssigner, + private TaxonsAssignerInterface $taxonsAssigner, + private ProductsInTaxonsAssignerInterface $productsInTaxonsAssigner, ) { } @@ -38,13 +47,7 @@ public function load(array $data): void $this->blockRepository->remove($block); } - if (null !== $fields['number']) { - for ($i = 0; $i < $fields['number']; ++$i) { - $this->createBlock(md5(uniqid()), $fields); - } - } else { - $this->createBlock($code, $fields); - } + $this->createBlock($code, $fields); } } @@ -53,11 +56,24 @@ private function createBlock(string $code, array $blockData): void /** @var BlockInterface $block */ $block = $this->blockFactory->createNew(); + $block->setCode($code); + $block->setName($blockData['name']); + $block->setEnabled($blockData['enabled']); + $this->collectionsAssigner->assign($block, $blockData['collections']); $this->channelAssigner->assign($block, $blockData['channels']); + $this->localesAssigner->assign($block, $blockData['locales']); + $this->productsAssigner->assign($block, $blockData['products']); + $this->taxonsAssigner->assign($block, $blockData['taxons']); + $this->productsInTaxonsAssigner->assign($block, $blockData['products_in_taxons']); - $block->setCode($code); - $block->setEnabled($blockData['enabled']); + foreach ($blockData['content_elements'] as $type => $data) { + $contentConfiguration = new ContentConfiguration(); + $contentConfiguration->setType($type); + $contentConfiguration->setConfiguration($data); + $contentConfiguration->setBlock($block); + $block->addContentElement($contentConfiguration); + } $this->blockRepository->add($block); } diff --git a/src/Fixture/Factory/CollectionFixtureFactory.php b/src/Fixture/Factory/CollectionFixtureFactory.php index 18f1165fa..658bc38b1 100755 --- a/src/Fixture/Factory/CollectionFixtureFactory.php +++ b/src/Fixture/Factory/CollectionFixtureFactory.php @@ -11,7 +11,9 @@ namespace BitBag\SyliusCmsPlugin\Fixture\Factory; use BitBag\SyliusCmsPlugin\Entity\CollectionInterface; +use BitBag\SyliusCmsPlugin\Entity\PageInterface; use BitBag\SyliusCmsPlugin\Repository\CollectionRepositoryInterface; +use BitBag\SyliusCmsPlugin\Repository\PageRepositoryInterface; use Sylius\Component\Resource\Factory\FactoryInterface; final class CollectionFixtureFactory implements FixtureFactoryInterface @@ -19,6 +21,7 @@ final class CollectionFixtureFactory implements FixtureFactoryInterface public function __construct( private FactoryInterface $collectionFactory, private CollectionRepositoryInterface $collectionRepository, + private PageRepositoryInterface $pageRepository, ) { } @@ -37,6 +40,16 @@ public function load(array $data): void /** @var CollectionInterface $collection */ $collection = $this->collectionFactory->createNew(); $collection->setCode($code); + $collection->setName($fields['name']); + $collection->setType($fields['type']); + + foreach ($fields['page_codes'] as $pageCode) { + /** @var PageInterface $page */ + $page = $this->pageRepository->findOneBy(['code' => $pageCode]); + if ($page) { + $collection->addPage($page); + } + } $this->collectionRepository->add($collection); } diff --git a/src/Fixture/Factory/MediaFixtureFactory.php b/src/Fixture/Factory/MediaFixtureFactory.php index 01ca4e58e..58f889d82 100644 --- a/src/Fixture/Factory/MediaFixtureFactory.php +++ b/src/Fixture/Factory/MediaFixtureFactory.php @@ -43,13 +43,7 @@ public function load(array $data): void $this->mediaRepository->remove($media); } - if (null !== $fields['number']) { - for ($i = 0; $i < $fields['number']; ++$i) { - $this->createMedia(md5(uniqid()), $fields); - } - } else { - $this->createMedia($code, $fields); - } + $this->createMedia($code, $fields); } } diff --git a/src/Fixture/Factory/PageFixtureFactory.php b/src/Fixture/Factory/PageFixtureFactory.php index b874fcb06..f31376891 100755 --- a/src/Fixture/Factory/PageFixtureFactory.php +++ b/src/Fixture/Factory/PageFixtureFactory.php @@ -12,6 +12,7 @@ use BitBag\SyliusCmsPlugin\Assigner\ChannelsAssignerInterface; use BitBag\SyliusCmsPlugin\Assigner\CollectionsAssignerInterface; +use BitBag\SyliusCmsPlugin\Entity\ContentConfiguration; use BitBag\SyliusCmsPlugin\Entity\PageInterface; use BitBag\SyliusCmsPlugin\Entity\PageTranslationInterface; use BitBag\SyliusCmsPlugin\Repository\PageRepositoryInterface; @@ -42,42 +43,45 @@ public function load(array $data): void $this->pageRepository->remove($page); } - if (null !== $fields['number']) { - for ($i = 0; $i < $fields['number']; ++$i) { - $this->createPage(md5(uniqid()), $fields, true); - } - } else { - $this->createPage($code, $fields); - } + $this->createPage($code, $fields); } } private function createPage( string $code, array $pageData, - bool $generateSlug = false, ): void { /** @var PageInterface $page */ $page = $this->pageFactory->createNew(); - $channelsCodes = $pageData['channels']; + $this->collectionsAssigner->assign($page, $pageData['collections']); - $this->channelAssigner->assign($page, $channelsCodes); + $this->channelAssigner->assign($page, $pageData['channels']); $page->setCode($code); + $page->setName($pageData['name']); $page->setEnabled($pageData['enabled']); foreach ($pageData['translations'] as $localeCode => $translation) { /** @var PageTranslationInterface $pageTranslation */ $pageTranslation = $this->pageTranslationFactory->createNew(); - $slug = true === $generateSlug ? md5(uniqid()) : $translation['slug']; + $slug = $translation['slug'] ?? md5(uniqid('', true)); $pageTranslation->setLocale($localeCode); $pageTranslation->setSlug($slug); + $pageTranslation->setTitle($translation['meta_title']); $pageTranslation->setMetaKeywords($translation['meta_keywords']); $pageTranslation->setMetaDescription($translation['meta_description']); $page->addTranslation($pageTranslation); - $page->setName($translation['name']); + } + + foreach ($pageData['content_elements'] as $data) { + dd($data); + $contentConfiguration = new ContentConfiguration(); + $contentConfiguration->setType($data['type']); + $contentConfiguration->setConfiguration($data['data']); + $contentConfiguration->setPage($page); + $page->addContentElement($contentConfiguration); } $this->pageRepository->add($page); diff --git a/src/Fixture/Factory/TemplateFixtureFactory.php b/src/Fixture/Factory/TemplateFixtureFactory.php new file mode 100755 index 000000000..725fcfef0 --- /dev/null +++ b/src/Fixture/Factory/TemplateFixtureFactory.php @@ -0,0 +1,51 @@ +templateRepository->findOneBy(['name' => $fields['name']]); + if ( + true === $fields['remove_existing'] && + null !== $template + ) { + $this->templateRepository->remove($template); + } + + $this->createPage($fields); + } + } + + private function createPage(array $pageData): void { + /** @var TemplateInterface $template */ + $template = $this->templateFactory->createNew(); + + $template->setName($pageData['name']); + $template->setType($pageData['type']); + $template->setContentElements($pageData['content_elements']); + + $this->templateRepository->add($template); + } +} diff --git a/src/Fixture/MediaFixture.php b/src/Fixture/MediaFixture.php index ef7c68b76..6affd5a6f 100644 --- a/src/Fixture/MediaFixture.php +++ b/src/Fixture/MediaFixture.php @@ -38,13 +38,11 @@ protected function configureOptionsNode(ArrayNodeDefinition $optionsNode): void ->arrayPrototype() ->children() ->booleanNode('remove_existing')->defaultTrue()->end() - ->integerNode('number')->defaultNull()->end() ->scalarNode('type')->isRequired()->cannotBeEmpty()->end() ->scalarNode('path')->isRequired()->cannotBeEmpty()->end() ->scalarNode('original_name')->isRequired()->cannotBeEmpty()->end() ->scalarNode('name')->defaultNull()->end() ->booleanNode('enabled')->defaultTrue()->end() - ->arrayNode('productCodes')->scalarPrototype()->end()->end() ->arrayNode('collections')->scalarPrototype()->end()->end() ->arrayNode('channels')->scalarPrototype()->end()->end() ->arrayNode('translations') diff --git a/src/Fixture/PageFixture.php b/src/Fixture/PageFixture.php index 3812353c4..4f3652acc 100755 --- a/src/Fixture/PageFixture.php +++ b/src/Fixture/PageFixture.php @@ -38,26 +38,54 @@ protected function configureOptionsNode(ArrayNodeDefinition $optionsNode): void ->arrayPrototype() ->children() ->booleanNode('remove_existing')->defaultTrue()->end() - ->integerNode('number')->defaultNull()->end() ->booleanNode('enabled')->defaultTrue()->end() - ->integerNode('products')->defaultNull()->end() - ->arrayNode('productCodes')->scalarPrototype()->end()->end() + ->scalarNode('name')->end() ->arrayNode('collections')->scalarPrototype()->end()->end() ->arrayNode('channels')->scalarPrototype()->end()->end() ->arrayNode('translations') ->prototype('array') ->children() ->scalarNode('slug')->defaultNull()->end() - ->scalarNode('name')->defaultNull()->end() - ->scalarNode('name_when_linked')->defaultNull()->end() - ->scalarNode('description_when_linked')->defaultNull()->end() - ->scalarNode('image_path')->defaultNull()->end() + ->scalarNode('meta_title')->defaultNull()->end() ->scalarNode('meta_keywords')->defaultNull()->end() ->scalarNode('meta_description')->defaultNull()->end() - ->scalarNode('content')->defaultNull()->end() ->end() ->end() ->end() + ->arrayNode('content_elements') + ->useAttributeAsKey('key') // Use keys from YAML as node names + ->arrayPrototype() + ->children() + ->scalarNode('type')->end() // "type" field at the top level of each content element + ->arrayNode('data') // "data" field containing the actual data + ->children() + ->scalarNode('heading_type')->end() + ->scalarNode('heading')->end() + ->scalarNode('textarea')->end() + ->scalarNode('single_media')->end() + ->scalarNode('products_carousel_by_taxon')->end() + ->scalarNode('products_grid_by_taxon')->end() + ->arrayNode('multiple_media')->scalarPrototype()->end()->end() + ->arrayNode('products_grid') + ->children() + ->arrayNode('products')->scalarPrototype()->end()->end() + ->end() + ->end() + ->arrayNode('products_carousel') + ->children() + ->arrayNode('products')->scalarPrototype()->end()->end() + ->end() + ->end() + ->arrayNode('taxons_list') + ->children() + ->arrayNode('taxons')->scalarPrototype()->end()->end() + ->end() + ->end() + ->end() + ->end() // End of data + ->end() + ->end() // End of each content element + ->end() // End of content_elements array ->end() ->end() ->end() diff --git a/src/Fixture/TemplateFixture.php b/src/Fixture/TemplateFixture.php new file mode 100755 index 000000000..5cfdc9b62 --- /dev/null +++ b/src/Fixture/TemplateFixture.php @@ -0,0 +1,56 @@ +templateFixtureFactory->load($options['custom']); + } + + public function getName(): string + { + return 'template'; + } + + protected function configureOptionsNode(ArrayNodeDefinition $optionsNode): void + { + $optionsNode + ->children() + ->arrayNode('custom') + ->arrayPrototype() + ->children() + ->booleanNode('remove_existing')->defaultTrue()->end() + ->scalarNode('name')->end() + ->scalarNode('type')->end() + ->arrayNode('content_elements') + ->arrayPrototype() + ->children() + ->scalarNode('type')->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ; + } +} diff --git a/src/Resources/config/services/fixture.xml b/src/Resources/config/services/fixture.xml index c65e24c69..df913fb6d 100644 --- a/src/Resources/config/services/fixture.xml +++ b/src/Resources/config/services/fixture.xml @@ -24,11 +24,20 @@ + + + + + + + + + @@ -42,6 +51,7 @@ + @@ -52,6 +62,11 @@ + + + + + diff --git a/src/Resources/views/Shop/Block/show.html.twig b/src/Resources/views/Shop/Block/show.html.twig index f739e1a88..16380c595 100644 --- a/src/Resources/views/Shop/Block/show.html.twig +++ b/src/Resources/views/Shop/Block/show.html.twig @@ -1,3 +1,4 @@
+ {{ dump(context) }} {{ content|raw }}
diff --git a/src/Resources/views/Shop/Media/Show/image.html.twig b/src/Resources/views/Shop/Media/Show/image.html.twig index 0b13ea9f0..8eb2c4cc9 100755 --- a/src/Resources/views/Shop/Media/Show/image.html.twig +++ b/src/Resources/views/Shop/Media/Show/image.html.twig @@ -1,10 +1,16 @@
-

{{ media.name|raw }}

- + {% if media.link %} + + {% endif %} {{ media.alt }} + {% if media.link %} + + {% endif %} -

{{ bitbag_cms_render_content(media) }}

+ {% if media.content %} + {{ bitbag_cms_render_content(media) }} + {% endif %}
diff --git a/src/Twig/Runtime/RenderBlockRuntime.php b/src/Twig/Runtime/RenderBlockRuntime.php index 6b8798be2..2af5317ec 100644 --- a/src/Twig/Runtime/RenderBlockRuntime.php +++ b/src/Twig/Runtime/RenderBlockRuntime.php @@ -27,7 +27,7 @@ public function __construct( ) { } - public function renderBlock(string $code, ?string $template = null, ProductInterface|TaxonInterface $context = null): string + public function renderBlock(string $code, ?string $template = null, ProductInterface|TaxonInterface|array $context = null): string { $block = $this->blockResourceResolver->findOrLog($code); if (null === $block) { @@ -49,6 +49,7 @@ public function renderBlock(string $code, ?string $template = null, ProductInter $template ?? self::DEFAULT_TEMPLATE, [ 'content' => $this->contentElementRendererStrategy->render($block), + 'context' => $context, ], ); } diff --git a/tests/Application/Resources/fixtures/homepage_logo.png b/tests/Application/Resources/fixtures/homepage_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..decba55dd051406b2e9024c096af86f78439bf75 GIT binary patch literal 20968 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 Trq$t800000NkvXXu0mjf%^U{S literal 0 HcmV?d00001 diff --git a/tests/Application/config/packages/bitbag_sylius_cms_plugin.yaml b/tests/Application/config/packages/bitbag_sylius_cms_plugin.yaml index 96ddd2675..36fb38a20 100644 --- a/tests/Application/config/packages/bitbag_sylius_cms_plugin.yaml +++ b/tests/Application/config/packages/bitbag_sylius_cms_plugin.yaml @@ -15,53 +15,116 @@ sylius_fixtures: options: custom: blog: - translations: - en_US: - name: "Blog" + name: "Blog" + type: "page" + page_codes: + - "lorem_ipsum" general: - translations: - en_US: - name: "General" + name: "General" + type: "block" store: - translations: - en_US: - name: "Store" + name: "Store" + type: "block" homepage: - translations: - en_US: - name: "Homepage" + name: "Homepage" + type: "page" products: - translations: - en_US: - name: "Products" + name: "Products" + type: "media" block: options: custom: - homepage_products_info: + homepage_products_carousel: + name: "Homepage products carousel" channels: - - "FASHION_WEB" - collection_info_block: - channels: - - "FASHION_WEB" + - "FASHION_WEB" collections: - - "products" - product_info_block: + - "products" + locales: + - "en_US" + content_elements: + heading: + heading_type: "h2" + heading: "Products carousel" + products_carousel: + products_carousel: + products: + - "Everyday_white_basic_T_Shirt" + - "Loose_white_designer_T_Shirt" + - "Ribbed_copper_slim_fit_Tee" + - "Sport_basic_white_T_Shirt" + homepage_products_carousel_by_taxon: + name: "Homepage products carousel by Taxon" channels: - - "FASHION_WEB" - homepage_intro: + - "FASHION_WEB" + collections: + - "products" + locales: + - "en_US" + content_elements: + heading: + heading_type: "h2" + heading: "Products carousel by Taxon" + products_carousel_by_taxon: + products_carousel_by_taxon: "t_shirts" + homepage_products_grid: + name: "Homepage products grid" channels: - - "FASHION_WEB" - lorem_ipsum: + - "FASHION_WEB" + collections: + - "products" + content_elements: + heading: + heading_type: "h2" + heading: "Products grid" + products_grid: + products_grid: + products: + - "Raglan_grey_&_black_Tee" + - "Loose_white_designer_T_Shirt" + - "Sport_basic_white_T_Shirt" + - "Ribbed_copper_slim_fit_Tee" + homepage_products_grid_by_taxon: + name: "Homepage products grid by Taxon" channels: - - "FASHION_WEB" + - "FASHION_WEB" collections: - - "homepage" - taxons_and_products_block: + - "products" + content_elements: + heading: + heading_type: "h2" + heading: "Products grid by Taxon" + products_grid_by_taxon: + products_grid_by_taxon: "caps" + homepage_taxons_list: + name: "Homepage taxons list" channels: - - "FASHION_WEB" + - "FASHION_WEB" + content_elements: + heading: + heading_type: "h2" + heading: "Taxons list" + taxons_list: + taxons_list: + taxons: + - "t_shirts" + - "caps" + - "dresses" + - "jeans" media: options: custom: + homepage_logo: + type: image + path: "%fixtures_dir%/homepage_logo.png" + original_name: "homepage_logo.png" + name: Homepage logo + channels: + - "FASHION_WEB" + translations: + en_US: + alt: "SyliusCmsPlugin" + link: "https://github.com/BitBagCommerce/SyliusCmsPlugin" homepage_header_image: type: image path: "%fixtures_dir%/homepage_header.jpeg" @@ -69,7 +132,7 @@ sylius_fixtures: name: | This is a linked title channels: - - "FASHION_WEB" + - "FASHION_WEB" translations: en_US: alt: Homepage image media @@ -87,7 +150,7 @@ sylius_fixtures: name: | Homepage video media channels: - - "FASHION_WEB" + - "FASHION_WEB" translations: en_US: alt: Homepage video @@ -104,7 +167,7 @@ sylius_fixtures: original_name: "BitBagOffer.pdf" name: Homepage PDF media channels: - - "FASHION_WEB" + - "FASHION_WEB" translations: en_US: alt: BitBag offer @@ -116,31 +179,21 @@ sylius_fixtures:

size_table: channels: - - "FASHION_WEB" + - "FASHION_WEB" type: image path: "%fixtures_dir%/size_table.jpeg" original_name: "size_table.jpeg" sale: channels: - - "FASHION_WEB" + - "FASHION_WEB" type: image path: "%fixtures_dir%/sale.jpeg" original_name: "sale.jpeg" collections: - - "products" - media_with_products: - type: image - path: "%fixtures_dir%/homepage_header.jpeg" - original_name: "homepage_header.jpeg" - channels: - - "FASHION_WEB" - productCodes: - - "666F_boyfriend_jeans_with_rips" - - "727F_patched_cropped_jeans" - - "111F_patched_jeans_with_fancy_badges" + - "products" media_with_parameters: channels: - - "FASHION_WEB" + - "FASHION_WEB" type: image path: "%fixtures_dir%/homepage_header.jpeg" original_name: "homepage_header.jpeg" @@ -151,53 +204,78 @@ sylius_fixtures: page: options: custom: + faq: + name: "FAQ page" + channels: + - "FASHION_WEB" + translations: + en_US: + slug: "faq" + meta_title: "FAQ" + meta_keywords: "faq" + content_elements: + multiple_media: + type: "multiple_media" + data: + multiple_media: + - "homepage_video" + - "homepage_pdf" + question1: + type: "heading" + data: + heading_type: "h3" + heading: "Lorem ipsum dolor sit amet, consectetur adipiscing elit?" + answer1: + type: "textarea" + data: + textarea: "

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

" + question2: + type: "heading" + data: + heading_type: "h3" + heading: "Lorem ipsum dolor sit amet, consectetur adipiscing elit?" + answer2: + type: "textarea" + data: + textarea: "

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

" lorem_ipsum: + name: "Lorem ipsum page" channels: - - "FASHION_WEB" - number: 14 - products: 5 + - "FASHION_WEB" collections: - - "blog" + - "blog" translations: en_US: - name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Verba tu fingas et ea dicas, quae non sentias?" - name_when_linked: "Lorem ipsum dolor" - description_when_linked: "Lorem ipsum dolor sit amet, consectetur adipiscing elit..." - image_path: "%fixtures_dir%/homepage_header.jpeg" - content: | -

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Verba tu fingas et ea dicas, quae non sentias? Fortitudinis quaedam praecepta sunt ac paene leges, quae effeminari virum vetant in dolore. Propter nos enim illam, non propter eam nosmet ipsos diligimus. At ego quem huic anteponam non audeo dicere;

- -

Estne, quaeso, inquam, sitienti in bibendo voluptas? Duo Reges: constructio interrete. Quam si explicavisset, non tam haesitaret. Non enim ipsa genuit hominem, sed accepit a natura inchoatum. Conclusum est enim contra Cyrenaicos satis acute, nihil ad Epicurum. Quis istud, quaeso, nesciebat? Verum tamen cum de rebus grandioribus dicas, ipsae res verba rapiunt;

- -

Quae cum praeponunt, ut sit aliqua rerum selectio, naturam videntur sequi; Ex quo intellegitur officium medium quiddam esse, quod neque in bonis ponatur neque in contrariis. Quid ergo hoc loco intellegit honestum? Ergo, si semel tristior effectus est, hilara vita amissa est?

- -

Nam his libris eum malo quam reliquo ornatu villae delectari. Quid est, quod ab ea absolvi et perfici debeat? Ex quo, id quod omnes expetunt, beate vivendi ratio inveniri et comparari potest. Stoici scilicet.

-

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Verba tu fingas et ea dicas, quae non sentias? Fortitudinis quaedam praecepta sunt ac paene leges, quae effeminari virum vetant in dolore. Propter nos enim illam, non propter eam nosmet ipsos diligimus. At ego quem huic anteponam non audeo dicere;

- -

Estne, quaeso, inquam, sitienti in bibendo voluptas? Duo Reges: constructio interrete. Quam si explicavisset, non tam haesitaret. Non enim ipsa genuit hominem, sed accepit a natura inchoatum. Conclusum est enim contra Cyrenaicos satis acute, nihil ad Epicurum. Quis istud, quaeso, nesciebat? Verum tamen cum de rebus grandioribus dicas, ipsae res verba rapiunt;

- -

Quae cum praeponunt, ut sit aliqua rerum selectio, naturam videntur sequi; Ex quo intellegitur officium medium quiddam esse, quod neque in bonis ponatur neque in contrariis. Quid ergo hoc loco intellegit honestum? Ergo, si semel tristior effectus est, hilara vita amissa est?

- -

Nam his libris eum malo quam reliquo ornatu villae delectari. Quid est, quod ab ea absolvi et perfici debeat? Ex quo, id quod omnes expetunt, beate vivendi ratio inveniri et comparari potest. Stoici scilicet.

+ slug: "lorem-ipsum" + meta_title: "Lorem ipsum" + meta_keywords: "lorem, ipsum" + meta_description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit" about: - products: 5 + name: "About us page" channels: - - "FASHION_WEB" + - "FASHION_WEB" collections: - - "general" - - "store" + - "general" + - "store" translations: en_US: - name: "About us" slug: "about" - name_when_linked: "Read more about us" - description_when_linked: "Lorem ipsum dolor sit amet, consectetur adipiscing elit..." - content: | -

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus

-
    -
  • Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu. Cras consequat.
  • -
  • Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus.
  • -
  • Phasellus ultrices nulla quis nibh. Quisque a lectus. Donec consectetuer ligula vulputate sem tristique cursus. Nam nulla quam, gravida non, commodo a, sodales sit amet, nisi.
  • -
  • Pellentesque fermentum dolor. Aliquam quam lectus, facilisis auctor, ultrices ut, elementum vulputate, nunc.
  • -
-

Pellentesque habitant morbi tristique sene

+ meta_title: "About us" + meta_keywords: "about, us" + meta_description: "About us page" + template: + options: + custom: + homepage: + name: "Page template" + type: "page" + content_elements: + - type: "textarea" + - type: "multiple_media" + about: + name: "Block template" + type: "block" + content_elements: + - type: "heading" + - type: "textarea" + - type: "single_media" diff --git a/tests/Application/templates/bundles/SyliusShopBundle/Homepage/index.html.twig b/tests/Application/templates/bundles/SyliusShopBundle/Homepage/index.html.twig index ab008b882..ca606c2ed 100755 --- a/tests/Application/templates/bundles/SyliusShopBundle/Homepage/index.html.twig +++ b/tests/Application/templates/bundles/SyliusShopBundle/Homepage/index.html.twig @@ -3,49 +3,14 @@ {% block content %}
- -
-
-
- {{ bitbag_cms_render_media('homepage_header_image') }} -
-
-
-
- {{ bitbag_cms_render_block('homepage_intro') }} -
-
- {{ bitbag_cms_render_media('homepage_pdf') }} -
-
-
-
-
-
- {{ bitbag_cms_render_media('homepage_video') }} -
-
-
-
- {{ bitbag_cms_render_media('media_with_parameters', "examples/media_custom_template.html.twig")}} -
-
-
-
-
-
- {{ bitbag_cms_render_block('homepage_products_info') }} + {{ bitbag_cms_render_media('homepage_logo') }}
+ {{ bitbag_cms_render_block('homepage_products_carousel') }} + {{ bitbag_cms_render_block('homepage_products_grid') }} + {{ bitbag_cms_render_block('homepage_taxons_list') }} + {{ bitbag_cms_render_block('homepage_products_carousel_by_taxon') }} + {{ bitbag_cms_render_block('homepage_products_grid_by_taxon') }}
- - {{ render(url('sylius_shop_partial_product_index_latest', {'count': 4, 'template': '@SyliusShop/Product/_horizontalList.html.twig'})) }} -
diff --git a/tests/Application/templates/bundles/SyliusShopBundle/layout.html.twig b/tests/Application/templates/bundles/SyliusShopBundle/layout.html.twig index f95cedc86..5b6168822 100755 --- a/tests/Application/templates/bundles/SyliusShopBundle/layout.html.twig +++ b/tests/Application/templates/bundles/SyliusShopBundle/layout.html.twig @@ -61,8 +61,7 @@ } .cms-logo { - margin-top: 20px; - margin-bottom: 20px; + padding: 20px !important; } pre { @@ -109,6 +108,11 @@ Blog NEW + + FAQ + NEW + Admin panel Login: sylius, password: sylius