Skip to content

Commit

Permalink
Add class to generate in-page navigation items
Browse files Browse the repository at this point in the history
Following on from the previous commit, we need a class that can generate
a list of items that represent H2s within a long-read post to be
navigated to.

This class parses the blocks in the content of a post, and then returns
an array of objects (one for each H2 in the content), where each object
has a 'title' property of the heading text, and an 'id' property of the
id attached to that H2, that we will then be able to use in an anchor
link.

Functionality to ensure WordPress auto-generates IDs for all heading
blocks will need to be activated for this to work correctly, and this
will be enforced in a forthcoming commit.

For: https://trello.com/c/KuFLpg6U/570-%F0%9F%8E%AF-goal-implement-long-read-template-for-lambeth-together-and-enable-gutenberg-for-this
  • Loading branch information
RobjS committed May 17, 2022
1 parent 33d405a commit 5eeeeb3
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 0 deletions.
77 changes: 77 additions & 0 deletions spec/in_page_navigation.spec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

describe(LongReadPlugin\InPageNavigation::class, function () {
beforeEach(function () {
$this->inPageNavigation = new \LongReadPlugin\InPageNavigation();
});

describe('->getItems()', function () {
it('does not return anything for non-heading blocks', function () {
global $post;
$post->post_content = 'Some content';
$blocks = [
[
'blockName' => 'not-heading'
],
[
'blockName' => 'also-not-heading'
],
];
allow('parse_blocks')->toBeCalled()->andReturn($blocks);

$result = $this->inPageNavigation->getItems();

expect($result)->toEqual([]);
});

it('does not return anything for heading blocks not of level 2', function () {
global $post;
$post->post_content = 'Some content';
$blocks = [
[
'blockName' => 'core/heading',
'attrs' => [
'level' => 3
]
],
[
'blockName' => 'core/heading',
'attrs' => [
'level' => 4
]
],
];
allow('parse_blocks')->toBeCalled()->andReturn($blocks);

$result = $this->inPageNavigation->getItems();

expect($result)->toEqual([]);
});

it('returns items for heading blocks with no level (as level 2 is the default)', function () {
global $post;
$post->post_content = 'Some content';
$blocks = [
[
'blockName' => 'core/heading',
'attrs' => [],
'innerHTML' => '<h2 id="first-heading">First heading</h2>'
],
[
'blockName' => 'core/heading',
'attrs' => [],
'innerHTML' => '<h2 id="second-heading">Second heading</h2>'
],
];
allow('parse_blocks')->toBeCalled()->andReturn($blocks);

$result = $this->inPageNavigation->getItems();

expect(count($result))->toEqual(2);
expect($result[0]->title)->toEqual("First heading");
expect($result[0]->id)->toEqual('first-heading');
expect($result[1]->title)->toEqual("Second heading");
expect($result[1]->id)->toEqual('second-heading');
});
});
});
24 changes: 24 additions & 0 deletions src/InPageNavigation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace LongReadPlugin;

class InPageNavigation
{
public function getItems() : array
{
$inPageNavItems = [];
global $post;
$blocks = parse_blocks($post->post_content);
foreach ($blocks as $block) {
if ($block['blockName'] == 'core/heading' && array_key_exists('attrs', $block) && (!isset($block['attrs']['level']) || $block['attrs']['level'] == 2)) {
$matches = [];
preg_match('/(id=")(.*)"/', $block['innerHTML'], $matches);
$inPageNavItems[] = (object) [
'title' => trim(strip_tags($block["innerHTML"])),
'id' => $matches[2]
];
}
}
return $inPageNavItems;
}
}

0 comments on commit 5eeeeb3

Please sign in to comment.