Reorganised and split out export templates & styles
Moved export templates elements into their own folder for better grouping of logical usage. Within the base export template, added some body classes to allow easier targeted customisation via custom head css. Split content of export templates into smaller partials for easier future customization. Closes #3443
This commit is contained in:
parent
e00d88f45d
commit
88012449f3
|
@ -39,7 +39,7 @@ class ExportFormatter
|
||||||
public function pageToContainedHtml(Page $page)
|
public function pageToContainedHtml(Page $page)
|
||||||
{
|
{
|
||||||
$page->html = (new PageContent($page))->render();
|
$page->html = (new PageContent($page))->render();
|
||||||
$pageHtml = view('pages.export', [
|
$pageHtml = view('exports.page', [
|
||||||
'page' => $page,
|
'page' => $page,
|
||||||
'format' => 'html',
|
'format' => 'html',
|
||||||
'cspContent' => $this->cspService->getCspMetaTagValue(),
|
'cspContent' => $this->cspService->getCspMetaTagValue(),
|
||||||
|
@ -59,7 +59,7 @@ class ExportFormatter
|
||||||
$pages->each(function ($page) {
|
$pages->each(function ($page) {
|
||||||
$page->html = (new PageContent($page))->render();
|
$page->html = (new PageContent($page))->render();
|
||||||
});
|
});
|
||||||
$html = view('chapters.export', [
|
$html = view('exports.chapter', [
|
||||||
'chapter' => $chapter,
|
'chapter' => $chapter,
|
||||||
'pages' => $pages,
|
'pages' => $pages,
|
||||||
'format' => 'html',
|
'format' => 'html',
|
||||||
|
@ -77,7 +77,7 @@ class ExportFormatter
|
||||||
public function bookToContainedHtml(Book $book)
|
public function bookToContainedHtml(Book $book)
|
||||||
{
|
{
|
||||||
$bookTree = (new BookContents($book))->getTree(false, true);
|
$bookTree = (new BookContents($book))->getTree(false, true);
|
||||||
$html = view('books.export', [
|
$html = view('exports.book', [
|
||||||
'book' => $book,
|
'book' => $book,
|
||||||
'bookChildren' => $bookTree,
|
'bookChildren' => $bookTree,
|
||||||
'format' => 'html',
|
'format' => 'html',
|
||||||
|
@ -95,7 +95,7 @@ class ExportFormatter
|
||||||
public function pageToPdf(Page $page)
|
public function pageToPdf(Page $page)
|
||||||
{
|
{
|
||||||
$page->html = (new PageContent($page))->render();
|
$page->html = (new PageContent($page))->render();
|
||||||
$html = view('pages.export', [
|
$html = view('exports.page', [
|
||||||
'page' => $page,
|
'page' => $page,
|
||||||
'format' => 'pdf',
|
'format' => 'pdf',
|
||||||
'engine' => $this->pdfGenerator->getActiveEngine(),
|
'engine' => $this->pdfGenerator->getActiveEngine(),
|
||||||
|
@ -116,7 +116,7 @@ class ExportFormatter
|
||||||
$page->html = (new PageContent($page))->render();
|
$page->html = (new PageContent($page))->render();
|
||||||
});
|
});
|
||||||
|
|
||||||
$html = view('chapters.export', [
|
$html = view('exports.chapter', [
|
||||||
'chapter' => $chapter,
|
'chapter' => $chapter,
|
||||||
'pages' => $pages,
|
'pages' => $pages,
|
||||||
'format' => 'pdf',
|
'format' => 'pdf',
|
||||||
|
@ -134,7 +134,7 @@ class ExportFormatter
|
||||||
public function bookToPdf(Book $book)
|
public function bookToPdf(Book $book)
|
||||||
{
|
{
|
||||||
$bookTree = (new BookContents($book))->getTree(false, true);
|
$bookTree = (new BookContents($book))->getTree(false, true);
|
||||||
$html = view('books.export', [
|
$html = view('exports.book', [
|
||||||
'book' => $book,
|
'book' => $book,
|
||||||
'bookChildren' => $bookTree,
|
'bookChildren' => $bookTree,
|
||||||
'format' => 'pdf',
|
'format' => 'pdf',
|
||||||
|
|
|
@ -59,4 +59,47 @@ ul.contents ul li {
|
||||||
}
|
}
|
||||||
.chapter-hint + h1 {
|
.chapter-hint + h1 {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// PDF specific overrides
|
||||||
|
body.export-format-pdf {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.2;
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
max-width: 800px !important;
|
||||||
|
font-size: 0.8em;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table td {
|
||||||
|
width: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-content .float {
|
||||||
|
float: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-content img.align-left, .page-content img.align-right {
|
||||||
|
float: none !important;
|
||||||
|
clear: both;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// DOMPDF pdf export specific overrides
|
||||||
|
body.export-format-pdf.export-engine-dompdf {
|
||||||
|
// Fix for full width linked image sizes on DOMPDF
|
||||||
|
.page-content a > img {
|
||||||
|
max-width: 700px;
|
||||||
|
}
|
||||||
|
// Undoes the above for table images to prevent visually worse scenario, Awaiting next DOMPDF release for patch
|
||||||
|
.page-content td a > img {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,46 +0,0 @@
|
||||||
@extends('layouts.export')
|
|
||||||
|
|
||||||
@section('title', $book->name)
|
|
||||||
|
|
||||||
@section('content')
|
|
||||||
<h1 style="font-size: 4.8em">{{$book->name}}</h1>
|
|
||||||
|
|
||||||
<p>{{ $book->description }}</p>
|
|
||||||
|
|
||||||
@if(count($bookChildren) > 0)
|
|
||||||
<ul class="contents">
|
|
||||||
@foreach($bookChildren as $bookChild)
|
|
||||||
<li><a href="#{{$bookChild->getType()}}-{{$bookChild->id}}">{{ $bookChild->name }}</a></li>
|
|
||||||
@if($bookChild->isA('chapter') && count($bookChild->visible_pages) > 0)
|
|
||||||
<ul>
|
|
||||||
@foreach($bookChild->visible_pages as $page)
|
|
||||||
<li><a href="#page-{{$page->id}}">{{ $page->name }}</a></li>
|
|
||||||
@endforeach
|
|
||||||
</ul>
|
|
||||||
@endif
|
|
||||||
@endforeach
|
|
||||||
</ul>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@foreach($bookChildren as $bookChild)
|
|
||||||
<div class="page-break"></div>
|
|
||||||
<h1 id="{{$bookChild->getType()}}-{{$bookChild->id}}">{{ $bookChild->name }}</h1>
|
|
||||||
|
|
||||||
@if($bookChild->isA('chapter'))
|
|
||||||
<p>{{ $bookChild->description }}</p>
|
|
||||||
|
|
||||||
@if(count($bookChild->visible_pages) > 0)
|
|
||||||
@foreach($bookChild->visible_pages as $page)
|
|
||||||
<div class="page-break"></div>
|
|
||||||
<div class="chapter-hint">{{$bookChild->name}}</div>
|
|
||||||
<h1 id="page-{{$page->id}}">{{ $page->name }}</h1>
|
|
||||||
{!! $page->html !!}
|
|
||||||
@endforeach
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@else
|
|
||||||
{!! $bookChild->html !!}
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@endforeach
|
|
||||||
@endsection
|
|
|
@ -1,23 +0,0 @@
|
||||||
@extends('layouts.export')
|
|
||||||
|
|
||||||
@section('title', $chapter->name)
|
|
||||||
|
|
||||||
@section('content')
|
|
||||||
<h1 style="font-size: 4.8em">{{$chapter->name}}</h1>
|
|
||||||
|
|
||||||
<p>{{ $chapter->description }}</p>
|
|
||||||
|
|
||||||
@if(count($pages) > 0)
|
|
||||||
<ul class="contents">
|
|
||||||
@foreach($pages as $page)
|
|
||||||
<li><a href="#page-{{$page->id}}">{{ $page->name }}</a></li>
|
|
||||||
@endforeach
|
|
||||||
</ul>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@foreach($pages as $page)
|
|
||||||
<div class="page-break"></div>
|
|
||||||
<h1 id="page-{{$page->id}}">{{ $page->name }}</h1>
|
|
||||||
{!! $page->html !!}
|
|
||||||
@endforeach
|
|
||||||
@endsection
|
|
|
@ -1,61 +0,0 @@
|
||||||
<style>
|
|
||||||
@if (!app()->runningUnitTests())
|
|
||||||
{!! file_get_contents(public_path('/dist/export-styles.css')) !!}
|
|
||||||
@endif
|
|
||||||
</style>
|
|
||||||
|
|
||||||
@if ($format === 'pdf')
|
|
||||||
<style>
|
|
||||||
|
|
||||||
/* PDF size adjustments */
|
|
||||||
body {
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 1.2;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1, h2, h3, h4, h5, h6 {
|
|
||||||
line-height: 1.2;
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
|
||||||
max-width: 800px !important;
|
|
||||||
font-size: 0.8em;
|
|
||||||
width: 100% !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
table td {
|
|
||||||
width: auto !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Patches for CSS variable colors */
|
|
||||||
a {
|
|
||||||
color: {{ setting('app-color') }};
|
|
||||||
}
|
|
||||||
|
|
||||||
blockquote {
|
|
||||||
border-left-color: {{ setting('app-color') }};
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Patches for content layout */
|
|
||||||
.page-content .float {
|
|
||||||
float: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-content img.align-left, .page-content img.align-right {
|
|
||||||
float: none !important;
|
|
||||||
clear: both;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
@if($engine === \BookStack\Entities\Tools\PdfGenerator::ENGINE_DOMPDF)
|
|
||||||
{{-- Fix for full width linked image sizes on DOMPDF --}}
|
|
||||||
.page-content a > img {
|
|
||||||
max-width: 700px;
|
|
||||||
}
|
|
||||||
{{-- Undoes the above for table images to prevent visually worse scenario, Awaiting next DOMPDF release for patch --}}
|
|
||||||
.page-content td a > img {
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
@endif
|
|
||||||
</style>
|
|
||||||
@endif
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
@extends('layouts.export')
|
||||||
|
|
||||||
|
@section('title', $book->name)
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
|
||||||
|
<h1 style="font-size: 4.8em">{{$book->name}}</h1>
|
||||||
|
<p>{{ $book->description }}</p>
|
||||||
|
|
||||||
|
@include('exports.parts.book-contents-menu', ['children' => $bookChildren])
|
||||||
|
|
||||||
|
@foreach($bookChildren as $bookChild)
|
||||||
|
@if($bookChild->isA('chapter'))
|
||||||
|
@include('exports.parts.chapter-item', ['chapter' => $bookChild])
|
||||||
|
@else
|
||||||
|
@include('exports.parts.page-item', ['page' => $bookChild, 'chapter' => null])
|
||||||
|
@endif
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
@endsection
|
|
@ -0,0 +1,16 @@
|
||||||
|
@extends('layouts.export')
|
||||||
|
|
||||||
|
@section('title', $chapter->name)
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
|
||||||
|
<h1 style="font-size: 4.8em">{{$chapter->name}}</h1>
|
||||||
|
<p>{{ $chapter->description }}</p>
|
||||||
|
|
||||||
|
@include('exports.parts.chapter-contents-menu', ['pages' => $pages])
|
||||||
|
|
||||||
|
@foreach($pages as $page)
|
||||||
|
@include('exports.parts.page-item', ['page' => $page, 'chapter' => null])
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
@endsection
|
|
@ -8,6 +8,6 @@
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<div class="text-muted text-small">
|
<div class="text-muted text-small">
|
||||||
@include('entities.export-meta', ['entity' => $page])
|
@include('exports.parts.meta', ['entity' => $page])
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
|
@ -0,0 +1,10 @@
|
||||||
|
@if(count($children) > 0)
|
||||||
|
<ul class="contents">
|
||||||
|
@foreach($children as $bookChild)
|
||||||
|
<li><a href="#{{$bookChild->getType()}}-{{$bookChild->id}}">{{ $bookChild->name }}</a></li>
|
||||||
|
@if($bookChild->isA('chapter') && count($bookChild->visible_pages) > 0)
|
||||||
|
@include('exports.parts.chapter-contents-menu', ['pages' => $bookChild->visible_pages])
|
||||||
|
@endif
|
||||||
|
@endforeach
|
||||||
|
</ul>
|
||||||
|
@endif
|
|
@ -0,0 +1,7 @@
|
||||||
|
@if (count($pages) > 0)
|
||||||
|
<ul class="contents">
|
||||||
|
@foreach($pages as $page)
|
||||||
|
<li><a href="#page-{{$page->id}}">{{ $page->name }}</a></li>
|
||||||
|
@endforeach
|
||||||
|
</ul>
|
||||||
|
@endif
|
|
@ -0,0 +1,10 @@
|
||||||
|
<div class="page-break"></div>
|
||||||
|
<h1 id="chapter-{{$chapter->id}}">{{ $chapter->name }}</h1>
|
||||||
|
|
||||||
|
<p>{{ $chapter->description }}</p>
|
||||||
|
|
||||||
|
@if(count($chapter->visible_pages) > 0)
|
||||||
|
@foreach($chapter->visible_pages as $page)
|
||||||
|
@include('exports.parts.page-item', ['page' => $page, 'chapter' => $chapter])
|
||||||
|
@endforeach
|
||||||
|
@endif
|
|
@ -0,0 +1,8 @@
|
||||||
|
<div class="page-break"></div>
|
||||||
|
|
||||||
|
@if (isset($chapter))
|
||||||
|
<div class="chapter-hint">{{$chapter->name}}</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<h1 id="page-{{$page->id}}">{{ $page->name }}</h1>
|
||||||
|
{!! $page->html !!}
|
|
@ -0,0 +1,20 @@
|
||||||
|
{{-- Fetch in our standard export styles --}}
|
||||||
|
<style>
|
||||||
|
@if (!app()->runningUnitTests())
|
||||||
|
{!! file_get_contents(public_path('/dist/export-styles.css')) !!}
|
||||||
|
@endif
|
||||||
|
</style>
|
||||||
|
|
||||||
|
{{-- Apply any additional styles that can't be applied via our standard SCSS export styles --}}
|
||||||
|
@if ($format === 'pdf')
|
||||||
|
<style>
|
||||||
|
/* Patches for CSS variable colors within PDF exports */
|
||||||
|
a {
|
||||||
|
color: {{ setting('app-color') }};
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
border-left-color: {{ setting('app-color') }};
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@endif
|
|
@ -8,10 +8,10 @@
|
||||||
<meta http-equiv="Content-Security-Policy" content="{{ $cspContent }}">
|
<meta http-equiv="Content-Security-Policy" content="{{ $cspContent }}">
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@include('common.export-styles', ['format' => $format, 'engine' => $engine ?? ''])
|
@include('exports.parts.styles', ['format' => $format, 'engine' => $engine ?? ''])
|
||||||
@include('common.export-custom-head')
|
@include('exports.parts.custom-head')
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body class="export export-format-{{ $format }} export-engine-{{ $engine ?? 'none' }}">
|
||||||
<div class="page-content">
|
<div class="page-content">
|
||||||
@yield('content')
|
@yield('content')
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -457,4 +457,12 @@ class ExportTest extends TestCase
|
||||||
$resp->assertElementExists('head meta[http-equiv="Content-Security-Policy"][content*="script-src "]');
|
$resp->assertElementExists('head meta[http-equiv="Content-Security-Policy"][content*="script-src "]');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_html_exports_contain_body_classes_for_export_identification()
|
||||||
|
{
|
||||||
|
$page = Page::query()->first();
|
||||||
|
|
||||||
|
$resp = $this->asEditor()->get($page->getUrl('/export/html'));
|
||||||
|
$resp->assertElementExists('body.export.export-format-html.export-engine-none');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue