Sonata Página 5: Ocultar bloques dentro de bloques compartidos.

Si estás usando el paquete SonataPage, podrías haber notado que algunos de los bloques ofrecidos son innecesarios o no funcionales.

Hablaremos sobre cómo ocultar estos bloques de la lista de forma limpia, con un archivo de configuración y sobrescribiendo las plantillas de administración de SonataPage.

image

1 – La Configuración

Necesitamos crear una lista de servicios que no queremos mostrar. Esta lista irá naturalmente en los parámetros de nuestro archivo de servicios:

#config/services.yaml
parameters:

    sonata_page_excluded_blocks:
        - 'sonata.media.block.gallery_list'
        - 'sonata.media.block.feature_media'
        - 'sonata.media.block.gallery'

Para descubrir el nombre del servicio a excluir, es bastante simple, está en la URL cuando haces clic en él en la vista de creación de bloques compartidos.

2 – Función Twig para Recuperar Nuestro Parámetro

Para ocultar los bloques, vamos a sobrescribir las plantillas de SonataPage. Así que necesitamos recuperar nuestra configuración directamente en nuestra plantilla. Por lo tanto, vamos a crear una extensión de Twig para nuestro proyecto. Es bastante común, probablemente ya tengas una.

#src/Twig/Extension/AppExtension.php
<?php
namespace App\Twig;

use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

class AppExtension extends AbstractExtension
{
    private $sonata_page_excluded_blocks;

    public function __construct(array $sonata_page_excluded_blocks)
    {
        $this->sonata_page_excluded_blocks = $sonata_page_excluded_blocks;
    }

    public function getFunctions(): array
    {
        return [
            new TwigFunction('sonata_page_excluded_blocks', [$this, 'getSonataPageExcludedBlocks']),
        ];
    }

    public function getSonataPageExcludedBlocks(): array
    {
        return $this->sonata_page_excluded_blocks;
    }
}

Luego necesitamos referenciarla en los servicios.

services:
    App\Twig\AppExtension:
        arguments:
            $sonata_page_excluded_blocks: '%sonata_page_excluded_blocks%'

3 – Sobrescribir Plantillas

Como sabrás, todas las plantillas pueden ser sobrescritas. Solo localiza la plantilla dentro de tu paquete. Generalmente, solo necesitas verificar la lista de plantillas Twig en el perfilador. Es muy a menudo la primera.

image-2


Vemos que nuestra plantilla está almacenada en:
vendor/sonata-project/page-bundle/src/Resources/views/BlockAdmin/select_type.html.twig

Para sobrescribirla, solo colócala en nuestro directorio de plantillas con la ruta:
templates/bundles/NomDuBundle/CarpetaDespuésDeViews/…/TuArchivo.html.twig

Lo que nos da:
templates/bundles/SonataPageBundle/BlockAdmin/select_type.html.twig


Una vez copiado el archivo, si recargamos la página, deberíamos encontrar el archivo correcto en la lista de plantillas en nuestra pestaña Twig del perfilador.

image-1

4 – Sobrescribir la Lista de Bloques en Nuestra Plantilla

Solo tenemos que recuperar nuestra lista de bloques configurados de nuestros parámetros y recrear la variable usada para crear el arreglo, sin nuestros bloques a excluir.

        {% set excluded_blocks = sonata_page_excluded_blocks() %}
        {% set filteredBlockServices = [] %}
        {% for key, service in blockServices %}
            {% if key not in excluded_blocks %}
                {% set filteredBlockServices = filteredBlockServices|merge({(key): service}) %}
            {% endif %}
        {% endfor %}
        {% set blockServices = filteredBlockServices %}

Esto nos da:

{#
templates/bundles/_SonataPageBundle/BlockAdmin/select_type.html.twig

#}

{% extends '@SonataAdmin/CRUD/action.html.twig' %}

{% block title %}{{ 'title_select_block_type'|trans({}, 'SonataPageBundle') }}{% endblock %}

{% block content %}
    <div class="box box-success">
        <div class="box-header">
            <h3 class="box-title">
                {{ 'title_select_block_type'|trans({}, 'SonataPageBundle') }}
            </h3>
        </div>

        {# surcharge pour exclude des blocs #}
        {% set excluded_blocks = sonata_page_excluded_blocks() %}
        {% set filteredBlockServices = [] %}
        {% for key, service in blockServices %}
            {% if key not in excluded_blocks %}
                {% set filteredBlockServices = filteredBlockServices|merge({(key): service}) %}
            {% endif %}
        {% endfor %}
        {% set blockServices = filteredBlockServices %}
        {# fin de surcharge pour exclude des blocs #}


        <div class="box-body">
            {% for code, blockService in blockServices %}
                <div class="col-lg-2 col-md-3 col-sm-4 col-xs-6">
                    <a  href="{{ admin.generateUrl('create', {'type': code}) }}"
                        class="btn btn-app btn-block sonata-block-type"
                        data-toggle="tooltip"
                        data-placement="top"
                        {% if blockService.metadata.description %}
                            title="{{ blockService.metadata.description|trans({}, blockService.metadata.domain|default('SonataBlockBundle')) }}"
                        {% endif %}
                            >
                        {% if not blockService.metadata.image %}
                            <i class="{{ blockService.metadata.option('class') }}" ></i>
                        {% else %}
                            <img src="{{ asset(blockService.metadata.image) }}" style="max-height: 20px; max-width: 100px;"/>
                            <br />
                        {% endif %}
                        <span>{{ blockService.metadata.title|trans({}, blockService.metadata.domain|default('SonataBlockBundle')) }}</span>
                    </a>
                </div>
            {% else %}
                <span class="alert alert-info">{{ 'no_type_available'|trans({}, 'SonataPageBundle') }}</span>
            {% endfor %}

            <div class="clearfix"></div>
        </div>
    </div>
{% endblock %}

Y si recargamos la página, deberíamos tener la lista, depurada de nuestros bloques.

Selection_011

En vez de

bloc

6 – Sobrescribir la Lista de Bloques en el Compositor de Páginas

Para el compositor de páginas, es exactamente la misma manipulación. El archivo a sobrescribir es:
vendor/sonata-project/page-bundle/src/Resources/views/PageAdmin/compose_container_show.html.twig

Esto nos da:
/templates/bundles/SonataPageBundle/PageAdmin/compose_container_show.html.twig

Ponemos exactamente el mismo código, lo que nos da un archivo completo siguiente:

{#
/templates/bundles/SonataPageBundle/PageAdmin/compose_container_show.html.twig
#}
<div class="page-composer__container__view block-view-{{ container.id }}"
     data-block-id="{{ container.id }}"
>
    <h2 class="page-composer__container__view__header">{{ container.name }}</h2>

    <span class="page-composer__container__view__notice">{{ 'notice'|trans({}, 'SonataPageBundle') }}</span>

    {# surcharge pour exclude des blocs #}
    {% set excluded_blocks = sonata_page_excluded_blocks() %}
    {% set filteredBlockServices = [] %}
    {% for key, service in blockServices %}
        {% if key not in excluded_blocks %}
            {% set filteredBlockServices = filteredBlockServices|merge({(key): service}) %}
        {% endif %}
    {% endfor %}
    {% set blockServices = filteredBlockServices %}
    {# fin de surcharge pour exclude des blocs #}

    <div class="page-composer__block-type-selector">
        <label>{{ 'composer.block.add.type'|trans({}, 'SonataPageBundle') }}</label>
        <select class="page-composer__block-type-selector__select" style="width: auto">
            {% for blockServiceId, blockService in blockServices %}
                <option value="{{ blockServiceId }}">{{ blockService.metadata.title|trans({}, blockService.metadata.domain|default('SonataBlockBundle')) }}</option>
            {% endfor %}
        </select>
        <a class="btn btn-action btn-small page-composer__block-type-selector__confirm"
           href="{{ admin.generateObjectUrl('sonata.page.admin.block.create', page, {'composer': true}) }}"
        ><i class="fa fa-plus"></i></a>
        <span class="page-composer__block-type-selector__loader">{{ 'loading'|trans({}, 'SonataPageBundle') }}</span>

        <small class="page-composer__container__child-count pull-right">
            {{ 'blocks'|trans({}, 'SonataPageBundle') }} <span class="badge">{{ container.children|length }}</span>
        </small>
    </div>

    <ul class="page-composer__container__children">
        {% for child in container.children %}
            {% include '@SonataPage/BlockAdmin/compose_preview.html.twig' with {
                'blockService': attribute(blockServices, child.type) ?? null
            } %}
        {% endfor %}
    </ul>
</div>

image-3