Anchor navigation to layouts

For a client I had to create a navigation that scrolls to speciffic ContentBlocks layout. For anyone who needs something similiar here is how I done it:

Create a snippet and put it anywhere you want that menu to appear and put following code in it:

$data = json_decode($input['contentblocks']['content'],true);
if(is_array($data) && $tpl && $wrapper){
	$pdo = $modx->getService('pdoTools');
	foreach($data as $k => $v){
		if($v['settings']['nav']) {			
			$o .= $pdo->getChunk($tpl, [
				'title' => $v['settings']['nav']
			]);
		}
	}
	if($i > 0) return $pdo->getChunk($wrapper, ['content' => $o]);
} else {
	return;
}

I used pdooTools parser to generate templates but you can easily update that snippet to use modx default parser.

Usage:

[[generate_anchor_menu? 
  &input=`[[*properties]]`
  &wrapper=`@INLINE <div class="hmeni">{$content}</div>'
  &tpl=`@INLINE <a href="#" {$class}>{$title}</a>'
]]

You need to add to each layout a settings named “nav”. Snippet will generate navigation from layouts which contains that field. On layout template you also need to insert something like this: [[+nav:gt=`0`:then=`data-menu="[[+nav]]"`]] so each layout gets a data attribute, so you know which menu needs to go where. Of course you need to all some javascript too to make it work.

I used this script:

$('.hMenu a').on('click', function(e) {
        e.preventDefault();
        var el = $('[data-menu="'+$(this).text()+'"]');
        let offset = el.offset().top - $("#header").height();
        $('html, body').animate({
            scrollTop: offset
        }, 1000);

});

If something is unclear feel free to ask :slight_smile:

1 Like