221 lines
8.6 KiB
PHP
221 lines
8.6 KiB
PHP
<?php
|
|
// Copyright 2026 Umbra Tools (umbratools.com)
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
/**
|
|
* Template Name: Book Detail
|
|
*
|
|
* Individual book page that pulls data from BD Bookshelf plugin database.
|
|
*
|
|
* @package BD_Murphy
|
|
*/
|
|
|
|
get_header();
|
|
|
|
$book_slug = get_query_var('book_slug');
|
|
if (empty($book_slug)) {
|
|
global $wp_query;
|
|
$book_slug = $wp_query->get('book_slug');
|
|
}
|
|
if (empty($book_slug)) {
|
|
$book_slug = get_post_field('post_name', get_the_ID());
|
|
}
|
|
|
|
$book = null;
|
|
if (class_exists('BDM_Book_Manager') && !empty($book_slug)) {
|
|
$book = BDM_Book_Manager::get_book_by_slug($book_slug);
|
|
}
|
|
|
|
if (!$book) {
|
|
?>
|
|
<div class="book-page-container">
|
|
<div style="text-align: center; padding: 60px 20px;">
|
|
<h1><?php esc_html_e('Book Not Found', 'bd-bookshelf'); ?></h1>
|
|
<p><?php esc_html_e('The book you are looking for could not be found.', 'bd-bookshelf'); ?></p>
|
|
<a href="<?php echo esc_url(home_url('/books/')); ?>" class="btn-primary"><?php esc_html_e('Browse All Books', 'bd-bookshelf'); ?></a>
|
|
</div>
|
|
</div>
|
|
<?php
|
|
get_footer();
|
|
return;
|
|
}
|
|
|
|
$title = esc_html($book->title);
|
|
$description = wp_kses_post($book->description);
|
|
$cover_url = esc_url($book->cover_image);
|
|
|
|
$author_names = [];
|
|
foreach ($book->authors as $ba) {
|
|
$author_names[] = esc_html($ba->author_name);
|
|
}
|
|
$author_string = !empty($author_names) ? implode(', ', $author_names) : 'B.D. Murphy';
|
|
|
|
$series = null;
|
|
if ($book->series_id > 0 && class_exists('BDM_Series')) {
|
|
$series = BDM_Series::get_series_by_id($book->series_id);
|
|
}
|
|
|
|
// Get retail links grouped by format and site name
|
|
$retail_links = [];
|
|
if (!empty($book->retail_links)) {
|
|
foreach ($book->retail_links as $link) {
|
|
$format = $link->format;
|
|
if (!isset($retail_links[$format])) {
|
|
$retail_links[$format] = [];
|
|
}
|
|
$retail_links[$format][$link->site_name] = $link;
|
|
}
|
|
}
|
|
|
|
// Define retailers per format (Google Play and Apple Books don't support paperback/hardcover)
|
|
$format_retailers = [
|
|
'ebook' => ['Amazon', 'Apple Books', 'Google Play', 'Barnes & Noble', 'Kobo'],
|
|
'paperback'=> ['Amazon', 'Barnes & Noble', 'Kobo'],
|
|
'hardcover'=> ['Amazon', 'Barnes & Noble', 'Kobo'],
|
|
'audio' => ['Amazon', 'Apple Books', 'Barnes & Noble', 'Kobo'],
|
|
];
|
|
|
|
$format_labels = [
|
|
'ebook' => __('eBook', 'bd-bookshelf'),
|
|
'paperback' => __('Paperback', 'bd-bookshelf'),
|
|
'hardcover' => __('Hardback', 'bd-bookshelf'),
|
|
'audio' => __('Audio', 'bd-bookshelf'),
|
|
];
|
|
|
|
// Determine which formats have at least one link
|
|
$available_formats = [];
|
|
foreach ($format_retailers as $fmt => $sites) {
|
|
if (!empty($retail_links[$fmt])) {
|
|
$available_formats[$fmt] = true;
|
|
}
|
|
}
|
|
|
|
// Rating display
|
|
$rating_html = '';
|
|
if ($book->rating_amazon > 0 || $book->rating_goodreads > 0) {
|
|
$rating_html .= '<div class="book-ratings">';
|
|
if ($book->rating_amazon > 0) {
|
|
$rating_html .= '<span class="rating amazon">' . number_format($book->rating_amazon, 1) . '/5 (Amazon)</span>';
|
|
}
|
|
if ($book->rating_goodreads > 0) {
|
|
$rating_html .= '<span class="rating goodreads">' . number_format($book->rating_goodreads, 1) . '/5 (Goodreads)</span>';
|
|
}
|
|
$rating_html .= '</div>';
|
|
}
|
|
?>
|
|
|
|
<div class="book-page-container">
|
|
<div class="book-page-layout">
|
|
<div class="book-page-left">
|
|
<div class="book-page-cover">
|
|
<?php if ($cover_url) : ?>
|
|
<img src="<?php echo $cover_url; ?>" alt="<?php echo $title; ?>">
|
|
<?php else : ?>
|
|
<div class="book-page-cover-placeholder"><?php echo $title; ?></div>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<div class="book-purchase-section">
|
|
<?php if (!empty($available_formats)) : ?>
|
|
<div class="book-format-toggle" role="tablist" aria-label="<?php esc_attr_e('Format selection', 'bd-bookshelf'); ?>">
|
|
<?php $active_format = key($available_formats); ?>
|
|
<?php foreach ($format_labels as $fmt => $label) : ?>
|
|
<?php if (isset($available_formats[$fmt])) : ?>
|
|
<button class="format-btn<?php echo ($fmt === $active_format) ? ' active' : ''; ?>"
|
|
data-format="<?php echo esc_attr($fmt); ?>"
|
|
role="tab"
|
|
aria-selected="<?php echo ($fmt === $active_format) ? 'true' : 'false'; ?>"
|
|
onclick="showFormat('<?php echo esc_attr($fmt); ?>')">
|
|
<?php echo $label; ?>
|
|
</button>
|
|
<?php endif; ?>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
|
|
<div class="book-retailer-links">
|
|
<?php foreach ($format_retailers as $fmt => $retailers) : ?>
|
|
<?php if (isset($available_formats[$fmt])) : ?>
|
|
<div class="format-links" id="links-<?php echo esc_attr($fmt); ?>" style="<?php echo ($fmt === $active_format) ? '' : 'display:none'; ?>">
|
|
<?php foreach ($retailers as $site_name) : ?>
|
|
<?php if (!empty($retail_links[$fmt][$site_name])) : ?>
|
|
<a href="<?php echo esc_url($retail_links[$fmt][$site_name]->url); ?>" class="retailer-link" target="_blank" rel="noopener noreferrer">
|
|
<?php echo esc_html($site_name); ?>
|
|
</a>
|
|
<?php else : ?>
|
|
<span class="retailer-link retailer-unavailable" title="<?php echo esc_attr(sprintf(__('No %s link available for %s', 'bd-bookshelf'), $site_name, $format_labels[$fmt])); ?>">
|
|
<?php echo esc_html($site_name); ?>
|
|
</span>
|
|
<?php endif; ?>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<?php else : ?>
|
|
<p class="no-purchase-links"><?php esc_html_e('Purchase links coming soon.', 'bd-bookshelf'); ?></p>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="book-page-center">
|
|
<div class="book-page-header">
|
|
<div class="book-title-section">
|
|
<h1 class="book-title"><?php echo $title; ?></h1>
|
|
<p class="book-pen-name"><?php echo $author_string; ?></p>
|
|
<?php if ($series) : ?>
|
|
<p class="book-series-info">
|
|
<?php printf(esc_html__('Part of the %s series', 'bd-bookshelf'), esc_html($series->name)); ?>
|
|
</p>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
|
|
<?php echo $rating_html; ?>
|
|
|
|
<?php if ($description) : ?>
|
|
<div class="book-blurb">
|
|
<div class="blurb-text"><?php echo $description; ?></div>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<div class="book-share-section">
|
|
<div class="social-share-buttons">
|
|
<?php get_template_part('template-parts/social-share'); ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<aside class="book-page-sidebar">
|
|
<?php if (is_active_sidebar('book-detail-sidebar')) : ?>
|
|
<div class="book-sidebar-widgets">
|
|
<?php dynamic_sidebar('book-detail-sidebar'); ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
</aside>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
function showFormat(format) {
|
|
document.querySelectorAll('.format-links').forEach(function(el) {
|
|
el.style.display = 'none';
|
|
});
|
|
var target = document.getElementById('links-' + format);
|
|
if (target) {
|
|
target.style.display = '';
|
|
}
|
|
document.querySelectorAll('.format-btn').forEach(function(btn) {
|
|
btn.classList.remove('active');
|
|
btn.setAttribute('aria-selected', 'false');
|
|
});
|
|
var activeBtn = document.querySelector('.format-btn[data-format="' + format + '"]');
|
|
if (activeBtn) {
|
|
activeBtn.classList.add('active');
|
|
activeBtn.setAttribute('aria-selected', 'true');
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<?php
|
|
get_footer();
|