]> BookStack Code Mirror - bookstack/commitdiff
Updated page include logic to use blade-style tags
authorDan Brown <redacted>
Sat, 21 Jan 2017 13:53:00 +0000 (13:53 +0000)
committerDan Brown <redacted>
Sat, 21 Jan 2017 13:53:00 +0000 (13:53 +0000)
It will also snippets of a page if and id is provided in a tag

app/Http/Controllers/PageController.php
app/Http/Middleware/Localization.php
app/Repos/EntityRepo.php
app/Services/ExportService.php
resources/assets/sass/_blocks.scss
resources/assets/sass/_components.scss
resources/assets/sass/export-styles.scss

index 276665e52c403a3197719dde6c11e1469f596bcd..4ed10d61e3efa2ba6ef8d1dd535040f0e68b1cc1 100644 (file)
@@ -156,12 +156,11 @@ class PageController extends Controller
             return redirect($page->getUrl());
         }
 
-
         $this->checkOwnablePermission('page-view', $page);
 
         $pageContent = $this->entityRepo->renderPage($page);
         $sidebarTree = $this->entityRepo->getBookChildren($page->book);
-        $pageNav = $this->entityRepo->getPageNav($page);
+        $pageNav = $this->entityRepo->getPageNav($pageContent);
         
         Views::add($page);
         $this->setPageTitle($page->getShortName());
@@ -434,6 +433,7 @@ class PageController extends Controller
     {
         $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
         $pdfContent = $this->exportService->pageToPdf($page);
+//        return $pdfContent;
         return response()->make($pdfContent, 200, [
             'Content-Type'        => 'application/octet-stream',
             'Content-Disposition' => 'attachment; filename="' . $pageSlug . '.pdf'
index 3624e0e017e71e1bfffad0a62ab82ee90974d76a..31cb5d9a2bfb2e7eb1fb48c67ddf5d9419faca97 100644 (file)
@@ -1,6 +1,4 @@
-<?php
-
-namespace BookStack\Http\Middleware;
+<?php namespace BookStack\Http\Middleware;
 
 use Carbon\Carbon;
 use Closure;
index 312e3536ecad99338165bd4e322eb4255d6d3e44..f1428735cc340149a3c33d0d3ed76e298cfe7f63 100644 (file)
@@ -13,7 +13,6 @@ use Carbon\Carbon;
 use DOMDocument;
 use DOMXPath;
 use Illuminate\Support\Collection;
-use Symfony\Component\DomCrawler\Crawler;
 
 class EntityRepo
 {
@@ -140,7 +139,7 @@ class EntityRepo
      */
     public function getById($type, $id, $allowDrafts = false)
     {
-        return $this->entityQuery($type, $allowDrafts)->findOrFail($id);
+        return $this->entityQuery($type, $allowDrafts)->find($id);
     }
 
     /**
@@ -805,34 +804,42 @@ class EntityRepo
      */
     public function renderPage(Page $page)
     {
-        libxml_use_internal_errors(true);
-        $doc = new DOMDocument();
-        $doc->loadHTML(mb_convert_encoding('<body>'.$page->html.'</body>', 'HTML-ENTITIES', 'UTF-8'));
-        $xpath = new DOMXpath($doc);
-
-        $bsElems = $xpath->query('body/div[@bs-embed-page]');
-        if (is_null($bsElems)) return $page->html;
-        foreach ($bsElems as $bsElem) {
-            $pageId = intval($bsElem->getAttribute('bs-embed-page'));
-            $embeddedPage = $this->getById('page', $pageId);
-            if ($embeddedPage !== null) {
-                $innerPage = $doc->createDocumentFragment();
-                $innerPage->appendXML($embeddedPage->html);
-                // Empty div then append in child content
-                foreach ($bsElem->childNodes as $child) {
-                    $bsElem->removeChild($child);
-                }
-                $bsElem->appendChild($innerPage);
+        $content = $page->html;
+        $matches = [];
+        preg_match_all("/{{@\s?([0-9].*?)}}/", $content, $matches);
+        if (count($matches[0]) === 0) return $content;
+
+        foreach ($matches[1] as $index => $includeId) {
+            $splitInclude = explode('#', $includeId, 2);
+            $pageId = intval($splitInclude[0]);
+            if (is_nan($pageId)) continue;
+
+            $page = $this->getById('page', $pageId);
+            if ($page === null) {
+                $content = str_replace($matches[0][$index], '', $content);
+                continue;
             }
-        }
 
-        $body = $doc->getElementsByTagName('body')->item(0);
-        $html = '';
-        foreach ($body->childNodes as $node) {
-            $html .= $doc->saveHTML($node);
+            if (count($splitInclude) === 1) {
+                $content = str_replace($matches[0][$index], $page->html, $content);
+                continue;
+            }
+
+            $doc = new DOMDocument();
+            $doc->loadHTML(mb_convert_encoding('<body>'.$page->html.'</body>', 'HTML-ENTITIES', 'UTF-8'));
+            $matchingElem = $doc->getElementById($splitInclude[1]);
+            if ($matchingElem === null) {
+                $content = str_replace($matches[0][$index], '', $content);
+                continue;
+            }
+            $innerContent = '';
+            foreach ($matchingElem->childNodes as $childNode) {
+                $innerContent .= $doc->saveHTML($childNode);
+            }
+            $content = str_replace($matches[0][$index], trim($innerContent), $content);
         }
 
-        return $html;
+        return $content;
     }
 
     /**
@@ -874,15 +881,15 @@ class EntityRepo
 
     /**
      * Parse the headers on the page to get a navigation menu
-     * @param Page $page
+     * @param String $pageContent
      * @return array
      */
-    public function getPageNav(Page $page)
+    public function getPageNav($pageContent)
     {
-        if ($page->html == '') return [];
+        if ($pageContent == '') return [];
         libxml_use_internal_errors(true);
         $doc = new DOMDocument();
-        $doc->loadHTML(mb_convert_encoding($page->html, 'HTML-ENTITIES', 'UTF-8'));
+        $doc->loadHTML(mb_convert_encoding($pageContent, 'HTML-ENTITIES', 'UTF-8'));
         $xPath = new DOMXPath($doc);
         $headers = $xPath->query("//h1|//h2|//h3|//h4|//h5|//h6");
 
index 50ba75c17a93a22f7dc8b16d7820fed26338e24d..880bc54ad4de920fa48f6247d2d5a1d1cac142b5 100644 (file)
@@ -1,10 +1,22 @@
 <?php namespace BookStack\Services;
 
 use BookStack\Page;
+use BookStack\Repos\EntityRepo;
 
 class ExportService
 {
 
+    protected $entityRepo;
+
+    /**
+     * ExportService constructor.
+     * @param $entityRepo
+     */
+    public function __construct(EntityRepo $entityRepo)
+    {
+        $this->entityRepo = $entityRepo;
+    }
+
     /**
      * Convert a page to a self-contained HTML file.
      * Includes required CSS & image content. Images are base64 encoded into the HTML.
@@ -14,7 +26,7 @@ class ExportService
     public function pageToContainedHtml(Page $page)
     {
         $cssContent = file_get_contents(public_path('/css/export-styles.css'));
-        $pageHtml = view('pages/export', ['page' => $page, 'css' => $cssContent])->render();
+        $pageHtml = view('pages/export', ['page' => $page, 'pageContent' => $this->entityRepo->renderPage($page), 'css' => $cssContent])->render();
         return $this->containHtml($pageHtml);
     }
 
@@ -26,7 +38,8 @@ class ExportService
     public function pageToPdf(Page $page)
     {
         $cssContent = file_get_contents(public_path('/css/export-styles.css'));
-        $pageHtml = view('pages/pdf', ['page' => $page, 'css' => $cssContent])->render();
+        $pageHtml = view('pages/pdf', ['page' => $page, 'pageContent' => $this->entityRepo->renderPage($page), 'css' => $cssContent])->render();
+//        return $pageHtml;
         $useWKHTML = config('snappy.pdf.binary') !== false;
         $containedHtml = $this->containHtml($pageHtml);
         if ($useWKHTML) {
@@ -59,9 +72,13 @@ class ExportService
                     $pathString = $srcString;
                 }
                 if ($isLocal && !file_exists($pathString)) continue;
-                $imageContent = file_get_contents($pathString);
-                $imageEncoded = 'data:image/' . pathinfo($pathString, PATHINFO_EXTENSION) . ';base64,' . base64_encode($imageContent);
-                $newImageString = str_replace($srcString, $imageEncoded, $oldImgString);
+                try {
+                    $imageContent = file_get_contents($pathString);
+                    $imageEncoded = 'data:image/' . pathinfo($pathString, PATHINFO_EXTENSION) . ';base64,' . base64_encode($imageContent);
+                    $newImageString = str_replace($srcString, $imageEncoded, $oldImgString);
+                } catch (\ErrorException $e) {
+                    $newImageString = '';
+                }
                 $htmlContent = str_replace($oldImgString, $newImageString, $htmlContent);
             }
         }
@@ -88,14 +105,14 @@ class ExportService
 
     /**
      * Converts the page contents into simple plain text.
-     * This method filters any bad looking content to
-     * provide a nice final output.
+     * This method filters any bad looking content to provide a nice final output.
      * @param Page $page
      * @return mixed
      */
     public function pageToPlainText(Page $page)
     {
-        $text = $page->text;
+        $html = $this->entityRepo->renderPage($page);
+        $text = strip_tags($html);
         // Replace multiple spaces with single spaces
         $text = preg_replace('/\ {2,}/', ' ', $text);
         // Reduce multiple horrid whitespace characters.
index 7eb595d3611a5dc705d486416ca708344174080c..a2023aa37643c7e50703b4e120854bf56dab94bd 100644 (file)
   background-color: #EEE;
   padding: $-s;
   display: block;
-  > * {
-    display: inline-block;
-  }
   &:before {
     font-family: 'Material-Design-Iconic-Font';
     padding-right: $-s;
index c8fd8bcfabd56235bf392fed177898c830115d0b..5328057d9da7af1d81767d2fd1a05d8d6b486541 100644 (file)
@@ -70,9 +70,6 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group {
 #entity-selector-wrap .popup-body .form-group {
   margin: 0;
 }
-//body.ie #entity-selector-wrap .popup-body .form-group {
-//  min-height: 60vh;
-//}
 
 .image-manager-body {
   min-height: 70vh;
index 60450f3e2e5a1436dacc4554f41c4e363030d5d6..7e1ab4e9ed5c1b7d3e8094783865af5211943af1 100644 (file)
@@ -1,4 +1,4 @@
-//@import "reset";
+@import "reset";
 @import "variables";
 @import "mixins";
 @import "html";