Skip to content

Latest commit

 

History

History
205 lines (170 loc) · 7.82 KB

012_Оптимизация кода и шаблонов.md

File metadata and controls

205 lines (170 loc) · 7.82 KB

Оптимизация кода и шаблонов

Оглавление

Убираем повторы в шаблоне, @include

Давайте вспомним, сколько раз в шаблонах повторяется один и тот же код - код поста в ленте.

  • главная
  • блоги
  • теги
  • тег

Стоит вынести повторяющуюся сущность в отдельный шаблон.

Создаём файл post.blade.php в папке /views/parts.

<article class="post">
    <header>
        <div class="title">
            <h2><a href="{{ urlProcessor::makeUrl($post['id'] ) }}">{{ $post['pagetitle'] }}</a></h2>
            <a href="{{ urlProcessor::makeUrl($post['id'] ) }}" class="image featured">
                <img src=" {{ $post['post_mainphoto'] }}" alt="" />
            </a>
        </div>
    </header>
    {{ $post['introtext'] }}
    <footer>
        <ul class="stats">
            @foreach ($post['post_tags_custom'] as $post_tag)
                <li><a href="{{ urlProcessor::makeUrl($post_tag['id'] ) }}" class="icon solid fa-tag">{{ $post_tag['pagetitle'] }}</a></li>
            @endforeach
        </ul>
    </footer>
</article>

Теперь заходим во все шаблоны, где есть вызов цикла по постам и изменяем их примерно вот так:

@extends('layouts.app')

@section('content')
    @foreach ($posts as $post)
        @include('parts.post', $post)
    @endforeach
@endsection

Я насчитал 3 шаблона:

  • main.blade.php
  • tag.blade.php
  • blogs.blade.php

Директива @include вставляет кусочек содержимого и при этом оперирует переданными ей данными.

Зайдите на страницу какого-нибудь тега. В Tracy вы увидите ошибку типа PHP Warning: Invalid argument supplied for foreach().

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

Цикл @foreach ($post['post_tags_custom'] as $post_tag) не может корректно сработать, так как отсутствует массив post_tags_custom.

Убираем ошибки

Поправьте наш кусочек поста:

<footer>
@if ($post['post_tags_custom'])
    <ul class="stats">
        @foreach ($post['post_tags_custom'] as $post_tag)
            <li><a href="{{ urlProcessor::makeUrl($post_tag['id'] ) }}" class="icon solid fa-tag">{{ $post_tag['pagetitle'] }}</a></li>
        @endforeach
    </ul>
@endif
</footer>

Мы использовали директиву @if для проверки существования переменной. Если тегов нет, то и дальнейший цикл не выполнится.

Проверять переменные, конечно же, хорошо. Но...

Убираем дубляж кода

Мы много раз дублируем код получения постов, а ведь он одинаковый. Одинаковый и способ получения тегов к постам и теги, по сути, требуются везде. То, что мы воткнули @if в шаблоне тега, это просто костыль.

Давайте сделаем так, чтобы мы могли получить посты с тегами в одном методе. А чтобы в разных ситуациях можно было задать разные способы вызова Доклистер, будет передавать этому методу массив с параметрами.

В BaseController пишем метод getPostsWithTags

public function getPostsWithTags($dl_params)
{
    $fixed_params = [
        'parents' => 2,
        'depth' => 1,
        'tvPrefix' => '',
        'tvList' => 'post_mainphoto,post_tags',
        'returnDLObject' => 1,
        'display' => 10,
        'TplPrevP' => '@CODE: <li><a href="[+link+]" class="button previous">&laquo;</a></li>',
        'TplNextP' => '@CODE: <li><a href="[+link+]" class="button  next">&raquo;</a></li>',
        'TplPage' => '@CODE: <li><a class="button" href="[+link+]">[+num+]</a></li>',
        'TplCurrentPage' => '@CODE: <li class=" is-active">[+num+]</li>',
        'TplWrapPaginate' => '@CODE: <ul class="actions special pagination">[+wrap+]</ul>',   
    ];
    $params = array_merge($fixed_params,$dl_params);
    $result = $this->evo->runSnippet('DocLister', $params)->getDocs();
    $tags_ids = null;
    foreach ($result as $document) {
        if ($document['post_tags']) {
            foreach (explode(',', $document['post_tags']) as $tag_id) {
                $tags_ids[] = $tag_id;
            }
        }
    }
    $tags_ids = array_unique($tags_ids);

    $tags =  $this->evo->runSnippet('DocLister', [
        'idType' => 'documents',
        'documents' => implode(",", $tags_ids),
        'returnDLObject' => 1,
    ]);
    $tags = $tags->getDocs();
    foreach ($result as $document) {
        if ($document['post_tags']) {
            foreach (explode(',', $document['post_tags']) as $tag_id) {
                $result[$document['id']]['post_tags_custom'][] = $tags[$tag_id];
            }
        } else {
            $result[$document['id']]['post_tags_custom'] = [];
        }
    }	
    return $result;
}

Это по сути копипаст того, что у нас наворочено в шаблонах с небольшими правками. В fixed_params задаём те параметры, что будут всегда по умолчанию. А в dl_params ждём новые/изменённые параметры.

Теперь правим контроллеры:

MainController

public function render()
{
    $result = $this->getPostsWithTags([
        'display' => 5,
    ]);
    $this->data['posts'] = $result;
    return $this->data['posts'];
}

BlogsController

public function render()
{
    $result = $this->getPostsWithTags([
        'paginate' => 'pages',
        'display' => 10,      
    ]);
    $this->data['posts'] = $result;
    return $this->data['posts'];
}

TagController

public function render()
{
    $id = $this->evo->documentObject['id'];
    $res = $this->evo->db->select("contentid", $this->evo->getFullTableName('site_tmplvar_contentvalues'), "FIND_IN_SET('" . $id . "',value) AND tmplvarid=4");
    $arr = $this->evo->db->makeArray($res);
    foreach ($arr as $k => $v) {
        $documents[] = ($v['contentid']);
    }
    $documents = implode(",", $documents);
    $result = $this->getPostsWithTags([
        'idType' => 'documents',
        'documents' => $documents,
        'paginate' => 'pages',     
    ]);
    $this->data['posts'] = $result;
    return $this->data['posts'];
}

Мы унесли повторы кода в базовый контроллер, сам код контроллеров для материалов стал более читаемый.


Итого

  • Код более читаемый
  • Нет повторов сущностей как в шаблонах, так и в контроллерах
  • Все материалы с тегами

Раз все сущности готовы,надо немного озаботиться сео и сделать карту сайта