ermakk / ms-cs-component
A component for Moonshine that displays the structure of markdown or other text as a hierarchical menu based on h1-h6 headings
Requires
- php: ^8.2|^8.3|^8.4
Requires (Dev)
- moonshine/moonshine: ^3.14.4
- rector/rector: ^1.0
Conflicts
- moonshine/moonshine: <3.0
README
Данный пакет представляет собой компонент для структурирования и обработки контентных блоков. Компонент предназначен для удобного разделения текста на логические блоки и автоматического формирования структуры документа. Использование компонента помогает упростить работу с большими объемами контента и повысить читаемость материала.

Компонент парсит переданное в него содержимое на предмет заголовков разного уровня (h1-h6). Модифицирует контент таким образом, чтобы все заголовки имели идентификатор. Строит из них иерархическую структуру и формирует из этой структуры меню с якорными ссылками на обновленный контент.
Заголовки, которые уже имеют идентификатор, так же попадут в меню, при этом их идентификатор затронут и изменен не будет!
Requirements
- MoonShine v3+
- Laravel v10+
- PHP v8.2+
Install
composer require ermakk/ms-cs-component
Добавьте провайдер в ваш config/app.php
'providers' => ServiceProvider::defaultProviders()->merge([ //... \Ermakk\CSComponent\Providers\CSComponentServiceProvider::class //... ])->toArray(),
Usage
Для вывода оглавления используется компонент Menu
.
Для инициализации обязателен один параметр - content
В качестве контента в меню передается класс реализующий интерфейс ContentContract
Задача этого класса - преобразование содержимого из необходимой вам разметки в HTML
для дальнейшего парсинга заголовков.
Вы можете создавать свои классы контента для вашей разметки, либо использовать существующие:
\Ermakk\CSComponent\Converters\MarkdownConverter
(Преобразует markdown разметку в html для дальнейшей работы парсера)\Ermakk\CSComponent\Converters\Html
(не конвертирует контент, но даже если у вас контент был в html разметке - необходимо передавать его в меню именно через класс)
В качестве второго аргумента можно передать класс парсера, для того чтобы переопределить поведение, разметку, правила генерации идентификаторов и т. п.
По умолчанию используется Ermakk\CSComponent\Parsers\HTMLParser
use Ermakk\CSComponent\Components\StructureMenu\Menu; use \Ermakk\CSComponent\Converters\MarkdownConverter; Menu::make(MarkdownConverter::make($content))
По умолчанию все якорные ссылки генерируются исходя из текущей, но могут появиться ситуации,
когда будет необходимость вручную задать базу для ссылки. Для этого можно воспользоваться методом
setRoute(?Closure $route)
у объекта Menu
use Ermakk\CSComponent\Components\StructureMenu\Menu; use \Ermakk\CSComponent\Converters\MarkdownConverter; // в таком случае все что вернет замыкание, будет использовано в качестве якорной ссылки // обратите внимание, что в таком случае вам нужно будет вручную добавить '#'.$item->id() // к возвращаемому замыканием значению Menu::make(MarkdownConverter::make($content))->setRoute(fn(StructureItem $item) => 'Ваш роут'.'#'.$item->id());
Последнее, что осталось сделать для полноценной работы - заменить контент на обновленный, чтобы у всех заголовков появились идентификаторы.
Для этого можно компонент не сразу встраивать в методы формирующие страницу moonshine,
а объявить в классе страницы переменную и в нее при формировании страницы поместить наше меню.
А затем с помощью метода getParser()
получить объект парсера и от него уже можно будет вернуть обновленную разметку
Str::markdown($this->structureMenu->getParser()->getNewHtml()),
В таком случае вы можете повторно использовать компонент Menu без повторного парсинга
Второй метод, для возврата обновленной разметки - это использовать метод getNewHtml()
прямо от объекта Menu
//... Menu(MarkdownConverter::make($resource->getItem()->content)) ->getNewHtml($this->newContent) ->setTitle('Оглавление') //...
в метод getNewHtml необходимо передать переменную, куда будет помещено новое значение
Methods
-
setTitle(string $title)
- устанавливает заголовок меню -
setPlaceholder(string $placeholder)
- устанавливает сообщение, которое отображается, когда нет содержимого -
simpleMode(bool $condition)
- меняет режим отображенияtrue
- простой режим, отображает только набор пунктовfalse
- стандартный режим, используемый по умолчанию, отображает заголовок меню и пункты в контейнере .box
-
getNewHtml()
- принимает в качестве параметра переменную, куда по ссылке помещает обновленную разметку -
так как
Menu
наследуетMoonShineComponent
, то будут доступны любые другие доступные для родительского класса методы
Published
Вы можете стандартными средствами laravel опубликовать ресурсы, для изменения внешнего вида
php artisan vendor:publish --provider="Ermakk\CSComponent\Providers\CSComponentServiceProvider"
Advanced
Пакет построен так, чтобы можно было дополнять его своими парсерами или конвертерами. Поэтому вы можете менять логику его работы