diff --git a/_images/quick_tour/3rd-party-bundles-homepage.png b/_images/quick_tour/3rd-party-bundles-homepage.png
index 1032fee5..ea6844e9 100644
Binary files a/_images/quick_tour/3rd-party-bundles-homepage.png and b/_images/quick_tour/3rd-party-bundles-homepage.png differ
diff --git a/_images/quick_tour/3rd-party-bundles-sonata-admin.png b/_images/quick_tour/3rd-party-bundles-sonata-admin.png
index 672c3b93..f38ab265 100644
Binary files a/_images/quick_tour/3rd-party-bundles-sonata-admin.png and b/_images/quick_tour/3rd-party-bundles-sonata-admin.png differ
diff --git a/_images/quick_tour/big-picture-createjs-bar.png b/_images/quick_tour/big-picture-createjs-bar.png
deleted file mode 100644
index 874f3e23..00000000
Binary files a/_images/quick_tour/big-picture-createjs-bar.png and /dev/null differ
diff --git a/_images/quick_tour/big-picture-edit-page.png b/_images/quick_tour/big-picture-edit-page.png
deleted file mode 100644
index 1756d59b..00000000
Binary files a/_images/quick_tour/big-picture-edit-page.png and /dev/null differ
diff --git a/_images/quick_tour/big-picture-new-page.png b/_images/quick_tour/big-picture-new-page.png
deleted file mode 100644
index 9e22e2c5..00000000
Binary files a/_images/quick_tour/big-picture-new-page.png and /dev/null differ
diff --git a/_images/quick_tour/the-model-new-page.png b/_images/quick_tour/the-model-new-page.png
deleted file mode 100644
index 459bc089..00000000
Binary files a/_images/quick_tour/the-model-new-page.png and /dev/null differ
diff --git a/_images/quick_tour/the-router-new-page.png b/_images/quick_tour/the-router-new-page.png
new file mode 100644
index 00000000..040bc6b8
Binary files /dev/null and b/_images/quick_tour/the-router-new-page.png differ
diff --git a/big-picture-home.png b/big-picture-home.png
new file mode 100644
index 00000000..a7180990
Binary files /dev/null and b/big-picture-home.png differ
diff --git a/quick_tour/the_big_picture.rst b/quick_tour/the_big_picture.rst
index 7a90256b..240332c7 100644
--- a/quick_tour/the_big_picture.rst
+++ b/quick_tour/the_big_picture.rst
@@ -4,7 +4,7 @@
The Big Picture
===============
-Start using the Symfony CMF in 10 minutes! This chapter will walk you through
+Start using the Symfony CMF in 10 minutes! This quick tour will walk you through
the base concepts of the Symfony CMF and get you started with it.
It's important to know that the Symfony CMF is a collection of bundles which
@@ -13,7 +13,7 @@ Framework. Before you read further, you should at least have a basic knowledge
of the Symfony Framework. If you don't know Symfony, start by reading the
`Symfony Framework Quick Tour`_.
-Solving the framework versus CMS dilemma
+Solving the Framework versus CMS Dilemma
----------------------------------------
Before starting a new project, there is a difficult decision on whether it
@@ -23,38 +23,33 @@ other hand, when choosing to use a CMS, it's more difficult to build custom
application functionality. It is impossible or at least very hard to customize
the core parts of the CMS.
-The CMF is created to solve this framework versus CMS dilemma. It provides
-bundles, so you can easily add CMS features to your project. But it also
-provides flexibility and in all cases you are using the framework, so you can
-build custom functionality the way you want. This is called a `decoupled CMS`_.
+The Symfony CMF is created to solve this framework versus CMS dilemma. It
+provides Symfony bundles to easily add CMS features to your project. Yet, as
+you're still using the Symfony framework, you can build any custom functionality
+you can think of. This flexibility is called a `decoupled CMS`_.
The bundles provided by the Symfony CMF can work together, but they are also
able to work standalone. This means that you don't need to add all bundles, you
-can decide to only use one of them (e.g. only the RoutingBundle or the MediaBundle).
+can decide to only use one of them (e.g. only the RoutingBundle).
-Downloading the Symfony CMF Standard Edition
---------------------------------------------
+Downloading the Symfony CMF Sandbox
+-----------------------------------
-When you want to start using the CMF for a new project, you can download the
+To explore the CMF, it is best to download the Symfony CMF Sandbox. The sandbox
+contains demonstrations for many of the CMF features and is a good playground
+to familiarize yourself with the CMF.
+
+When you want to start an actual project with the CMF, best download the
Symfony CMF Standard Edition. The Symfony CMF Standard Edition is similar to
the `Symfony Standard Edition`_, but contains and configures essential Symfony
-CMF bundles. It also adds a very simple bundle to show some of the basic
-Symfony CMF features.
+CMF bundles.
-The best way to download the Symfony CMF Standard Edition is using Composer_:
+The best way to download the Symfony CMF Sandbox is using Composer_:
.. code-block:: bash
- $ composer create-project symfony-cmf/standard-edition cmf '1.2.1'
-
-.. note::
+ $ composer create-project symfony-cmf/sandbox cmf-sandbox
- The `AcmeDemoBundle` that is used in this tour was removed in
- version 1.3 of the Symfony CMF Standard Edition. Since then it has
- become the skeleton for a simple CMS application. This is why we
- install version 1.2.1. If you insist on checking out the most
- recent versions of the CMF, check out `symfony-cmf/cmf-sandbox`.
-
Setting up the Database
~~~~~~~~~~~~~~~~~~~~~~~
@@ -63,15 +58,20 @@ something you are used to doing when creating Symfony applications, but the
Symfony CMF needs a database in order to make a lot of things configurable
using an admin interface.
-To quickly get started, it is expected that you have enabled the sqlite
+To quickly get started, it is expected that you have enabled the sqlite PHP
extension. After that, run these commands:
.. code-block:: bash
+ $ cd cmf-sandbox
+ $ cp app/config/phpcr_doctrine_dbal.yml.dist app/config/phpcr.yml
+ # Or when you're on a Windows PC:
+ # $ copy app\config\phpcr_doctrine_dbal.yml.dist app\config\phpcr.yml
+
$ php bin/console doctrine:database:create
- $ php bin/console doctrine:phpcr:init:dbal
+ $ php bin/console doctrine:phpcr:init:dbal --force
$ php bin/console doctrine:phpcr:repository:init
- $ php bin/console doctrine:phpcr:fixtures:load
+ $ php bin/console doctrine:phpcr:fixtures:load -n
.. tip::
@@ -88,11 +88,13 @@ The Request Flow
.. tip::
- When you have at least PHP 5.4, use the ``server:run`` command to run a
- local server for the demo. Otherwise, use a ``localhost`` and prefix the URLs
- in this document with ``/path-to-project/web/app_dev.php/``.
+ Use the ``server:run`` command to run a local server for the demo. If you
+ use a web server like Nginx or Apache, you need to prefix the URLs
+ in this document with ``app_dev.php/`` (and the path to the ``web`` folder
+ inside the Symfony project, if that is not already the root folder of your
+ server).
-Now, the Standard Edition is ready to use. Navigate to the homepage
+Now, the Sandbox is ready to use. Navigate to the homepage
(``http://localhost:8000/``) to see the demo:
.. image:: ../_images/quick_tour/big-picture-home.png
@@ -170,53 +172,24 @@ this template.
A view also uses a Menu, provided by the KnpMenuBundle_, and it can have
integration with Create.js, for live editing.
-Adding a New Page
------------------
-
-Now you know the request flow, you can start adding a new page. In the Symfony
-CMF Standard Edition, the data is stored in data files, which are loaded when
-executing the ``doctrine:phpcr:fixtures:load`` command. To add a new page, you
-just need to edit such a data file, which is located in the
-``src/Acme/DemoBundle/Resources/data`` directory:
-
-.. code-block:: yaml
-
- # src/Acme/DemoBundle/Resources/data/pages.yml
- Symfony\Cmf\Bundle\SimpleCmsBundle\Doctrine\Phpcr\Page:
- # ...
-
- quick_tour:
- id: /cms/simple/quick_tour
- label: "Quick Tour"
- title: "Reading the Quick Tour"
- body: "I've added this page while reading the quick tour"
-
-After this, you need to run the ``doctrine:phpcr:fixtures:load`` to reflect
-the changes on the database and after refreshing, you can see your new page!
-
-.. image:: ../_images/quick_tour/big-picture-new-page.png
-
-Live Editing
+The Fixtures
------------
-Now is the time you become an admin of this site and editing the content using
-the Web Interface. To do this click on "Admin Login" and use the provided
-credentials.
-
-You'll see that you have a new bar at the top of the page:
-
-.. image:: ../_images/quick_tour/big-picture-createjs-bar.png
-
-This bar is generated by the `Create.js`_ library. The Symfony CMF integrates
-the CreatePHP_ and `Create.js`_ libraries using a CreateBundle. This enables
-you to edit a page using a full WYSIWYG editor when you are reading the page.
-
-Now you can change the content of our new page using Create.js:
-
-.. image:: ../_images/quick_tour/big-picture-edit-page.png
-
-After clicking "save", the changes are saved using the CreateBundle and the
-content is updated.
+Now you know the request flow, you can start editing content. While the normal
+usage will be to edit content through a web interface, the CMF sandbox also
+supports loading content from static files. This is mainly useful for testing
+purposes.
+
+The fixtures are loaded with the ``doctrine:phpcr:fixtures:load`` command. To
+edit the home page, edit the first entry in
+``src/AppBundle/Resources/data/page.yml`` to say something different. Then, run
+the ``doctrine:phpcr:fixtures:load`` command to get the changes into the
+content repository. After refreshing the browser, you can see your
+modifications!
+
+Don't worry, editing fixture files is only done for developing and testing. The
+CMF comes with a Sonata admin integration for convenient online editing, or you
+can build your own editing systems.
Final Thoughts
--------------
diff --git a/quick_tour/the_model.rst b/quick_tour/the_model.rst
index 3c95fad6..f887c376 100644
--- a/quick_tour/the_model.rst
+++ b/quick_tour/the_model.rst
@@ -11,8 +11,8 @@ of the CMF.
.. note::
Again, this chapter is talking about the PHPCR storage layer. But the CMF
- is storage agnostically created, meaning it is not tied to specific storage
- system.
+ is written in a storage agnostic way, meaning it is not tied to specific
+ storage system.
Getting Familiar with PHPCR
---------------------------
@@ -23,7 +23,7 @@ data stored with PHPCR has a relationship with at least one other data: its
parent. The inverse relation also exists, you can also get the children of a
data element.
-Let's take a look at the dump of the tree of the Standard Edition you
+Let's take a look at the dump of the tree of the CMF Sandbox you
downloaded in the previous chapter. Go to your directory and execute the
following command:
@@ -36,36 +36,49 @@ The result will be the PHPCR tree:
.. code-block:: text
ROOT:
- cms:
- simple:
- about:
- contact:
- map:
- team:
- quick_tour:
- dynamic:
- docs:
- demo:
- demo_redirect:
- hardcoded_dynamic:
- hardcoded_static:
-
-Each data is called a *node* in PHPCR. In this tree, there are 13 nodes and
-one ROOT node (created by PHPCR). You may have already seen the document you
-created in the previous section, it's called ``quick_tour`` (and it's path is
-``/cms/simple/quick_tour``). When using the SimpleCmsBundle, all nodes are
-stored in the ``/cms/simple`` path.
+ cms:
+ menu:
+ main:
+ admin-item:
+ projects-item:
+ cmf-item:
+ company-item:
+ team-item:
+ ...
+ content:
+ home:
+ phpcr_locale:en:
+ phpcr_locale:fr:
+ phpcr_locale:de:
+ seoMetadata:
+ additionalInfoBlock:
+ child1:
+ ...
+ routes:
+ en:
+ company:
+ team:
+ more:
+ about:
+ ...
+
+Each data is called a *node* in PHPCR. Everything is attached under the ROOT
+node (created by PHPCR itself).
Each node has properties, which contain the data. The content, title and label
-you set for your page are saved in such properties for the ``quick_tour``
+you set for your page are saved in such properties for the ``home``
node. You can view these properties by adding the ``--props`` switch to the
-dump command.
+dump command:
+
+.. code-block:: bash
+
+ $ php bin/console doctrine:phpcr:node:dump --props /cms/content/home
.. note::
Previously, the PHPCR tree was compared with a Filesystem. While this
- gives you a good image of what happens, it's not the truth. You can
- better compare it to an XML file, where each node is an element and its
+ gives you a good image of what happens, it's not the only truth. You can
+ compare it to an XML file, where each node is an element and its
properties are attributes.
Doctrine PHPCR-ODM
@@ -74,37 +87,39 @@ Doctrine PHPCR-ODM
The Symfony CMF uses the `Doctrine PHPCR-ODM`_ to interact with PHPCR.
Doctrine allows a user to create objects (called *documents*) which are
directly persisted into and retrieved from the PHPCR tree. This is similar to
-the Doctrine ORM used by the Symfony2 Framework, but then for PHPCR.
+the Doctrine ORM provided by default in the Symfony Standard Edition, but for
+PHPCR instead of SQL databases.
-Creating a Page with code
--------------------------
+Creating Content from Code
+--------------------------
-Now you know a little bit more about PHPCR and you know the tool to interact
-with it, you can start using it yourself. In the previous chapter, you created
-a page by using a yaml file which was parsed by the SimpleCmsBundle. This
-time, you'll create a page by doing it yourself.
+Now that you know a little bit more about PHPCR and you know the tool to interact
+with it, you can start using it yourself. In the previous chapter, you edited
+a page by using a Yaml file which was parsed by the fixture loader of the
+sandbox. This time, you'll create a page with PHP code.
First, you have to create a new DataFixture to add your new page. You do this
-by creating a new class in the AcmeDemoBundle::
+by creating a new class in the AppBundle::
- // src/Acme/DemoBundle/DataFixtures/PHPCR/LoadPageData.php
- namespace Acme\DemoBundle\DataFixtures\PHPCR;
+ // src/AppBundle/DataFixtures/PHPCR/LoadQuickTourData.php
+ namespace AppBundle\DataFixtures\PHPCR;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
- class LoadPageData implements FixtureInterface, OrderedFixtureInterface
+ class LoadQuickTourData implements FixtureInterface, OrderedFixtureInterface
{
public function getOrder()
{
// refers to the order in which the class' load function is called
// (lower return values are called first)
- return 10;
+ return 100;
}
public function load(ObjectManager $documentManager)
{
+ // you will add code to this method in the next steps
}
}
@@ -112,63 +127,48 @@ The ``$documentManager`` is the object which will persist the document to
PHPCR. But first, you have to create a new Page document::
use Doctrine\ODM\PHPCR\DocumentManager;
- use Symfony\Cmf\Bundle\SimpleCmsBundle\Doctrine\Phpcr\Page;
+ use Symfony\Cmf\Bundle\ContentBundle\Doctrine\Phpcr\StaticContent;
// ...
public function load(ObjectManager $documentManager)
{
if (!$documentManager instanceof DocumentManager) {
- $class = get_class($documentManager);
- throw new \RuntimeException("Fixture requires a PHPCR ODM DocumentManager instance, instance of '$class' given.");
+ throw new \RuntimeException(sprintf(
+ 'Fixture requires a PHPCR ODM DocumentManager instance, instance of "%s" given.',
+ get_class($documentManager)
+ ));
}
- $page = new Page(); // create a new Page object (document)
- $page->setName('new_page'); // the name of the node
- $page->setLabel('Another new Page');
- $page->setTitle('Another new Page');
- $page->setBody('I have added this page myself!');
+ $content = new StaticContent();
+ $content->setName('quick-tour'); // the name of the node
+ $content->setTitle('Quick tour new Page');
+ $content->setBody('I have added this page myself!');
}
-Each document needs a parent. In this case, the parent should just be the root
+Each document needs a parent. In this case, the parent should be the content root
node. To do this, we first retrieve the root document from PHPCR and then set
it as its parent::
- // ...
public function load(ObjectManager $documentManager)
{
- if (!$documentManager instanceof DocumentManager) {
- $class = get_class($documentManager);
- throw new \RuntimeException("Fixture requires a PHPCR ODM DocumentManager instance, instance of '$class' given.");
- }
-
// ...
-
- // get root document (/cms/simple)
- $simpleCmsRoot = $documentManager->find(null, '/cms/simple');
-
- $page->setParentDocument($simpleCmsRoot); // set the parent to the root
+ // get the root document
+ $contentRoot = $documentManager->find(null, '/cms/content');
+ $content->setParentDocument($contentRoot); // set the parent to the root
}
-And at last, we have to tell the Document Manager to persist our Page
+And finally, we have to tell the Document Manager to persist our content
document using the Doctrine API::
- // ...
public function load(ObjectManager $documentManager)
{
- if (!$documentManager instanceof DocumentManager) {
- $class = get_class($documentManager);
- throw new \RuntimeException("Fixture requires a PHPCR ODM DocumentManager instance, instance of '$class' given.");
- }
-
// ...
- $documentManager->persist($page); // add the Page in the queue
- $documentManager->flush(); // add the Page to PHPCR
+ $documentManager->persist($content); // tell the document manager to track the content
+ $documentManager->flush(); // doctrine is like a toilet: never forget to flush
}
-Now you need to execute the ``doctrine:phpcr:fixtures:load`` command again and
-then you can visit your website again. You'll see your new page you added!
-
-.. image:: ../_images/quick_tour/the-model-new-page.png
+Now you need to execute the ``doctrine:phpcr:fixtures:load`` command again.
+When dumping the nodes again, your new page should show up under ``/cms/content/quick-tour``!
.. seealso::
diff --git a/quick_tour/the_router.rst b/quick_tour/the_router.rst
index e7eddcaf..32bdc52e 100644
--- a/quick_tour/the_router.rst
+++ b/quick_tour/the_router.rst
@@ -4,27 +4,27 @@
The Router
==========
-Welcome at the third part of the Quick Tour. You seem to have fallen in love
-with the CMF, getting this far! And that's a good thing, as you will learn
-about the backbone of the CMF in this chapter: The Router.
+Welcome at the third part of the Quick Tour. Well done, making it this far!
+And that's a good thing, as you will learn about the backbone of the CMF in
+this chapter: The Router.
The Backbone of the CMF
-----------------------
-As already said, the router is the backbone. To understand this, you have a
-good view of what a CMS tries to do. In a normal Symfony application, a route
+The router is central to the CMF. To understand this, let us
+look at what a CMS tries to do. In a normal Symfony application, a route
refers to a controller which can handle a specific entity. Another route
refers to another controller which can handle another entity. This way, a
route is tied to a controller. In fact, using the Symfony core you are also
-limited at this.
+limited by this pattern.
-But if you look at the base of a CMS, it only needs to handle 1 type of
+But if you look at the base of a CMS, it only needs to handle one type of
entity: The Content. So most of the routes don't have to be tied to a
controller anymore, as only one controller is needed. The Route has to be tied
-to a specific Content object, which - on its side - can reference a specific
+to a specific Content object, which - on its side - may need a specific
template and controller.
-Other parts of the CMF are also related to the Router. To give 2 examples: The
+Other parts of the CMF are also related to the Router. Two examples: The
menu is created by generating specific routes using the Router and the blocks
are displayed to specific routes (as they are related to a template).
@@ -35,162 +35,51 @@ In the first chapter, you have already learned that routes are loaded from the
database using a special ``DynamicRouter``. This way, not all routes need to
be loaded each request.
-Matching routes from a PHPCR is really simple. If you remember the previous
-chapter, you know that you can get the ``quick_tour`` page from PHPCR using
-``/cms/simple/quick_tour``. The URL to get this page is ``quick_tour``. Some
-other examples:
+Matching routes from a PHPCR is straightforward: The router takes the request
+path and looks for a document with that path. Some examples:
.. code-block:: text
/cms
- /simple
- /about # /about Route
- /contact # /contact Route
- /team # /contact/team Route
- /docs # /contact/docs Route
+ /routes
+ /en # /en Route
+ /company # /en/company Route
+ /team # /en/company/team Route
+ /about # /en/about Route
+ /de # /de Route
+ /ueber # /de/ueber Route
OK, you got it? The only thing the Router has to do is prefix the route with a
-specific path prefix and load that document. In the case of the SimpleCmsBundle,
-all routes are prefixed with ``/cms/simple``.
+specific path prefix and load that document. In the case of the RoutingBundle,
+all routes are prefixed with ``/cms/routes``.
-You see that a route like ``/contact/team``, which consist of 2 "path units",
-has 2 documents in the PHPCR tree: ``contact`` and ``team``.
-
-Chaining multiple Routers
--------------------------
-
-You may need to have several prefixes or several routes. For instance, you may
-want to use both the ``DynamicRouter`` for the page routes, but also the
-static routing files from Symfony for your custom logic. To be able to do that,
-the CMF provides a ``ChainRouter``. This router chains over multiple router
-and stops whenever a router matches.
-
-By default, the ``ChainRouter`` overrides the Symfony router and only has the
-core router in its chain. You can add more routers to the chain in the
-configuration or by tagging the router services. For instance, the router used
-by the SimpleCmsBundle is a service registered by that bundle and tagged with
-``cmf_routing.router``.
+You see that a route like ``/company/team``, which consist of two "path units",
+has two documents in the PHPCR tree: ``company`` and ``team``.
Creating a new Route
--------------------
-Now you know the basics of routing, you can add a new route to the tree. In
-the configuration file, configure a new chain router so that you can put your
-new routes in ``/cms/routes``:
-
-.. configuration-block::
-
- .. code-block:: yaml
-
- # app/config/config.yml
-
- # ...
- cmf_routing:
- chain:
- routers_by_id:
- # the standard DynamicRouter
- cmf_routing.dynamic_router: 200
-
- # the core symfony router
- router.default: 100
- dynamic:
- persistence:
- phpcr:
- route_basepaths:
- - /cms/routes
- # /cms/routes is the default base path, the above code is
- # equivalent to:
- # phpcr: true
-
- .. code-block:: xml
-
-
-
-
-
-
-
-
-
- 200
-
-
- 100
-
-
-
-
-
- /cms/routes
-
-
-
-
-
-
-
- .. code-block:: php
-
- // app/config/config.php
- $container->loadFromExtension('cmf_routing', array(
- 'chain' => array(
- 'routers_by_id' => array(
- // the standard DynamicRouter
- 'cmf_routing.dynamic_router' => 200,
-
- // the core symfony router
- 'router.default' => 100,
- ),
- ),
- 'dynamic' => array(
- 'persistence' => array(
- 'phpcr' => array(
- 'route_basepaths' => '/cms/routes',
- ),
- /* /cms/routes is the default base path, the above code is
- equivalent to:
- 'phpcr' => true,
- */
- ),
- ),
- ));
-
-Now you can add a new ``Route`` to the tree using Doctrine::
-
- // src/Acme/DemoBundle/DataFixtures/PHPCR/LoadRoutingData.php
- namespace Acme\DemoBundle\DataFixtures\PHPCR;
+Now you know the basics of routing, you can add a new route to the tree using
+Doctrine::
+
+ // src/AppBundle/DataFixtures/PHPCR/LoadQuickTourData.php
+ namespace AppBundle\DataFixtures\PHPCR;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\ODM\PHPCR\DocumentManager;
-
use PHPCR\Util\NodeHelper;
-
use Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr\Route;
- class LoadRoutingData implements FixtureInterface, OrderedFixtureInterface
+ class LoadQuickTourData implements FixtureInterface, OrderedFixtureInterface
{
- public function getOrder()
- {
- return 20;
- }
-
public function load(ObjectManager $documentManager)
{
- if (!$documentManager instanceof DocumentManager) {
- $class = get_class($documentManager);
- throw new \RuntimeException("Fixture requires a PHPCR ODM DocumentManager instance, instance of '$class' given.");
- }
-
- $session = $documentManager->getPhpcrSession();
- NodeHelper::createPath($session, '/cms/routes');
+ // static content from model chapter, resulting in $content being defined
+ // ...
$routesRoot = $documentManager->find(null, '/cms/routes');
-
$route = new Route();
// set $routesRoot as the parent and 'new-route' as the node name,
// this is equal to:
@@ -198,27 +87,31 @@ Now you can add a new ``Route`` to the tree using Doctrine::
// $route->setParentDocument($routesRoot);
$route->setPosition($routesRoot, 'new-route');
- $page = $documentManager->find(null, '/cms/simple/quick_tour');
- $route->setContent($page);
+ $route->setContent($content);
$documentManager->persist($route); // put $route in the queue
$documentManager->flush(); // save it
}
}
-
-Above we implemented the ``OrderedFixtureInterface`` so that our routes were loaded in the correct sequence relative to other fixtures.
Now execute the ``doctrine:phpcr:fixtures:load`` command again.
This creates a new node called ``/cms/routes/new-route``, which will display
our ``quick_tour`` page when you go to ``/new-route``.
-.. tip::
+.. image:: ../_images/quick_tour/the-router-new-page.png
- When doing this in a real app, you may want to use a ``RedirectRoute``
- instead.
+Chaining multiple Routers
+-------------------------
+
+Usually, you want to use both the ``DynamicRouter`` for the editable routes,
+but also the static routing files from Symfony for your custom logic. To be
+able to do that, the CMF provides a ``ChainRouter``. This router tries each
+registered router and stops on the first router that returns a match.
-.. TODO write something about templates_by_class, etc.
+By default, the ``ChainRouter`` overrides the Symfony router and only has the
+core and dynamic router in its chain. You can add more routers to the chain in the
+configuration or by tagging the router services with ``cmf_routing.router``.
Final Thoughts
--------------
@@ -228,7 +121,7 @@ basics of the Symfony CMF. First, you have learned about the Request flow and
quickly learned each new step in this process. After that, you have learned
more about the default storage layer and the routing system.
-The Routing system is created together with some developers from Drupal8. In
+The Routing system is created together with some developers from Drupal 8. In
fact, Drupal 8 uses the Routing component of the Symfony CMF. The Symfony CMF
also uses some 3rd party bundles from others and integrated them into PHPCR.
In :doc:`the next chapter ` you'll learn more about
diff --git a/quick_tour/the_third_party_bundles.rst b/quick_tour/the_third_party_bundles.rst
index 6d2cef25..3dc5fa45 100644
--- a/quick_tour/the_third_party_bundles.rst
+++ b/quick_tour/the_third_party_bundles.rst
@@ -5,77 +5,81 @@ The Third Party Bundles
=======================
You're still here? You already learned the basics of the Symfony CMF and you
-just wanted to learn more and more? Then you can read this chapter! This
+want to learn more and more? Then you can read this chapter! This
chapter will walk you quickly through some other CMF bundles. Most of the
-other bundles are based on the shoulders of some giants, like the KnpMenuBundle_
+other bundles are integrations of great existing bundles like the KnpMenuBundle_
or SonataAdminBundle_.
The MenuBundle
--------------
Let's start with the MenuBundle. If you visit the page, you can see a nice
-menu. You can find the rendering of this menu in the layout view in the
-AcmeDemoBundle:
+menu. You can find the rendering of this menu in the base view:
.. code-block:: html+jinja
-
+
-