Important
You are browsing the documentation for version 4.1 of OroCommerce, OroCRM and OroPlatform, which is no longer maintained. Read version 5.1 (the latest LTS version) of the Oro documentation to get up-to-date information.
See our Release Process documentation for more information on the currently supported and upcoming releases.
OroWebCatalogBundle¶
OroWebCatalogBundle enables the OroCommerce back-office administrators to set a different structure and content of the storefront for individual customers, customer groups, or all visitors of the website by combining product pages, category pages, system pages, and product collections into custom catalogs for these audiences.
Create a Content Variant¶
There are 5 content variant types registered out-of-the-box:
System page
Landing page
Category
Product page
Product Collection page
The main entity responsible for content variants is ContentVariant. Entity ContentVariant is extendable. If you want to add another entity to a content variant, you should extend it.
To create your own content variant, create a relation between the content variant and your entity.
For example, to create a Blog Post Content Variant, proceed through the steps below.
1. Create migration
You should create migration which adds relation between the content variant entity and your entity. In our example it is relation between the ContentVariant and BlogPost entities. This migration should implement ExtendExtensionAwareInterface.
1 class OroWebCatalogBundle implements Migration, ExtendExtensionAwareInterface
2 {
3 /**
4 * {@inheritdoc}
5 */
6 public function up(Schema $schema, QueryBag $queries)
7 {
8 $this->createRelationToBlogPostFromContentVariant($schema);
9 ...
10 }
11
12 /**
13 * @param Schema $schema
14 */
15 private function createRelationToBlogPostFromContentVariant(Schema $schema)
16 {
17 if ($schema->hasTable('oro_web_catalog_variant')) {
18 $table = $schema->getTable('oro_web_catalog_variant');
19 $this->extendExtension->addManyToOneRelation(
20 $schema,
21 $table,
22 'content_variant_blog_post', // Relation field name
23 'blog_post', // Your entity table name
24 'id',
25 [
26 'entity' => ['label' => 'blog_post.entity_label'], // Your entity label translation key
27 'extend' => [
28 'is_extend' => true,
29 'owner' => ExtendScope::OWNER_CUSTOM,
30 'cascade' => ['persist', 'remove'],
31 'on_delete' => 'CASCADE',
32 ],
33 'datagrid' => ['is_visible' => false],
34 'form' => ['is_enabled' => false],
35 'view' => ['is_displayable' => false],
36 'merge' => ['display' => false],
37 ]
38 );
39 }
40 }
41 ...
42 }
2. Add form type
Add form type for your entity content variant.
This form type is used on the Create Content Node page to add and edit you content variant.
1 use Symfony\Component\Form\AbstractType;
2
3 class BlogPostPageVariantType extends AbstractType
4 {
5 ...
6 }
3. Create content variant type
Next, create a service which should implement ContentVariantTypeInterface and be tagged with oro_web_catalog.content_variant_type tag. In this service, provide individual type name, title, created before form the type which is used to create and update the content variant. The getRouteData method should return the route data to render your content variant on the frontend application side. In our case it can be new RouteData(‘frontend_blog_post_view’, [‘id’ => $post->getId()]);
1 use Oro\Component\WebCatalog\ContentVariantTypeInterface;
2
3 class ProductPageContentVariantType implements ContentVariantTypeInterface
4 {
5 const TYPE = 'blog_post_page';
6
7 ...
8
9 /**
10 * {@inheritdoc}
11 */
12 public function getName()
13 {
14 return self::TYPE;
15 }
16
17 /**
18 * {@inheritdoc}
19 */
20 public function getTitle()
21 {
22 return 'blog_post_page.label';
23 }
24
25 /**
26 * {@inheritdoc}
27 */
28 public function getFormType()
29 {
30 return BlogPostPageVariantType::class;
31 }
32
33 /**
34 * {@inheritdoc}
35 */
36 public function getRouteData(ContentVariantInterface $contentVariant)
37 {
38 /** @var BlogPost $post */
39 $post = $this->propertyAccessor->getValue($contentVariant, 'contentVariantBlogPost');
40
41 return new RouteData('frontend_blog_post_view', ['id' => $post->getId()]);
42 }
43
44 /**
45 * {@inheritdoc}
46 */
47 public function getApiResourceClassName()
48 {
49 return BlogPost::class;
50 }
51
52 /**
53 * {@inheritdoc}
54 */
55 public function getApiResourceIdentifierDqlExpression($alias)
56 {
57 return sprintf('IDENTITY(%s.content_variant_blog_post)', $alias);
58 }
59 }
ContentVariantTypeContentVariantTypeRegistry is used to collect all content variant types. To render Add Content Variant dropdown button with all available content variants, WebCatalogExtension twig extension is used.
4. Create Storefront API
If your content variant is represented by an ORM entity (like the blog post described in this example), enable the storefront API for it using the Resources/config/oro/api_frontend.yml configuration file. For more details, see Storefront REST API.
If your content variant is represented by a non-ORM entity, enabling storefront API may be more time-consuming. As an example you can investigate how it is done for the system page content variant:
Adding scope selectors for content variants is automatic
PageVariantTypeExtension form type extension adds scope type with appropriate selectors for each content variant type. ContentVariant can has only one scope, any Scope can be applied for different Content Variants.
As a result, you will have possibility to add a content node variant for your entity and render this content variant in the storefront according selected scopes.
Default Content Variant¶
Each content variant of content node can be selected as default using the ContentVariant is_default flag. It means that if Content Node has scopes not assigned to any Content Variant of this node, that scopes will be assigned to the content variant that is marked as default.
Sitemap¶
To add the created content variant to Sitemap, create an appropriate provider. Please see Sitemap documentation.