add node attributes and node paramters
This commit is contained in:
parent
310689eae5
commit
633e16771a
|
@ -342,7 +342,6 @@ table.table-fixed, .table-fixed > table {
|
||||||
|
|
||||||
*[data-collection-delete-container] {
|
*[data-collection-delete-container] {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
margin-top: 35px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*[data-collection-add] {
|
*[data-collection-add] {
|
||||||
|
|
|
@ -44,13 +44,13 @@ const FormCollection = () => {
|
||||||
CollectionInitilizedAndUpdated
|
CollectionInitilizedAndUpdated
|
||||||
);
|
);
|
||||||
|
|
||||||
$('*[data-collection]').on(
|
$('body').on(
|
||||||
'click',
|
'click',
|
||||||
'*[data-collection-delete], *[data-collection-delete-container]',
|
'*[data-collection-delete], *[data-collection-delete-container]',
|
||||||
DeleteHandler
|
DeleteHandler
|
||||||
);
|
);
|
||||||
|
|
||||||
$('*[data-collection-add]').click((e) => {
|
$('body').on('click', '*[data-collection-add]', (e) => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
|
|
||||||
const collectionId = $(e.target).attr('data-collection-add')
|
const collectionId = $(e.target).attr('data-collection-add')
|
||||||
|
|
|
@ -97,6 +97,21 @@ class Node implements EntityInterface
|
||||||
*/
|
*/
|
||||||
private $code;
|
private $code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="array", nullable=true)
|
||||||
|
*/
|
||||||
|
private $parameters = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="array", nullable=true)
|
||||||
|
*/
|
||||||
|
private $attributes = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="string", length=255, nullable=true)
|
||||||
|
*/
|
||||||
|
private $controller;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->children = new ArrayCollection();
|
$this->children = new ArrayCollection();
|
||||||
|
@ -305,4 +320,48 @@ class Node implements EntityInterface
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getParameters(): ?array
|
||||||
|
{
|
||||||
|
if (!is_array($this->parameters)) {
|
||||||
|
$this->parameters = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setParameters(array $parameters): self
|
||||||
|
{
|
||||||
|
$this->parameters = $parameters;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAttributes(): ?array
|
||||||
|
{
|
||||||
|
if (!is_array($this->attributes)) {
|
||||||
|
$this->attributes = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setAttributes(array $attributes): self
|
||||||
|
{
|
||||||
|
$this->attributes = $attributes;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getController(): ?string
|
||||||
|
{
|
||||||
|
return $this->controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setController(?string $controller): self
|
||||||
|
{
|
||||||
|
$this->controller = $controller;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ class Block
|
||||||
return $this->value;
|
return $this->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setValue(string $value): self
|
public function setValue($value): self
|
||||||
{
|
{
|
||||||
$this->value = $value;
|
$this->value = $value;
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ use App\Core\Manager\EntityManager;
|
||||||
use App\Core\Repository\Site\NodeRepository;
|
use App\Core\Repository\Site\NodeRepository;
|
||||||
use App\Core\Slugify\Slugify;
|
use App\Core\Slugify\Slugify;
|
||||||
use Symfony\Component\HttpKernel\KernelInterface;
|
use Symfony\Component\HttpKernel\KernelInterface;
|
||||||
|
use App\Core\Slugify\CodeSlugify;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* class NodeEventSubscriber.
|
* class NodeEventSubscriber.
|
||||||
|
@ -23,17 +24,20 @@ class NodeEventSubscriber extends EntityManagerEventSubscriber
|
||||||
protected EntityManager $entityManager;
|
protected EntityManager $entityManager;
|
||||||
protected KernelInterface $kernel;
|
protected KernelInterface $kernel;
|
||||||
protected Slugify $slugify;
|
protected Slugify $slugify;
|
||||||
|
protected CodeSlugify $codeSlugify;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
NodeFactory $nodeFactory,
|
NodeFactory $nodeFactory,
|
||||||
NodeRepository $nodeRepository,
|
NodeRepository $nodeRepository,
|
||||||
EntityManager $entityManager,
|
EntityManager $entityManager,
|
||||||
Slugify $slugify
|
Slugify $slugify,
|
||||||
|
CodeSlugify $codeSlugify
|
||||||
) {
|
) {
|
||||||
$this->nodeFactory = $nodeFactory;
|
$this->nodeFactory = $nodeFactory;
|
||||||
$this->nodeRepository = $nodeRepository;
|
$this->nodeRepository = $nodeRepository;
|
||||||
$this->entityManager = $entityManager;
|
$this->entityManager = $entityManager;
|
||||||
$this->slugify = $slugify;
|
$this->slugify = $slugify;
|
||||||
|
$this->codeSlugify = $codeSlugify;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function support(EntityInterface $entity)
|
public function support(EntityInterface $entity)
|
||||||
|
@ -49,6 +53,8 @@ class NodeEventSubscriber extends EntityManagerEventSubscriber
|
||||||
|
|
||||||
$node = $event->getEntity();
|
$node = $event->getEntity();
|
||||||
|
|
||||||
|
$node->setCode($this->codeSlugify->slugify($node->getCode()));
|
||||||
|
|
||||||
if ($node->getUrl()) {
|
if ($node->getUrl()) {
|
||||||
$generatedUrl = $node->getUrl();
|
$generatedUrl = $node->getUrl();
|
||||||
} else {
|
} else {
|
||||||
|
@ -68,6 +74,17 @@ class NodeEventSubscriber extends EntityManagerEventSubscriber
|
||||||
$generatedUrl = '/'.implode('/', $path);
|
$generatedUrl = '/'.implode('/', $path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$generatedUrl = rtrim($generatedUrl, '/');
|
||||||
|
|
||||||
|
foreach ($node->getParameters() as $parameter) {
|
||||||
|
$routeParameter = sprintf('{%s}', $parameter['name']);
|
||||||
|
$regex = '/'.preg_quote($routeParameter).'/';
|
||||||
|
|
||||||
|
if (!preg_match($regex, $generatedUrl)) {
|
||||||
|
$generatedUrl.= '/'.$routeParameter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$urlExists = $this->nodeRepository->urlExists($generatedUrl, $node);
|
$urlExists = $this->nodeRepository->urlExists($generatedUrl, $node);
|
||||||
|
|
||||||
if ($urlExists) {
|
if ($urlExists) {
|
||||||
|
|
58
core/EventSuscriber/Site/Page/BlockEventSubscriber.php
Normal file
58
core/EventSuscriber/Site/Page/BlockEventSubscriber.php
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Core\EventSuscriber\Site\Page;
|
||||||
|
|
||||||
|
use App\Core\Entity\EntityInterface;
|
||||||
|
use App\Core\Entity\Site\Page\Block;
|
||||||
|
use App\Core\Event\EntityManager\EntityManagerEvent;
|
||||||
|
use App\Core\EventSuscriber\EntityManagerEventSubscriber;
|
||||||
|
use App\Core\Form\FileUploadHandler;
|
||||||
|
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* class BlockEventSubscriber.
|
||||||
|
*
|
||||||
|
* @author Simon Vieille <simon@deblan.fr>
|
||||||
|
*/
|
||||||
|
class BlockEventSubscriber extends EntityManagerEventSubscriber
|
||||||
|
{
|
||||||
|
protected FileUploadHandler $fileUpload;
|
||||||
|
|
||||||
|
public function __construct(FileUploadHandler $fileUpload)
|
||||||
|
{
|
||||||
|
$this->fileUpload = $fileUpload;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function support(EntityInterface $entity)
|
||||||
|
{
|
||||||
|
return $entity instanceof Block;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onPreUpdate(EntityManagerEvent $event)
|
||||||
|
{
|
||||||
|
if (!$this->support($event->getEntity())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$block = $event->getEntity();
|
||||||
|
|
||||||
|
if (!$block->getValue() instanceof UploadedFile) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$directory = 'uploads/page/block';
|
||||||
|
|
||||||
|
$fileUpload->handleForm(
|
||||||
|
$block->getValue(),
|
||||||
|
$directory,
|
||||||
|
function ($filename) use ($block) {
|
||||||
|
$block->setValue($directory.'/'.$filename);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onPreCreate(EntityManagerEvent $event)
|
||||||
|
{
|
||||||
|
return $this->onPreUpdate($event);
|
||||||
|
}
|
||||||
|
}
|
50
core/Form/Site/NodeAttributeType.php
Normal file
50
core/Form/Site/NodeAttributeType.php
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Core\Form\Site;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
|
use Symfony\Component\Validator\Constraints\NotBlank;
|
||||||
|
|
||||||
|
class NodeAttributeType extends AbstractType
|
||||||
|
{
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
|
{
|
||||||
|
$builder->add(
|
||||||
|
'label',
|
||||||
|
TextType::class,
|
||||||
|
[
|
||||||
|
'label' => 'Libellé',
|
||||||
|
'required' => true,
|
||||||
|
'attr' => [
|
||||||
|
],
|
||||||
|
'constraints' => [
|
||||||
|
new NotBlank(),
|
||||||
|
],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$builder->add(
|
||||||
|
'value',
|
||||||
|
TextType::class,
|
||||||
|
[
|
||||||
|
'label' => 'Valeur',
|
||||||
|
'required' => false,
|
||||||
|
'attr' => [
|
||||||
|
],
|
||||||
|
'constraints' => [
|
||||||
|
],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
$resolver->setDefaults([
|
||||||
|
'data_class' => null,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
62
core/Form/Site/NodeParameterType.php
Normal file
62
core/Form/Site/NodeParameterType.php
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Core\Form\Site;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
|
use Symfony\Component\Validator\Constraints\NotBlank;
|
||||||
|
|
||||||
|
class NodeParameterType extends AbstractType
|
||||||
|
{
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
|
{
|
||||||
|
$builder->add(
|
||||||
|
'name',
|
||||||
|
TextType::class,
|
||||||
|
[
|
||||||
|
'label' => 'Nom',
|
||||||
|
'required' => true,
|
||||||
|
'attr' => [
|
||||||
|
],
|
||||||
|
'constraints' => [
|
||||||
|
new NotBlank(),
|
||||||
|
],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$builder->add(
|
||||||
|
'defaultValue',
|
||||||
|
TextType::class,
|
||||||
|
[
|
||||||
|
'label' => 'Valeur par défaut',
|
||||||
|
'required' => false,
|
||||||
|
'attr' => [
|
||||||
|
],
|
||||||
|
'constraints' => [
|
||||||
|
],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$builder->add(
|
||||||
|
'requirement',
|
||||||
|
TextType::class,
|
||||||
|
[
|
||||||
|
'label' => 'Éxigence',
|
||||||
|
'required' => false,
|
||||||
|
'attr' => [
|
||||||
|
],
|
||||||
|
'constraints' => [
|
||||||
|
],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
$resolver->setDefaults([
|
||||||
|
'data_class' => null,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,6 +12,7 @@ use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
use Symfony\Component\Validator\Constraints\NotBlank;
|
use Symfony\Component\Validator\Constraints\NotBlank;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
|
||||||
|
|
||||||
class NodeType extends AbstractType
|
class NodeType extends AbstractType
|
||||||
{
|
{
|
||||||
|
@ -59,6 +60,20 @@ class NodeType extends AbstractType
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$builder->add(
|
||||||
|
'controller',
|
||||||
|
TextType::class,
|
||||||
|
[
|
||||||
|
'label' => 'Contrôleur',
|
||||||
|
'required' => false,
|
||||||
|
'help' => 'Laisser vide pour utiliser celui par défaut. Notation : App\\Controller\\FooController::barAction',
|
||||||
|
'attr' => [
|
||||||
|
],
|
||||||
|
'constraints' => [
|
||||||
|
],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
$actions = [
|
$actions = [
|
||||||
'Nouvelle page' => 'new',
|
'Nouvelle page' => 'new',
|
||||||
'Associer à une page existante' => 'existing',
|
'Associer à une page existante' => 'existing',
|
||||||
|
@ -125,6 +140,30 @@ class NodeType extends AbstractType
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$builder->add(
|
||||||
|
'parameters',
|
||||||
|
CollectionType::class,
|
||||||
|
[
|
||||||
|
'entry_type' => NodeParameterType::class,
|
||||||
|
'by_reference' => false,
|
||||||
|
'allow_add' => true,
|
||||||
|
'allow_delete' => true,
|
||||||
|
'prototype' => true,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$builder->add(
|
||||||
|
'attributes',
|
||||||
|
CollectionType::class,
|
||||||
|
[
|
||||||
|
'entry_type' => NodeAttributeType::class,
|
||||||
|
'by_reference' => false,
|
||||||
|
'allow_add' => true,
|
||||||
|
'allow_delete' => true,
|
||||||
|
'prototype' => true,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
if (null === $builder->getData()->getId()) {
|
if (null === $builder->getData()->getId()) {
|
||||||
$builder->add(
|
$builder->add(
|
||||||
'position',
|
'position',
|
||||||
|
|
|
@ -42,13 +42,20 @@ class SiteRouteLoader extends Loader
|
||||||
$requirements = [];
|
$requirements = [];
|
||||||
|
|
||||||
$defaults = [
|
$defaults = [
|
||||||
'_controller' => PageController::class.'::show',
|
'_controller' => $node->getController() ?? PageController::class.'::show',
|
||||||
'_node' => $node->getId(),
|
'_node' => $node->getId(),
|
||||||
'_menu' => $menu->getId(),
|
'_menu' => $menu->getId(),
|
||||||
'_page' => $node->getPage() ? $node->getPage()->getId() : null,
|
'_page' => $node->getPage() ? $node->getPage()->getId() : null,
|
||||||
'_navigation' => $navigation->getId(),
|
'_navigation' => $navigation->getId(),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
foreach ($node->getParameters() as $parameter) {
|
||||||
|
$name = $parameter['name'];
|
||||||
|
|
||||||
|
$requirements[$name] = $parameter['requirement'];
|
||||||
|
$defaults[$name] = $parameter['defaultValue'];
|
||||||
|
}
|
||||||
|
|
||||||
$route = new Route($node->getUrl(), $defaults, $requirements);
|
$route = new Route($node->getUrl(), $defaults, $requirements);
|
||||||
$route->setHost($navigation->getDomain());
|
$route->setHost($navigation->getDomain());
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,14 @@ use Cocur\Slugify\Slugify as BaseSlugify;
|
||||||
*/
|
*/
|
||||||
class CodeSlugify extends Slugify
|
class CodeSlugify extends Slugify
|
||||||
{
|
{
|
||||||
|
public function slugify($data): ? string
|
||||||
|
{
|
||||||
|
$slug = parent::slugify($data);
|
||||||
|
$slug = preg_replace('/[^\w]+/', '', $slug);
|
||||||
|
|
||||||
|
return $slug;
|
||||||
|
}
|
||||||
|
|
||||||
protected function create(): BaseSlugify
|
protected function create(): BaseSlugify
|
||||||
{
|
{
|
||||||
$slugify = new BaseSlugify([
|
$slugify = new BaseSlugify([
|
||||||
|
@ -19,7 +27,6 @@ class CodeSlugify extends Slugify
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$slugify->activateRuleSet('french');
|
$slugify->activateRuleSet('french');
|
||||||
$slugify->addRule("'", '');
|
|
||||||
|
|
||||||
return $slugify;
|
return $slugify;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ use Cocur\Slugify\Slugify as BaseSlugify;
|
||||||
*/
|
*/
|
||||||
class Slugify
|
class Slugify
|
||||||
{
|
{
|
||||||
public function slugify($data)
|
public function slugify($data): ?string
|
||||||
{
|
{
|
||||||
return $this->create()->slugify($data);
|
return $this->create()->slugify($data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,11 +69,13 @@ class PostAdminController extends AdminController
|
||||||
$form->handleRequest($request);
|
$form->handleRequest($request);
|
||||||
|
|
||||||
if ($form->isValid()) {
|
if ($form->isValid()) {
|
||||||
|
$directory = 'uploads/post/'.date('Y');
|
||||||
|
|
||||||
$fileUpload->handleForm(
|
$fileUpload->handleForm(
|
||||||
$form->get('image')->getData(),
|
$form->get('image')->getData(),
|
||||||
'uploads/post/'.date('Y'),
|
$directory,
|
||||||
function ($filename) use ($entity) {
|
function ($filename) use ($entity) {
|
||||||
$entity->setImage('post/'.date('Y').'/'.$filename);
|
$entity->setImage($directory.'/'.$filename);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,11 @@ namespace App\Entity\Page;
|
||||||
|
|
||||||
use App\Core\Entity\Site\Page\Block;
|
use App\Core\Entity\Site\Page\Block;
|
||||||
use App\Core\Entity\Site\Page\Page;
|
use App\Core\Entity\Site\Page\Page;
|
||||||
use App\Form\Site\Page\TextareaBlockType;
|
|
||||||
use App\Form\Site\Page\TextBlockType;
|
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use App\Core\Form\Site\Page\FileBlockType;
|
||||||
|
use App\Core\Form\Site\Page\TextBlockType;
|
||||||
|
use App\Core\Form\Site\Page\TextareaBlockType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Entity
|
* @ORM\Entity
|
||||||
|
@ -44,6 +45,20 @@ class SimplePage extends Page
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// $builder->add(
|
||||||
|
// 'file',
|
||||||
|
// FileBlockType::class,
|
||||||
|
// [
|
||||||
|
// 'label' => 'Fichier',
|
||||||
|
// 'options' => [
|
||||||
|
// 'attr' => [
|
||||||
|
// ],
|
||||||
|
// 'constraints' => [
|
||||||
|
// ],
|
||||||
|
// ],
|
||||||
|
// ]
|
||||||
|
// );
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setTitle(Block $block)
|
public function setTitle(Block $block)
|
||||||
|
@ -65,4 +80,14 @@ class SimplePage extends Page
|
||||||
{
|
{
|
||||||
return $this->getBlock('content');
|
return $this->getBlock('content');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setFile(Block $block)
|
||||||
|
{
|
||||||
|
return $this->setBlock($block);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFile()
|
||||||
|
{
|
||||||
|
return $this->getBlock('file');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td class="col-6">
|
<td class="col-6">
|
||||||
{% if item.image %}
|
{% if item.image %}
|
||||||
{% set image = asset('uploads/' ~ item.image) %}
|
{% set image = asset(item.image) %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% set image = asset('build/images/no-image.png') %}
|
{% set image = asset('build/images/no-image.png') %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -68,7 +68,7 @@
|
||||||
|
|
||||||
{% if entity.image %}
|
{% if entity.image %}
|
||||||
<figure>
|
<figure>
|
||||||
<img src="{{ asset('uploads/' ~ entity.image) }}" alt="{{ entity.imageCaption }}" title="{{ entity.imageCaption }}" class="img-fluid">
|
<img src="{{ asset(entity.image) }}" alt="{{ entity.imageCaption }}" title="{{ entity.imageCaption }}" class="img-fluid">
|
||||||
|
|
||||||
<figcaption>
|
<figcaption>
|
||||||
{{ entity.imageCaption }}
|
{{ entity.imageCaption }}
|
||||||
|
|
|
@ -1,108 +1,248 @@
|
||||||
{{ form_row(form.label) }}
|
<ul class="nav nav-pills" id="myTab" role="tablist">
|
||||||
{{ form_row(form.url) }}
|
<li class="nav-item" role="presentation">
|
||||||
|
<a class="nav-link active" data-toggle="tab" href="#form-node-edit-content">Contenu</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<a class="nav-link" data-toggle="tab" href="#form-node-edit-routing">Routage</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<a class="nav-link" data-toggle="tab" href="#form-node-edit-attributes">Attributs</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
{% if form.position is defined %}
|
<div class="tab-content pt-4">
|
||||||
{{ form_row(form.position) }}
|
<div class="tab-pane show active" id="form-node-edit-content">
|
||||||
{% endif %}
|
{{ form_row(form.label) }}
|
||||||
|
|
||||||
<div class="accordion mb-3" id="node-page-action">
|
{% if form.position is defined %}
|
||||||
<div class="card">
|
{{ form_row(form.position) }}
|
||||||
{% set action = form.pageAction[0] %}
|
{% endif %}
|
||||||
{% set options = not entity.id ? {'attr': {'checked': 'checked'}} : {} %}
|
|
||||||
|
|
||||||
<div class="card-header p-0">
|
<div class="accordion mb-3" id="node-page-action">
|
||||||
<h2 class="mb-0">
|
<div class="card">
|
||||||
<label class="btn btn-link btn-block text-left"
|
{% set action = form.pageAction[0] %}
|
||||||
for="{{ action.vars.id }}"
|
{% set options = not entity.id ? {'attr': {'checked': 'checked'}} : {} %}
|
||||||
data-toggle="collapse"
|
|
||||||
data-target="#form-node-page-action-new">
|
|
||||||
{{ action.vars.label }}
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<div class="d-none">
|
<div class="card-header p-0">
|
||||||
{{ form_row(action, options) }}
|
<h2 class="mb-0">
|
||||||
|
<label class="btn btn-link btn-block text-left"
|
||||||
|
for="{{ action.vars.id }}"
|
||||||
|
data-toggle="collapse"
|
||||||
|
data-target="#form-node-page-action-new">
|
||||||
|
{{ action.vars.label }}
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="d-none">
|
||||||
|
{{ form_row(action, options) }}
|
||||||
|
</div>
|
||||||
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
</h2>
|
<div id="form-node-page-action-new" class="collapse {% if not entity.id %}show{% endif %}" data-parent="#node-page-action">
|
||||||
</div>
|
<div class="card-body">
|
||||||
<div id="form-node-page-action-new" class="collapse {% if not entity.id %}show{% endif %}" data-parent="#node-page-action">
|
{{ form_row(form.pageType) }}
|
||||||
<div class="card-body">
|
|
||||||
{{ form_row(form.pageType) }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card">
|
|
||||||
{% set action = form.pageAction[1] %}
|
|
||||||
|
|
||||||
<div class="card-header p-0">
|
|
||||||
<h2 class="mb-0">
|
|
||||||
<label class="btn btn-link btn-block text-left"
|
|
||||||
for="{{ action.vars.id }}"
|
|
||||||
data-toggle="collapse"
|
|
||||||
data-target="#form-node-page-action-existing">
|
|
||||||
{{ action.vars.label }}
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<div class="d-none">
|
|
||||||
{{ form_row(action) }}
|
|
||||||
</div>
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
<div id="form-node-page-action-existing" class="collapse" data-parent="#node-page-action">
|
|
||||||
<div class="card-body">
|
|
||||||
{{ form_row(form.pageEntity) }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card">
|
|
||||||
{% set action = form.pageAction[2] %}
|
|
||||||
|
|
||||||
<div class="card-header p-0">
|
|
||||||
<h2 class="mb-0">
|
|
||||||
<label class="btn btn-link btn-block text-left"
|
|
||||||
for="{{ action.vars.id }}"
|
|
||||||
data-toggle="collapse"
|
|
||||||
data-target="#form-node-page-action-none">
|
|
||||||
{{ action.vars.label }}
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<div class="d-none">
|
|
||||||
{{ form_row(action) }}
|
|
||||||
</div>
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
<div id="form-node-page-action-none" class="collapse" data-parent="#node-page-action">
|
|
||||||
<div class="card-body">
|
|
||||||
Aucune action
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% if entity.id %}
|
|
||||||
<div class="card">
|
|
||||||
{% set action = form.pageAction[3] %}
|
|
||||||
{% set options = {'attr': {'checked': 'checked'}} %}
|
|
||||||
|
|
||||||
<div class="card-header p-0">
|
|
||||||
<h2 class="mb-0">
|
|
||||||
<label class="btn btn-link btn-block text-left"
|
|
||||||
for="{{ action.vars.id }}"
|
|
||||||
data-toggle="collapse"
|
|
||||||
data-target="#form-node-page-action-keep">
|
|
||||||
{{ action.vars.label }}
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<div class="d-none">
|
|
||||||
{{ form_row(action, options) }}
|
|
||||||
</div>
|
</div>
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
<div id="form-node-page-action-keep" class="collapse show" data-parent="#node-page-action">
|
|
||||||
<div class="card-body">
|
|
||||||
Aucune action
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
{% set action = form.pageAction[1] %}
|
||||||
|
|
||||||
|
<div class="card-header p-0">
|
||||||
|
<h2 class="mb-0">
|
||||||
|
<label class="btn btn-link btn-block text-left"
|
||||||
|
for="{{ action.vars.id }}"
|
||||||
|
data-toggle="collapse"
|
||||||
|
data-target="#form-node-page-action-existing">
|
||||||
|
{{ action.vars.label }}
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="d-none">
|
||||||
|
{{ form_row(action) }}
|
||||||
|
</div>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div id="form-node-page-action-existing" class="collapse" data-parent="#node-page-action">
|
||||||
|
<div class="card-body">
|
||||||
|
{{ form_row(form.pageEntity) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
{% set action = form.pageAction[2] %}
|
||||||
|
|
||||||
|
<div class="card-header p-0">
|
||||||
|
<h2 class="mb-0">
|
||||||
|
<label class="btn btn-link btn-block text-left"
|
||||||
|
for="{{ action.vars.id }}"
|
||||||
|
data-toggle="collapse"
|
||||||
|
data-target="#form-node-page-action-none">
|
||||||
|
{{ action.vars.label }}
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="d-none">
|
||||||
|
{{ form_row(action) }}
|
||||||
|
</div>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div id="form-node-page-action-none" class="collapse" data-parent="#node-page-action">
|
||||||
|
<div class="card-body">
|
||||||
|
Aucune action
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if entity.id %}
|
||||||
|
<div class="card">
|
||||||
|
{% set action = form.pageAction[3] %}
|
||||||
|
{% set options = {'attr': {'checked': 'checked'}} %}
|
||||||
|
|
||||||
|
<div class="card-header p-0">
|
||||||
|
<h2 class="mb-0">
|
||||||
|
<label class="btn btn-link btn-block text-left"
|
||||||
|
for="{{ action.vars.id }}"
|
||||||
|
data-toggle="collapse"
|
||||||
|
data-target="#form-node-page-action-keep">
|
||||||
|
{{ action.vars.label }}
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="d-none">
|
||||||
|
{{ form_row(action, options) }}
|
||||||
|
</div>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div id="form-node-page-action-keep" class="collapse show" data-parent="#node-page-action">
|
||||||
|
<div class="card-body">
|
||||||
|
Aucune action
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
</div>
|
||||||
|
<div class="tab-pane" id="form-node-edit-routing">
|
||||||
|
{{ form_row(form.url) }}
|
||||||
|
|
||||||
|
<div class="pb-1">
|
||||||
|
Nom de la route : <code>{{ entity.routeName }}</code>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ form_row(form.code) }}
|
||||||
|
|
||||||
|
{{ form_row(form.controller) }}
|
||||||
|
|
||||||
|
<div class="accordion mb-3" data-collection="collection-node-parameters" id="form-node-edit-parameters-collection">
|
||||||
|
{% for item in form.parameters %}
|
||||||
|
<div class="card" data-collection-item="{{ loop.index }}">
|
||||||
|
<div class="card-header p-0">
|
||||||
|
<span class="btn btn-link btn-block text-left" data-toggle="collapse" data-target="#form-node-parameter-{{ loop.index }}">
|
||||||
|
{{ item.vars.data.name }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="collapse" data-parent="#form-node-edit-parameters-collection" id="form-node-parameter-{{ loop.index }}">
|
||||||
|
<div class="card-body">
|
||||||
|
{{ form_row(item.name) }}
|
||||||
|
{{ form_row(item.defaultValue) }}
|
||||||
|
{{ form_row(item.requirement) }}
|
||||||
|
|
||||||
|
<div class="text-right">
|
||||||
|
<span data-collection-delete-container class="btn btn-sm btn-danger">
|
||||||
|
<span data-collection-delete="{{ loop.index }}" class="fa fa-trash"></span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ form_rest(item) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div data-collection-add="collection-node-parameters" class="collection-add">
|
||||||
|
<span class="btn btn-primary" data-collection-add="collection-node-parameters">
|
||||||
|
<span class="fa fa-plus"></span>
|
||||||
|
Ajouter un paramètre
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tab-pane" id="form-node-edit-attributes">
|
||||||
|
<div class="accordion mb-3" data-collection="collection-node-attributes" id="form-node-edit-attributes-collection">
|
||||||
|
{% for item in form.attributes %}
|
||||||
|
<div class="card" data-collection-item="{{ loop.index }}">
|
||||||
|
<div class="card-header p-0">
|
||||||
|
<span class="btn btn-link btn-block text-left" data-toggle="collapse" data-target="#form-node-attribute-{{ loop.index }}">
|
||||||
|
{{ item.vars.data.label }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="collapse" data-parent="#form-node-edit-attributes-collection" id="form-node-attribute-{{ loop.index }}">
|
||||||
|
<div class="card-body">
|
||||||
|
{{ form_row(item.label) }}
|
||||||
|
{{ form_row(item.value) }}
|
||||||
|
|
||||||
|
<div class="text-right">
|
||||||
|
<span data-collection-delete-container class="btn btn-sm btn-danger">
|
||||||
|
<span data-collection-delete="{{ loop.index }}" class="fa fa-trash"></span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ form_rest(item) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div data-collection-add="collection-node-attributes" class="collection-add">
|
||||||
|
<span class="btn btn-primary" data-collection-add="collection-node-attributes">
|
||||||
|
<span class="fa fa-plus"></span>
|
||||||
|
Ajouter un attribut
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template type="text/template" id="collection-node-parameters">
|
||||||
|
<div class="card" data-collection-item="__name__">
|
||||||
|
<div class="card-header p-0">
|
||||||
|
<span class="btn btn-link btn-block text-left" data-toggle="collapse" data-target="#form-node-parameter-__name__">
|
||||||
|
Nouveau paramètre
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="collapse show" id="form-node-parameter-__name__" data-parent="#form-node-edit-parameters-collection">
|
||||||
|
<div class="card-body">
|
||||||
|
{{ form_row(form.parameters.vars.prototype.name) }}
|
||||||
|
{{ form_row(form.parameters.vars.prototype.defaultValue) }}
|
||||||
|
{{ form_row(form.parameters.vars.prototype.requirement) }}
|
||||||
|
|
||||||
|
<div class="text-right">
|
||||||
|
<span data-collection-delete-container class="btn btn-sm btn-danger"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ form_rest(form.parameters.vars.prototype) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template type="text/template" id="collection-node-attributes">
|
||||||
|
<div class="card" data-collection-item="__name__">
|
||||||
|
<div class="card-header p-0">
|
||||||
|
<span class="btn btn-link btn-block text-left" data-toggle="collapse" data-target="#form-node-attribute-__name__">
|
||||||
|
Nouveau attribut
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="collapse show" id="form-node-attribute-__name__" data-parent="#form-node-edit-attributes-collection">
|
||||||
|
<div class="card-body">
|
||||||
|
{{ form_row(form.attributes.vars.prototype.label) }}
|
||||||
|
{{ form_row(form.attributes.vars.prototype.value) }}
|
||||||
|
|
||||||
|
<div class="text-right">
|
||||||
|
<span data-collection-delete-container class="btn btn-sm btn-danger"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ form_rest(form.attributes.vars.prototype) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div class="d-none">
|
||||||
|
{{ form_rest(form) }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{ form_rest(form) }}
|
|
||||||
|
|
|
@ -10,10 +10,6 @@
|
||||||
<form action="{{ path('admin_site_node_edit', {entity: entity.id}) }}" id="form-node-edit" method="POST">
|
<form action="{{ path('admin_site_node_edit', {entity: entity.id}) }}" id="form-node-edit" method="POST">
|
||||||
{{ include('site/node_admin/_form.html.twig') }}
|
{{ include('site/node_admin/_form.html.twig') }}
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div class="p1">
|
|
||||||
Nom de la route : <code>{{ entity.routeName }}</code>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Annuler</button>
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Annuler</button>
|
||||||
|
|
|
@ -113,10 +113,10 @@
|
||||||
{{ node.label }}
|
{{ node.label }}
|
||||||
|
|
||||||
{% if node.url %}
|
{% if node.url %}
|
||||||
<span class="ml-3 btn-group">
|
<span class="ml-3">
|
||||||
<a href="{{ absolute_url(path(node.routeName)) }}" target="_blank" class="btn btn-sm border border-secondary btn-light">
|
<span class="btn btn-sm border border-secondary btn-light">
|
||||||
{{ node.url }}
|
{{ node.url }}
|
||||||
</a>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue