Problem/Motivation
Livre is based off of book 3.0.x and the token module which provides the book tokens is not aware of book 3.0.x. The token module assumes you're using book 1.0.x.
How to fix this? Well, here it goes:
Steps to reproduce
Proposed resolution
Add mymodule.token.inc to mymodule
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\node\NodeInterface;
/**
* Implements hook_token_info().
*/
function mymodule_token_info() {
return [
'types' => [
'node' => [
'name' => t('Node'),
'description' => t('Node tokens extended for Livre/Book 3.x.'),
],
],
'tokens' => [
'node' => [
'book:parents:join-path' => [
'name' => t('Book parents joined as path'),
'description' => t('Titles of ancestor book pages, joined as a path.'),
],
],
],
];
}
/**
* Implements hook_tokens().
*/
function mymodule_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) {
$replacements = [];
if ($type !== 'node' || empty($data['node']) || !$data['node'] instanceof NodeInterface) {
return $replacements;
}
/** @var \Drupal\node\NodeInterface $node */
$node = $data['node'];
/** @var \Drupal\book\BookManagerInterface $book_manager */
$book_manager = \Drupal::service('book.manager');
// --- 1. Load book link for THIS node ---
$book_link = $book_manager->loadBookLink($node->id());
if (!$book_link) {
return $replacements; // Not part of a book.
}
// --- 2. Load the parent link if pid > 0 ---
$parent_link = [];
if (!empty($book_link['pid'])) {
$parent_link = $book_manager->loadBookLink($book_link['pid']) ?: [];
}
// --- 3. Get parent chain array ---
// Returns array: ['depth'=>X, 'p1'=>nid, 'p2'=>nid, ...]
$parents = $book_manager->getBookParents($book_link, $parent_link);
$depth = $parents['depth'] ?? 0;
// --- 4. Build clean path segments from ancestor titles ---
$titles = [];
if ($depth > 0) {
$node_storage = \Drupal::entityTypeManager()->getStorage('node');
$cleaner = \Drupal::service('pathauto.alias_cleaner');
$current_nid = $node->id();
for ($i = 1; $i <= $depth; $i++) {
$key = 'p' . $i;
if (!empty($parents[$key]) && $parents[$key] != $current_nid) {
if ($parent = $node_storage->load($parents[$key])) {
$titles[] = $cleaner->cleanString($parent->label());
}
}
}
}
// The final joined path.
$joined_path = implode('/', $titles);
foreach ($tokens as $name => $original) {
if ($name === 'book:parents:join-path') {
$replacements[$original] = $joined_path;
}
}
return $replacements;
}
Now with this implemented correctly, the following pathauto pattern is functional:
[node:book:parents:join-path]/[node:title]
Remaining tasks
Turn this into a patch/Merge request for book and test it.
User interface changes
The token should work as expected.
API changes
None
Issue fork livre-3563005
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
joseph.olstadComment #6
joseph.olstadMerged since book 3.0.x is going to do this OO+, there won't be a conflict.