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

Added documentation for the CmfResourceBundle #838

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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bundles/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Bundles
phpcr_odm/index
media/index
menu/index
resource/index
routing_auto/index
routing/index
search/index
Expand Down
6 changes: 6 additions & 0 deletions bundles/map.rst.inc
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ library or they introduce a complete new concept.
* :doc:`menu/voters`
* :doc:`menu/configuration`

* :doc:`resource/index`

* :doc:`resource/introduction`
* :doc:`resource/repositories`
* :doc:`resource/description_enhancers`

* :doc:`routing/index`

* :doc:`routing/introduction`
Expand Down
185 changes: 185 additions & 0 deletions bundles/resource/description_enhancers.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
.. index::
single: Resource; Description Enhancer

Resource Description Enhancers
==============================

The resources retrieved from the :doc:`resource repositories <repositories>`
can be enhanced with descriptions: Bits of information about the resource. This
Copy link
Member

Choose a reason for hiding this comment

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

For me that kind of naming "description" or "descriptors" was new on API or resources, So i would extend the explenation a little bit.

Copy link
Member

Choose a reason for hiding this comment

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

I mean there is some more on index, but for a direct visitor this would not be enough.

Copy link
Member

Choose a reason for hiding this comment

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

Bits of information => Standardized bits of information (for example URLs, thumbnails, titles, etc.) which can be consumed by disparate components or applications or similar?

is done by so-called *description enhancers*.

Configuring Description Enhancers
---------------------------------

In order to use a description enhancers, enable it in your configuration:

.. configuration-block::

.. code-block:: yaml

# app/config/config.yml
cmf_resource:
description:
# enables two enhancers
enhancers: [doctrine_phpcr_odm, your_custom_enhancer]

repositories:
# ...

.. code-block:: xml

<!-- app/config/config.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services">

<config xmlns="http://cmf.symfony.com/schema/dic/resource">
<description>
<!-- enables two enhancers -->
<enhancer>doctrine_phpcr_odm</enhancer>
<enhancer>your_custom_enhancer</enhancer>
</description>

<!-- ... -->
</config>
</container>

.. code-block:: php

// app/config/config.yml
$container->loadFromExtension('cmf_resource', [
'description' => [
// enables two enhancers
'enhancers' => ['doctrine_phpcr_odm', 'your_custom_enhancer'],
],

'repositories' => [
// ...
],
]);

Retrieving the Resource Description
-----------------------------------

The description for a specific resource can be retrieved using the
``cmf_resource.description.factory`` service::

namespace AppBundle\Controller;

use Symfony\Cmf\Component\Resource\Description\Descriptor;

class PageController extends Controller
{
public function indexAction()
{
$homepageResource = $this->get('cmf_resource.repository.default')->get('/pages/homepage');

$descriptionFactory = $this->get('cmf_resource.description.factory');
Copy link
Member

Choose a reason for hiding this comment

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

why sould i retrieve description server side? Should i use them to change application output flow at the end?

Copy link
Member Author

Choose a reason for hiding this comment

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

Well, using them on the front-end in the tree is only one use-case (and even in this use-case, the description is retrieved in the back-end by the ResourceRestBundle).

But resource is waaaaay more usefull than just TreeBrowser. E.g. symfony-cmf/routing-bundle#314 , on the long run all other bundles will just use resources. The resource component then provides an ORM repository and all bundles have ORM support \o/.

Another example is rendering, imagine a controller passing only the resource and resource description to a template. The template can then render it's title, body and metadata (e.g. SeoBundle has an enhancer as well) without knowing the backend. This means we can easily swap the PHPCR repository for Puli's FilesystemRepository and have static-CMS like functionality.

Copy link
Member

Choose a reason for hiding this comment

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

You would render the attributes in your Twig template. There was also a twig helper somewhere... But you may also want to generate a JSON response.

$resourceDescription = $descriptionFactory->getPayloadDescriptionFor($homepageResource);

// check if there is a title descriptor
if ($resourceDescription->has(Descriptor::TITLE)) {
// get a descriptor (i.e. the title)
$title = $resourceDescription->get(Descriptor::TITLE);
}

// get all descriptors
$descriptors = $resourceDescription->all();

// ...
}
}

Descriptors can contain any type and consist of an identifier and the value.
Some common identifiers are defined in the ``Descriptor`` class, but any
descriptor identifier is allowed.

CMF Description Enhancers
-------------------------

Some CMF bundles ship description enhancers to add specific descriptors used by that bundle:

:doc:`../tree_browser/introduction`
Ships a ``cmf_tree_icons`` enhancer, which sets an ``icon`` description to
an icon used in the tree.

:doc:`../sonata_phpcr_admin_integration/introduction`
Ships a ``sonata_phpcr_admin`` enhancer, which sets edit links to the admin
dashboard and payload title and type aliases using the related Admin class.

:doc:`introduction`
Ships a ``doctrine_phpcr_odm`` enhancer, which sets allowed children classes.

:doc:`introduction`
Ships a ``sylius_resource`` enhancer, adding CRUD links for the SyliusResourceBundle_.

Copy link
Member

Choose a reason for hiding this comment

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

i also added a position enhancer to servie the position property inside SonataDoctrinePhpcrAdminBundle. I helps to keep sorting alive after d&d.

Creating a Custom Enhancer
--------------------------

You can create your own enhancer by implementing ``DescriptionEnhancerInterface``::

// src/AppBundle/Description/PageEnhancer.php
namespace AppBundle\Description;

use AppBundle\Document\Page;
use Symfony\Cmf\Component\Resource\Description\Descriptor;
use Symfony\Cmf\Component\Resource\Description\Description;
use Symfony\Cmf\Component\Resource\Description\DescriptionEnhancerInterface;
use Symfony\Cmf\Component\Resource\Puli\Api\PuliResource;

class PageEnhancer implements DescriptionEnhancerInterface
{
public function supports(PuliResource $resource)
{
// check if the resource is supported by this enhancer (i.e. whether it's an app page).
return $resource->getPayload() instanceof Page;
}

public function enhance(Description $description)
{
$resource = $description->getResource();

// set the payload title descriptor to ``Page#getTitle()``
$description->set(Descriptor::PAYLOAD_TITLE, $resource->getTitle());
}
}

Then, create a service and tag it with ``cmf_resource.description.enhancer``:

.. configuration-block::

.. code-block:: yaml

# app/config/services.yml
services:
app.page_enhancer:
class: AppBundle\Description\PageEnhancer
tags:
- { name: cmf_resource.description.enhancer, alias: app_page }

.. code-block:: xml

<!-- app/config/services.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services">

<services>
<service id="app.page_enhancer" class="AppBundle\Description\PageEnhancer">
<tag name="cmf_resource.description.enhancer" alias="app_page" />
</service>
</services>
</container>

.. code-block:: php

// app/config/services.php
use AppBundle\Description\PageEnhancer;

$container->register('app.page_enhancer', PageEnhancer::class)
->addTag('cmf_resource.description.enhancer', [
'alias' => 'app_page',
])
;

After this, you can enable your enhancer using it's alias (``app_page``).

.._SyliusResourceBundle: http://docs.sylius.org/en/latest/bundles/SyliusResourceBundle
9 changes: 9 additions & 0 deletions bundles/resource/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
ResourceBundle
==============

.. toctree::
:maxdepth: 2

introduction
repositories
description_enhancers
36 changes: 36 additions & 0 deletions bundles/resource/introduction.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
.. index::
single: Resource; Bundles
single: ResourceBundle

ResourceBundle
==============

The ResourceBundle provides object resource location for CMF documents,
originally based on Puli_.

.. caution::

As the Puli project is stalled in beta-phase, this bundle currently ships a
light version of Puli.

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

You can install this bundle `with composer`_ using the
`symfony-cmf/resource-bundle`_ package.

Usage
-----

This bundle provides a generic layer on top of the persistence layer used in
the CMF. Documents can be located using *resource repositories*. These
repositories can use a variety of backends (Doctrine PHPCR-ODM and PHPCR
repositories are provided). Read more about repositories in ":doc:`repositories`".

The retrieved resources come with description information (e.g. the path and
some other information). This description is provided by *description
enhancers*. The :doc:`TreeBrowserBundle <../tree_browser/introduction>` for
instance ships with an enhancer to add paths to document icons. Read more
about adding your own description enhancers in :doc:`description_enhancers`.

Copy link
Member

Choose a reason for hiding this comment

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

Maybe something on the idea behind this originally, here or in the relevant section


Description enhancers allow you (or a third-party) to provide descriptions, for example, you are developing a component which requires a title and thumbnail image to represent an entity (for example a browser). Your component may be used with either Sylius or Sonata Admin. Both of these applications are capable of providing the required metadata, but they do so in very ways.

Description enhancers enable you to abstract yourself away from these differences.

.. _Puli: http://puli.io/
116 changes: 116 additions & 0 deletions bundles/resource/repositories.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
.. index::
single: Resource; Repository

Resource Repositories
=====================

Repositories are the access point of the ResourceBundle, allowing you to find
and move resources. In the bundle, currently two repository types are provided:
Doctrine PHPCR-ODM and PHPCR.

Creating a new repository is as simple as configuring the ResourceBundle:

.. configuration-block::

.. code-block:: yaml

# app/config/config.yml
cmf_resource:
repositories:
# defines a repository named "default" using a Doctrine PHPCR-ODM backend
default:
type: doctrine/phpcr-odm

# defines an "other_site" repository using a PHPCR backend with
# /cms/other-site.com as root
other_site:
type: phpcr/phpcr
basepath: /cms/other-site.com

.. code-block:: xml

<!-- app/config/config.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services">

<config xmlns="http://cmf.symfony.com/schema/dic/resource">
<!-- defines a repository named "default" using a Doctrine PHPCR-ODM backend -->
<repository name="default"
type="doctrine/phpcr-odm"
/>

<!-- defines an "other_site" repository using a PHPCR backend
with /cms/other-site.com as root -->
<repository name="other_site"
type="phpcr/phpcr"
basepath="/cms/other-site.com"
/>
</config>
</container>

.. code-block:: php

// app/config/config.php
$container->loadFromExtension('cmf_resource', [
'repositories' => [
// defines a repository named "default" using a Doctrine PHPCR-ODM backend
'default' => [
'type' => 'doctrine/phpcr-odm',
],

// defines an "other_site" repository using a PHPCR backend with
// /cms/other-site.com as root
'other_site' => [
'type' => 'phpcr/phpcr',
'basepath' => '/cms/other-site.com',
],
],
]);

Both repositories allow to configure a ``basepath``. This becomes the root of
the repository.

If you have configured your repositories, you can start using them as
services::

namespace AppBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class HomepageController extends Controller
{
public function indexAction()
{
// The generated service ID is cmf_resource.repository.<REPOSITORY NAME>
$defaultRepository = $this->get('cmf_resource.repository.default');

// Get resources directly using get($path)
$homepageResource = $defaultRepository->get('/pages/homepage');

// Or find resources using a glob pattern
$menuResources = $defaultRepository->get('/menu/*-item');

// Get the CMF documented related to this resource
$homepageDocument = $homepageResource->getPayload();

return $this->render('static/page.html.twig', [
'page' => $homepageDocument
]);
}
}

Besides retrieving and finding documents, repositories also provide some
methods to edit resources:

``remove($path)``
Remove a resource at the given path (i.e. ``remove('/cms/pages/homepage')``)
or multiple documents using a glob pattern (i.e. ``/cms/menu/legacy-*``).

``move($path, $targetPath)``
Move a resource (i.e. ``move('/cms/pages/contact', '/cms/pages/about-us/contact')``)
or multiple resources (i.e. ``move('/cms/menu/contact-*', '/cms/menu/about-us')``).

``reorder($path, $position)``
Reorders a resource relative to it's siblings. For instance, use position
``0`` to set it as first child, ``2`` to set it as third child and a high
number to set it as last child.