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
La clave de configuración para este paquete es symfony_cmf_tree_browser
# app/config/config.yml
symfony_cmf_tree_browser:
session: default
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:
# app/config/routing.yml
symfony_cmf_tree:
resource: .
type: 'symfony_cmf_tree'
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
- config.output: Dónde escribir el id del nodo seleccionado
- 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.
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:
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).
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: []
...
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
{% render(controller('sonata.admin.doctrine_phpcr.tree_controller:treeAction')) with { 'root': websiteId~"/menu", 'selected': menuNodeId, '_locale': app.request.locale } %}
For Symfony 2.1
{% render 'sonata.admin.doctrine_phpcr.tree_controller:treeAction' with { 'root': websiteId~"/menu", 'selected': menuNodeId, '_locale': app.request.locale } %}
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) :
{% 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 :
<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 :
$('#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 :
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