Search code examples
symfonysonata-adminsonata

Sonata Admin : get dropdown list of all pages


I have created a block for sonata page that includes a title, a text, an image (from sonata media) and should include a link to another page on the site.

Considering the website will be bilingual (including the URLs), I can't have the user type the link in the admin. The best option would probably be to have a dropdown list of all active pages on the site, but I didn't manage to do it.

In sonata page admin, when you create (or edit) a page, there is actually such a list, the "Destination" field. So I dug a little and found the PageSelectorType which uses a function called getChoices() that would do the trick. However I didn't manage to use that function (or that field) in my block's admin.

Here's my block form so far :

public function buildEditForm(FormMapper $formMapper, BlockInterface $block)
{
    $formMapper
        ->add('settings', 'sonata_type_immutable_array', array(
            'keys' => array(
                array('title', 'text', array('required' => false)),
                array('texte', 'text', array('required' => false)),
                array($this->getMediaBuilder($formMapper), null, array('context' => 'media_accueil')),
            )
        ))
    ;
}

Any idea ?


Solution

  • Got it, there may be a better (cleaner) solution, but at least it works. Here are the steps :

    In services.yml, add the page manager service as a parameter :

    sonata.block.service.text_with_link:
        class: Application\Sonata\PageBundle\Block\TextWithLinkBlockService
        arguments:
            - sonata.block.service.text_with_link
            - "@templating"
            - @sonata.page.manager.page
        tags:
            - { name: sonata.block }
    

    In your BlockService php file, add the __construct method as follow to initialize the page manager :

    class TexteTitreBlockService extends BaseBlockService
    {
        /**
         * @var PageManagerInterface
         */
        protected $pageManager;
    
        /**
         * @param string               $name
         * @param EngineInterface      $templating
         * @param PageManagerInterface $pageManager
         */
        public function __construct($name, EngineInterface $templating, PageManagerInterface $pageManager)
        {
            parent::__construct($name, $templating);
    
            $this->pageManager = $pageManager;
        }
    }
    

    Then all you need to do is to get the list of pages :

    $pageList = $this->pageManager->findBy(array(
        'routeName' => Page::PAGE_ROUTE_CMS_NAME,
    ));
    

    And you can then use the content of that variable to use in a ChoiceType::class (with whatever is useful to you, the page name, the page slug, etc...)