Search code examples
phpsymfonytwigsylius

Using a custom template for a new entity in Sylius with its ResourceBundle


Following the Documentation for Resource-Bundle i get lost when it comes to setup a template for the backend for a new entity. Short version: I end up with an error "Unable to find template "AppBundle:Book:Backend:index.twig".

I created a new entity "Book" and configured it the right way, that the entity exists also in database and that Sylius automatically prepared routing for GET/POST/DELETE.

Now i want to create a template in the backend-section for displaying all books and also to provide edit- and delete-capabilities.

The routing works fine. But the template will not be found. What do i wrong here?

What I did:

1. Adding the Entity

I added a new Entity named "Book" to the App-Bundle as shown in the documentation.

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

use Sylius\Component\Resource\Model\ResourceInterface;

/**
 * Class Book
 * @ORM\Entity
 * @ORM\Table(name="book")
 */
class Book implements ResourceInterface
{
    /**
     * @var int
     * @ORM\Column(name="id", type="bigint")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    protected $id;

    /**
     * @var string
     *
     * @ORM\Column(name="title", type="string", length=100, nullable=false)
     */
    protected $title;

    /**
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @return string
     */
    public function getTitle()
    {
        return $this->title;
    }

    /**
     * @param string $title
     * @return Book
     */
    public function setTitle($title)
    {
        $this->title = $title;

        return $this;
    }
}

2. Configuring the new resource

Then i configured "book" as a new resource in app/config/config.yml:

sylius_resource:
    resources:
        app.book:
            templates: AppBundle:Book:Backend
            classes:
                model: AppBundle\Entity\Book
                controller: Sylius\Bundle\ResourceBundle\Controller\ResourceController
                repository: Sylius\Bundle\ResourceBundle\Doctrine\ORM\EntityRepository

I've found out that i have to configure the controller and the repository also. Otherwise, sylius wouldn't be able to use a custom template because no controller would be assigned to these routes.

3. Routing to this new resource (backend only)

Then I added the following lines to app/config/routing.yml:

app_book:
   resource: |
       alias: app.book
       section: admin
   type: sylius.resource
   prefix: /administration
   defaults:
        _sylius:
            permission: false

I switched "permission" to false, because Sylius will throw an access-denied-exception unless further RBAC-configuration will be done (which i don't know how to do and which is poorly documented for the case of new models/entities). That's why i bypass any permission checks here for now.

Running php app/console debug:router will list the new routes for my new entity Book:

app_book_index                                        GET              ANY      ANY    /administration/books/                                                                   
app_book_create                                       GET|POST         ANY      ANY    /administration/books/new                                                                
app_book_update                                       GET|PUT|PATCH    ANY      ANY    /administration/books/{id}/edit                                                          
app_book_show                                         GET              ANY      ANY    /administration/books/{id}                                                               
app_book_delete                                       DELETE           ANY      ANY    /administration/books/{id}                                                               

4. Calling the page

But when i login into the Backend (while everything works fine), and call explicitly the URL "/administration/books", this error occurs:

Unable to find template "AppBundle:Book:Backend:index.twig".

CRITICAL - Uncaught PHP Exception InvalidArgumentException: "Unable to find template "AppBundle:Book/Backend:index.twig"." at sylius/acme/vendor/symfony/symfony/src/Symfony/Bridge/Twig/TwigEngine.php line 128

The template file was placed under "AppBundle \ Resources \ Views \ Book \ Backend \ index.html.twig", as you can see in the tree structure below:

enter image description here

What did I wrong here?

UPDATE

Thanks to @gvf, i updated the config.dev and provided a template-property like this:

sylius_resource:
    resources:
        app.book:
            templates: AppBundle:Book/Backend
            classes:
                model: AppBundle\Entity\Book
                controller: Sylius\Bundle\ResourceBundle\Controller\ResourceController
                repository: Sylius\Bundle\ResourceBundle\Doctrine\ORM\EntityRepository

And the file tree now looks like this:

enter image description here

But this works only for the update-action. Index-Action and show-Action end up with "template not found index.twig / show.twig". Renaming the filenames to the mentioned one isn't a valid solution here.

UPDATE II

I released the test installation with entity and config files at github, if interested: https://github.com/itinance/sylius_new_entity

Udpate 3

I opened an issue at github. Maybe someone will clarify.


Solution

  • PR with the fix to Sylius is on its way: https://github.com/Sylius/Sylius/pull/5061 Just leaving here a note if someone was looking for the answer.

    Alternatively you could have used a separate routing for each action:

    app_admin_book_index:
        path: /administration/books/
        methods: [GET]
        defaults:
            _controller: app.controller.book:indexAction
            _sylius:
                permission: false
                template: book/Backend/index.html.twig
    

    Passing a template into _sylius template option was not affected by the bug.