Давайте вспомним, сколько раз в шаблонах повторяется один и тот же код - код поста в ленте.
- главная
- блоги
- теги
- тег
Стоит вынести повторяющуюся сущность в отдельный шаблон.
Создаём файл 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">«</a></li>',
'TplNextP' => '@CODE: <li><a href="[+link+]" class="button next">»</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;
}
BlogsController
public function render()
{
$result = $this->getPostsWithTags([
'paginate' => 'pages',
'display' => 10,
]);
$this->data['posts'] = $result;
return $this;
}
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;
}
Мы унесли повторы кода в базовый контроллер, сам код контроллеров для материалов стал более читаемый.
- Код более читаемый
- Нет повторов сущностей как в шаблонах, так и в контроллерах
- Все материалы с тегами
Раз все сущности готовы,надо немного озаботиться сео и сделать карту сайта