Skip to content

Instantly share code, notes, and snippets.

@Ibochkarev
Last active October 15, 2020 18:02
Show Gist options
  • Save Ibochkarev/9da9c0ffb4aeb172cf8847edf9e703ad to your computer and use it in GitHub Desktop.
Save Ibochkarev/9da9c0ffb4aeb172cf8847edf9e703ad to your computer and use it in GitHub Desktop.
Формирование содержания у ресурса по заголовкам H1-H6

Формирование содержания у ресурса по заголовкам H1-H6

Сниппет makeContentsSide

<?php
if (!preg_match_all('#<h(\d)[^>]*?>(.*?)<[^>]*?/h\d>#i', $input, $headers)) {
    return ['content' => $input, 'links' => null];
}

if (count($headers[0]) < 1) {
    return ['content' => $input, 'links' => null];
}

$base = $modx->makeUrl($modx->resource->id, '', '', 'full');
$from = $to = array();
$depth = 0;
$start = null;

$contents = '<div class="contents"><div class="contents__title">содержание</div><ul class="nav-on-page-list" id="page-contents">';
foreach ($headers[2] as $i => $header) {
    $header = preg_replace('#\s+#', ' ', trim(rtrim($header, ':!.?;')));
    $anchor = str_replace(' ', '-', $header);
    $anchor = preg_replace('/[^a-zа-яё \-]/iu', '', $anchor);
    $header = "<a class=\"nav-on-page-link\" href=\"{$base}#{$anchor}\" data-id=\"#{$anchor}\">{$header}</a>";
    
    if ($depth > 0) {
        if ($headers[1][$i] > $depth) {
            while ($headers[1][$i] > $depth) {
                $contents .= '<ul>';
                $depth++;
            }
        } elseif ($headers[1][$i] < $depth) {
            while ($headers[1][$i] < $depth) {
                $contents .= str_repeat('</li>', $depth - $headers[1][$i]);
                $contents .= '</li></ul></div>';
                $depth--;
            }
        }
    }

    $depth = $headers[1][$i];
    if ($start === null) {
        $start = $depth;
    }
    
    $contents .= '<li class="nav-on-page-item">' . $header;

    $from[$i] = $headers[0][$i];
    $to[$i] = '<a id="' . $anchor . '" class="page-contents-link"></a>' . $headers[0][$i];
}

for ($i = 0; $i <= ($depth - $start); $i++) {
    $contents .= str_repeat('</li></ul>', 1);
}
$input = str_replace($from, $to, $input);

return ['links' => $contents, 'content' => $input];

Вывод в ресурсе

{set $contents = $_modx->resource.content | makeContentsSide}

{$contents.content}

{if $contents}
    {$contents.links}
{/if}

jQuery

$(document).ready(function () {
    $(".nav-on-page-item a").on("click", function(event) {
        event.preventDefault();

        var anchor = $(this).data("id"), // Ищем якорь
            anchorPX = $(anchor).offset().top; // Определяем положение якоря
        $('html, body').animate({scrollTop: anchorPX}, 600);
    });
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment