Extra simple manage page by slug

This post is available in french

In this article, we are going to create a Page entity, which allows us to create public pages which will be accessible by the corresponding slug.

Image Title

First we create the entity src/Entity/Page.php

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\PageRepository")
 */
class Page implements PageInterface
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $slug;

    /**
     * @ORM\Column(type="text", nullable=true)
     */
    private $content;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getSlug(): ?string
    {
        return $this->slug;
    }

    public function setSlug(string $slug): self
    {
        $this->slug = $slug;

        return $this;
    }

    public function getContent(): ?string
    {
        return $this->content;
    }

    public function setContent(?string $content): self
    {
        $this->content = $content;

        return $this;
    }
}

then its interface

src/Entity/PageInterface.php

<?php

namespace App\Entity;

use Sylius\Component\Resource\Model\ResourceInterface;

interface PageInterface extends ResourceInterface
{
    public function getSlug();
    public function setSlug(string $slug);
    public function getContent();
    public function setContent(?string $content);
}

We update the database : php bin/console doctrine:migration:diff then php bin/console doctrine:migration:migrate

We add the resource config/packages/resources.yaml

sylius_resource:
    resources:
        app.page:
            classes:
                model: App\Entity\Page

We create the route config/routes.yaml

app_page:
    resource: |
        alias: app.page
        section: admin
        templates: SyliusAdminBundle:Crud
        grid: app_admin_page
        redirect: index
    type: sylius.resource
    prefix: admin

We create the grid config/packages/grids.yaml

sylius_grid:
    grids:
        app_admin_page:
            driver:
                name: doctrine/orm
                options:
                    class: App\Entity\Page
            fields:
                slug:
                    type: string
                content:
                    type: string
            actions:
                main:
                    create:
                        type: create
                item:
                    update:
                        type: update
                    delete:
                        type: delete

If we go to the page /admin/pages we should have this result

Image Title

Now we have to create the controller that will make the link between the slug and the content

src/Controller/PageController.php

<?php

namespace App\Controller;

use App\Repository\PageRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

class PageController extends AbstractController
{
    public function index($slug, PageRepository $pages)
    {
        $page = $pages->findOneBy(array('slug' => $slug));
        if (is_null($page)) {
            throw new NotFoundHttpException('Page not found.');
        }

        return $this->render('page.html.twig',
            array('page' => $page)
        );
    }
}

templates/page.html.twig

{% extends '@SyliusShop/layout.html.twig' %}

{% block content %}
    <div class="">
        <div class="ui hidden divider"></div>

        {{ page.content|raw }}
    </div>
{% endblock %}

and finally we add the controller route config/routes.yaml

app_page_public:
    path: /page/{slug}
    controller: App\Controller\PageController::index

You can now create and access a page by going to /page/son-slug