TreeBrowserBundle

El TreeBrowserBundle proporciona un árbol de navegación en lo alto de un repositorio PHPCR.

Este paquete consta de dos partes:

  • Árbol de navegación genérico con una TreeInterface
  • Implementación del árbol PHPCR e IGU para un navegador PHPCR

Dependencias

Configurando

La clave de configuración para este paquete es symfony_cmf_tree_browser

  • YAML
    # app/config/config.yml
    symfony_cmf_tree_browser:
        session:  default
    

Enrutado

El paquete creará las rutas para cada implementación del árbol encontrado. In order to make those routes available you need to include the following in your routing configuration:

  • YAML
    # app/config/routing.yml
    symfony_cmf_tree:
        resource: .
        type: 'symfony_cmf_tree'
    

Usando

Tienes select.js e init.js los cuáles son una envoltura para construir un árbol jQuery. Úsalos con SelectTree.initTree resp. AdminTree.initTree

  • SelectTree en select.js es un árbol para seleccionar un nodo para poner el id a un campo
  • AdminTree en init.js es para crear un árbol, mover y editar nodos

Ambos tienen las siguientes opciones al crearlos:

  • config.selector: selector jQuery dónde enganchar en el árbol js
  • config.rootNode: id para el nodo raíz de tu árbol, predefinido a «/»
  • config.selected: id del nodo seleccionado
  • config.ajax.children_url: URL al controlador que proporciona los hijos de un nodo
  • config.routing_defaults: array for route parameters (such as _locale etc.)
  • config.path.expanded: ruta de árbol donde el árbol se tendría que expandir al momento
  • config.path.preloaded: árbol de rutas en el cual se debería precargar el nodo para acelerar la experiencia del usuario

Solo select.js

  • config.output: Dónde escribir el id del nodo seleccionado

Solo init.js

  • config.labels: arreglo conteniendo la traducción para las etiquetas del contexto menú (claves 'createItem' y 'deleteItem')
  • config.ajax.move_url: URL al controlador para mover un hijo (es decir, asignarle un nuevo nodo padre)
  • config.ajax.reorder_url: URL al controlador para reorganizar hermanos
  • config.types: arreglo indexado con los tipos de nodo conteniendo información sobre valid_children, iconos y rutas disponibles, utilizados para crear el contexto del menú y para comprobación durante las operaciones de movimiento.

Ejemplos

Ve en las plantillas del paquete de administración de Sonata los ejemplos sobre cómo construir el árbol:

En el mismo paquete el PhpcrOdmTree implementa la interfaz de árbol y da un ejemplo sobre cómo implementar los métodos.

Aquí tienes algunos consejos comunes sobre la utilización del TreeBrowser:

Define tree elements

The first step, is to define all the elements allowed in the tree and their children. Have a look at the cmf-sandbox configuration, the section document_tree in sonata_doctrine_phpcr_admin.

This configuration is set for all your application trees regardless their type (admin or select).

  • YAML
    sonata_doctrine_phpcr_admin:
        document_tree_defaults: [locale]
        document_tree:
            Doctrine\ODM\PHPCR\Document\Generic:
                valid_children:
                    - all
            Symfony\Cmf\Bundle\ContentBundle\Document\MultilangStaticContent:
                valid_children:
                    - Symfony\Cmf\Bundle\BlockBundle\Document\SimpleBlock
                    - Symfony\Cmf\Bundle\BlockBundle\Document\ContainerBlock
                    - Symfony\Cmf\Bundle\BlockBundle\Document\ReferenceBlock
                    - Symfony\Cmf\Bundle\BlockBundle\Document\ActionBlock
            Symfony\Cmf\Bundle\BlockBundle\Document\ReferenceBlock:
                valid_children: []
            ...
    

How to add an admin tree to your page

This can be done either in an action template or in a custom block.

You have to specify the tree root and the selected item, this allows you to have different type of content in your tree.

In this example, we will have the menu elements.

For Symfony 2.2 and later

  • Twig
    {% render(controller('sonata.admin.doctrine_phpcr.tree_controller:treeAction')) with { 'root': websiteId~"/menu", 'selected': menuNodeId, '_locale': app.request.locale } %}
    

For Symfony 2.1

  • Twig
    {% render 'sonata.admin.doctrine_phpcr.tree_controller:treeAction' with { 'root': websiteId~"/menu", 'selected': menuNodeId, '_locale': app.request.locale } %}
    

How to customize the tree behaviour

The TreeBrowserBundle is based on jsTree. jsTree works with events, dispatched everytime the user does an action.

A simple way to customize the tree behavior is to bind your actions to those events.

If you have a look at init.js and select.js, you will notice that actions are already bound to some of the tree events. If the default behavior is not what you need, JQuery provide the unbind function to solve the problem.

Here is a simple way to remove the context menu from the admin tree (add the controller call around the controller name inside render for Symfony 2.2) :

  • Twig
    {% render 'sonata.admin.doctrine_phpcr.tree_controller:treeAction' with { 'root': websiteId~"/menu", 'selected': menuNodeId, '_locale': app.request.locale } %}
    <script type="text/javascript">
        $(document).ready(function() {
            $('#tree').bind("before.jstree", function (e, data) {
                if (data.plugin === "contextmenu") {
                    e.stopImmediatePropagation();
                        return false;
                }
            });
        });
    </script>
    

By default, the item selection open the edit route of the admin class of the element. This action is bind to the “select_node.jstree”.

If you want to remove it, you just need to call the unbind function on this event :

  • Twig
    <script type="text/javascript">
        $(document).ready(function() {
            $('#tree').unbind('select_node.jstree');
        });
    </script>
    

Then you can bind it on another action.

For example, if your want to open a custom action :

  • Twig
    $('#tree').bind("select_node.jstree", function (event, data) {
        if ((data.rslt.obj.attr("rel") == 'Symfony_Cmf_Bundle_MenuBundle_Document_MenuNode'
            || data.rslt.obj.attr("rel") == 'Symfony_Cmf_Bundle_MenuBundle_Document_MultilangMenuNode')
            && data.rslt.obj.attr("id") != '{{ menuNodeId }}'
        ) {
            var routing_defaults = {'locale': '{{ locale }}', '_locale': '{{ _locale }}'};
            routing_defaults["id"] = data.rslt.obj.attr("url_safe_id");
            window.location = Routing.generate('presta_cms_page_edit', routing_defaults);
        }
    });

Don’t forget to add your custom route to the fos_js_routing.routes_to_expose configuration :

  • YAML
    fos_js_routing:
        routes_to_expose:
            - symfony_cmf_tree_browser.phpcr_children
            - symfony_cmf_tree_browser.phpcr_move
            - sonata.admin.doctrine_phpcr.phpcrodm_children
            - sonata.admin.doctrine_phpcr.phpcrodm_move
            - presta_cms_page_edit
    
Bifúrcame en GitHub