Dan Brown

Updated page include logic to use blade-style tags

It will also snippets of a page if and id is provided in a tag
...@@ -156,12 +156,11 @@ class PageController extends Controller ...@@ -156,12 +156,11 @@ class PageController extends Controller
156 return redirect($page->getUrl()); 156 return redirect($page->getUrl());
157 } 157 }
158 158
159 -
160 $this->checkOwnablePermission('page-view', $page); 159 $this->checkOwnablePermission('page-view', $page);
161 160
162 $pageContent = $this->entityRepo->renderPage($page); 161 $pageContent = $this->entityRepo->renderPage($page);
163 $sidebarTree = $this->entityRepo->getBookChildren($page->book); 162 $sidebarTree = $this->entityRepo->getBookChildren($page->book);
164 - $pageNav = $this->entityRepo->getPageNav($page); 163 + $pageNav = $this->entityRepo->getPageNav($pageContent);
165 164
166 Views::add($page); 165 Views::add($page);
167 $this->setPageTitle($page->getShortName()); 166 $this->setPageTitle($page->getShortName());
...@@ -434,6 +433,7 @@ class PageController extends Controller ...@@ -434,6 +433,7 @@ class PageController extends Controller
434 { 433 {
435 $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); 434 $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
436 $pdfContent = $this->exportService->pageToPdf($page); 435 $pdfContent = $this->exportService->pageToPdf($page);
436 +// return $pdfContent;
437 return response()->make($pdfContent, 200, [ 437 return response()->make($pdfContent, 200, [
438 'Content-Type' => 'application/octet-stream', 438 'Content-Type' => 'application/octet-stream',
439 'Content-Disposition' => 'attachment; filename="' . $pageSlug . '.pdf' 439 'Content-Disposition' => 'attachment; filename="' . $pageSlug . '.pdf'
......
1 -<?php 1 +<?php namespace BookStack\Http\Middleware;
2 -
3 -namespace BookStack\Http\Middleware;
4 2
5 use Carbon\Carbon; 3 use Carbon\Carbon;
6 use Closure; 4 use Closure;
......
...@@ -13,7 +13,6 @@ use Carbon\Carbon; ...@@ -13,7 +13,6 @@ use Carbon\Carbon;
13 use DOMDocument; 13 use DOMDocument;
14 use DOMXPath; 14 use DOMXPath;
15 use Illuminate\Support\Collection; 15 use Illuminate\Support\Collection;
16 -use Symfony\Component\DomCrawler\Crawler;
17 16
18 class EntityRepo 17 class EntityRepo
19 { 18 {
...@@ -140,7 +139,7 @@ class EntityRepo ...@@ -140,7 +139,7 @@ class EntityRepo
140 */ 139 */
141 public function getById($type, $id, $allowDrafts = false) 140 public function getById($type, $id, $allowDrafts = false)
142 { 141 {
143 - return $this->entityQuery($type, $allowDrafts)->findOrFail($id); 142 + return $this->entityQuery($type, $allowDrafts)->find($id);
144 } 143 }
145 144
146 /** 145 /**
...@@ -805,34 +804,42 @@ class EntityRepo ...@@ -805,34 +804,42 @@ class EntityRepo
805 */ 804 */
806 public function renderPage(Page $page) 805 public function renderPage(Page $page)
807 { 806 {
808 - libxml_use_internal_errors(true); 807 + $content = $page->html;
809 - $doc = new DOMDocument(); 808 + $matches = [];
810 - $doc->loadHTML(mb_convert_encoding('<body>'.$page->html.'</body>', 'HTML-ENTITIES', 'UTF-8')); 809 + preg_match_all("/{{@\s?([0-9].*?)}}/", $content, $matches);
811 - $xpath = new DOMXpath($doc); 810 + if (count($matches[0]) === 0) return $content;
811 +
812 + foreach ($matches[1] as $index => $includeId) {
813 + $splitInclude = explode('#', $includeId, 2);
814 + $pageId = intval($splitInclude[0]);
815 + if (is_nan($pageId)) continue;
816 +
817 + $page = $this->getById('page', $pageId);
818 + if ($page === null) {
819 + $content = str_replace($matches[0][$index], '', $content);
820 + continue;
821 + }
812 822
813 - $bsElems = $xpath->query('body/div[@bs-embed-page]'); 823 + if (count($splitInclude) === 1) {
814 - if (is_null($bsElems)) return $page->html; 824 + $content = str_replace($matches[0][$index], $page->html, $content);
815 - foreach ($bsElems as $bsElem) { 825 + continue;
816 - $pageId = intval($bsElem->getAttribute('bs-embed-page'));
817 - $embeddedPage = $this->getById('page', $pageId);
818 - if ($embeddedPage !== null) {
819 - $innerPage = $doc->createDocumentFragment();
820 - $innerPage->appendXML($embeddedPage->html);
821 - // Empty div then append in child content
822 - foreach ($bsElem->childNodes as $child) {
823 - $bsElem->removeChild($child);
824 } 826 }
825 - $bsElem->appendChild($innerPage); 827 +
828 + $doc = new DOMDocument();
829 + $doc->loadHTML(mb_convert_encoding('<body>'.$page->html.'</body>', 'HTML-ENTITIES', 'UTF-8'));
830 + $matchingElem = $doc->getElementById($splitInclude[1]);
831 + if ($matchingElem === null) {
832 + $content = str_replace($matches[0][$index], '', $content);
833 + continue;
826 } 834 }
835 + $innerContent = '';
836 + foreach ($matchingElem->childNodes as $childNode) {
837 + $innerContent .= $doc->saveHTML($childNode);
827 } 838 }
828 - 839 + $content = str_replace($matches[0][$index], trim($innerContent), $content);
829 - $body = $doc->getElementsByTagName('body')->item(0);
830 - $html = '';
831 - foreach ($body->childNodes as $node) {
832 - $html .= $doc->saveHTML($node);
833 } 840 }
834 841
835 - return $html; 842 + return $content;
836 } 843 }
837 844
838 /** 845 /**
...@@ -874,15 +881,15 @@ class EntityRepo ...@@ -874,15 +881,15 @@ class EntityRepo
874 881
875 /** 882 /**
876 * Parse the headers on the page to get a navigation menu 883 * Parse the headers on the page to get a navigation menu
877 - * @param Page $page 884 + * @param String $pageContent
878 * @return array 885 * @return array
879 */ 886 */
880 - public function getPageNav(Page $page) 887 + public function getPageNav($pageContent)
881 { 888 {
882 - if ($page->html == '') return []; 889 + if ($pageContent == '') return [];
883 libxml_use_internal_errors(true); 890 libxml_use_internal_errors(true);
884 $doc = new DOMDocument(); 891 $doc = new DOMDocument();
885 - $doc->loadHTML(mb_convert_encoding($page->html, 'HTML-ENTITIES', 'UTF-8')); 892 + $doc->loadHTML(mb_convert_encoding($pageContent, 'HTML-ENTITIES', 'UTF-8'));
886 $xPath = new DOMXPath($doc); 893 $xPath = new DOMXPath($doc);
887 $headers = $xPath->query("//h1|//h2|//h3|//h4|//h5|//h6"); 894 $headers = $xPath->query("//h1|//h2|//h3|//h4|//h5|//h6");
888 895
......
1 <?php namespace BookStack\Services; 1 <?php namespace BookStack\Services;
2 2
3 use BookStack\Page; 3 use BookStack\Page;
4 +use BookStack\Repos\EntityRepo;
4 5
5 class ExportService 6 class ExportService
6 { 7 {
7 8
9 + protected $entityRepo;
10 +
11 + /**
12 + * ExportService constructor.
13 + * @param $entityRepo
14 + */
15 + public function __construct(EntityRepo $entityRepo)
16 + {
17 + $this->entityRepo = $entityRepo;
18 + }
19 +
8 /** 20 /**
9 * Convert a page to a self-contained HTML file. 21 * Convert a page to a self-contained HTML file.
10 * Includes required CSS & image content. Images are base64 encoded into the HTML. 22 * Includes required CSS & image content. Images are base64 encoded into the HTML.
...@@ -14,7 +26,7 @@ class ExportService ...@@ -14,7 +26,7 @@ class ExportService
14 public function pageToContainedHtml(Page $page) 26 public function pageToContainedHtml(Page $page)
15 { 27 {
16 $cssContent = file_get_contents(public_path('/css/export-styles.css')); 28 $cssContent = file_get_contents(public_path('/css/export-styles.css'));
17 - $pageHtml = view('pages/export', ['page' => $page, 'css' => $cssContent])->render(); 29 + $pageHtml = view('pages/export', ['page' => $page, 'pageContent' => $this->entityRepo->renderPage($page), 'css' => $cssContent])->render();
18 return $this->containHtml($pageHtml); 30 return $this->containHtml($pageHtml);
19 } 31 }
20 32
...@@ -26,7 +38,8 @@ class ExportService ...@@ -26,7 +38,8 @@ class ExportService
26 public function pageToPdf(Page $page) 38 public function pageToPdf(Page $page)
27 { 39 {
28 $cssContent = file_get_contents(public_path('/css/export-styles.css')); 40 $cssContent = file_get_contents(public_path('/css/export-styles.css'));
29 - $pageHtml = view('pages/pdf', ['page' => $page, 'css' => $cssContent])->render(); 41 + $pageHtml = view('pages/pdf', ['page' => $page, 'pageContent' => $this->entityRepo->renderPage($page), 'css' => $cssContent])->render();
42 +// return $pageHtml;
30 $useWKHTML = config('snappy.pdf.binary') !== false; 43 $useWKHTML = config('snappy.pdf.binary') !== false;
31 $containedHtml = $this->containHtml($pageHtml); 44 $containedHtml = $this->containHtml($pageHtml);
32 if ($useWKHTML) { 45 if ($useWKHTML) {
...@@ -59,9 +72,13 @@ class ExportService ...@@ -59,9 +72,13 @@ class ExportService
59 $pathString = $srcString; 72 $pathString = $srcString;
60 } 73 }
61 if ($isLocal && !file_exists($pathString)) continue; 74 if ($isLocal && !file_exists($pathString)) continue;
75 + try {
62 $imageContent = file_get_contents($pathString); 76 $imageContent = file_get_contents($pathString);
63 $imageEncoded = 'data:image/' . pathinfo($pathString, PATHINFO_EXTENSION) . ';base64,' . base64_encode($imageContent); 77 $imageEncoded = 'data:image/' . pathinfo($pathString, PATHINFO_EXTENSION) . ';base64,' . base64_encode($imageContent);
64 $newImageString = str_replace($srcString, $imageEncoded, $oldImgString); 78 $newImageString = str_replace($srcString, $imageEncoded, $oldImgString);
79 + } catch (\ErrorException $e) {
80 + $newImageString = '';
81 + }
65 $htmlContent = str_replace($oldImgString, $newImageString, $htmlContent); 82 $htmlContent = str_replace($oldImgString, $newImageString, $htmlContent);
66 } 83 }
67 } 84 }
...@@ -88,14 +105,14 @@ class ExportService ...@@ -88,14 +105,14 @@ class ExportService
88 105
89 /** 106 /**
90 * Converts the page contents into simple plain text. 107 * Converts the page contents into simple plain text.
91 - * This method filters any bad looking content to 108 + * This method filters any bad looking content to provide a nice final output.
92 - * provide a nice final output.
93 * @param Page $page 109 * @param Page $page
94 * @return mixed 110 * @return mixed
95 */ 111 */
96 public function pageToPlainText(Page $page) 112 public function pageToPlainText(Page $page)
97 { 113 {
98 - $text = $page->text; 114 + $html = $this->entityRepo->renderPage($page);
115 + $text = strip_tags($html);
99 // Replace multiple spaces with single spaces 116 // Replace multiple spaces with single spaces
100 $text = preg_replace('/\ {2,}/', ' ', $text); 117 $text = preg_replace('/\ {2,}/', ' ', $text);
101 // Reduce multiple horrid whitespace characters. 118 // Reduce multiple horrid whitespace characters.
......
...@@ -136,9 +136,6 @@ ...@@ -136,9 +136,6 @@
136 background-color: #EEE; 136 background-color: #EEE;
137 padding: $-s; 137 padding: $-s;
138 display: block; 138 display: block;
139 - > * {
140 - display: inline-block;
141 - }
142 &:before { 139 &:before {
143 font-family: 'Material-Design-Iconic-Font'; 140 font-family: 'Material-Design-Iconic-Font';
144 padding-right: $-s; 141 padding-right: $-s;
......
...@@ -70,9 +70,6 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group { ...@@ -70,9 +70,6 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group {
70 #entity-selector-wrap .popup-body .form-group { 70 #entity-selector-wrap .popup-body .form-group {
71 margin: 0; 71 margin: 0;
72 } 72 }
73 -//body.ie #entity-selector-wrap .popup-body .form-group {
74 -// min-height: 60vh;
75 -//}
76 73
77 .image-manager-body { 74 .image-manager-body {
78 min-height: 70vh; 75 min-height: 70vh;
......
1 -//@import "reset"; 1 +@import "reset";
2 @import "variables"; 2 @import "variables";
3 @import "mixins"; 3 @import "mixins";
4 @import "html"; 4 @import "html";
......