3. Document Tree

This admin integrates with the CmfTreeBrowserBundle to provide a tree view of the documents.

3.1. Download the Bundles

1
composer require symfony-cmf/tree-browser-bundle
1
composer require friendsofsymfony/jsrouting-bundle

3.2. Enable the Bundles

Then, enable the bundle by adding it to the list of registered bundles in bundles.php file of your project:

// config/bundles.php

return [
    // ...
    FOS\JsRoutingBundle\FOSJsRoutingBundle::class => ['all' => true],
    Symfony\Cmf\Bundle\TreeBrowserBundle\CmfTreeBrowserBundle::class => ['all' => true],
];

You also need to load the routing of those bundles:

  • YAML
    1
    2
    3
    4
    5
    6
    7
    8
    # config/routes.yaml
    
    cmf_tree:
        resource: .
        type: 'cmf_tree'
    
    fos_js_routing:
        resource: "@FOSJsRoutingBundle/Resources/config/routing/routing.xml"
    
  • XML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <!-- config/routes.xml -->
    
    <?xml version="1.0" encoding="UTF-8" ?>
    <routes xmlns="http://symfony.com/schema/routing"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://symfony.com/schema/routing
            http://symfony.com/schema/routing/routing-1.0.xsd">
    
        <import
            resource="."
            type="cmf_tree"
        />
    
        <import
            resource="@FOSJsRoutingBundle/Resources/config/routing/routing.xml"
        />
    
    </routes>
    
  • PHP
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    // config/routes.php
    
    use Symfony\Component\Routing\RouteCollection;
    
    $collection = new RouteCollection();
    
    $collection
        ->addCollection($loader->import('.', 'cmf_tree'))
        ->addCollection($loader->import(
            "@FOSJsRoutingBundle/Resources/config/routing/routing.xml"
        ));
    
    return $collection;
    

3.3. Dashboard Block

This bundle provides a block suitable for showing all documents on the sonata dashboard. We recommend using the ajax_layout and adding the sonata_admin_doctrine_phpcr.tree_block to get a tree view of your PHPCR content:

  • YAML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    # config/packages/sonata_block.yaml
    
    sonata_block:
        blocks:
            sonata_admin_doctrine_phpcr.tree_block:
                settings:
                    id: '/cms'
                contexts:   [admin]
    
    # config/packages/sonata_admin.yaml
    
    sonata_admin:
        dashboard:
            blocks:
                - { position: left, type: sonata_admin_doctrine_phpcr.tree_block }
                - { position: right, type: sonata.admin.block.admin_list }
    
  • XML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <!-- app/config/config.xml -->
    
    <?xml version="1.0" encoding="UTF-8" ?>
    <container xmlns="http://symfony.com/schema/dic/services">
    
        <config xmlns="http://sonata-project.org/schema/dic/block">
            <! ... -->
            <block id="sonata_admin_doctrine_phpcr.tree_block">
                <setting id="id">/cms</setting>
                <context>admin</context>
            </block>
        </config>
    
        <config xmlns="http://sonata-project.org/schema/dic/admin">
            <dashboard>
                <block position="left" type="sonata_admin_doctrine_phpcr.tree_block"/>
                <block position="right" type="sonata.admin.block.admin_list"/>
            </dashboard>
        </config>
    
    </container>
    
  • PHP
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    // app/config/config.php
    
    $container->loadFromExtension('sonata_block', [
        'blocks' => [
            // ...
            'sonata_admin_doctrine_phpcr.tree_block' => [
                'settings' => [
                    'id' => '/cms',
                ],
                'contexts' => ['admin'],
            ],
        ],
    ]);
    
    $container->loadFromExtension('sonata_admin', [
        'dashboard' => [
            'blocks' => [
                ['position' => 'left', 'type' => 'sonata_admin_doctrine_phpcr.tree_block'],
                ['position' => 'right', 'type' => 'sonata.admin.block.admin_list'],
            ],
        ],
    ]);
    

3.4. Configuring the tree

You have to manually configure what types of documents are allowed in the tree and which class may accept what classes as children to manage the creation and move operations. Documents that have no configuration entry or are not configured as valid child of the respective parent document will not be visible in the tree.

This configuration is global for all your document trees.

  • YAML
    1
    2
    3
    4
    5
    6
    7
    # config/packages/sonata_doctrine_phpcr_admin.yaml
    
    sonata_doctrine_phpcr_admin:
        document_tree:
            routing_defaults: [locale]
            repository_name: default
            sortable_by: position
    
  • XML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <!-- app/config/config.xml -->
    
    <?xml version="1.0" encoding="UTF-8" ?>
    <container xmlns="http://symfony.com/schema/dic/services">
    
        <config xmlns="http://sonata-project.org/schema/dic/doctrine_phpcr_admin"/>
    
            <document-tree-default>locale</document-tree-default>
    
            <document-tree class="Doctrine\ODM\PHPCR\Document\Generic">
                <routing-default>locale</routing-default>
                <repository-name>default</repository-name>
                <sortable-by>position</sortable-by>
            </document-tree>
    
            <!-- ... -->
        </config>
    </container>
    
  • PHP
    1
    2
    3
    4
    5
    6
    7
    8
    9
    // app/config/config.php
    
    $container->loadFromExtension('sonata_doctrine_phpcr_admin', [
        'document_tree' => [
            'routing_defaults' => ['locale'],
            'repository_name' => 'default',
            'sortable_by' => 'position',
        ],
    ]);
    

Tip

A real world example can be found in the cmf-sandbox configuration, the section document_tree in sonata_doctrine_phpcr_admin.

3.5. Rendering a Tree Directly

Instead of using the block, you can also use an action to render an admin tree. You can specify the tree root and the selected item, allowing you to have different type of content in your tree. For instance, you could show the tree of menu documents like this:

  • Twig
    1
    2
    3
    4
    5
    6
    7
    8
    {% render(controller(
        'sonata.admin.doctrine_phpcr.tree_controller::treeAction',
         {
            'root':     basePath ~ "/menu",
            'selected': menuNodeId,
            '_locale':  app.request.locale
        }
    )) %}
    
  • PHP
    1
    2
    3
    4
    5
    6
    7
    8
    echo $view['actions']->render(new ControllerReference(
        'sonata.admin.doctrine_phpcr.tree_controller::treeAction',
        [
            'root'     => $basePath . '/menu',
            'selected' => $menuNodeId,
            '_locale'  => $app->getRequest()->getLocale(),
        ],
    ));