Creando un CMS con CMF y Sonata

El objetivo de esta guía es crear un sistema de administración de contenido sencillo que utiliza el CMF así como SonataAdminBundle y SonataDoctrinePhpcrAdminBundle.

Requisitos previos

Instalando

Descarga los paquetes

Añade lo siguiente a tu archivo composer.json:

"require": {
    ...
    "sonata-project/doctrine-phpcr-admin-bundle": "1.0.*",
}

Y luego ejecuta:

php composer.phar update

Iniciando los paquetes

Luego, inicia los paquetes en el archivo app/AppKernel.php añadiéndolos al método registerBundles:

public function registerBundles()
{
    $bundles = array(
        // ...

        // soporte para la administración
        new Symfony\Cmf\Bundle\TreeBrowserBundle\SymfonyCmfTreeBrowserBundle(),
        new Sonata\jQueryBundle\SonatajQueryBundle(),
        new Sonata\BlockBundle\SonataBlockBundle(),
        new Sonata\AdminBundle\SonataAdminBundle(),
        new Sonata\DoctrinePHPCRAdminBundle\SonataDoctrinePHPCRAdminBundle(),
        new FOS\JsRoutingBundle\FOSJsRoutingBundle(),
    );
    // ...
}

Configurando

Añade los paquetes de sonata a la configuración de tu aplicación

  • YAML
    # app/config/config.yml
    sonata_block:
        default_contexts: [cms]
        blocks:
            sonata.admin.block.admin_list:
                contexts:   [admin]
            sonata_admin_doctrine_phpcr.tree_block:
                settings:
                    id: '/cms'
                contexts:   [admin]
    
    sonata_admin:
        templates:
            # plantillas globales predefinidas
            ajax:    SonataAdminBundle::ajax_layout.html.twig
        dashboard:
            blocks:
                # muestra un bloque panel
                - { position: right, type: sonata.admin.block.admin_list }
                - { position: left, type: sonata_admin_doctrine_phpcr.tree_block }
    
    sonata_doctrine_phpcr_admin:
        document_tree:
            Doctrine\ODM\PHPCR\Document\Generic:
                valid_children:
                    - all
            Symfony\Cmf\Bundle\SimpleCmsBundle\Document\Page: ~
            Symfony\Cmf\Bundle\RoutingExtraBundle\Document\Route:
                valid_children:
                    - Symfony\Cmf\Bundle\RoutingExtraBundle\Document\Route
                    - Symfony\Cmf\Bundle\RoutingExtraBundle\Document\RedirectRoute
            Symfony\Cmf\Bundle\RoutingExtraBundle\Document\RedirectRoute:
                valid_children: []
            Symfony\Cmf\Bundle\MenuBundle\Document\MenuNode:
                valid_children:
                    - Symfony\Cmf\Bundle\MenuBundle\Document\MenuNode
                    - Symfony\Cmf\Bundle\MenuBundle\Document\MultilangMenuNode
            Symfony\Cmf\Bundle\MenuBundle\Document\MultilangMenuNode:
                valid_children:
                    - Symfony\Cmf\Bundle\MenuBundle\Document\MenuNode
                    - Symfony\Cmf\Bundle\MenuBundle\Document\MultilangMenuNode
    
    fos_js_routing:
        routes_to_expose:
            - admin_sandbox_main_editablestaticcontent_create
            - admin_sandbox_main_editablestaticcontent_delete
            - admin_sandbox_main_editablestaticcontent_edit
            - admin_bundle_menu_menunode_create
            - admin_bundle_menu_menunode_delete
            - admin_bundle_menu_menunode_edit
            - admin_bundle_menu_multilangmenunode_create
            - admin_bundle_menu_multilangmenunode_delete
            - admin_bundle_menu_multilangmenunode_edit
            - admin_bundle_content_multilangstaticcontent_create
            - admin_bundle_content_multilangstaticcontent_delete
            - admin_bundle_content_multilangstaticcontent_edit
            - admin_bundle_routingextra_route_create
            - admin_bundle_routingextra_route_delete
            - admin_bundle_routingextra_route_edit
            - admin_bundle_simplecms_page_create
            - admin_bundle_simplecms_page_delete
            - admin_bundle_simplecms_page_edit
            - symfony_cmf_tree_browser.phpcr_children
            - symfony_cmf_tree_browser.phpcr_move
            - sonata.admin.doctrine_phpcr.phpcrodm_children
            - sonata.admin.doctrine_phpcr.phpcrodm_move
    

Añade la ruta a la configuración de enrutado:

  • YAML
    # app/config/routing.yml
    admin:
        resource: '@SonataAdminBundle/Resources/config/routing/sonata_admin.xml'
        prefix: /admin
    
    sonata_admin:
        resource: .
        type: sonata_admin
        prefix: /admin
    
    doctrine_phpcr_admin_bundle_odm_browser:
        resource: "@SonataDoctrinePHPCRAdminBundle/Resources/config/routing/phpcrodmbrowser.xml"
    
    fos_js_routing:
        resource: "@FOSJsRoutingBundle/Resources/config/routing/routing.xml"
    
    symfony_cmf_tree:
        resource: .
        type: 'symfony_cmf_tree'
    

Activos de Sonata

app/console assets:install --symlink

Defining own Admin classes

The CMF bundles come with predefined admin classes which will be activated automatically if Sonata PHPCR-ODM Admin is loaded. If you need to write different admins and do not want to load the defaults, you can deactivate the loading - see the documentation of the respective bundles.

To load your own Admin service, you need to declare it as a service, tag with sonata.admin with manager_type="doctrine_phpcr". For the admin to work properly, you need to add a call for method setRouteBuilder to set it to the service sonata.admin.route.path_info_slashes, or your Admin will not work.

The constructor expects three arguments, code, document class and controller name. You can pass an empty argument for the code, the document class must be the fully qualified class name of the document this admin is for and the third argument can be used to set a custom controller that does additional operations over the default sonata CRUD controller.

  • XML
    <service id="my_bundle.admin" class="%my_bundle.admin_class%">
        <tag name="sonata.admin" manager_type="doctrine_phpcr" group="dashboard.group_content" label_catalogue="MyBundle" label="dashboard.label_my_admin" label_translator_strategy="sonata.admin.label.strategy.underscore" />
        <argument/>
        <argument>%my_bundle.document_class%</argument>
        <argument>SonataAdminBundle:CRUD</argument>
    
        <call method="setRouteBuilder">
            <argument type="service" id="sonata.admin.route.path_info_slashes" />
        </call>
    </service>
    

Finalmente

Ahora Sonata está configurado para trabajar con PHPCR, puedes acceder al panel vía /admin/dashboard de tu sitio.

Tree Problems

If you have not yet added anything to the content repository, the tree view will not load as it cannot find a root node. To fix this, load some data as fixtures by following this doc:

Bifúrcame en GitHub