add blog entities; add repository query logic
This commit is contained in:
parent
2ce9de08ff
commit
40782e56ab
27
src/Controller/Blog/CategoryAdminController.php
Normal file
27
src/Controller/Blog/CategoryAdminController.php
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace App\Controller\Blog;
|
||||
|
||||
use App\Controller\Admin\AdminController;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
/**
|
||||
* @Route("/admin/blog/category")
|
||||
*/
|
||||
class CategoryAdminController extends AdminController
|
||||
{
|
||||
/**
|
||||
* @Route("/", name="admin_blog_category_index")
|
||||
*/
|
||||
public function index(): Response
|
||||
{
|
||||
return $this->render('blog/category_admin/index.html.twig', [
|
||||
]);
|
||||
}
|
||||
|
||||
public function getSection(): string
|
||||
{
|
||||
return 'blog_category';
|
||||
}
|
||||
}
|
27
src/Controller/Blog/PostAdminController.php
Normal file
27
src/Controller/Blog/PostAdminController.php
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace App\Controller\Blog;
|
||||
|
||||
use App\Controller\Admin\AdminController;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
/**
|
||||
* @Route("/admin/blog/post")
|
||||
*/
|
||||
class PostAdminController extends AdminController
|
||||
{
|
||||
/**
|
||||
* @Route("/", name="admin_blog_post_index")
|
||||
*/
|
||||
public function index(): Response
|
||||
{
|
||||
return $this->render('blog/post_admin/index.html.twig', [
|
||||
]);
|
||||
}
|
||||
|
||||
public function getSection(): string
|
||||
{
|
||||
return 'blog_post';
|
||||
}
|
||||
}
|
57
src/Doctrine/Timestampable.php
Normal file
57
src/Doctrine/Timestampable.php
Normal file
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
namespace App\Doctrine;
|
||||
|
||||
trait Timestampable
|
||||
{
|
||||
/**
|
||||
* @ORM\Column(name="created_at", type="datetime")
|
||||
*/
|
||||
protected $createdAt;
|
||||
|
||||
/**
|
||||
* @ORM\Column(name="updated_at", type="datetime")
|
||||
*/
|
||||
protected $updatedAt;
|
||||
|
||||
/**
|
||||
* @ORM\PrePersist
|
||||
*/
|
||||
public function onPrePersist(): void
|
||||
{
|
||||
$this->createdAt = new \DateTime();
|
||||
$this->updatedAt = new \DateTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* @ORM\PreUpdate
|
||||
*/
|
||||
public function onPreUpdate(): void
|
||||
{
|
||||
$this->updatedAt = new \DateTime();
|
||||
}
|
||||
|
||||
public function setCreatedAt(?\DateTime $createdAt): self
|
||||
{
|
||||
$this->createdAt = $createdAt;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCreatedAt():?\DateTime
|
||||
{
|
||||
return $this->createdAt;
|
||||
}
|
||||
|
||||
public function setUpdatedAt(?\DateTime $updatedAt): self
|
||||
{
|
||||
$this->updatedAt = $updatedAt;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUpdatedAt():?\DateTime
|
||||
{
|
||||
return $this->updatedAt;
|
||||
}
|
||||
}
|
92
src/Entity/Blog/Category.php
Normal file
92
src/Entity/Blog/Category.php
Normal file
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
|
||||
namespace App\Entity\Blog;
|
||||
|
||||
use App\Repository\Blog\CategoryRepository;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Entity(repositoryClass=CategoryRepository::class)
|
||||
*/
|
||||
class Category
|
||||
{
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255)
|
||||
*/
|
||||
private $title;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
*/
|
||||
private $subTitle;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="text", nullable=true)
|
||||
*/
|
||||
private $description;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
*/
|
||||
private $slug;
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getTitle(): ?string
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
public function setTitle(string $title): self
|
||||
{
|
||||
$this->title = $title;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSubTitle(): ?string
|
||||
{
|
||||
return $this->subTitle;
|
||||
}
|
||||
|
||||
public function setSubTitle(?string $subTitle): self
|
||||
{
|
||||
$this->subTitle = $subTitle;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDescription(): ?string
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function setDescription(string $description): self
|
||||
{
|
||||
$this->description = $description;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSlug(): ?string
|
||||
{
|
||||
return $this->slug;
|
||||
}
|
||||
|
||||
public function setSlug(?string $slug): self
|
||||
{
|
||||
$this->slug = $slug;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
198
src/Entity/Blog/Post.php
Normal file
198
src/Entity/Blog/Post.php
Normal file
|
@ -0,0 +1,198 @@
|
|||
<?php
|
||||
|
||||
namespace App\Entity\Blog;
|
||||
|
||||
use App\Entity\User;
|
||||
use App\Repository\Blog\PostRepository;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use App\Doctrine\Timestampable;
|
||||
|
||||
/**
|
||||
* @ORM\Entity(repositoryClass=PostRepository::class)
|
||||
*/
|
||||
class Post
|
||||
{
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255)
|
||||
*/
|
||||
private $title;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="text", nullable=true)
|
||||
*/
|
||||
private $subTitle;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="text", nullable=true)
|
||||
*/
|
||||
private $content;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
*/
|
||||
private $metaDescription;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private $status;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
*/
|
||||
private $image;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
*/
|
||||
private $slug;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="datetime", nullable=true)
|
||||
*/
|
||||
private $publishedAt;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
*/
|
||||
private $imageCaption;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=User::class, inversedBy="posts")
|
||||
*/
|
||||
private $author;
|
||||
|
||||
use Timestampable;
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getTitle(): ?string
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
public function setTitle(string $title): self
|
||||
{
|
||||
$this->title = $title;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSubTitle(): ?string
|
||||
{
|
||||
return $this->subTitle;
|
||||
}
|
||||
|
||||
public function setSubTitle(?string $subTitle): self
|
||||
{
|
||||
$this->subTitle = $subTitle;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getContent(): ?string
|
||||
{
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
public function setContent(?string $content): self
|
||||
{
|
||||
$this->content = $content;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMetaDescription(): ?string
|
||||
{
|
||||
return $this->metaDescription;
|
||||
}
|
||||
|
||||
public function setMetaDescription(?string $metaDescription): self
|
||||
{
|
||||
$this->metaDescription = $metaDescription;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getStatus(): ?int
|
||||
{
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
public function setStatus(int $status): self
|
||||
{
|
||||
$this->status = $status;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getImage(): ?string
|
||||
{
|
||||
return $this->image;
|
||||
}
|
||||
|
||||
public function setImage(?string $image): self
|
||||
{
|
||||
$this->image = $image;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSlug(): ?string
|
||||
{
|
||||
return $this->slug;
|
||||
}
|
||||
|
||||
public function setSlug(?string $slug): self
|
||||
{
|
||||
$this->slug = $slug;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPublishedAt(): ?\DateTimeInterface
|
||||
{
|
||||
return $this->publishedAt;
|
||||
}
|
||||
|
||||
public function setPublishedAt(?\DateTimeInterface $publishedAt): self
|
||||
{
|
||||
$this->publishedAt = $publishedAt;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getImageCaption(): ?string
|
||||
{
|
||||
return $this->imageCaption;
|
||||
}
|
||||
|
||||
public function setImageCaption(?string $imageCaption): self
|
||||
{
|
||||
$this->imageCaption = $imageCaption;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAuthor(): ?User
|
||||
{
|
||||
return $this->author;
|
||||
}
|
||||
|
||||
public function setAuthor(?User $author): self
|
||||
{
|
||||
$this->author = $author;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
|
@ -2,11 +2,15 @@
|
|||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Entity\Blog\Post;
|
||||
use App\Repository\UserRepository;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Scheb\TwoFactorBundle\Model\Google\TwoFactorInterface;
|
||||
use Scheb\TwoFactorBundle\Model\Totp\TotpConfiguration;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
use App\Doctrine\Timestampable;
|
||||
|
||||
/**
|
||||
* @ORM\Entity(repositoryClass=UserRepository::class)
|
||||
|
@ -62,6 +66,18 @@ class User implements UserInterface, TwoFactorInterface, Entity
|
|||
*/
|
||||
private $isAdmin;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity=Post::class, mappedBy="author")
|
||||
*/
|
||||
private $posts;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->posts = new ArrayCollection();
|
||||
}
|
||||
|
||||
use Timestampable;
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
|
@ -241,4 +257,34 @@ class User implements UserInterface, TwoFactorInterface, Entity
|
|||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection|Post[]
|
||||
*/
|
||||
public function getPosts(): Collection
|
||||
{
|
||||
return $this->posts;
|
||||
}
|
||||
|
||||
public function addPost(Post $post): self
|
||||
{
|
||||
if (!$this->posts->contains($post)) {
|
||||
$this->posts[] = $post;
|
||||
$post->setAuthor($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removePost(Post $post): self
|
||||
{
|
||||
if ($this->posts->removeElement($post)) {
|
||||
// set the owning side to null (unless already changed)
|
||||
if ($post->getAuthor() === $this) {
|
||||
$post->setAuthor(null);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
|
50
src/Repository/Blog/CategoryRepository.php
Normal file
50
src/Repository/Blog/CategoryRepository.php
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace App\Repository\Blog;
|
||||
|
||||
use App\Entity\Blog\Category;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @method Category|null find($id, $lockMode = null, $lockVersion = null)
|
||||
* @method Category|null findOneBy(array $criteria, array $orderBy = null)
|
||||
* @method Category[] findAll()
|
||||
* @method Category[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
|
||||
*/
|
||||
class CategoryRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, Category::class);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return Category[] Returns an array of Category objects
|
||||
// */
|
||||
/*
|
||||
public function findByExampleField($value)
|
||||
{
|
||||
return $this->createQueryBuilder('c')
|
||||
->andWhere('c.exampleField = :val')
|
||||
->setParameter('val', $value)
|
||||
->orderBy('c.id', 'ASC')
|
||||
->setMaxResults(10)
|
||||
->getQuery()
|
||||
->getResult()
|
||||
;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
public function findOneBySomeField($value): ?Category
|
||||
{
|
||||
return $this->createQueryBuilder('c')
|
||||
->andWhere('c.exampleField = :val')
|
||||
->setParameter('val', $value)
|
||||
->getQuery()
|
||||
->getOneOrNullResult()
|
||||
;
|
||||
}
|
||||
*/
|
||||
}
|
20
src/Repository/Blog/CategoryRepositoryQuery.php
Normal file
20
src/Repository/Blog/CategoryRepositoryQuery.php
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
namespace App\Repository\Blog;
|
||||
|
||||
use Knp\Component\Pager\PaginatorInterface;
|
||||
use App\Repository\Blog\PostRepository;
|
||||
use App\Repository\RepositoryQuery;
|
||||
|
||||
/**
|
||||
* class CategoryRepositoryQuery.
|
||||
*
|
||||
* @author Simon Vieille <simon@deblan.fr>
|
||||
*/
|
||||
class CategoryRepositoryQuery extends RepositoryQuery
|
||||
{
|
||||
public function __construct(CategoryRepositoryQuery $repository, PaginatorInterface $paginator)
|
||||
{
|
||||
parent::__construct($repository, 'c', $paginator);
|
||||
}
|
||||
}
|
50
src/Repository/Blog/PostRepository.php
Normal file
50
src/Repository/Blog/PostRepository.php
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace App\Repository\Blog;
|
||||
|
||||
use App\Entity\Blog\Post;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @method Post|null find($id, $lockMode = null, $lockVersion = null)
|
||||
* @method Post|null findOneBy(array $criteria, array $orderBy = null)
|
||||
* @method Post[] findAll()
|
||||
* @method Post[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
|
||||
*/
|
||||
class PostRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, Post::class);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return Post[] Returns an array of Post objects
|
||||
// */
|
||||
/*
|
||||
public function findByExampleField($value)
|
||||
{
|
||||
return $this->createQueryBuilder('p')
|
||||
->andWhere('p.exampleField = :val')
|
||||
->setParameter('val', $value)
|
||||
->orderBy('p.id', 'ASC')
|
||||
->setMaxResults(10)
|
||||
->getQuery()
|
||||
->getResult()
|
||||
;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
public function findOneBySomeField($value): ?Post
|
||||
{
|
||||
return $this->createQueryBuilder('p')
|
||||
->andWhere('p.exampleField = :val')
|
||||
->setParameter('val', $value)
|
||||
->getQuery()
|
||||
->getOneOrNullResult()
|
||||
;
|
||||
}
|
||||
*/
|
||||
}
|
20
src/Repository/Blog/PostRepositoryQuery.php
Normal file
20
src/Repository/Blog/PostRepositoryQuery.php
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
namespace App\Repository\Blog;
|
||||
|
||||
use Knp\Component\Pager\PaginatorInterface;
|
||||
use App\Repository\Blog\PostRepository;
|
||||
use App\Repository\RepositoryQuery;
|
||||
|
||||
/**
|
||||
* class PostRepositoryQuery.
|
||||
*
|
||||
* @author Simon Vieille <simon@deblan.fr>
|
||||
*/
|
||||
class PostRepositoryQuery extends RepositoryQuery
|
||||
{
|
||||
public function __construct(PostRepository $repository, PaginatorInterface $paginator)
|
||||
{
|
||||
parent::__construct($repository, 'p', $paginator);
|
||||
}
|
||||
}
|
90
src/Repository/RepositoryQuery.php
Normal file
90
src/Repository/RepositoryQuery.php
Normal file
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Criteria\CriteriaMap;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Knp\Component\Pager\PaginatorInterface;
|
||||
|
||||
/**
|
||||
* class RepositoryQuery.
|
||||
*
|
||||
* @author Simon Vieille <simon@deblan.fr>
|
||||
*/
|
||||
abstract class RepositoryQuery
|
||||
{
|
||||
protected ServiceEntityRepository $repository;
|
||||
protected QueryBuilder $query;
|
||||
protected PaginatorInterface $paginator;
|
||||
protected string $id;
|
||||
|
||||
public function __construct(ServiceEntityRepository $repository, string $id, PaginatorInterface $paginator = null)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
$this->query = $repository->createQueryBuilder($id);
|
||||
$this->paginator = $paginator;
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
$class = get_called_class();
|
||||
|
||||
return new $class($this->repository, $this->paginator);
|
||||
}
|
||||
|
||||
public function __call(string $name, $params): self
|
||||
{
|
||||
$fn = function(&$data) {
|
||||
if (is_string($data)) {
|
||||
$words = explode(' ', $data);
|
||||
|
||||
foreach ($words as $k => $v) {
|
||||
if (isset($v[0]) && $v[0] === '.') {
|
||||
$words[$k] = $this->id.$v;
|
||||
}
|
||||
}
|
||||
|
||||
$data = implode(' ', $words);
|
||||
} else {
|
||||
foreach ($data as $k => $v) {
|
||||
$fn($data[$k]);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
};
|
||||
|
||||
foreach ($params as $key => $value)
|
||||
{
|
||||
$fn($params[$key]);
|
||||
}
|
||||
|
||||
call_user_func_array([$this->query, $name], $params);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function call(callable $fn): self
|
||||
{
|
||||
$fn($this->query, $this);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function findOne()
|
||||
{
|
||||
return $this->query->getQuery()->getOneOrNullResult();
|
||||
}
|
||||
|
||||
public function find()
|
||||
{
|
||||
return $this->query->getQuery()->getResult();
|
||||
}
|
||||
|
||||
public function paginate(int $page = 1, int $limit = 20)
|
||||
{
|
||||
return $this->paginator->paginate($this->query->getQuery(), $page, $limit);
|
||||
}
|
||||
}
|
18
src/Repository/UserRepositoryQuery.php
Normal file
18
src/Repository/UserRepositoryQuery.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use Knp\Component\Pager\PaginatorInterface;
|
||||
|
||||
/**
|
||||
* class UserRepositoryQuery.
|
||||
*
|
||||
* @author Simon Vieille <simon@deblan.fr>
|
||||
*/
|
||||
class UserRepositoryQuery extends RepositoryQuery
|
||||
{
|
||||
public function __construct(UserRepository $repository, PaginatorInterface $paginator)
|
||||
{
|
||||
parent::__construct($repository, 'u', $paginator);
|
||||
}
|
||||
}
|
|
@ -64,7 +64,7 @@
|
|||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {{ macros.active_class('blog_post', section) }}" href="{{ path('admin_dashboard_index') }}">
|
||||
<a class="nav-link {{ macros.active_class('blog_post', section) }}" href="{{ path('admin_blog_post_index') }}">
|
||||
<span class="fa fa-pen"></span>
|
||||
|
||||
<span class="nav-item-label">Articles</span>
|
||||
|
@ -72,7 +72,7 @@
|
|||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {{ macros.active_class('blog_post', section) }}" href="{{ path('admin_dashboard_index') }}">
|
||||
<a class="nav-link {{ macros.active_class('blog_category', section) }}" href="{{ path('admin_blog_category_index') }}">
|
||||
<span class="fa fa-puzzle-piece"></span>
|
||||
|
||||
<span class="nav-item-label">Catégories</span>
|
||||
|
|
1
templates/blog/category_admin/index.html.twig
Normal file
1
templates/blog/category_admin/index.html.twig
Normal file
|
@ -0,0 +1 @@
|
|||
{% extends 'admin/layout.html.twig' %}
|
1
templates/blog/post_admin/index.html.twig
Normal file
1
templates/blog/post_admin/index.html.twig
Normal file
|
@ -0,0 +1 @@
|
|||
{% extends 'admin/layout.html.twig' %}
|
Loading…
Reference in a new issue