Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Frontend] introduce template installer and better define best-practice #2739

Merged
merged 2 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions docs/03_Development/15_Frontend_Bundle/02_Best_Practices.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Best Practices for Frontend in CoreShop

We learned a lot over the years and want to share our best practices with you. This guide will help you to get the most
out of CoreShop and to avoid common pitfalls.

## Server Side Rendering
If you do PHP Server Side Rendering with Twig, you should enable the Frontend Bundle in bundles.php:

```php
// config/bundles.php
return [
// ...
CoreShop\Bundle\FrontendBundle\CoreShopFrontendBundle::class => ['all' => true],
];
```

### Templates
Symfony allows to override Bundle templates by placing them in the `templates` directory. This is something we don't recommend!
We, at CoreShop, sometimes change Templates, add templates, or rename them. Sometimes on accident, sometimes on purpose.

To not run into any issues with CoreShop Demo Files to be loaded, we recommend to copy the Templates from the Demo Frontend.
There is also a new command for that:

```bash
php bin/console coreshop:frontend:install
```

This will copy all the templates from CoreShop into `coreshop` and it also replaces all the Bundle Prefixes. That way, you
can be sure that you are using the correct templates.

This command also creates a configuration to change the `TemplateConfigurator` to use your app template paths and not the
FrontendBundle paths.

## Headless
If you are going headless, you can simply not enable the Frontend Bundle and do whatever need for your Headless API.
40 changes: 1 addition & 39 deletions docs/03_Development/15_Frontend_Bundle/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,42 +20,4 @@ is meant as a Demo and not as a production-ready store.

## Best Practice

Best practice is not to use any Templates from the Demo Frontend, but to create your own Templates and use the
Controllers from the Demo Frontend.

## Copy Templates

To copy the Templates from the Demo Frontend, you can use the following command:

```bash
cp -R vendor/coreshop/core-shop/src/CoreShop/Bundle/FrontendBundle/Resources/views templates/coreshop
```

Overwrite the `TemplateConfiguratorInterface` by creating a new Service and decorate the original one:

```php
<?php
// src/CoreShop/TemplateConfigurator/TemplateConfigurator.php
declare(strict_types=1);

namespace App\CoreShop\TemplateConfigurator;

use CoreShop\Bundle\FrontendBundle\TemplateConfigurator\TemplateConfiguratorInterface;

class TemplateConfigurator implements TemplateConfiguratorInterface
{
public function findTemplate(string $templateName): string
{
return sprintf('coreshop/%s.twig', $templateName);
}
}
```

And configure the new Service:

```yaml
# config/services.yaml
services:
App\CoreShop\TemplateConfigurator\TemplateConfigurator:
decorates: 'CoreShop\Bundle\FrontendBundle\TemplateConfigurator\TemplateConfigurator'
```
We have a separate Guide how we recommend you use the Frontend Bundle: [Best Practices](02_Best_Practices.md)
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

declare(strict_types=1);

/*
* CoreShop
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - CoreShop Commercial License (CCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) CoreShop GmbH (https://www.coreshop.org)
* @license https://www.coreshop.org/license GPLv3 and CCL
*
*/

namespace CoreShop\Bundle\FrontendBundle\Command;

use CoreShop\Bundle\CoreBundle\Command\AbstractInstallCommand;
use CoreShop\Bundle\CoreBundle\Installer\Checker\CommandDirectoryChecker;
use CoreShop\Bundle\FrontendBundle\Installer\FrontendInstallerInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\HttpKernel\KernelInterface;

final class InstallFrontendCommand extends AbstractInstallCommand
{
public function __construct(
KernelInterface $kernel,
CommandDirectoryChecker $directoryChecker,
protected FrontendInstallerInterface $frontendInstaller,
) {
parent::__construct($kernel, $directoryChecker);
}

protected function configure(): void
{
$this
->setName('coreshop:frontend:install')
->setDescription('Install CoreShop Demo Frontend.')
->setHelp(
<<<EOT
The <info>%command.name%</info> command install CoreShop Frontend Controllers/Templates/Configs.
EOT
)
->addOption('templatePath', null, InputOption::VALUE_OPTIONAL, 'Path to the template directory', 'templates')
;
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$coreBundle = $this->kernel->getBundle('CoreShopFrontendBundle');
$frontendBundlePath = $coreBundle->getPath();

$rootPath = $this->kernel->getProjectDir();

$templatePath = $rootPath . '/' . $input->getOption('templatePath');

$this->frontendInstaller->installFrontend(
$frontendBundlePath,
$rootPath,
$templatePath
);

return 0;
}
}
2 changes: 2 additions & 0 deletions src/CoreShop/Bundle/FrontendBundle/CoreShopFrontendBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

use Composer\InstalledVersions;
use CoreShop\Bundle\CoreBundle\CoreShopCoreBundle;
use CoreShop\Bundle\FrontendBundle\DependencyInjection\CompilerPass\FrontendInstallerPass;
use CoreShop\Bundle\FrontendBundle\DependencyInjection\CompilerPass\RegisterFrontendControllerPass;
use Pimcore\Extension\Bundle\AbstractPimcoreBundle;
use Pimcore\HttpKernel\Bundle\DependentBundleInterface;
Expand All @@ -38,6 +39,7 @@ public function build(ContainerBuilder $container): void
parent::build($container);

$container->addCompilerPass(new RegisterFrontendControllerPass());
$container->addCompilerPass(new FrontendInstallerPass());
}

public function getNiceName(): string
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

/*
* CoreShop
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - CoreShop Commercial License (CCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) CoreShop GmbH (https://www.coreshop.org)
* @license https://www.coreshop.org/license GPLv3 and CCL
*
*/

namespace CoreShop\Bundle\FrontendBundle\DependencyInjection\CompilerPass;

use CoreShop\Component\Registry\RegisterSimpleRegistryTypePass;

final class FrontendInstallerPass extends RegisterSimpleRegistryTypePass
{
public const FRONTEND_INSTALLER_TAG = 'coreshop.frontend.installer';

public function __construct()
{
parent::__construct(
'coreshop.registry.frontend.installers',
'coreshop.frontend.installers',
self::FRONTEND_INSTALLER_TAG,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ public function getConfigTreeBuilder(): TreeBuilder
$rootNode
->children()
->scalarNode('view_suffix')->defaultValue('twig')->end()
->scalarNode('view_bundle')->defaultValue('CoreShopFrontend')->end()
->scalarNode('view_bundle')->setDeprecated('coreshop_frontend', '4.1', 'Use view_prefix instead')->defaultValue('@CoreShopFrontend')->end()
->scalarNode('view_prefix')->defaultValue('@CoreShopFrontend')->end()
->end()
;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,15 @@ public function load(array $configs, ContainerBuilder $container): void
}
}

$container->setParameter('coreshop.frontend.view_bundle', $configs['view_bundle']);
$container->setParameter('coreshop.frontend.view_suffix', $configs['view_suffix']);

if (isset($configs['view_prefix'])) {
$container->setParameter('coreshop.frontend.view_prefix', $configs['view_prefix']);
}
else {
$container->setParameter('coreshop.frontend.view_prefix', '@' . $configs['view_bundle']);
}

$container->setParameter('coreshop.frontend.category.valid_sort_options', $configs['category']['valid_sort_options']);
$container->setParameter('coreshop.frontend.category.default_sort_name', $configs['category']['default_sort_name']);
$container->setParameter('coreshop.frontend.category.default_sort_direction', $configs['category']['default_sort_direction']);
Expand Down
36 changes: 36 additions & 0 deletions src/CoreShop/Bundle/FrontendBundle/Installer/FrontendInstaller.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);

/*
* CoreShop
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - CoreShop Commercial License (CCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) CoreShop GmbH (https://www.coreshop.org)
* @license https://www.coreshop.org/license GPLv3 and CCL
*
*/

namespace CoreShop\Bundle\FrontendBundle\Installer;

use CoreShop\Component\Registry\ServiceRegistryInterface;

class FrontendInstaller implements FrontendInstallerInterface
{
public function __construct(private readonly ServiceRegistryInterface $installers)
{
}

public function installFrontend(string $frontendBundlePath, string $rootPath, string $templatePath): void
{
/** @var FrontendInstallerInterface $installer */
foreach ($this->installers->all() as $installer) {
$installer->installFrontend($frontendBundlePath, $rootPath, $templatePath);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

/*
* CoreShop
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - CoreShop Commercial License (CCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) CoreShop GmbH (https://www.coreshop.org)
* @license https://www.coreshop.org/license GPLv3 and CCL
*
*/

namespace CoreShop\Bundle\FrontendBundle\Installer;

interface FrontendInstallerInterface
{
public function installFrontend(string $frontendBundlePath, string $rootPath, string $templatePath): void;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

declare(strict_types=1);

/*
* CoreShop
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - CoreShop Commercial License (CCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) CoreShop GmbH (https://www.coreshop.org)
* @license https://www.coreshop.org/license GPLv3 and CCL
*
*/

namespace CoreShop\Bundle\FrontendBundle\Installer;

use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Yaml\Yaml;

class TemplateConfiguratorInstaller implements FrontendInstallerInterface
{
public function installFrontend(string $frontendBundlePath, string $rootPath, string $templatePath): void
{
$configFile = $rootPath . '/config/packages/coreshop_frontend.yaml';

$configContent = <<<CONFIG
core_shop_frontend:
view_prefix: 'coreshop'
CONFIG;
$fs = new Filesystem();
if (!file_exists($configFile)) {
$fs->dumpFile($configFile, $configContent);
return;
}

$configContent = file_get_contents($configFile);

$content = Yaml::parse($configContent);

if (!isset($content['core_shop_frontend']['view_prefix'])) {
$content['core_shop_frontend']['view_prefix'] = 'coreshop';
}

$configContent = Yaml::dump($content, 4, 2);
$fs->dumpFile($configFile, $configContent);
}
}
Loading
Loading