Перейти к содержанию

Общие рецепты⚓︎

Эта страница содержит набор проблем и их решения, относящиеся к Grav в целом.

Изменение версии PHP CLI⚓︎

Иногда на терминале версия PHP отличается от версии PHP, используемой веб-сервером.

Вы можете проверить версию PHP, запущенную в CLI, выполнив команду php -v. Если версия PHP ниже 5.5.9, Grav не запустится, поскольку для этого требуется PHP 5.5.9.

Как исправить?

Вам нужно ввести некоторую конфигурацию в .bashrc или в.bash_profile в вашей домашней папке пользователя. Создайте эти файлы, если у вас их ещё нет в папке пользователя. Это скрытые файлы, поэтому вам, возможно, придется выполнить команду ls -al, чтобы их показать. После добавления конфигурации вам нужно будет запустить новый сеанс терминала, чтобы применить эти настройки.

Пример конфигурации может быть:

alias php="/usr/local/bin/php53"
export PHP_PATH = /usr/local/bin/php53

Альтернативный способ - добавить:

# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

PATH=/usr/local/lib/php-5.5/bin:$PATH:$HOME/bin

export PATH

Точный путь, конечно, зависит от того, как настроена ваша система, где хранятся бинарные файлы последней версии PHP. Это может быть что-то, что вы найдете в документации по хостингу, или вы можете спросить настройку своего хостинга, если вы нигде не нашли.

Вы также можете попробовать поискать файлы или папки php-something в папках /usr/local/bin или /usr/local/lib с помощью ls -la /usr/local/lib/ |grep -i php.

Создание простой галереи⚓︎

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

Самый простой способ решить эту проблему - использовать мультимедийные функции Grav, которые позволяют странице узнавать об изображениях, доступных в её папке.

Предположим, у вас есть страница, которую вы назвали gallery.md, а также у вас есть множество изображений в том же каталоге. Сами имена файлов не важны, поскольку мы просто перебираем каждое из изображений. Поскольку мы хотим иметь дополнительные данные, связанные с каждым изображением, мы включим файл meta.yaml для каждого изображения. Например, у нас есть несколько изображений:

- fido-playing.jpg
- fido-playing.jpg.meta.yaml
- fido-sleeping.jpg
- fido-sleeping.jpg.meta.yaml
- fido-eating.jpg
- fido-eating.jpg.meta.yaml
- fido-growling.jpg
- fido-growling.jpg.meta.yaml

Каждый из файлов .jpg имеет относительно хороший размер, который подходит для полноразмерной версии, размером 1280 x 720 пикселей. Каждый из файлов meta.yaml содержит несколько ключевых записей, давайте посмотрим наfido-plays.jpg.meta.yaml:

title: Fido Playing with his Bone
description: The other day, Fido got a new bone, and he became really captivated by it.

У вас есть полный контроль над тем, что вы помещаете в эти метафайлы, они могут быть абсолютно всем, что вам нужно.

Теперь нам нужно отобразить эти изображения в обратном хронологическом порядке, чтобы новые изображения показывались первыми и отображали их. Поскольку наша страница называется gallery.md, мы должны создать соответствующий templates/gallery.html.twig, который будет содержать необходимую нам логику рендеринга:

{% extends 'partials/base.html.twig' %}

{% block content %}
    {{ page.content }}

    <ul>
    {% for image in page.media.images %}
    <li>
        <div class="image-surround">
            {{ image.cropResize(300,200).html }}
        </div>
        <div class="image-info">
            <h2>{{ image.meta.title }}</h2>
            <p>{{ image.meta.description }}</p>
        </div>
    </li>
    {% endfor %}
    </ul>

{% endblock %}

Чтобы модульная галерея отображалась на другой странице, удалите следующий код из файла Twig, чтобы он работал:

{% extends 'partials/base.html.twig' %}

{% block content %}
    {{ page.content }}

и

{% endblock %}

По сути, это расширяет стандартный partials/base.html.twig (если в вашей теме есть этот файл), затем он определяет блок content и предоставляет для него контент. Первое, что мы делаем, это выводим любой page.content. Это будет содержимое файла gallery.md, поэтому он может содержать заголовок и описание этой страницы.

Следующий раздел просто перебирает все медиа страницы, которые являются изображениями. Мы выводим их в виде неупорядоченного списка, чтобы сделать вывод семантическим и легко стилизованным с помощью CSS. мы присваиваем каждому изображению имя переменной image, а затем мы можем выполнить простой метод cropResize(), чтобы изменить размер изображения до подходящего, а затем под ним мы предоставляем информационный раздел с title и описание.

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

Отображение содержимого в колонках⚓︎

Несколько раз возникал вопрос, как быстро отобразить одну страницу в нескольких колонках.

Есть много потенциальных решений, но одно простое решение - разделить ваш контент на логические разделы с помощью разделителя, такого как HTML <hr /> или тег тематический разрыв. В Markdown это представлено 3 или более дефисами или ---. Мы просто создаем наш контент и разделяем наши разделы этими чёрточками:

columns.md

---
title: 'Columns Page Test'
---

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas arcu leo, hendrerit ut rhoncus eu, dictum vitae ligula. Suspendisse interdum at purus eget congue. Aliquam erat volutpat. Proin ultrices ligula vitae nisi congue sagittis. Nulla mollis, libero id maximus elementum, ante dolor auctor sem, sed volutpat mauris nisl non quam.

---

Phasellus id eleifend risus. In dui tellus, dignissim id viverra non, convallis sed ante. Suspendisse dignissim, felis vitae faucibus dictum, dui mi tempor lectus, non porta elit libero quis orci. Morbi porta neque quis magna imperdiet hendrerit.

---

Praesent eleifend commodo purus, sit amet viverra nunc dictum nec. Mauris vehicula, purus sed convallis blandit, massa sem egestas ex, a congue odio lacus non quam. Donec vitae metus vitae enim imperdiet tempus vitae sit amet quam. Nam sed aliquam justo, in semper eros. Suspendisse magna turpis, mollis quis dictum sit amet, luctus id tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean eu rutrum mi.

Дополнительная строка после столбца и перед ---. Это потому, что если вы поставите тройное тире прямо под текстом, он фактически будет интерпретирован как заголовок.

Затем нам просто нужно отрендерить это содержимое с помощью шаблона columns.html.twig (поскольку файл страницы был назван columns.md):

{% extends 'partials/base.html.twig' %}

{% block content %}
    <table>
        <tr>
            {% for column in page.content|split('<hr />') %}
            <td>{{ column }}</td>
            {% endfor %}
        </tr>
    </table>
{% endblock %}

Вы можете видеть, как содержимое разделяется тегом <hr /> и конвертируется в массив из 3 столбцов, которые мы перебираем и визуализируем. В этом примере мы используем простой тег таблицы HTML, но вы можете использовать все, что захотите.

При использовании плагина page-toc необходимо использовать |split('<hr>'), так как плагин page-toc очищает HTML-код.

Действительно простой CSS-слайдер изображений⚓︎

Вам нужен слайдер изображений без каких-либо накладных расходов.

Этот рецепт состоит из 4 изображений и страницы под названием slider.md! Просто поместите изображения там, где находится файл .md. Затем создайте новый шаблон Twig и расширьте base.html.twig.

{% extends 'partials/base.html.twig' %}

{% block content %}

    <div id="slider">
        <figure>
        {% for image in page.media.images %}
            {{ image.html }}
        {% endfor %}
        </figure>
    </div>

    {{ page.content }}
{% endblock %}

Для модульного слайдера удалите

{% extends 'partials/base.html.twig' %}

{% block content %}

и

{% endblock %}

из предыдущего файла Twig.

Пришло время заняться css. Добавьте это в свой _custom.scss

@keyframes slidy {
  0% {
    left: 0%;
  }
  20% {
    left: 0%;
  }
  25% {
    left: -100%;
  }
  45% {
    left: -100%;
  }
  50% {
    left: -200%;
  }
  70% {
    left: -200%;
  }
  75% {
    left: -300%;
  }
  95% {
    left: -300%;
  }
  100% {
    left: -400%;
  }
}
body {
  margin: 0;
}
div#slider {
  overflow: hidden;
  margin-top: -3rem;
  max-height: 30rem;
}
div#slider figure img {
  width: 20%;
  float: left;
}
div#slider figure {
  position: relative;
  width: 500%;
  margin: 0;
  left: 0;
  animation: 30s slidy infinite;
}

Вот и всё.

Перенос Markdown в HTML⚓︎

На некоторых страницах вы можете захотеть обернуть части содержимого Markdown в некоторый пользовательский HTML-код вместо создания нового шаблона Twig.

Для этого выполните следующие действия:

в файле конфигурации вашей системы user/config/system.yaml не забудьте активировать дополнительную опцию Markdown:

pages:
  markdown:
    extra: true

в теге оболочки обязательно добавьте параметр markdown="1", чтобы активировать обработку содержимого Markdown:

<div class="myWrapper" markdown="1">
# my markdown content

this content is wrapped into a div with class "myWrapper"

</div>

Готово.

Добавление виджета недавних записей на боковую панель⚓︎

Вы хотите создать виджет недавних записей на боковой панели

Всегда можно создать частичный шаблон, расширяющий partials/base.html.twig (см. другие решения на этой странице), но вместо этого вы собираетесь создать полный шаблон. Окончательный код для вашего шаблона Twig показан ниже:

<div class="sidebar-content recent-posts">
    <h3>Недавние записи</h3>
    {% for p in page.find('/blog').children.order('date', 'desc').slice(0, 5) %}
        {% set bannerimage = p.media['banner.jpg'] %}
        <div class="recent-post">
            {% if bannerimage %}
                <div class="recent-post-image">{{ bannerimage.cropZoom(60,60).quality(60) }}</div>
            {% else %}
                <div class="recent-post-image"><img src="{{ url('theme://images/logo.png') }}" width="60" height="60"></div>
            {% endif %}
            <div class="recent-post-text">
                <h4><a href="{{p.url}}">{{ p.title }}</a></h4>
                <p>{{ p.date|date("M j, Y")}}</p>
            </div>
        </div>
    {% endfor %}
</div>

Весь этот код выполняет сортировку дочерних элементов (сообщений в блогах) страницы/blog по убыванию даты. Затем он берет первые пять сообщений в блоге, используя фильтр Twig slice. Между прочим, slice (n, m) принимает элементы от n до m - 1. В этом примере все сообщения в блоге с изображением баннера называются banner.jpg. Это устанавливается в переменной bannerimage. Если существует bannerimage, он будет уменьшен до размера 60px x 60px и появится слева от текста заголовка и даты публикации. Если он не существует, размер логотипа веб-сайта изменяется до 60px x 60px и вместо этого помещается слева от заголовка и текста даты.

CSS для этого виджета приведен ниже:

.sidebar-content .recent-post {
  margin-bottom: 25px;
  padding-bottom: 25px;
  border-bottom: 1px solid #f0f0f0;
  float: left;
  clear: both;
  width: 100%;
}

.sidebar-content [class~='recent-post']:last-of-type {
  border-bottom: none;
}

.sidebar-content .recent-post .recent-post-image,
.sidebar-content .recent-post .recent-post-text {
  float: left;
}

.sidebar-content .recent-post .recent-post-image {
  margin-right: 10px;
}

.sidebar-content .recent-post .recent-post-text h4 {
  font-family: serif;
  margin-bottom: 10px;
}

.sidebar-content .recent-post .recent-post-text h4 a {
  color: #193441;
}

.sidebar-content .recent-post .recent-post-text p {
  font-family: Arial, sans-serif;
  font-size: 1.5rem;
  color: #737373;
  margin: 0;
}

Отрегулируйте интервал между последними элементами публикации, семейством шрифтов, размером шрифта и толщиной шрифта по своему вкусу.

Создание закрытого раздела⚓︎

Grav позволяет очень легко создать приватный раздел на веб-сайте. Всё это работает благодаря плагину Login.

Требование от пользователей входа в систему перед доступом к части сайта⚓︎

Если у вас его ещё нет, установите его через панель администратора или с помощью утилиты командной строки GPM.

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

access:
  site.login: true

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

Обратите внимание, что разрешение по умолчанию не распространяется на подстраницы. Для этого в конфигурации плагина входа в систему включите «Использовать родительские правила доступа».

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

Требование специальных разрешений для просмотра одной или нескольких страниц⚓︎

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

Например:

access:
  site.onlybob: true

Затем добавьте Бобу разрешение site.onlybob в его пользовательский файл bob.yaml в папке user/accounts:

access:
  site.onlybob: true

Использование разрешений на основе группы⚓︎

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

Добавьте файл user/config/groups.yaml, например, с таким содержимым:

registered:
  readableName: 'Зарегистрированные пользователи'
  description: 'Группа обычных пользователей'
  access:
    site:
      login: true
premium:
  readableName: 'Премиум-пользователи'
  description: 'Группа донатеров'
  access:
    site:
      login: true
      paid: true

Теперь назначьте пользователей в группу, добавив

groups:
  - premium

в yaml-файлы пользователей в директории user/accounts.

Теперь пользователям, принадлежащим к группе premium, будет разрешен доступ к страницам с разрешением site.paid.

Добавление кода JavaScript в нижний колонтитул⚓︎

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

Хороший пример этого - проверка темы Antimatter.

templates/partials/base.html.twig определяет нижний блок для js, вызывая {{ assets.js('bottom') }}

{% block bottom %}
    {{ assets.js('bottom') }}
{% endblock %}

Вы можете добавить активы в этот блок в Twig, например, вызвав

{% do assets.addJs('theme://js/slidebars.min.js', {group: 'bottom'}) %}

или в PHP

$this->grav['assets']->addJs($this->grav['base_url'] . '/user/plugins/yourplugin/js/somefile.js', ['group' => 'bottom']);

Переопределение расположения папки журналов по умолчанию⚓︎

Расположение по умолчанию для вывода журналов Grav просто называется logs/. К сожалению, есть случаи, когда эта папка logs/ уже используется или недоступна для использования. Гибкая потоковая система Grav позволяет настраивать расположение этих папок.

Во-первых, вам нужно создать новую папку. В этом примере мы создадим новую папку в корне вашей установки Grav под названием grav-logs/. Затем создайте новый файл корневого уровня с именем setup.php и вставьте следующий код:

<?php

use Grav\Common\Utils;

return [
    'streams' => [
        'schemes' => [
            'log' => [
               'type' => 'ReadOnlyStream',
               'prefixes' => [
                   '' => ["grav-logs"],
               ]
            ]
        ]
    ]
];

Это в основном заменяет поток log папкой grav-logs/, а не папкой logs/ по умолчанию, как определено в system/src/Grav/Common/Config/Setup.php.

Разделенная система вертикального меню⚓︎

Чтобы создать вертикальное сворачиваемое иерархическое меню страниц, вам понадобится Twig-loop, немного CSS и немного JavaScript. Окончательный результат при использовании темы Antimatter будет выглядеть так:

Vertical Menu

Давайте начнем с Twig:

<ol class="tree">
    {% for page in pages.children.visible %}
        {% if page.children.visible is empty %}
            <li class="item">
            <a href="{{ page.url }}">{{ page.title }}</a>
        {% else %}
            <li class="parent">
            <a href="javascript:void(0);">{{ page.title }}</a>
            <ol>
                {% for child in page.children.visible %}
                    {% if child.children.visible is empty %}
                        <li class="item">
                        <a href="{{ child.url }}">{{ child.title }}</a>
                    {% else %}
                        <li class="parent">
                        <a href="javascript:void(0);">{{ child.title }}</a>
                        <ol>
                            {% for subchild in child.children.visible %}
                                <li><a href="{{ subchild.url }}">{{ subchild.title }}</a></li>
                            {% endfor %}
                        </ol>
                    {% endif %}
                    </li>
                {% endfor %}
            </ol>
        {% endif %}
        </li>
    {% endfor %}
</ol>

Это создает упорядоченный список, который перебирает все видимые страницы в Grav, переходя на три уровня в глубину, чтобы создать структуру для каждого уровня. Список, охватывающий всю структуру, имеет класс tree, и каждый элемент списка имеет класс parent, если он содержит дочерние элементы, или элемент, если его нет.

При нажатии на родительский элемент открывается список, в то время как обычные элементы ссылаются на саму страницу. Вы можете добавить это практически в любой шаблон Twig в теме Grav, при условии, что Grav имеет доступ к видимым страницам.

Чтобы добавить немного стиля, мы добавляем немного CSS:

<style>
ol.tree li {
    position: relative;
}
ol.tree li ol {
    display: none;
}
ol.tree li.open > ol {
    display: block;
}
ol.tree li.parent:after {
    content: '[+]';
}
ol.tree li.parent.open:after {
    content: '';
}
</style>

Обычно его следует размещать перед структурой Twig или, в идеале, транслировать в менеджере активов вашей темы. Эффект заключается в добавлении [+] после каждого родительского элемента, указывающего, что он может быть открыт, который исчезает при открытии.

Наконец, давайте добавим немного JavaScript для переключения дескрипторов класса open:

<script type="text/javascript">
var tree = document.querySelectorAll('ol.tree a:not(:last-child)');
for(var i = 0; i < tree.length; i++){
    tree[i].addEventListener('click', function(e) {
        var parent = e.target.parentElement;
        var classList = parent.classList;
        if(classList.contains("open")) {
            classList.remove('open');
            var opensubs = parent.querySelectorAll(':scope .open');
            for(var i = 0; i < opensubs.length; i++){
                opensubs[i].classList.remove('open');
            }
        } else {
            classList.add('open');
        }
    });
}
</script>

Его всегда следует размещать после структуры Twig, также в идеале в менеджере активов.

Динамическое оформление одной или нескольких страниц⚓︎

Вы можете динамически стилизовать разные страницы/сообщения на своем сайте Grav (независимо от назначения файла шаблона), настроив файл Twig темы для применения класса CSS, переданного как переменная в метаданных страницы.

Вы можете стилизовать разные сообщения/страницы на своем сайте Grav двумя способами:

  1. Если вы используете тему Antimatter, вы можете использовать существующее свойство заголовка body_classes, чтобы установить свой собственный класс CSS для этой страницы.
  2. Если вы используете тему, не основанную на Antimatter (или не реализуя body_classes, как это делает), вы можете настроить файл Twig темы для применения класса CSS, переданного как переменная в свойстве заголовка страницы.

Например, в файле вашей темы base.html.twig или в более конкретном шаблоне, таком как файл page.html.twig, вы можете добавить класс для отображения содержимого страницы, например:

<div class="{{ page.header.body_classes }}">
...
</div>

Затем для каждой страницы, которую вы хотите иметь уникальный стиль, вы должны добавить следующее свойство заголовка (при условии, что вы определили класс CSS для featurepost):

body_classes: featurepost

Примечание. Именно так тема Antimatter применяет классы, зависящие от страницы, и поэтому это хороший стандарт для подражания.

Перенос HTML-темы в Grav⚓︎

Перенос HTML-темы на Grav - обычная задача. Вот практический пошаговый процесс, который можно использовать для достижения этой цели.

Вы, вероятно, скачали тему, и она состоит из нескольких файлов HTML. Начнем с того, что просто заставим Grav загрузить домашнюю страницу. Никакого настраиваемого контента, просто копируйте тему HTML, но в структуре Grav.

Во-первых, используйте плагин Grav Devtools, чтобы создать пустую тему, и настройте Grav для её использования в системных настройках.

Создайте шаблон Twig templates/home.html.twig внутри папки шаблонов темы. Это будет представлять собой шаблон, специфичный для домашней страницы. Обычно главная страница — это уникальная страница на сайте, поэтому она, вероятно, заслуживает отдельного файла Twig.

Скопируйте HTML-код с домашней страницы шаблона, начиная с <html> и заканчивая </html> в ваш новый файл home.html.twig.

Теперь переместите все ресурсы темы HTML (изображения, CSS, JS) в папку вашей темы. Вы можете сохранить существующую структуру папок темы или изменить ее.

Создайте пустой файл pages/01.home/home.md. Теперь укажите в браузере yoursite.com/home: он должен отображать контент, но CSS, JS и изображения не будут загружены, вероятно, потому, что в теме они жестко запрограммированы как ссылки /img/* или /css/*.

Добавление правильных ссылок на ресурсы⚓︎

В Grav ссылки не работают, потому что они указывают на домашний маршрут, поэтому вместо того, чтобы указывать на /user/themes/mytheme/img, они указывают на /img в корне Grav. Поскольку все связанные с темой ресурсы лучше всего хранить внутри темы, нам нужно указать Grav в правильное место.

Найдите на странице ресурсы и измените ссылки на изображения с img/*.* на <img src="{{ url('theme://img/*.*', true) }}" />.

Таблицы стилей требуют немного большего внимания, так как есть конвейер ресурсов, который мы захотим включить в какой-то момент, поэтому мы перемещаем их в блок таблиц стилей в теге <head>.

Пример:

{% block stylesheets %}
    {% do assets.addCss('theme://css/styles.min.css', 100) %}
{% endblock %}
{{ assets.css()|raw }}

То же самое относится и к файлам JavaScript с дополнительным требованием, чтобы часть JS загружалась в нижний колонтитул.

Пример:

{% block javascripts %}
    {% do assets.addJs('theme://js/custom.js') %}
    {% do assets.addJs('jquery', 101) %}
{% endblock %}
{{ assets.js()|raw }}

Изменения страницы теперь должны отображаться в вашем браузере. Если нет, убедитесь, что кэш страниц и кэш Twig отключены в настройках конфигурации системы Grav.

Это только начало. Теперь вам может потребоваться добавить больше страниц и придумать более эффективные способы представления содержимого ваших страниц с помощью метаданных и настраиваемого Twig, который обрабатывает обычные необходимые строительные блоки: отзывы на домашней странице, обзоры, функции продукта и т. д.

Добавление ещё одной страницы⚓︎

Чтобы добавить ещё одну страницу, процесс аналогичен. Например, предположим, что вы хотите создать следующую страницу блога. Повторите процесс, чтобы добавить файл templates/blog.html.twig, вставить исходный HTML-код и создать страницу pages/02.blog/blog.md.

Теперь, хотя ссылки на изображения внутри страниц по-прежнему необходимо перенести на синтаксис ресурсов Grav (или просто изменить путь), вы не хотите повторять ту же работу, которую вы проделали выше для ресурсов CSS и JS. Его следует повторно использовать на сайте.

Общие элементы⚓︎

Определите общие части страниц (верхний и нижний колонтитулы) и переместите их в файл templates/partials/base.html.twig.

Затем каждый шаблон страницы должен расширить partials/base.html.twig и просто добавить свое уникальное содержание.

Добавить актив на определенную страницу⚓︎

Вам необходимо добавить актив в определённый шаблон вашей темы.

В большинстве случаев ваши активы будут добавлены внутри блока Twig в вашем базовом шаблоне, как показано ниже.

{% block javascripts %}
    {% do assets.addJs('theme://js/jquery.js', 91) %}
{% endblock %}
{{ assets.js()|raw }}

Чтобы добавить свой актив, вы должны расширить этот блок в своем шаблоне и вызвать {{parent ()}}, который получит активы, уже добавленные в ваш базовый шаблон. Допустим, вы хотите добавить файл «gallery.js» на страницу «Галерея портфолио». Отредактируйте свой шаблон и добавьте свой ресурс с помощью {{parent ()}}.

{% block javascripts %}
    {% do assets.addJs('theme://js/gallery.js', 100) %}
    {{ parent() }}
{% endblock %}

Повторно использовать страницу или модульный контент на другой странице⚓︎

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

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

Примечание: существует также плагин Grav Page Inject Plugin для этой функции, которая может быть подходящей для более сложных сценариев.

Во-первых, создайте новый файл шаблона, который будет служить заполнителем для содержимого - он может иметь любое имя, это имя называется "modular*reuse" и будет храниться в папке templates/modular* вашей темы для этого примера, но может храниться где угодно. в папке шаблонов.

modular_reuse.html.twig содержит только одну строку:

{{ page.content }}

Затем создайте новую модульную страницу в панели администратора, где этот контент должен отображаться с использованием этого нового шаблона «модульного повторного использования». Имя новой страницы может быть любым, поскольку оно не будет отображаться - будет выводиться исходный заголовок страницы.

Содержимое страницы - это всего одна строка: Страница:

{% include 'modular_reuse.html.twig' with {'page': page.find('/test-page/amazing-offers')} %}

Модульная:

{% include 'modular/modular_reuse.html.twig' with {'page': page.find('/test-page/_amazing-offers')} %}

То, что идет после «include», - это место, где хранится шаблон из первого шага, вероятно, в папке templates для обычных страниц, и в папке templates/modular для модульных страниц.

После page.find должна идти фактическая ссылка на исходный контент, который вы хотите использовать повторно. Модульный контент начинается с _, а страницы - нет. Самый простой способ найти правильную ссылку - открыть страницу в панели администратора и скопировать URL-адрес после слова admin.

The final page should look like this:

---
title: 'Modular Reuse Example'
---

{% include 'modular/modular_reuse.html.twig' with {'page': page.find('/test-page/_amazing-offers')} %}

Теперь «удивительные предложения» могут отображаться в нескольких местах, но их нужно обновлять только один раз.

Создайте настраиваемое поле защиты от спама для вашей контактной формы⚓︎

Обычные методы предотвращения спама, такие как поле-приманка, некоторые спам-боты обходят стороной.

Сделайте так, чтобы боту было сложнее угадать, что он может и не может заполнить, при заполнении контактной формы. Проще говоря, задайте вопрос, на который пользователь обязательно ответит, но в ответах на который бот не может понять значение. В вашем Markdown-файле с Form-data добавьте это поле:

- name: personality
  type: radio
  label: What is five times eight?
  options:
    alaska: 32
    oklahoma: 40
    california: 48
  validate:
    required: true
    pattern: '^oklahoma$'
    message: Not quite, try that math again.

Вопрос должен быть простым, но с множеством простых неправильных ответов. Важен порядок ответов. Правильный ответ никогда не должен быть первым; стремитесь где-то посередине. Важно самостоятельно рандомизировать значения, стоящие за ответами (метками), поэтому база данных связанных значений и ответов не поможет при ответе.

Боты все время становятся умнее, но они, как правило, не пытаются ответить на один и тот же вопрос несколько раз, если первая попытка не удалась. Кроме того, даже самые умные из них полагаются на словари известных данных, чтобы угадать ответ. Мы задаем простой вопрос: «Сколько будет пять умножить на восемь?» И даем три варианта: «32», «40» и «48». Правильный ответ - «40», но вместо проверки математических навыков бота мы присваиваем этим числам значения «alaska», «oklahoma» и «california» соответственно. Поскольку боты смотрят на возможные значения, а не на их ярлыки, ответы не имеют отношения к вопросу. Вы даже можете добавить ответ «Ананас» со значением «миссисипи» и подтвердить его, и просто попросить своих пользователей выбрать его в качестве своего ответа. Дело в том, чтобы персонализировать рандомизацию данных.

Отображение разного содержимого robots.txt для разных сред⚓︎

Вы настроили поддомен dev.yourdomain.com в качестве сайта разработки для предварительного просмотра того, над чем вы работаете, перед публикацией изменений в yourdomain.com, и хотите запретить поисковым индексаторам сканировать его, сохраняя при этом рабочую среду. сайт виден в результатах поиска.

Хотя вы должны защищать свой сайт разработки паролем, чтобы он действительно оставался конфиденциальным, иногда достаточно, и даже более практично, просто запретить индексаторам поисковых систем сканировать ваш сайт. К счастью, Grav может обрабатывать страницы в формате txt так же, как и html, поэтому мы можем использовать конфигурации среды и шаблоны twig для завершения работы.

Сначала давайте создадим файл конфигурации site.yaml, который сообщит нашему шаблону, что dev.yourdomain.com - это среда разработки.

/user/[dev.yourdomain.com]/config/site.yaml:

environment: dev

Затем создайте шаблон страницы robots.txt.twig, который проверяет, работает ли Grav в настоящее время на нашем сайте разработки, и отображает другое содержимое, если это так.

/user/themes/[yourtheme]/templates/robots.txt.twig:

{% if config.site.environment == 'dev' %}
{% for rule in page.header.dev %}
{{ rule }}
{% endfor %}

{% else %}
{{ page.content }}

{% endif %}

Наконец, создайте страницу с маршрутизацией в /robots.txt с правилами по умолчанию robots.txt в содержимом страницы и правилами нашей альтернативной версии для разработки во внешнем интерфейсе страницы. Чтобы отображать содержимое страницы как необработанный текст вместо HTML, мы также отключим рендеринг Markdown.

/user/pages/robots/robots.md:

---
routes:
  default: /robots.txt
process:
  markdown: false

dev:
  - 'User-agent: *'
  - 'Disallow: /'
---

User-agent: _
Disallow: /backup/
Disallow: /bin/
Disallow: /cache/
Disallow: /grav/
Disallow: /logs/
Disallow: /system/
Disallow: /vendor/
Disallow: /user/
Allow: /user/pages/
Allow: /user/themes/
Allow: /user/images/
Allow: /user/plugins/_.css$
Allow: /user/plugins/*.js$

Теперь у вас должен быть файл robots.txt, размещенный в корне вашего сайта с динамическим содержимым, также доступный для редактирования с помощью плагина админки.

Убедитесь, что ваш рабочий сайт не отображает Disallow: /, так как это полностью уничтожит его видимость в поисковых системах.