Каков наилучший способ вставить часть одной страницы в другую в Symfony? - PullRequest
0 голосов
/ 16 сентября 2018

В моем проекте мне часто нужно повторно использовать один и тот же шаблон на разных страницах, обычно с разными параметрами фильтра.Я решил использовать методы контроллера и функцию ветки render для его выполнения.

В моем контроллере:

public function index(Request $request) {
    return $this->render("index.html.twig");
}
public function list(Request $request, array $filterArray = []) {
    return $this->render("list.html.twig", [
        'items' => $this->getFilteredItems($filterArray)
    ]);
}
public function entry(Request $request, string $alias) {
    return $this->render("entry.html.twig"[
        'item' => $this->getItemByAlias($alias)
    ]);
}

В index.html.twig:

{{ render(controller(
    'App\\Controller\\SynthesisController::entityList', {},
    {  }
)) }}

В list.html.twig:

{% for item in items %}
<div class="">
    <a href="">{{item.name}}</a>
</div>
{% endfor %}

И поэтому он позволяет повторно использовать список объектов на других страницах с его макетом.В entry.html.twig:

<div class="synthesis-participants">
    <div class="row">
        <div class="col-sm-6 mb-4">
            <div class="h5">Reagents:</div>

            {{ render(controller(
                'App\\Controller\\SubstanceController::entityList', { 'filterArray': {
                    'participate': { 'synthesis': item.id, 'role': 10 }
                } }, { }
            )) }}
        </div>
        <div class="col-sm-6 mb-4">
            <div class="h5">Products:</div>

            {{ render(controller(
                'App\\Controller\\SubstanceController::entityList', { 'filterArray': {
                    'participate': { 'synthesis': item.id, 'role': 20 }
                } }, { }
            )) }}
        </div>
    </div>
    <div class="row">
        <div class="col-sm-6 mb-4">
            <div class="h5">Diluents:</div>

            {{ render(controller(
                'App\\Controller\\SubstanceController::entityList', { 'filterArray': {
                    'participate': { 'synthesis': item.id, 'role': 30 }
                } }, { }
            )) }}
        </div>
        <div class="col-sm-6 mb-4">
            <div class="h5">Catalysts:</div>

            {{ render(controller(
                'App\\Controller\\SubstanceController::entityList', { 'filterArray': {
                    'participate': { 'synthesis': item.id, 'role': 40 }
                } }, { }
            )) }}
        </div>
    </div>
    <p class="mt-2">{{ item.text }}</p>
</div>

Может быть, это может быть достигнуто лучше?

1 Ответ

0 голосов
/ 16 сентября 2018

По моему мнению, вам следует избегать этого, поскольку вы встраиваете слишком много контроллеров, и я считаю, что издержки больше, чем выгода.

В качестве альтернативы вы можете добавить некоторые функции в каждый из ваших контроллеров, чтобы получить необходимую информацию, а затем включить соответствующие шаблоны в свою веточку.

Я бы изменил ваши контроллеры на что-то вроде этого:

public function index(Request $request) {
    return $this->render("index.html.twig", [
        'items' => $this->getFilteredItems()
    ]);
}

public function list(Request $request, array $filterArray = []) {
    return $this->render("list.html.twig", [
        'items' => $this->getFilteredItems($filterArray)
    ]);
}

public function entry(Request $request, string $alias) {
    $item = $this->getItemByAlias($alias);
    $items = [];
    $titles = ['Reagents', 'Products', 'Diluents', 'Catalysts']; 
    foreach (range(10, 40, 10) as $key => $role) {
        $filter['participate'] = [
            'synthesis' => $item['id'], // $item->getId()
            'role' => $role
        ];
        $title = $titles[$key];
        $items[$title] = $this->getFilteredItems($filter);
    }

    return $this->render("entry.html.twig"[
        'item' => $this->getItemByAlias($alias),
        'items' => $items
    ]);
}

Наконец, в вашем entry.html.twig:

<div class="synthesis-participants">
    {% for key, itemArray in items %}
    <div class="row">
        <div class="col-sm-6 mb-4">
            <div class="h5">{{ key }} :</div>
            {% include 'list.html.twig' with {'items': itemArray} only %} 
        </div>
    </div>
    {% endfor %}
    <p class="mt-2">{{ item.text }}</p>
</div>

Я бы также предположил, что функции getItemByAlias, getFilteredItems должны находиться не в контроллере, а в репозитории или службе.

...