mirror of
https://github.com/standardebooks/web.git
synced 2025-07-06 06:40:33 -04:00
Switch from JSON-LD to RDFa for internal metadata
This commit is contained in:
parent
a12200c1ac
commit
99f1c1537a
7 changed files with 125 additions and 36 deletions
|
@ -25,3 +25,7 @@ parameters:
|
|||
- %rootDir%/../../../lib
|
||||
- %rootDir%/../../../www
|
||||
- %rootDir%/../../../scripts
|
||||
dynamicConstantNames:
|
||||
- DONATION_ALERT_ON
|
||||
- DONATION_ALERT_ALWAYS_ON
|
||||
- DONATION_ALERT_ON_DURING_HOLIDAYS
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?
|
||||
// Auto-included by Composer in composer.json to satisfy PHPStan
|
||||
use function Safe\define;
|
||||
use function Safe\strtotime;
|
||||
|
||||
const EBOOKS_PER_PAGE = 12;
|
||||
const SORT_NEWEST = 'newest';
|
||||
|
@ -36,7 +38,7 @@ define('PD_YEAR', intval(gmdate('Y')) - 96);
|
|||
|
||||
const DONATION_ALERT_ALWAYS_ON = false;
|
||||
const DONATION_ALERT_ON_DURING_HOLIDAYS = true;
|
||||
define('DONATION_ALERT_ON', DONATION_ALERT_ALWAYS_ON | (DONATION_ALERT_ON_DURING_HOLIDAYS && (strtotime('December 1, ' . gmdate('Y')) < time() && time() < strtotime('January 7, ' . (intval(gmdate('Y') + 1))))));
|
||||
define('DONATION_ALERT_ON', DONATION_ALERT_ALWAYS_ON | (DONATION_ALERT_ON_DURING_HOLIDAYS && (strtotime('December 1, ' . gmdate('Y')) < time() && time() < strtotime('January 7, ' . (intval(gmdate('Y')) + 1)))));
|
||||
// No trailing slash on any of the below constants.
|
||||
const SITE_URL = 'https://standardebooks.org';
|
||||
const SITE_ROOT = '/standardebooks.org';
|
||||
|
|
|
@ -239,16 +239,19 @@ class Ebook{
|
|||
$id = $author->attributes()->id;
|
||||
}
|
||||
|
||||
$refines = null;
|
||||
$refinesElement = $xml->xpath('/package/metadata/meta[@property="file-as"][@refines="#' . $id . '"]');
|
||||
if($refinesElement !== false && sizeof($refinesElement) > 0){
|
||||
$refines = (string)$refinesElement[0];
|
||||
$fileAs = null;
|
||||
$fileAsElement = $xml->xpath('/package/metadata/meta[@property="file-as"][@refines="#' . $id . '"]');
|
||||
if($fileAsElement !== false && sizeof($fileAsElement) > 0){
|
||||
$fileAs = (string)$fileAsElement[0];
|
||||
}
|
||||
|
||||
$this->Authors[] = new Contributor( (string)$author,
|
||||
$refines,
|
||||
$this->Authors[] = new Contributor(
|
||||
(string)$author,
|
||||
$fileAs,
|
||||
$this->NullIfEmpty($xml->xpath('/package/metadata/meta[@property="se:name.person.full-name"][@refines="#' . $id . '"]')),
|
||||
$this->NullIfEmpty($xml->xpath('/package/metadata/meta[@property="se:url.encyclopedia.wikipedia"][@refines="#' . $id . '"]'))
|
||||
$this->NullIfEmpty($xml->xpath('/package/metadata/meta[@property="se:url.encyclopedia.wikipedia"][@refines="#' . $id . '"]')),
|
||||
'aut',
|
||||
$this->NullIfEmpty($xml->xpath('/package/metadata/meta[@property="se:url.authority.nacoaf"][@refines="#' . $id . '"]'))
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -256,7 +259,7 @@ class Ebook{
|
|||
throw new EbookParsingException('Invalid <dc:creator> element.');
|
||||
}
|
||||
|
||||
$this->AuthorsUrl = preg_replace('|url:https://standardebooks.org/ebooks/([^/]+)/.*|ius', '/ebooks/\1/', $this->Identifier);
|
||||
$this->AuthorsUrl = preg_replace('|url:https://standardebooks.org/ebooks/([^/]+)/.*|ius', '/ebooks/\1', $this->Identifier);
|
||||
|
||||
foreach($xml->xpath('/package/metadata/dc:contributor') ?: [] as $contributor){
|
||||
$id = '';
|
||||
|
@ -270,6 +273,7 @@ class Ebook{
|
|||
$this->NullIfEmpty($xml->xpath('/package/metadata/meta[@property="file-as"][@refines="#' . $id . '"]')),
|
||||
$this->NullIfEmpty($xml->xpath('/package/metadata/meta[@property="se:name.person.full-name"][@refines="#' . $id . '"]')),
|
||||
$this->NullIfEmpty($xml->xpath('/package/metadata/meta[@property="se:url.encyclopedia.wikipedia"][@refines="#' . $id . '"]')),
|
||||
$role,
|
||||
$this->NullIfEmpty($xml->xpath('/package/metadata/meta[@property="se:url.authority.nacoaf"][@refines="#' . $id . '"]'))
|
||||
);
|
||||
|
||||
|
@ -437,6 +441,16 @@ class Ebook{
|
|||
$this->TitleWithCreditsHtml = Formatter::ToPlainText($this->Title) . ', by ' . str_replace('&', '&', $this->AuthorsHtml . $titleContributors);
|
||||
}
|
||||
|
||||
public function GetCollectionPosition(Collection $collection): ?int{
|
||||
foreach($this->Collections as $c){
|
||||
if($c->Name == $collection->Name){
|
||||
return $c->SequenceNumber;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function Contains(string $query): bool{
|
||||
// When searching an ebook, we search the title, alternate title, author(s), SE tags, series data, and LoC tags.
|
||||
// Also, if the ebook is shorts or poetry, search the ToC as well.
|
||||
|
@ -587,11 +601,34 @@ class Ebook{
|
|||
$string = '';
|
||||
$i = 0;
|
||||
foreach($contributors as $contributor){
|
||||
|
||||
$role = 'schema:contributor';
|
||||
switch($contributor->MarcRole){
|
||||
case 'trl':
|
||||
$role = 'schema:translator';
|
||||
break;
|
||||
case 'ill':
|
||||
$role = 'schema:illustrator';
|
||||
break;
|
||||
}
|
||||
|
||||
if($contributor->WikipediaUrl){
|
||||
$string .= '<a href="' . Formatter::ToPlainText($contributor->WikipediaUrl) .'">' . Formatter::ToPlainText($contributor->Name) . '</a>';
|
||||
$string .= '<a property="' . $role . '" typeof="schema:Person" href="' . Formatter::ToPlainText($contributor->WikipediaUrl) .'"><span property="schema:name">' . Formatter::ToPlainText($contributor->Name) . '</span>';
|
||||
|
||||
if($contributor->NacoafUrl){
|
||||
$string .= '<meta property="schema:sameAs" content="' . Formatter::ToPlainText($contributor->NacoafUrl) . '"/>';
|
||||
}
|
||||
|
||||
$string .= '</a>';
|
||||
}
|
||||
else{
|
||||
$string .= Formatter::ToPlainText($contributor->Name);
|
||||
$string .= '<span property="' . $role . '" typeof="schema:Person"><span property="schema:name">' . Formatter::ToPlainText($contributor->Name) . '</span>';
|
||||
|
||||
if($contributor->NacoafUrl){
|
||||
$string .= '<meta property="schema:sameAs" content="' . Formatter::ToPlainText($contributor->NacoafUrl) . '"/>';
|
||||
}
|
||||
|
||||
$string .= '</span>';
|
||||
}
|
||||
|
||||
if($i == sizeof($contributors) - 2 && sizeof($contributors) > 2){
|
||||
|
|
|
@ -8,20 +8,26 @@ if(!isset($ebooks)){
|
|||
$ebooks = [];
|
||||
}
|
||||
?>
|
||||
<ol<? if($view == VIEW_LIST){ ?> class="list"<? } ?>>
|
||||
<ol<? if($view == VIEW_LIST){ ?> class="list"<? } ?><? if($collection !== null){ ?> typeof="schema:BookSeries" about="<?= $collection->Url ?>"<? } ?>>
|
||||
<? if($collection !== null){ ?>
|
||||
<meta property="schema:name" content="<?= Formatter::ToPlainText($collection->Name) ?>"/>
|
||||
<? } ?>
|
||||
<? foreach($ebooks as $ebook){ ?>
|
||||
<li>
|
||||
<a href="<?= $ebook->Url ?>" tabindex="-1">
|
||||
<li typeof="schema:Book"<? if($collection !== null){ ?> resource="<?= $ebook->Url ?>" property="schema:hasPart" value="<?= $ebook->GetCollectionPosition($collection) ?>"<? }else{ ?> about="<?= $ebook->Url ?>"<? } ?>>
|
||||
<? if($collection !== null){ ?>
|
||||
<meta property="schema:position" content="<?= $ebook->GetCollectionPosition($collection) ?>"/>
|
||||
<? } ?>
|
||||
<a href="<?= $ebook->Url ?>" tabindex="-1" property="schema:url">
|
||||
<picture>
|
||||
<? if($ebook->CoverImage2xAvifUrl !== null){ ?><source srcset="<?= $ebook->CoverImage2xAvifUrl ?> 2x, <?= $ebook->CoverImageAvifUrl ?> 1x" type="image/avif"/><? } ?>
|
||||
<source srcset="<?= $ebook->CoverImage2xUrl ?> 2x, <?= $ebook->CoverImageUrl ?> 1x" type="image/jpg"/>
|
||||
<img src="<?= $ebook->CoverImage2xUrl ?>" title="<?= Formatter::ToPlainText($ebook->Title) ?>" alt="The cover for the Standard Ebooks edition of <?= Formatter::ToPlainText(strip_tags($ebook->TitleWithCreditsHtml)) ?>"/>
|
||||
<img src="<?= $ebook->CoverImage2xUrl ?>" title="<?= Formatter::ToPlainText($ebook->Title) ?>" alt="The cover for the Standard Ebooks edition of <?= Formatter::ToPlainText(strip_tags($ebook->TitleWithCreditsHtml)) ?>" property="schema:image"/>
|
||||
</picture>
|
||||
</a>
|
||||
<p><a href="<?= $ebook->Url ?>"><?= Formatter::ToPlainText($ebook->Title) ?></a></p>
|
||||
<p><a href="<?= $ebook->Url ?>" property="schema:url"><span property="schema:name"><?= Formatter::ToPlainText($ebook->Title) ?></span></a></p>
|
||||
<? if($view == VIEW_GRID){ ?>
|
||||
<? foreach($ebook->Authors as $author){ ?>
|
||||
<p class="author"><? if($author->Name != 'Anonymous'){ ?><a href="<?= Formatter::ToPlainText($ebook->AuthorsUrl) ?>"><?= Formatter::ToPlainText($author->Name) ?></a><? } ?></p>
|
||||
<p class="author" typeof="schema:Person" property="schema:author" resource="<?= $ebook->AuthorsUrl ?>"><? if($author->Name != 'Anonymous'){ ?><a href="<?= Formatter::ToPlainText(SITE_URL . $ebook->AuthorsUrl) ?>" property="schema:url"><span property="schema:name"><?= Formatter::ToPlainText($author->Name) ?></span></a><? } ?></p>
|
||||
<? } ?>
|
||||
<? }else{ ?>
|
||||
<div>
|
||||
|
|
|
@ -23,7 +23,7 @@ print('<?xml version="1.0" encoding="utf-8"?>');
|
|||
print("\n");
|
||||
?><!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
|
||||
<head>
|
||||
<head prefix="twitter: https://twitter.com schema: https://schema.org"><? /* the og RDFa prefix is part of the RDFa spec */ ?>
|
||||
<meta charset="utf-8"/>
|
||||
<title><? if($title != ''){ ?><?= Formatter::ToPlainText($title) ?> - <? } ?>Standard Ebooks: Free and liberated ebooks, carefully produced for the true book lover.</title>
|
||||
<? if($description != ''){ ?><meta content="<?= Formatter::ToPlainText($description) ?>" name="description"/><? } ?>
|
||||
|
@ -49,11 +49,6 @@ print("\n");
|
|||
<meta content="summary_large_image" name="twitter:card"/>
|
||||
<meta content="@standardebooks" name="twitter:site"/>
|
||||
<meta content="@standardebooks" name="twitter:creator"/>
|
||||
<? if(isset($jsonld)){ ?>
|
||||
<script type="application/ld+json">
|
||||
<?= $jsonld ?>
|
||||
</script>
|
||||
<? } ?>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
|
|
|
@ -68,22 +68,45 @@ catch(\Exception $ex){
|
|||
include(WEB_ROOT . '/404.php');
|
||||
exit();
|
||||
}
|
||||
?><?= Template::Header(['title' => strip_tags($ebook->TitleWithCreditsHtml), 'ogType' => 'book', 'coverUrl' => $ebook->DistCoverUrl, 'highlight' => 'ebooks', 'description' => 'The Standard Ebooks edition of ' . $ebook->Title . ': ' . $ebook->Description, 'jsonld' => htmlentities($ebook->GenerateJsonLd(), ENT_NOQUOTES)]) ?>
|
||||
?><?= Template::Header(['title' => strip_tags($ebook->TitleWithCreditsHtml), 'ogType' => 'book', 'coverUrl' => $ebook->DistCoverUrl, 'highlight' => 'ebooks', 'description' => 'The Standard Ebooks edition of ' . $ebook->Title . ': ' . $ebook->Description]) ?>
|
||||
<main>
|
||||
<article class="ebook">
|
||||
<article class="ebook" typeof="schema:Book" about="<?= $ebook->Url ?>">
|
||||
<meta property="schema:bookFormat" content="EBook"/>
|
||||
<meta property="schema:image" content="<?= Formatter::ToPlainText(SITE_URL . $ebook->DistCoverUrl) ?>"/>
|
||||
<meta property="schema:thumnailUrl" content="<?= Formatter::ToPlainText(SITE_URL . $ebook->Url . '/downloads/cover-thumbnail.jpg') ?>"/>
|
||||
<meta property="schema:description" content="<?= Formatter::ToPlainText($ebook->Description) ?>"/>
|
||||
<meta property="schema:url" content="<?= SITE_URL . Formatter::ToPlainText($ebook->Url) ?>"/>
|
||||
<meta property="schema:license" content="https://creativecommons.org/publicdomain/zero/1.0/"/>
|
||||
<meta property="schema:inLanguage" content="<?= Formatter::ToPlainText($ebook->Language) ?>"/>
|
||||
<? if($ebook->WikipediaUrl){ ?>
|
||||
<meta property="schema:sameAs" content="<?= Formatter::ToPlainText($ebook->WikipediaUrl) ?>"/>
|
||||
<? } ?>
|
||||
<div property="schema:publisher" typeof="schema:Organization">
|
||||
<meta property="schema:name" content="Standard Ebooks"/>
|
||||
<meta property="schema:logo" content="https://standardebooks.org/images/logo-full.svg"/>
|
||||
<meta property="schema:url" content="https://standardebooks.org"/>
|
||||
</div>
|
||||
<header>
|
||||
<hgroup>
|
||||
<h1><?= Formatter::ToPlainText($ebook->Title) ?></h1>
|
||||
<h1 property="schema:name"><?= Formatter::ToPlainText($ebook->Title) ?></h1>
|
||||
<? foreach($ebook->Authors as $author){ ?>
|
||||
<? /* We include the `resource` attr here because we can have multiple authors, and in that case their href URLs will link to their combined corpus.
|
||||
For example, William Wordsworth & Samuel Coleridge will both link to /ebooks/william-wordsworth_samuel-taylor-coleridge
|
||||
But, each author is an individual, so we have to differentiate them in RDFa with `resource` */ ?>
|
||||
<? if($author->Name != 'Anonymous'){ ?>
|
||||
<h2><a href="<?= Formatter::ToPlainText($ebook->AuthorsUrl) ?>"><?= Formatter::ToPlainText($author->Name) ?></a></h2>
|
||||
<h2><a property="schema:author" typeof="schema:Person" href="<?= Formatter::ToPlainText($ebook->AuthorsUrl) ?>" resource="<?= '/ebooks/' . $author->UrlName ?>">
|
||||
<span property="schema:name"><?= Formatter::ToPlainText($author->Name) ?></span>
|
||||
<meta property="schema:url" content="<?= SITE_URL . Formatter::ToPlainText($ebook->AuthorsUrl) ?>"/>
|
||||
<? if($author->NacoafUrl){ ?><meta property="schema:sameAs" content="<?= Formatter::ToPlainText($author->NacoafUrl) ?>"/><? } ?>
|
||||
</a>
|
||||
</h2>
|
||||
<? } ?>
|
||||
<? } ?>
|
||||
</hgroup>
|
||||
<picture>
|
||||
<? if($ebook->HeroImage2xAvifUrl !== null){ ?><source srcset="<?= $ebook->HeroImage2xAvifUrl ?> 2x, <?= $ebook->HeroImageAvifUrl ?> 1x" type="image/avif"/><? } ?>
|
||||
<source srcset="<?= $ebook->HeroImage2xUrl ?> 2x, <?= $ebook->HeroImageUrl ?> 1x" type="image/jpg"/>
|
||||
<img src="<?= $ebook->HeroImage2xUrl ?>" alt="The cover for the Standard Ebooks edition of <?= Formatter::ToPlainText(strip_tags($ebook->TitleWithCreditsHtml)) ?>"/>
|
||||
<img src="<?= $ebook->HeroImage2xUrl ?>" role="presentation" alt=""/>
|
||||
</picture>
|
||||
</header>
|
||||
|
||||
|
@ -94,7 +117,7 @@ catch(\Exception $ex){
|
|||
<? } ?>
|
||||
<? if(sizeof($ebook->Collections) > 0){ ?>
|
||||
<? foreach($ebook->Collections as $collection){ ?>
|
||||
<p><? if($collection->SequenceNumber !== null){ ?>№ <?= number_format($collection->SequenceNumber) ?> in the<? }else{ ?>Part of the<? } ?> <a href="<?= $collection->Url ?>"><?= Formatter::ToPlainText(preg_replace('/^The /ius', '', (string)$collection->Name) ?? '') ?></a>
|
||||
<p><? if($collection->SequenceNumber !== null){ ?>№ <?= number_format($collection->SequenceNumber) ?> in the<? }else{ ?>Part of the<? } ?> <a href="<?= $collection->Url ?>" property="schema:isPartOf"><?= Formatter::ToPlainText(preg_replace('/^The /ius', '', (string)$collection->Name) ?? '') ?></a>
|
||||
<? if($collection->Type !== null){ ?>
|
||||
<? if(substr_compare(mb_strtolower($collection->Name), mb_strtolower($collection->Type), -strlen(mb_strtolower($collection->Type))) !== 0){ ?>
|
||||
<?= $collection->Type ?>.
|
||||
|
@ -128,22 +151,38 @@ catch(\Exception $ex){
|
|||
<h3>Download for ereaders</h3>
|
||||
<ul>
|
||||
<? if($ebook->EpubUrl !== null){ ?>
|
||||
<li><p><span><a href="<?= $ebook->EpubUrl ?>" class="epub">Compatible epub</a> </span><span>—</span> <span>All devices and apps except Kindles and Kobos.</span></p>
|
||||
<li property="schema:encoding" typeof="schema:MediaObject"><p>
|
||||
<span><a property="schema:contentUrl" href="<?= $ebook->EpubUrl ?>" class="epub">
|
||||
Compatible epub
|
||||
<meta property="schema:encodingFormat" content="application/epub+zip"/>
|
||||
</a></span> <span>—</span> <span>All devices and apps except Kindles and Kobos.</span></p>
|
||||
</li>
|
||||
<? } ?>
|
||||
|
||||
<? if($ebook->Azw3Url !== null){ ?>
|
||||
<li><p><span><a href="<?= $ebook->Azw3Url ?>" class="amazon">azw3</a></span> <span>—</span> <span>Kindle devices and apps.<? if($ebook->KindleCoverUrl !== null){ ?> Also download the <a href="<?= $ebook->KindleCoverUrl ?>">Kindle cover thumbnail</a> to see the cover in your Kindle’s library.<? } ?></span></p>
|
||||
<li property="schema:encoding" typeof="schema:MediaObject"><p>
|
||||
<span><a property="schema:contentUrl" href="<?= $ebook->Azw3Url ?>" class="amazon">
|
||||
azw3
|
||||
<meta property="schema:encodingFormat" content="application/x-mobipocket-ebook"/>
|
||||
</a></span> <span>—</span> <span>Kindle devices and apps.<? if($ebook->KindleCoverUrl !== null){ ?> Also download the <a href="<?= $ebook->KindleCoverUrl ?>">Kindle cover thumbnail</a> to see the cover in your Kindle’s library.<? } ?></span></p>
|
||||
</li>
|
||||
<? } ?>
|
||||
|
||||
<? if($ebook->KepubUrl !== null){ ?>
|
||||
<li><p><span><a href="<?= $ebook->KepubUrl ?>" class="kobo">kepub</a> </span><span>—</span> <span>Kobo devices and apps.</span></p>
|
||||
<li property="schema:encoding" typeof="schema:MediaObject"><p>
|
||||
<span><a property="schema:contentUrl" href="<?= $ebook->KepubUrl ?>" class="kobo">
|
||||
kepub
|
||||
<meta property="schema:encodingFormat" content="application/kepub+zip"/>
|
||||
</a></span> <span>—</span> <span>Kobo devices and apps.</span></p>
|
||||
</li>
|
||||
<? } ?>
|
||||
|
||||
<? if($ebook->AdvancedEpubUrl !== null){ ?>
|
||||
<li><p><span><a href="<?= $ebook->AdvancedEpubUrl ?>" class="epub">Advanced epub</a></span> <span>—</span> <span>An advanced format not yet fully compatible with most ereaders.</span></p>
|
||||
<li property="schema:encoding" typeof="schema:MediaObject"><p>
|
||||
<span><a property="schema:contentUrl" href="<?= $ebook->AdvancedEpubUrl ?>" class="epub">
|
||||
Advanced epub
|
||||
<meta property="schema:encodingFormat" content="application/epub+zip"/>
|
||||
</a></span> <span>—</span> <span>An advanced format not yet fully compatible with most ereaders.</span></p>
|
||||
</li>
|
||||
<? } ?>
|
||||
</ul>
|
||||
|
@ -159,7 +198,12 @@ catch(\Exception $ex){
|
|||
<li><p><a href="<?= $ebook->TextUrl ?>" class="list">Start from the table of contents</a></p></li>
|
||||
<? } ?>
|
||||
<? if($ebook->TextSinglePageUrl !== null){ ?>
|
||||
<li><p><a href="<?= $ebook->TextSinglePageUrl ?>" class="page">Read on one page</a></p></li>
|
||||
<li property="schema:encoding" typeof="schema:mediaObject"><p>
|
||||
<a property="schema:contentUrl" href="<?= $ebook->TextSinglePageUrl ?>" class="page">
|
||||
Read on one page
|
||||
<meta property="schema:encodingFormat" content="application/xhtml+xml"/>
|
||||
</a>
|
||||
</p></li>
|
||||
<? } ?>
|
||||
</ul>
|
||||
</section>
|
||||
|
|
|
@ -13,6 +13,7 @@ try{
|
|||
$sort = HttpInput::GetString('sort', false);
|
||||
$pages = 0;
|
||||
$totalEbooks = 0;
|
||||
$collectionObject = null;
|
||||
|
||||
if($page <= 0){
|
||||
$page = 1;
|
||||
|
@ -51,7 +52,7 @@ try{
|
|||
// Are we looking at a collection?
|
||||
if($collection !== null){
|
||||
$ebooks = Library::GetEbooksByCollection($collection);
|
||||
$collectionObject = null;
|
||||
|
||||
// Get the *actual* name of the collection, in case there are accent marks (like "Arsène Lupin")
|
||||
if(sizeof($ebooks) > 0){
|
||||
foreach($ebooks[0]->Collections as $c){
|
||||
|
@ -138,7 +139,7 @@ catch(\Exception $ex){
|
|||
<? if(sizeof($ebooks) == 0){ ?>
|
||||
<p class="no-results">No ebooks matched your filters. You can try different filters, or <a href="/ebooks">browse all of our ebooks</a>.</p>
|
||||
<? }else{ ?>
|
||||
<?= Template::EbookGrid(['ebooks' => $ebooks, 'view' => $view]) ?>
|
||||
<?= Template::EbookGrid(['ebooks' => $ebooks, 'view' => $view, 'collection' => $collectionObject]) ?>
|
||||
<? } ?>
|
||||
<? if(sizeof($ebooks) > 0 && $collection === null){ ?>
|
||||
<nav>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue