We are open sourcing our integration of eCommerce solution (Sylius) with CMS (eZ Publish)
Recently we have built a website alutec.no with our partners Keyteq as project leaders and Locastic as development partners. That would not be such a special news if the site was not built on top of a very interesting combination:
- Content is managed with the eZ Publish 5.* version which is based on Symfony framework.
- Shop features are implemented with Sylius components which are installed on top of the same Symfony instance.
The requirement for the project was to make it possible to edit content which would then reflect the web shop products. We didn't have any difficulties choosing a content management system: we went with eZ Publish CMS, which we have been using for years, on the new stack. Then we were left with the decision which eCommerce solution to use. eZ Publish offered web shop legacy module, but it hasn’t been implemented on the new stack, and we felt it hasn’t been offering extensibility in the way we wanted and needed. The final choice was Sylius, complete eCommerce solution, which although not yet in 1.0 version, seemed like an appropriate tool. Sylius is constructed from decoupled components, and all of that on top of the Symfony2 framework - just like eZ Publish 5! Locastic team helped us with their experience in using Sylius on several projects.
We were pleased to have successfully integrated the combination of two big open-source products working together! Having CMS and eCommerce solution on top of the same framework instance made syncing or importing/exporting redundant - everything is readily available. This has some huge positive implications:
- it is possible to instantiate classes or call services of the other system directly
- it is possible to access the persistent layer directly as all tables are in the same database
- the database connection is also shared (Doctrine)
- templating engine is the same (Twig)
- front caching is the same
- installation is simplified as much as possible
There are two repos we will present to you: one is the basic integration of the eZ Publish community version 2014.11 and Sylius 0.14 together with the installation procedure, and the other presenting deeper integration through eZ Publish field type and legacy datatype.
If you want to describe the integration, you could call it, for lack of a better word, both tightly and loosely coupled. It is tightly coupled in a sense that both eZ Publish and Sylius are part of the same Symfony application: they both use the same database and the same Doctrine connection to talk to the database. At the same time (and for the time being), they're loosely coupled in a sense that both parts, eZ Publish and Sylius, function completely separate from each other. They do not share users, session, or any data between themselves. Our plan is to change that. The next logical step would be to integrate the eZ Publish and Sylius users: When you authenticate as an eZ Publish user, you should automatically be authenticated in Sylius, too, and vice versa.
Installing eZ Sylius (our code name for the integration) is pretty straightforward. Installation instructions are the combination of the eZ Publish and Sylius installation instructions and are split in a couple of steps:
1. Setting up apache/Nginx virtual host: The templates are provided in the doc folder in the eZ Sylius repo. Basically, the virtual host should be identical to standard eZ Publish virtual host setup, but with additional rules to allow access to web/media and web/assets directories which are Sylius specific.
2. Creating a project with Composer: You can get the code by running the following in your terminal:
$ composer create-project netgen/ezpublish-community-sylius
This will clone the repo and install the dependencies for you. The only thing you need to setup before running the command is the database which you will reference when generating parameters with Incenteev Parameter Handler.
3. Installing Sylius: You will need to run a couple of Symfony commands which will prepare the Sylius database, install sample data (products and orders) and create an admin account. The exact commands to run are available in installation instructions in the repo.
4. Installing eZ Publish: eZ Publish comes with an installation wizard which prepares the database and sample data and you need to run it to finish the install. It's a standard next/next/finish procedure, so it should be fairly simple to complete. The only catch is to select the same database which was selected during composer install.
After completing these four steps, your eZ Sylius install should be up and running. eZ Publish will be accessible by opening the homepage and Sylius should be accessible by opening the /shop link.
The same installation could be applied to eZ Platform alpha version, but we didn’t want to show this for 2 reasons:
- well, it's still alpha :)
- there is a problem with logging into eZ Platform UI so we would need to install the legacy bundle
There are two main integration points of eZ Publish and Sylius which have been implemented in this bundle:
- eZ Publish field type and legacy datatype which provide the ability to create and edit Sylius products by publishing eZ Publish content
- Ability to generate links to eZ Publish content that is wrapping Sylius products instead of generating the links to products themselves
There are several key features that we believe were the first step in this integration:
- both field type and legacy type have been developed and supported. This means it is possible to create eZ Publish content with the sylius_product datatype in the legacy administration or with public API, and by publishing them, products in Sylius database are created/updated.
- Translation of products as the related eZ Publish content is translated.
- Sort clause for sorting by product number (SKU) has been implemented.
- Trash and untrash slots have been implemented in order to handle deleting and recovering products in Sylius database.
- Url generator, which can generate eZ Publish URL alias from Sylius product entity (useful for linking to eZ content from Sylius front-end; eg. from cart)
The end result is the ability to create, edit, delete, and even translate products in Sylius directly from eZ Publish interface - be it legacy interface, or the new public API - together with the content that is related to the product; and you can use the full CMS experience for that content, everything that eZ Publish provides. If needed, though, you can edit same products in the Sylius administration - the changes will be instantly visible on the eZ content as well.
On the other hand, if you don’t want such tight coupling, you can also manage products and other Sylius components through Sylius administration, but still use, for example, pagelayout you use on the eZ pages - making them effectively a part of the same site.
Of course, viewing the information is equally important, and for that basic content field template is provided, which means you can use Twig function which is familiar to any eZ developer on the new stack: ez_render_field. It shows all the exposed fields of the product and the “add to cart” form by default, but by setting just one parameter you can choose which fields to show. You can find more on this and other usage details in USAGE.md in the repo.
This covers the eZ front end, but when in the Sylius part of the application (eg. cart or order), you might want to link back to the CMS content, rather than the Sylius product itself. We have that covered, too! There is a URL generator, which takes product entity, and if it finds related eZ content, it generates URL for the content. We have decided to make this the default behavior, but if you’d rather link to the Sylius product, you can simply turn off this feature in the configuration.
This is the first release, so everything isn’t dandy just yet. There are a couple of issues that we are planning to fix/implement for the next releases:
- Due to the fact that Sylius uses lazy loading of translations, there have been issues with the eZ Publish properly caching translations in the SPI cache. Therefore, we have enabled eager loading of translations for all entities that are extending base Product entity. This could cause performance issues if there is a large number of languages used on a site.
- Currently, Sylius product attributes that are exposed through the eZ Publish field type/datatype are limited and hard coded. Future releases should expose configuration which would make it possible to determine which fields are to be manipulated through the eZ Publish interface.
- Fix the issue with eZ Platform UI login
- Automate creation of proxy product objects in eZ when products are managed in Sylius administration
- Make transparent user authentication across both systems
We will do our best to update the main repo, following stable releases of both eZ Publish/eZ Platform and Sylius.
We are eager to hear feedback from eZ and Sylius community, feel free to comment here or on Github :)