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

Commit cd994e8

Browse files
committed
Rewrite Menu bundles docs for 2.0
1 parent 4cb9bec commit cd994e8

File tree

5 files changed

+200
-230
lines changed

5 files changed

+200
-230
lines changed

bundles/menu/introduction.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ tree:
120120
121121
echo $view['knp_menu']->render('main-menu');
122122
123-
Here the ``main-menu`` document from the previous
124-
example is specified. This will render an unordered list as follows:
123+
Here the ``main-menu`` document from the previous example is specified. This
124+
will render an unordered list as follows:
125125

126126
.. code-block:: html
127127

bundles/menu/menu_factory.rst

Lines changed: 107 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -5,143 +5,135 @@ Menu Factory
55
============
66

77
The menu documents are only used for persisting the menu data, they are not
8-
actually used when rendering a menu. ``MenuItem`` classes from the KnpMenu
9-
component are the objects that are needed, a menu factory takes data provided by
10-
a class implementing ``NodeInterface`` and creates a ``MenuItem`` tree.
8+
actually used when rendering a menu. Menu items are the objects that are needed
9+
to render a menu. A menu factory creates such *menu items* from the *menu
10+
nodes* provided by the menu provider.
1111

1212
.. _bundles_menu_menu_factory_url_generation:
1313

1414
URL Generation
1515
--------------
1616

17-
A menu item should have a URL associated with it. The CMF provides the
18-
``ContentAwareFactory``, which extends the KnpMenu ``RouterAwareFactory`` and
19-
``MenuFactory``.
20-
21-
* The ``MenuFactory`` only supports using the ``uri`` option to specify the
22-
menu items link.
23-
* The ``RouterAwareFactory`` adds support for for generating a URL from the
24-
``route`` and ``routeParameters`` options.
25-
* The CMF adds the ``ContentAwareFactory`` which supports generating the URL
26-
from the ``content`` and ``routeParameters`` options when using the
27-
:ref:`dynamic router <bundles-routing-dynamic-generator>`.
28-
29-
The ``content`` option, if specified, must contain something that the content
30-
URL generator can work with. When using the :ref:`dynamic router
31-
<bundles-routing-dynamic-generator>`, this needs to be a class implementing
32-
the ``RouteReferrersInterface``. You can alternatively specify a custom
33-
``UrlGeneratorInterface`` with the ``content_url_generator`` configuration
34-
option.
35-
36-
.. versionadded:: 1.2
37-
The ``content_url_generator`` option was introduced in CmfMenuBundle 1.2.0.
38-
Prior to 1.2, the default service ``router`` was hardcoded to generate URLs
39-
from content.
40-
41-
URL generation is absolute or relative, depending on the boolean value of the
42-
``routeAbsolute`` option.
17+
.. versionadded:: 2.0
18+
Adding content support to the ``knp_menu.factory`` service was introduced
19+
in CmfMenuBundle 2.0. Prior to 2.0, you had to use the
20+
``ContentAwareFactory`` class and ``cmf_menu.factory`` service.
21+
22+
Most menu items will need a URL. By default, KnpMenu allows generating such
23+
route by specifying a URI or a Symfony route name.
24+
25+
The CmfMenuBundle provides another way to generate URLs: By using the
26+
:ref:`dynamic router <bundles-routing-dynamic-generator>` to generate routes
27+
from content objects.
28+
29+
The ``content`` menu node option, if specified, must contain something that the
30+
content URL generator can work with. When using the :ref:`dynamic router
31+
<bundles-routing-dynamic-generator>`, this needs to be a class implementing the
32+
``RouteReferrersInterface``.
33+
34+
.. tip::
35+
36+
When you don't use the dynamic router, you can create a custom url
37+
generator by implementing ``UrlGeneratorInterface`` and configure it using
38+
the ``content_url_generator`` option in ``config.yml``.
39+
40+
.. versionadded:: 1.2
41+
The ``content_url_generator`` option was introduced in CmfMenuBundle 1.2.
42+
43+
How to handle Items without a URL
44+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
45+
46+
When menu nodes refer to content that has been deleted or there is another
47+
error during route generation, a menu node is skipped by default. You can set
48+
the ``allow_empty_items`` setting of the CmfMenuBundle to ``true`` to render
49+
these nodes as plain text instead.
4350

4451
.. _bundles_menu_menu_factory_link_type:
4552

46-
Link Type
47-
---------
53+
Specifying the Link Type
54+
~~~~~~~~~~~~~~~~~~~~~~~~
4855

49-
The ``linkType`` option is a CMF addition which enables you to specify which
50-
of the three URL generation techniques to use.
56+
The CMF provides a ``linkType`` option, which enables you to specify which URL
57+
generation technique (URI, route or content) should be used.
5158

5259
The values for this options can be one of the following:
5360

54-
* ``null``: If the value is ``null`` (or the options is not set) then the link
55-
type is determined automatically by looking at each of the ``uri``, ``route``
56-
and ``content`` options and using the first one which is non-null.
57-
* **uri**: Use the URI provided by the ``uri`` option.
58-
* **route**: Generate a URL using the route named by the ``route`` option
59-
and the parameters provided by the ``routeParameters`` option.
60-
* **content**: Generate a URL by passing the value of the ``content`` option to
61-
the content URL generator, using any parameters provided by the
62-
``routeParameters`` option.
61+
`null``
62+
If the value is ``null`` (or the option is not set) then the link type is
63+
determined automatically by looking at each of the ``uri``, ``route`` and
64+
``content`` options; using the first one which is non-null;
6365

64-
Menu Nodes without URL
65-
~~~~~~~~~~~~~~~~~~~~~~
66+
uri
67+
Use the URI provided by the ``uri`` option;
6668

67-
A menu node document might not have a URL, when that information was never set
68-
or it points to a content that has been deleted meanwhile. In that case, there
69-
are two options: The menu node can be skipped, or it can be rendered as text
70-
without link. By default, the node is skipped.
69+
route
70+
Generate a URL using the route named by the ``route`` option and the
71+
parameters provided by the ``routeParameters`` option;
7172

72-
You can set ``cmf_menu.allow_empty_items`` to true to render nodes without URL.
73+
content
74+
Generate a URL by passing the value of the ``content`` option to the
75+
content URL generator, using any parameters provided by the
76+
``routeParameters`` option.
7377

7478
Publish Workflow
75-
----------------
76-
77-
The CMF menu factory also determines if menu nodes are published and therefore
78-
visible by use of the :doc:`publish workflow checker
79-
<../core/publish_workflow>`.
79+
~~~~~~~~~~~~~~~~
8080

81-
.. versionadded:: 1.1
82-
The ``MenuContentVoter`` was introduced in CmfMenuBundle 1.1.
83-
84-
The ``MenuContentVoter`` decides that a menu node is not published if the
85-
content it is pointing to is not published.
81+
The CmfMenuBundle provides a ``MenuContentVoter``, which checks if the
82+
referenced content is published using the
83+
:doc:`publish workflow checker <../core/publish_workflow>`. If the content is
84+
not yet published, the menu item not will not be rendered.
8685

8786
Customizing Menus using Events
8887
------------------------------
8988

90-
The CMF menu factory dispatches a ``cmf_menu.create_menu_item_from_node`` event
91-
during the process of creating a ``MenuItem`` from a class implementing
92-
``NodeInterface``. You can use this event to control the ``MenuItem`` that is
93-
created. The ``CreateMenuItemFromNodeEvent`` provides access to the
94-
``NodeInterface`` and ``ContentAwareFactory``, which can be used to create a
95-
custom ``MenuItem``, or to tell the factory to ignore the current node or its
96-
children. For example, this event is used by the
97-
:doc:`publish workflow checker <../core/publish_workflow>` to skip
98-
``MenuItem`` generation for unpublished nodes.
99-
100-
The ``CreateMenuItemFromNodeEvent`` which is dispatched includes the following
101-
methods which can be used to customize the creation of the ``MenuItem`` for a
102-
``NodeInterface``.
103-
104-
* ``CreateMenuItemFromNodeEvent::setSkipNode(true|false)``: Setting
105-
``skipNode`` to true will prevent creation of item from the node and skip
106-
any child nodes.
107-
**Note:** If ``setSkipNode(true)`` is called for ``Menu`` the
108-
``ContentAwareFactory`` will still create an empty item for the menu. This is
109-
to prevent the KnpMenuBundle code from throwing an exception due to ``null``
110-
being passed to a function to render a menu;
111-
* ``CreateMenuItemFromNodeEvent::setItem(ItemInterface $item|null)``: A
112-
listener can call ``setItem`` to provide a custom item to use for the given node.
113-
If an item is set, the ``ContentAwareFactory`` will use it instead of
114-
creating one for the node. The children of the node will still be processed
115-
by the ``ContentAwareFactory`` and listeners will have an opportunity then to
116-
override their items using this method;
117-
* ``CreateMenuItemFromNodeEvent::setSkipChildren(true|false)``: Listeners can
118-
set this to true and the ``ContentAwareFactory`` will skip processing of the
119-
children of the current node.
89+
The CmfMenuBundle dispatches a ``cmf_menu.create_menu_item_from_node`` event
90+
during the process of creating a menu item from a menu node. You can use this
91+
event to control the ``MenuItem`` that is created and to mark the current node
92+
or its children as skipped.
93+
94+
Listeners for this method recieve a ``CreateMenuItemFromNodeEvent`` instance,
95+
which provides access to node using the ``getNode()`` method and allows
96+
skipping nodes using the ``setSkipNode()`` and ``setSkipChildren()`` methods.
97+
98+
.. note::
99+
100+
If you mark the ``Menu`` document (the root node of each menu) as skipped,
101+
an empty item is still created to avoid errors when rendering a menu.
102+
103+
You can use the ``setItem()`` method to set the menu item to use instead of one
104+
generated using the menu node. The child nodes are still processed like normal
105+
and added to this new item.
106+
107+
.. tip::
108+
109+
You can inject the ``knp_menu.factory`` service in the listener to generate
110+
new menu items from nodes.
120111

121112
Example Menu Listener
122113
~~~~~~~~~~~~~~~~~~~~~
123114

124115
This listener handles menu nodes that point to a different menu by implementing
125116
the ``MenuReferrerInterface``::
126117

127-
// src/Acme/DemoBundle/MenuReferrerInterface.php
128-
namespace Acme\DemoBundle;
118+
// src/AppBundle/Menu/MenuReferrerInterface.php
119+
namespace AppBundle\Menu;
129120

130121
interface MenuReferrerInterface
131122
{
132123
public function getMenuName();
133124
public function getMenuOptions();
134125
}
135126

136-
namespace Acme\DemoBundle\EventListener;
127+
// src/AppBundle/EventListener/CreateMenuItemFromMenuListener.php
128+
namespace AppBundle\EventListener;
137129

138130
use Symfony\Cmf\Bundle\MenuBundle\Event\CreateMenuItemFromNodeEvent;
139-
use Acme\DemoBundle\MenuReferrerInterface;
140131
use Knp\Menu\Provider\MenuProviderInterface;
132+
use AppBundle\Menu\MenuReferrerInterface;
141133

142-
class CreateMenuItemFromNodeListener
134+
class CreateMenuItemFromMenuListener
143135
{
144-
protected $provider;
136+
private $provider;
145137

146138
public function __construct(MenuProviderInterface $provider)
147139
{
@@ -162,9 +154,6 @@ the ``MenuReferrerInterface``::
162154

163155
$menu = $this->provider->get($menuName, $menuOptions);
164156
$event->setItem($menu);
165-
166-
// as this does not call $event->setSkipChildren(true),
167-
// children of $node will be rendered as children items of $menu.
168157
}
169158
}
170159

@@ -176,12 +165,11 @@ The service needs to be tagged as event listener:
176165

177166
.. code-block:: yaml
178167
179-
# src/Acme/DemoBundle/Resources/config/services.yml
168+
# app/config/services.yml
180169
services:
181-
acme_demo.listener.menu_referrer_listener:
182-
class: Acme\DemoBundle\EventListener\CreateMenuItemFromNodeListener
183-
arguments:
184-
- "@knp_menu.menu_provider"
170+
app.menu_referrer_listener:
171+
class: AppBundle\EventListener\CreateMenuItemFromMenuListener
172+
arguments: ['@knp_menu.menu_provider']
185173
tags:
186174
-
187175
name: kernel.event_listener
@@ -190,25 +178,31 @@ The service needs to be tagged as event listener:
190178
191179
.. code-block:: xml
192180
193-
<!-- src/Acme/DemoBundle/Resources/config/services.xml -->
181+
<!-- app/config/services.xml -->
194182
<?xml version="1.0" encoding="UTF-8" ?>
195183
<container xmlns="http://symfony.com/schema/dic/services">
196-
<service id="acme_demo.listener.menu_referrer_listener" class="Acme\DemoBundle\EventListener\CreateMenuItemFromNodeListener">
197-
<argument type="service" id="knp_menu.menu_provider" />
198-
<tag name="kernel.event_listener"
199-
event="cmf_menu.create_menu_item_from_node"
200-
method="onCreateMenuItemFromNode"
201-
/>
202-
</service>
184+
185+
<services>
186+
<service id="acme_demo.listener.menu_referrer_listener"
187+
class="AppBundle\EventListener\CreateMenuItemFromMenuListener"
188+
>
189+
<argument type="service" id="knp_menu.menu_provider" />
190+
191+
<tag name="kernel.event_listener"
192+
event="cmf_menu.create_menu_item_from_node"
193+
method="onCreateMenuItemFromNode"
194+
/>
195+
</service>
196+
</services>
203197
</container>
204198
205199
.. code-block:: php
206200
207-
// src/Acme/DemoBundle/Resources/config/services.php
201+
// app/config/services.php
208202
use Symfony\Component\DependencyInjection\Definition;
209203
use Symfony\Component\DependencyInjection\Reference;
210204
211-
$definition = new Definition('Acme\DemoBundle\EventListener\CreateMenuItemFromNodeListener', array(
205+
$definition = new Definition('AppBundle\EventListener\CreateMenuItemFromMenuListener', array(
212206
new Reference('knp_menu.menu_provider'),
213207
));
214208
$definition->addTag('kernel.event_listener', array(

bundles/menu/menu_provider.rst

Lines changed: 19 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,39 +5,31 @@ Menu Provider
55
=============
66

77
A menu provider is responsible for loading a menu when it is requested. KnpMenu
8-
supports having several providers. The MenuBundle provides the
9-
``PhpcrMenuProvider`` to load menu items from PHPCR-ODM.
10-
11-
Every menu is identified by the name of its root node under the path given by
12-
the configuration key ``persistence.phpcr.menu_basepath``. The default path is
13-
``/cms/menu``, so in the following document structure example ``main-menu`` and
14-
``side-menu`` are both valid menu names:
15-
16-
.. code-block:: text
17-
18-
ROOT
19-
cms:
20-
menu:
21-
main-menu:
22-
item-1:
23-
item-2:
24-
side-menu:
25-
item-1:
26-
27-
You can use custom document classes for menu nodes if needed, as long as they
28-
implement ``Knp\Menu\NodeInterface`` (so that they integrate with
29-
KnpMenuBundle). The default ``MenuNode`` class discards children that do not
30-
implement the ``Knp\Menu\NodeInterface``.
8+
supports having several providers. The MenuBundle provides the ``PhpcrMenuProvider``
9+
to load menu items using the PHPCR-ODM.
10+
11+
Every menu is identified by the name of the node. These paths are relative to
12+
the path configured by the ``cmf_menu.persistence.phpcr.menu_basepath``
13+
setting. This defaults to ``/cmf/menu``. In order to get a menu located in
14+
``/cms/menu/main-menu``, you can use the identifier ``main-menu``. You can also
15+
use an absolute path to get menus that are not located in the menu basepath.
16+
17+
.. tip::
18+
19+
You can use custom document classes for menu nodes if needed. But KnpMenu
20+
requires all nodes to implement ``Knp\Menu\NodeInterface``.
3121

3222
.. note::
3323

3424
There is currently no support for Doctrine ORM or other persistence
3525
managers. This is not by design, but only because nobody built that yet.
3626
We would be glad for a pull request refactoring ``PhpcrMenuProvider`` into
37-
a base class suitable for all doctrine implementations, and storage
38-
specific providers.
27+
a base class suitable for all doctrine implementations and storage specific
28+
providers.
29+
30+
.. seealso::
3931

40-
You can also write your completely custom provider and register it with the
41-
KnpMenu as explained in the `KnpMenuBundle custom provider documentation`_.
32+
You can also write your completely custom provider and register it with the
33+
KnpMenu as explained in the `KnpMenuBundle custom provider documentation`_.
4234

4335
.. _`KnpMenuBundle custom provider documentation`: https://github.com/KnpLabs/KnpMenuBundle/blob/master/Resources/doc/custom_provider.md

bundles/menu/sonata_admin.rst

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,15 @@ Menu Admin with Sonata PHPCR-ODM
55
================================
66

77
If the SonataDoctrinePHPCRAdminBundle_ is loaded in the application kernel,
8-
menu node and menu documents can be administrated in Sonata admin. For
9-
instructions on how to configure Sonata, see `configuring sonata admin`_.
8+
menu nodes and documents can be administrated in the Sonata admin panel. For
9+
instructions on how to configure Sonata, see `the sonata admin documentation`_.
1010

11-
Loading of Sonata is controlled with the ``use_sonata_admin`` configuration
12-
setting. By default, this option is automatically set based on whether
13-
SonataDoctrinePHPCRAdminBundle is available, but you can explicitly
14-
disable the flag to not provide the Sonata services even if Sonata would be
15-
available. You can also explicitly enable the flag to get an error if Sonata
16-
becomes unavailable.
11+
The ``use_sonata_admin`` option configures whether to enable the menu admin.
12+
This defaults to ``auto``, meaning it will be enabled when the
13+
SonataAdminBundle is registered. Other values are ``true`` and ``false``,
14+
forcing the admin to respectively be enabled or disabled.
1715

18-
Sonata admin is using the ``content_basepath`` to show the tree of content to
16+
The menu admin uses the ``content_basepath`` to show the tree of nodes to
1917
select the menu node target.
2018

2119
.. configuration-block::

0 commit comments

Comments
 (0)