Skip to content
This repository has been archived by the owner on Sep 16, 2021. It is now read-only.

[WIP] TreeBrowser 2.0 docs #815

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
83 changes: 37 additions & 46 deletions bundles/tree_browser/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,73 +5,64 @@ The TreeBrowserBundle can be configured under the ``cmf_tree_browser`` key in
your application configuration. When using XML, you can use the
``http://cmf.symfony.com/schema/dic/treebrowser`` namespace.

.. note::

To use this bundle with the tree provided by SonataDoctrinePHPCRAdminBundle_,
you do not need to provide any configuration here.

Configuration
-------------

.. _config-tree_browser-persistence:
.. _config-tree_browser-icons:

``icons``
~~~~~~~~~

``persistence``
~~~~~~~~~~~~~~~
**prototype**: ``scalar``

``phpcr``
.........
A mapping of interfaces/classes to icons. These icons will be shown in the tree
whenever an instance of this interface/class is shown.

This defines the persistence driver. The default configuration of persistence
is the following configuration:
The icon can be either a CSS class (e.g. to use an icon font) or a URI to an
image. The value is considered to be an URI when it contains a ``.`` or ``/``
character.

.. configuration-block::

.. code-block:: yaml

cmf_tree_browser:
persistence:
phpcr:
enabled: false
session_name: default
icons:
# URI to an image
Symfony\Cmf\Component\Routing\RouteObjectInterface: '/img/route-icon.png'

# CSS classes
Symfony\Cmf\Bundle\SeoBundle\Model\SeoMetadata: 'fa fa-search'

.. code-block:: xml

<?xml version="1.0" charset="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services">
<?xml version="2.0" encoding="UTF-8"?>
<container xmlns="http://symfony.com/dic/schema/services"
xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance"
xsd:schemaLocation="http://symfony.com/dic/schema/services http://symfony.com/dic/schema/services/services-1.0.xsd
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we not rename this xsd file to 2.0 or remove the version if we completely change the configuration format?

http://cmf.symfony.com/dic/schema/tree_browser http://cmf.symfony.com/dic/schema/tree_browser/tree_browser-1.0.xsd"
>

<config xmlns="http://cmf.symfony.com/schema/dic/treebrowser">
<persistence>
<phpcr
enabled="false"
session-name="default"
/>
</persistence>
</config>
<config xmlns="http://cmf.symfony.com/dic/schema/tree_browser">

<!-- URI to an image -->
<icon class="Symfony\Cmf\Component\Routing\RouteObjectInterface">/img/route-icon.png</icon>

<!-- CSS classes -->
<icon class="Symfony\Cmf\Bundle\SeoBundle\Model\SeoMetadata">fa fa-search</icon>
</config>
</container>

.. code-block:: php

$container->loadFromExtension('cmf_tree_browser', array(
'persistence' => array(
'phpcr' => array(
'enabled' => false,
'session_name' => 'default',
),
),
));


``enabled``
"""""""""""

.. include:: ../_partials/persistence_phpcr_enabled.rst.inc

``session_name``
""""""""""""""""

**type**: ``string`` **default**: ``default``
$container->loadFromExtension('cmf_tree_browser', [
'icons' => [
// URI to an image
'Symfony\Cmf\Component\Routing\RouteObjectInterface' => '/img/route-icon.png',

The name of the PHPCR connection to use.
// CSS classes
'Symfony\Cmf\Bundle\SeoBundle\Model\SeoMetadata' => 'fa fa-search',
],
]);

.. _SonataDoctrinePHPCRAdminBundle: http://sonata-project.org/bundles/doctrine-phpcr-admin/master/doc/index.html
5 changes: 5 additions & 0 deletions bundles/tree_browser/forms.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.. index::
single: Forms; TreeBrowserBundle

How to Use the Tree as a Form Type
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO document the form type

==================================
3 changes: 3 additions & 0 deletions bundles/tree_browser/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@ TreeBrowserBundle
:maxdepth: 2

introduction
forms
tree
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we find a better filename for this? all chapters are somehow about trees - is this one about rendering? about the js side?

configuration
context_menu
197 changes: 27 additions & 170 deletions bundles/tree_browser/introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,53 +5,49 @@
TreeBrowserBundle
=================

The TreeBrowserBundle provides a tree navigation on top of a PHPCR
repository. The front-end implementation is based on the jQuery plugin
`jsTree`_.

This bundle consists of two parts:

* Generic Tree Browser with a ``TreeInterface``
* PHPCR tree implementation and GUI for a PHPCR browser
The TreeBrowserBundle provides a tree view to visualize the backend and
make it easy to manage the backend. It uses the ResourceRestBundle to get
the nodes.

Installation
------------

You can install this bundle `with composer`_ using the
``symfony-cmf/tree-browser-bundle`` package on `Packagist`_.

Both the CmfTreeBrowserBundle and FOSJsRoutingBundle_ must be registered in the
``AppKernel``::
The CmfTreeBrowserBundle, ResourceRestBundle and ResourceBundle must be
registered in the ``AppKernel``::

// app/appKernel.php

// ...
public function registerBundles()
{
$bundles = array(
// ...
new FOS\JsRoutingBundle\FOSJsRoutingBundle(),
new Symfony\Cmf\Bundle\ResourceBundle\CmfResourceBundle(),
new Symfony\Cmf\Bundle\ResourceRestBundle\CmfResourceRestBundle(),
new Symfony\Cmf\Bundle\TreeBrowserBundle\CmfTreeBrowserBundle(),
);

// ...

return $bundles;
}

Routing
-------
~~~~~~~

The bundle will create routes for each tree implementation found. In order to
make those routes available you need to include the following in your routing
configuration:
The ResourceRestBundle provides a REST interface using Symfony routes. In order
to make this work, you have to import the routes in your routing configuration:

.. configuration-block::

.. code-block:: yaml

# app/config/routing.yml
cmf_tree:
resource: .
type: 'cmf_tree'
cmf_resource_rest:
resource: "@CmfResourceRest/Resources/config/routing.xml"

.. code-block:: xml

Expand All @@ -62,7 +58,7 @@ configuration:
xsi:schemaLocation="http://symfony.com/schema/routing
http://symfony.com/schema/routing/routing-1.0.xsd">

<import resource="." type="cmf_tree" />
<import resource="@CmfResourceRestBundle/Resources/config/routing.xml" />

</routes>

Expand All @@ -72,173 +68,34 @@ configuration:
use Symfony\Component\Routing\RouteCollection;

$collection = new RouteCollection();
$collection->addCollection($loader->import('.', 'cmf_tree'));
$collection->addCollection($loader->import(
'@CmfResourceRestBundle/Resources/config/routing.xml'
));

return $collection;

Usage
-----

The TreeBrowserBundle provides the ``select_tree.js`` and ``admin_tree.js``
files, which are wrappers to build a jQuery tree. Use them with
``SelectTree.initTree`` resp. ``AdminTree.initTree``.

* ``SelectTree`` in ``select_tree.js`` is a tree to select a target tree node,
e.g. in a form. The id of the target is put into a text field;
* ``AdminTree`` in ``admin_tree.js`` is a tree to create, move and edit nodes.

Both have the following options when creating:

* **config.selector**: jQuery selector where to hook in the js tree;
* **config.rootNode**: id to the root node of the tree, defaults to ``/``;
* **config.selected**: id of the selected node;
* **config.ajax.children_url**: URL to the controller that provides the
children of a node;
* **config.routing_defaults**: array for route parameters (e.g. ``_locale``);
* **config.path.expanded**: tree path where the tree should be expanded to at
the moment;
* **config.path.preloaded**: tree path what node should be preloaded for
faster user experience.

select_tree.js only
~~~~~~~~~~~~~~~~~~~

* **config.output**: where to write the id of the selected node.

admin_tree.js only
~~~~~~~~~~~~~~~~~~

* **config.labels**: array containing the translations for the labels of the
context menu (keys ``createItem`` and ``deleteItem``);
* **config.ajax.move_url**: Url to the controller for moving a child (i.e.
giving it a new parent node);
* **config.ajax.reorder_url**: Url to the controller for reordering siblings;
* **config.types**: array indexed with the node types containing information
about valid_children, icons and available routes, used for the creation of
context menus and checking during move operations.

Examples
--------

Look at the templates in the SonataDoctrinePHPCRAdminBundle_ for examples how
you could build a tree:

* `admin_tree.js`_
* `select_tree.js`_ (look for ``doctrine_phpcr_type_tree_model_widget``)

In the same bundle, the `PhpcrOdmTree`_ implements the tree interface and
provides an example how to implement the methods.

Customizing the Tree Behavior
-----------------------------

The TreeBrowserBundle is based on `jsTree`_. jsTree works with events,
dispatched every time 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 ``admin_tree.js`` and ``select_tree.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`` method
to remove the default events. Here is a simple way to remove the context menu
from the admin tree:

.. configuration-block::

.. code-block:: html+jinja

{% render 'sonata.admin.doctrine_phpcr.tree_controller:treeAction' with {
'root': sitePath ~ "/menu",
'selected': menuNodeId
} %}
<script type="text/javascript">
$(document).ready(function() {
$('#tree').bind("before.jstree", function (e, data) {
if ("contextmenu" === data.plugin) {
e.stopImmediatePropagation(); // stops executing of default event

return false;
}
});
});
</script>

.. code-block:: html+php

<?php
$view['actions']->render('sonata.admin.doctrine_phpcr.tree_controller:treeAction', array(
'root' => $sitePath . '/menu',
'selected' => $menuNodeId,
))?>
<script type="text/javascript">
$(document).ready(function() {
$('#tree').bind("before.jstree", function (e, data) {
if ("contextmenu" === data.plugin) {
e.stopImmediatePropagation(); // stops executing of default event

return false;
}
});
});
</script>

.. note::

This example assumes you have the SonataDoctrinePHPCRAdminBundle_
available, to have a tree implementation.

By default, the item selection opens 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:

.. code-block:: javascript

$(document).ready(function() {
$('#tree').unbind('select_node.jstree');
});

Then you can bind it on another action.

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

.. configuration-block::

.. code-block:: jinja

$('#tree').bind("select_node.jstree", function (event, data) {
if ((data.rslt.obj.attr("rel") == 'Symfony_Cmf_Bundle_MenuBundle_Doctrine_Phpcr_MenuNode'
&& 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);
}
});

.. code-block:: php

$('#tree').bind("select_node.jstree", function (event, data) {
if ((data.rslt.obj.attr("rel") == 'Symfony_Cmf_Bundle_MenuBundle_Doctrine_Phpcr_MenuNode'
&& data.rslt.obj.attr("id") != '<?php echo $menuNodeId ?>'
) {
var routing_defaults = {'locale': '<?php echo $locale ?>', '_locale': '<?php echo $_locale ?>'};
routing_defaults["id"] = data.rslt.obj.attr("url_safe_id");
window.location = Routing.generate('presta_cms_page_edit', routing_defaults);
}
});
The TreeBrowserBundle provides a two jQuery plugins, ready for you to use:

.. note::
* :doc:`$(elem).cmfTree() <tree>`
* :doc:`$(elem).cmfContextMenu() <context_menu>`

This bundle automatically exposes routes with the FOSJsRoutingBundle_
to allow the tree to work.
The bundle also ships a ``TreeSelectType`` form type. Using this form type,
users can select nodes from the tree instead of typing the path in a text
field. Read more about this form type in :doc:`it's own section <forms>`.

Read On
-------

* :doc:`forms`
* :doc:`tree`
* :doc:`configuration`
* :doc:`context_menu`

.. _`Packagist`: https://packagist.org/packages/symfony-cmf/tree-browser-bundle
.. _`with composer`: http://getcomposer.org
.. _`FOSJsRoutingBundle`: https://github.com/FriendsOfSymfony/FOSJsRoutingBundle
.. _`admin_tree.js`: https://github.com/sonata-project/SonataDoctrinePhpcrAdminBundle/blob/master/Resources/views/Tree/tree.html.twig
.. _`select_tree.js`: https://github.com/sonata-project/SonataDoctrinePhpcrAdminBundle/blob/master/Resources/views/Form/form_admin_fields.html.twig
.. _`PhpcrOdmTree`: https://github.com/sonata-project/SonataDoctrinePhpcrAdminBundle/blob/master/Tree/PhpcrOdmTree.php
Expand Down