Showing
12 changed files
with
263 additions
and
121 deletions
| ... | @@ -3,6 +3,7 @@ | ... | @@ -3,6 +3,7 @@ |
| 3 | namespace BookStack\Http\Controllers; | 3 | namespace BookStack\Http\Controllers; |
| 4 | 4 | ||
| 5 | use Activity; | 5 | use Activity; |
| 6 | +use BookStack\Services\ExportService; | ||
| 6 | use Illuminate\Http\Request; | 7 | use Illuminate\Http\Request; |
| 7 | 8 | ||
| 8 | use Illuminate\Support\Facades\Auth; | 9 | use Illuminate\Support\Facades\Auth; |
| ... | @@ -18,18 +19,21 @@ class PageController extends Controller | ... | @@ -18,18 +19,21 @@ class PageController extends Controller |
| 18 | protected $pageRepo; | 19 | protected $pageRepo; |
| 19 | protected $bookRepo; | 20 | protected $bookRepo; |
| 20 | protected $chapterRepo; | 21 | protected $chapterRepo; |
| 22 | + protected $exportService; | ||
| 21 | 23 | ||
| 22 | /** | 24 | /** |
| 23 | * PageController constructor. | 25 | * PageController constructor. |
| 24 | - * @param PageRepo $pageRepo | 26 | + * @param PageRepo $pageRepo |
| 25 | - * @param BookRepo $bookRepo | 27 | + * @param BookRepo $bookRepo |
| 26 | - * @param ChapterRepo $chapterRepo | 28 | + * @param ChapterRepo $chapterRepo |
| 29 | + * @param ExportService $exportService | ||
| 27 | */ | 30 | */ |
| 28 | - public function __construct(PageRepo $pageRepo, BookRepo $bookRepo, ChapterRepo $chapterRepo) | 31 | + public function __construct(PageRepo $pageRepo, BookRepo $bookRepo, ChapterRepo $chapterRepo, ExportService $exportService) |
| 29 | { | 32 | { |
| 30 | $this->pageRepo = $pageRepo; | 33 | $this->pageRepo = $pageRepo; |
| 31 | $this->bookRepo = $bookRepo; | 34 | $this->bookRepo = $bookRepo; |
| 32 | $this->chapterRepo = $chapterRepo; | 35 | $this->chapterRepo = $chapterRepo; |
| 36 | + $this->exportService = $exportService; | ||
| 33 | parent::__construct(); | 37 | parent::__construct(); |
| 34 | } | 38 | } |
| 35 | 39 | ||
| ... | @@ -221,4 +225,30 @@ class PageController extends Controller | ... | @@ -221,4 +225,30 @@ class PageController extends Controller |
| 221 | Activity::add($page, 'page_restore', $book->id); | 225 | Activity::add($page, 'page_restore', $book->id); |
| 222 | return redirect($page->getUrl()); | 226 | return redirect($page->getUrl()); |
| 223 | } | 227 | } |
| 228 | + | ||
| 229 | + public function exportPdf($bookSlug, $pageSlug) | ||
| 230 | + { | ||
| 231 | + $book = $this->bookRepo->getBySlug($bookSlug); | ||
| 232 | + $page = $this->pageRepo->getBySlug($pageSlug, $book->id); | ||
| 233 | + $cssContent = file_get_contents(public_path('/css/styles.css')); | ||
| 234 | + | ||
| 235 | + return $pdf->download($pageSlug . '.pdf'); | ||
| 236 | + } | ||
| 237 | + | ||
| 238 | + /** | ||
| 239 | + * Export a page to a self-contained HTML file. | ||
| 240 | + * @param $bookSlug | ||
| 241 | + * @param $pageSlug | ||
| 242 | + * @return \Illuminate\Http\Response | ||
| 243 | + */ | ||
| 244 | + public function exportHtml($bookSlug, $pageSlug) | ||
| 245 | + { | ||
| 246 | + $book = $this->bookRepo->getBySlug($bookSlug); | ||
| 247 | + $page = $this->pageRepo->getBySlug($pageSlug, $book->id); | ||
| 248 | + $containedHtml = $this->exportService->pageToContainedHtml($page); | ||
| 249 | + return response()->make($containedHtml, 200, [ | ||
| 250 | + 'Content-Type' => 'application/octet-stream', | ||
| 251 | + 'Content-Disposition' => 'attachment; filename="'.$pageSlug.'.html' | ||
| 252 | + ]); | ||
| 253 | + } | ||
| 224 | } | 254 | } | ... | ... |
| ... | @@ -18,17 +18,18 @@ Route::group(['middleware' => 'auth'], function () { | ... | @@ -18,17 +18,18 @@ Route::group(['middleware' => 'auth'], function () { |
| 18 | Route::get('/{bookSlug}/sort', 'BookController@sort'); | 18 | Route::get('/{bookSlug}/sort', 'BookController@sort'); |
| 19 | Route::put('/{bookSlug}/sort', 'BookController@saveSort'); | 19 | Route::put('/{bookSlug}/sort', 'BookController@saveSort'); |
| 20 | 20 | ||
| 21 | - | ||
| 22 | // Pages | 21 | // Pages |
| 23 | Route::get('/{bookSlug}/page/create', 'PageController@create'); | 22 | Route::get('/{bookSlug}/page/create', 'PageController@create'); |
| 24 | Route::post('/{bookSlug}/page', 'PageController@store'); | 23 | Route::post('/{bookSlug}/page', 'PageController@store'); |
| 25 | Route::get('/{bookSlug}/page/{pageSlug}', 'PageController@show'); | 24 | Route::get('/{bookSlug}/page/{pageSlug}', 'PageController@show'); |
| 25 | + Route::get('/{bookSlug}/page/{pageSlug}/export/pdf', 'PageController@exportPdf'); | ||
| 26 | + Route::get('/{bookSlug}/page/{pageSlug}/export/html', 'PageController@exportHtml'); | ||
| 26 | Route::get('/{bookSlug}/page/{pageSlug}/edit', 'PageController@edit'); | 27 | Route::get('/{bookSlug}/page/{pageSlug}/edit', 'PageController@edit'); |
| 27 | Route::get('/{bookSlug}/page/{pageSlug}/delete', 'PageController@showDelete'); | 28 | Route::get('/{bookSlug}/page/{pageSlug}/delete', 'PageController@showDelete'); |
| 28 | Route::put('/{bookSlug}/page/{pageSlug}', 'PageController@update'); | 29 | Route::put('/{bookSlug}/page/{pageSlug}', 'PageController@update'); |
| 29 | Route::delete('/{bookSlug}/page/{pageSlug}', 'PageController@destroy'); | 30 | Route::delete('/{bookSlug}/page/{pageSlug}', 'PageController@destroy'); |
| 30 | 31 | ||
| 31 | - //Revisions | 32 | + // Revisions |
| 32 | Route::get('/{bookSlug}/page/{pageSlug}/revisions', 'PageController@showRevisions'); | 33 | Route::get('/{bookSlug}/page/{pageSlug}/revisions', 'PageController@showRevisions'); |
| 33 | Route::get('/{bookSlug}/page/{pageSlug}/revisions/{revId}', 'PageController@showRevision'); | 34 | Route::get('/{bookSlug}/page/{pageSlug}/revisions/{revId}', 'PageController@showRevision'); |
| 34 | Route::get('/{bookSlug}/page/{pageSlug}/revisions/{revId}/restore', 'PageController@restoreRevision'); | 35 | Route::get('/{bookSlug}/page/{pageSlug}/revisions/{revId}/restore', 'PageController@restoreRevision'); | ... | ... |
app/Services/ExportService.php
0 → 100644
| 1 | +<?php namespace BookStack\Services; | ||
| 2 | + | ||
| 3 | + | ||
| 4 | +use BookStack\Page; | ||
| 5 | + | ||
| 6 | +class ExportService | ||
| 7 | +{ | ||
| 8 | + | ||
| 9 | + | ||
| 10 | + /** | ||
| 11 | + * Convert a page to a self-contained HTML file. | ||
| 12 | + * Includes required CSS & image content. Images are base64 encoded into the HTML. | ||
| 13 | + * @param Page $page | ||
| 14 | + * @return mixed|string | ||
| 15 | + */ | ||
| 16 | + public function pageToContainedHtml(Page $page) | ||
| 17 | + { | ||
| 18 | + $cssContent = file_get_contents(public_path('/css/export-styles.css')); | ||
| 19 | + $pageHtml = view('pages/pdf', ['page' => $page, 'css' => $cssContent])->render(); | ||
| 20 | + | ||
| 21 | + $imageTagsOutput = []; | ||
| 22 | + preg_match_all("/\<img.*src\=(\'|\")(.*?)(\'|\").*?\>/i", $pageHtml, $imageTagsOutput); | ||
| 23 | + | ||
| 24 | + // Replace image src with base64 encoded image strings | ||
| 25 | + if (isset($imageTagsOutput[0]) && count($imageTagsOutput[0]) > 0) { | ||
| 26 | + foreach ($imageTagsOutput[0] as $index => $imgMatch) { | ||
| 27 | + $oldImgString = $imgMatch; | ||
| 28 | + $srcString = $imageTagsOutput[2][$index]; | ||
| 29 | + if (strpos(trim($srcString), 'http') !== 0) { | ||
| 30 | + $pathString = public_path($srcString); | ||
| 31 | + } else { | ||
| 32 | + $pathString = $srcString; | ||
| 33 | + } | ||
| 34 | + $imageContent = file_get_contents($pathString); | ||
| 35 | + $imageEncoded = 'data:image/' . pathinfo($pathString, PATHINFO_EXTENSION) . ';base64,' . base64_encode($imageContent); | ||
| 36 | + $newImageString = str_replace($srcString, $imageEncoded, $oldImgString); | ||
| 37 | + $pageHtml = str_replace($oldImgString, $newImageString, $pageHtml); | ||
| 38 | + } | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + $linksOutput = []; | ||
| 42 | + preg_match_all("/\<a.*href\=(\'|\")(.*?)(\'|\").*?\>/i", $pageHtml, $linksOutput); | ||
| 43 | + | ||
| 44 | + // Replace image src with base64 encoded image strings | ||
| 45 | + if (isset($linksOutput[0]) && count($linksOutput[0]) > 0) { | ||
| 46 | + foreach ($linksOutput[0] as $index => $linkMatch) { | ||
| 47 | + $oldLinkString = $linkMatch; | ||
| 48 | + $srcString = $linksOutput[2][$index]; | ||
| 49 | + if (strpos(trim($srcString), 'http') !== 0) { | ||
| 50 | + $newSrcString = url($srcString); | ||
| 51 | + $newLinkString = str_replace($srcString, $newSrcString, $oldLinkString); | ||
| 52 | + $pageHtml = str_replace($oldLinkString, $newLinkString, $pageHtml); | ||
| 53 | + } | ||
| 54 | + } | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + // Replace any relative links with system domain | ||
| 58 | + return $pageHtml; | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| ... | @@ -9,16 +9,16 @@ | ... | @@ -9,16 +9,16 @@ |
| 9 | "packages": [ | 9 | "packages": [ |
| 10 | { | 10 | { |
| 11 | "name": "aws/aws-sdk-php", | 11 | "name": "aws/aws-sdk-php", |
| 12 | - "version": "3.12.1", | 12 | + "version": "3.13.1", |
| 13 | "source": { | 13 | "source": { |
| 14 | "type": "git", | 14 | "type": "git", |
| 15 | "url": "https://github.com/aws/aws-sdk-php.git", | 15 | "url": "https://github.com/aws/aws-sdk-php.git", |
| 16 | - "reference": "5ee0f33fafe47740c03ff38ddb73ae4f52b4da5b" | 16 | + "reference": "cc1796d1c21146cdcbfb7628aee816acb7b85e09" |
| 17 | }, | 17 | }, |
| 18 | "dist": { | 18 | "dist": { |
| 19 | "type": "zip", | 19 | "type": "zip", |
| 20 | - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/5ee0f33fafe47740c03ff38ddb73ae4f52b4da5b", | 20 | + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/cc1796d1c21146cdcbfb7628aee816acb7b85e09", |
| 21 | - "reference": "5ee0f33fafe47740c03ff38ddb73ae4f52b4da5b", | 21 | + "reference": "cc1796d1c21146cdcbfb7628aee816acb7b85e09", |
| 22 | "shasum": "" | 22 | "shasum": "" |
| 23 | }, | 23 | }, |
| 24 | "require": { | 24 | "require": { |
| ... | @@ -40,7 +40,7 @@ | ... | @@ -40,7 +40,7 @@ |
| 40 | "ext-simplexml": "*", | 40 | "ext-simplexml": "*", |
| 41 | "ext-spl": "*", | 41 | "ext-spl": "*", |
| 42 | "nette/neon": "^2.3", | 42 | "nette/neon": "^2.3", |
| 43 | - "phpunit/phpunit": "~4.0" | 43 | + "phpunit/phpunit": "~4.0|~5.0" |
| 44 | }, | 44 | }, |
| 45 | "suggest": { | 45 | "suggest": { |
| 46 | "aws/aws-php-sns-message-validator": "To validate incoming SNS notifications", | 46 | "aws/aws-php-sns-message-validator": "To validate incoming SNS notifications", |
| ... | @@ -84,7 +84,7 @@ | ... | @@ -84,7 +84,7 @@ |
| 84 | "s3", | 84 | "s3", |
| 85 | "sdk" | 85 | "sdk" |
| 86 | ], | 86 | ], |
| 87 | - "time": "2016-01-06 22:50:48" | 87 | + "time": "2016-01-19 22:46:22" |
| 88 | }, | 88 | }, |
| 89 | { | 89 | { |
| 90 | "name": "barryvdh/laravel-debugbar", | 90 | "name": "barryvdh/laravel-debugbar", |
| ... | @@ -829,16 +829,16 @@ | ... | @@ -829,16 +829,16 @@ |
| 829 | }, | 829 | }, |
| 830 | { | 830 | { |
| 831 | "name": "laravel/framework", | 831 | "name": "laravel/framework", |
| 832 | - "version": "v5.2.7", | 832 | + "version": "v5.2.10", |
| 833 | "source": { | 833 | "source": { |
| 834 | "type": "git", | 834 | "type": "git", |
| 835 | "url": "https://github.com/laravel/framework.git", | 835 | "url": "https://github.com/laravel/framework.git", |
| 836 | - "reference": "26cd65eaa4bcc0fb0be381cfb7cfdcda06a3c2b4" | 836 | + "reference": "93dc5b0089eef468157fd7200e575c3861ec59a5" |
| 837 | }, | 837 | }, |
| 838 | "dist": { | 838 | "dist": { |
| 839 | "type": "zip", | 839 | "type": "zip", |
| 840 | - "url": "https://api.github.com/repos/laravel/framework/zipball/26cd65eaa4bcc0fb0be381cfb7cfdcda06a3c2b4", | 840 | + "url": "https://api.github.com/repos/laravel/framework/zipball/93dc5b0089eef468157fd7200e575c3861ec59a5", |
| 841 | - "reference": "26cd65eaa4bcc0fb0be381cfb7cfdcda06a3c2b4", | 841 | + "reference": "93dc5b0089eef468157fd7200e575c3861ec59a5", |
| 842 | "shasum": "" | 842 | "shasum": "" |
| 843 | }, | 843 | }, |
| 844 | "require": { | 844 | "require": { |
| ... | @@ -953,7 +953,7 @@ | ... | @@ -953,7 +953,7 @@ |
| 953 | "framework", | 953 | "framework", |
| 954 | "laravel" | 954 | "laravel" |
| 955 | ], | 955 | ], |
| 956 | - "time": "2016-01-07 13:54:34" | 956 | + "time": "2016-01-13 20:29:10" |
| 957 | }, | 957 | }, |
| 958 | { | 958 | { |
| 959 | "name": "laravel/socialite", | 959 | "name": "laravel/socialite", |
| ... | @@ -1849,16 +1849,16 @@ | ... | @@ -1849,16 +1849,16 @@ |
| 1849 | }, | 1849 | }, |
| 1850 | { | 1850 | { |
| 1851 | "name": "symfony/class-loader", | 1851 | "name": "symfony/class-loader", |
| 1852 | - "version": "v2.8.1", | 1852 | + "version": "v2.8.2", |
| 1853 | "source": { | 1853 | "source": { |
| 1854 | "type": "git", | 1854 | "type": "git", |
| 1855 | "url": "https://github.com/symfony/class-loader.git", | 1855 | "url": "https://github.com/symfony/class-loader.git", |
| 1856 | - "reference": "ec74b0a279cf3a9bd36172b3e3061591d380ce6c" | 1856 | + "reference": "98e9089a428ed0e39423b67352c57ef5910a3269" |
| 1857 | }, | 1857 | }, |
| 1858 | "dist": { | 1858 | "dist": { |
| 1859 | "type": "zip", | 1859 | "type": "zip", |
| 1860 | - "url": "https://api.github.com/repos/symfony/class-loader/zipball/ec74b0a279cf3a9bd36172b3e3061591d380ce6c", | 1860 | + "url": "https://api.github.com/repos/symfony/class-loader/zipball/98e9089a428ed0e39423b67352c57ef5910a3269", |
| 1861 | - "reference": "ec74b0a279cf3a9bd36172b3e3061591d380ce6c", | 1861 | + "reference": "98e9089a428ed0e39423b67352c57ef5910a3269", |
| 1862 | "shasum": "" | 1862 | "shasum": "" |
| 1863 | }, | 1863 | }, |
| 1864 | "require": { | 1864 | "require": { |
| ... | @@ -1897,7 +1897,7 @@ | ... | @@ -1897,7 +1897,7 @@ |
| 1897 | ], | 1897 | ], |
| 1898 | "description": "Symfony ClassLoader Component", | 1898 | "description": "Symfony ClassLoader Component", |
| 1899 | "homepage": "https://symfony.com", | 1899 | "homepage": "https://symfony.com", |
| 1900 | - "time": "2015-12-05 17:37:59" | 1900 | + "time": "2016-01-03 15:33:41" |
| 1901 | }, | 1901 | }, |
| 1902 | { | 1902 | { |
| 1903 | "name": "symfony/console", | 1903 | "name": "symfony/console", | ... | ... |
| ... | @@ -21,6 +21,7 @@ elixir.extend('queryVersion', function(inputFiles) { | ... | @@ -21,6 +21,7 @@ elixir.extend('queryVersion', function(inputFiles) { |
| 21 | elixir(function(mix) { | 21 | elixir(function(mix) { |
| 22 | mix.sass('styles.scss') | 22 | mix.sass('styles.scss') |
| 23 | .sass('print-styles.scss') | 23 | .sass('print-styles.scss') |
| 24 | + .sass('export-styles.scss') | ||
| 24 | .browserify('global.js', 'public/js/common.js') | 25 | .browserify('global.js', 'public/js/common.js') |
| 25 | .queryVersion(['css/styles.css', 'css/print-styles.css', 'js/common.js']); | 26 | .queryVersion(['css/styles.css', 'css/print-styles.css', 'js/common.js']); |
| 26 | }); | 27 | }); | ... | ... |
resources/assets/sass/_fonts.scss
0 → 100644
| 1 | +/* Generated by Font Squirrel (http://www.fontsquirrel.com) on December 30, 2015 */ | ||
| 2 | +@font-face { | ||
| 3 | + font-family: 'Roboto'; | ||
| 4 | + src: url('/fonts/roboto-bold-webfont.eot'); | ||
| 5 | + src: url('/fonts/roboto-bold-webfont.eot?#iefix') format('embedded-opentype'), | ||
| 6 | + url('/fonts/roboto-bold-webfont.woff2') format('woff2'), | ||
| 7 | + url('/fonts/roboto-bold-webfont.woff') format('woff'), | ||
| 8 | + url('/fonts/roboto-bold-webfont.ttf') format('truetype'), | ||
| 9 | + url('/fonts/roboto-bold-webfont.svg#robotobold') format('svg'); | ||
| 10 | + font-weight: bold; | ||
| 11 | + font-style: normal; | ||
| 12 | +} | ||
| 13 | + | ||
| 14 | +@font-face { | ||
| 15 | + font-family: 'Roboto'; | ||
| 16 | + src: url('/fonts/roboto-bolditalic-webfont.eot'); | ||
| 17 | + src: url('/fonts/roboto-bolditalic-webfont.eot?#iefix') format('embedded-opentype'), | ||
| 18 | + url('/fonts/roboto-bolditalic-webfont.woff2') format('woff2'), | ||
| 19 | + url('/fonts/roboto-bolditalic-webfont.woff') format('woff'), | ||
| 20 | + url('/fonts/roboto-bolditalic-webfont.ttf') format('truetype'), | ||
| 21 | + url('/fonts/roboto-bolditalic-webfont.svg#robotobold_italic') format('svg'); | ||
| 22 | + font-weight: bold; | ||
| 23 | + font-style: italic; | ||
| 24 | +} | ||
| 25 | + | ||
| 26 | +@font-face { | ||
| 27 | + font-family: 'Roboto'; | ||
| 28 | + src: url('/fonts/roboto-italic-webfont.eot'); | ||
| 29 | + src: url('/fonts/roboto-italic-webfont.eot?#iefix') format('embedded-opentype'), | ||
| 30 | + url('/fonts/roboto-italic-webfont.woff2') format('woff2'), | ||
| 31 | + url('/fonts/roboto-italic-webfont.woff') format('woff'), | ||
| 32 | + url('/fonts/roboto-italic-webfont.ttf') format('truetype'), | ||
| 33 | + url('/fonts/roboto-italic-webfont.svg#robotoitalic') format('svg'); | ||
| 34 | + font-weight: normal; | ||
| 35 | + font-style: italic; | ||
| 36 | +} | ||
| 37 | + | ||
| 38 | +@font-face { | ||
| 39 | + font-family: 'Roboto'; | ||
| 40 | + src: url('/fonts/roboto-light-webfont.eot'); | ||
| 41 | + src: url('/fonts/roboto-light-webfont.eot?#iefix') format('embedded-opentype'), | ||
| 42 | + url('/fonts/roboto-light-webfont.woff2') format('woff2'), | ||
| 43 | + url('/fonts/roboto-light-webfont.woff') format('woff'), | ||
| 44 | + url('/fonts/roboto-light-webfont.ttf') format('truetype'), | ||
| 45 | + url('/fonts/roboto-light-webfont.svg#robotolight') format('svg'); | ||
| 46 | + font-weight: 300; | ||
| 47 | + font-style: normal; | ||
| 48 | +} | ||
| 49 | + | ||
| 50 | +@font-face { | ||
| 51 | + font-family: 'Roboto'; | ||
| 52 | + src: url('/fonts/roboto-lightitalic-webfont.eot'); | ||
| 53 | + src: url('/fonts/roboto-lightitalic-webfont.eot?#iefix') format('embedded-opentype'), | ||
| 54 | + url('/fonts/roboto-lightitalic-webfont.woff2') format('woff2'), | ||
| 55 | + url('/fonts/roboto-lightitalic-webfont.woff') format('woff'), | ||
| 56 | + url('/fonts/roboto-lightitalic-webfont.ttf') format('truetype'), | ||
| 57 | + url('/fonts/roboto-lightitalic-webfont.svg#robotolight_italic') format('svg'); | ||
| 58 | + font-weight: 300; | ||
| 59 | + font-style: italic; | ||
| 60 | +} | ||
| 61 | + | ||
| 62 | +@font-face { | ||
| 63 | + font-family: 'Roboto'; | ||
| 64 | + src: url('/fonts/roboto-medium-webfont.eot'); | ||
| 65 | + src: url('/fonts/roboto-medium-webfont.eot?#iefix') format('embedded-opentype'), | ||
| 66 | + url('/fonts/roboto-medium-webfont.woff2') format('woff2'), | ||
| 67 | + url('/fonts/roboto-medium-webfont.woff') format('woff'), | ||
| 68 | + url('/fonts/roboto-medium-webfont.ttf') format('truetype'), | ||
| 69 | + url('/fonts/roboto-medium-webfont.svg#robotomedium') format('svg'); | ||
| 70 | + font-weight: 500; | ||
| 71 | + font-style: normal; | ||
| 72 | +} | ||
| 73 | + | ||
| 74 | +@font-face { | ||
| 75 | + font-family: 'Roboto'; | ||
| 76 | + src: url('/fonts/roboto-mediumitalic-webfont.eot'); | ||
| 77 | + src: url('/fonts/roboto-mediumitalic-webfont.eot?#iefix') format('embedded-opentype'), | ||
| 78 | + url('/fonts/roboto-mediumitalic-webfont.woff2') format('woff2'), | ||
| 79 | + url('/fonts/roboto-mediumitalic-webfont.woff') format('woff'), | ||
| 80 | + url('/fonts/roboto-mediumitalic-webfont.ttf') format('truetype'), | ||
| 81 | + url('/fonts/roboto-mediumitalic-webfont.svg#robotomedium_italic') format('svg'); | ||
| 82 | + font-weight: 500; | ||
| 83 | + font-style: italic; | ||
| 84 | +} | ||
| 85 | + | ||
| 86 | +@font-face { | ||
| 87 | + font-family: 'Roboto'; | ||
| 88 | + src: url('/fonts/roboto-regular-webfont.eot'); | ||
| 89 | + src: url('/fonts/roboto-regular-webfont.eot?#iefix') format('embedded-opentype'), | ||
| 90 | + url('/fonts/roboto-regular-webfont.woff2') format('woff2'), | ||
| 91 | + url('/fonts/roboto-regular-webfont.woff') format('woff'), | ||
| 92 | + url('/fonts/roboto-regular-webfont.ttf') format('truetype'), | ||
| 93 | + url('/fonts/roboto-regular-webfont.svg#robotoregular') format('svg'); | ||
| 94 | + font-weight: normal; | ||
| 95 | + font-style: normal; | ||
| 96 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| ... | @@ -52,101 +52,3 @@ $text-light: #EEE; | ... | @@ -52,101 +52,3 @@ $text-light: #EEE; |
| 52 | $bs-light: 0 0 4px 1px #CCC; | 52 | $bs-light: 0 0 4px 1px #CCC; |
| 53 | $bs-med: 0 1px 3px 1px rgba(76, 76, 76, 0.26); | 53 | $bs-med: 0 1px 3px 1px rgba(76, 76, 76, 0.26); |
| 54 | $bs-hover: 0 2px 2px 1px rgba(0,0,0,.13); | 54 | $bs-hover: 0 2px 2px 1px rgba(0,0,0,.13); |
| 55 | - | ||
| 56 | - | ||
| 57 | -/* Generated by Font Squirrel (http://www.fontsquirrel.com) on December 30, 2015 */ | ||
| 58 | -@font-face { | ||
| 59 | - font-family: 'Roboto'; | ||
| 60 | - src: url('/fonts/roboto-bold-webfont.eot'); | ||
| 61 | - src: url('/fonts/roboto-bold-webfont.eot?#iefix') format('embedded-opentype'), | ||
| 62 | - url('/fonts/roboto-bold-webfont.woff2') format('woff2'), | ||
| 63 | - url('/fonts/roboto-bold-webfont.woff') format('woff'), | ||
| 64 | - url('/fonts/roboto-bold-webfont.ttf') format('truetype'), | ||
| 65 | - url('/fonts/roboto-bold-webfont.svg#robotobold') format('svg'); | ||
| 66 | - font-weight: bold; | ||
| 67 | - font-style: normal; | ||
| 68 | -} | ||
| 69 | - | ||
| 70 | -@font-face { | ||
| 71 | - font-family: 'Roboto'; | ||
| 72 | - src: url('/fonts/roboto-bolditalic-webfont.eot'); | ||
| 73 | - src: url('/fonts/roboto-bolditalic-webfont.eot?#iefix') format('embedded-opentype'), | ||
| 74 | - url('/fonts/roboto-bolditalic-webfont.woff2') format('woff2'), | ||
| 75 | - url('/fonts/roboto-bolditalic-webfont.woff') format('woff'), | ||
| 76 | - url('/fonts/roboto-bolditalic-webfont.ttf') format('truetype'), | ||
| 77 | - url('/fonts/roboto-bolditalic-webfont.svg#robotobold_italic') format('svg'); | ||
| 78 | - font-weight: bold; | ||
| 79 | - font-style: italic; | ||
| 80 | -} | ||
| 81 | - | ||
| 82 | -@font-face { | ||
| 83 | - font-family: 'Roboto'; | ||
| 84 | - src: url('/fonts/roboto-italic-webfont.eot'); | ||
| 85 | - src: url('/fonts/roboto-italic-webfont.eot?#iefix') format('embedded-opentype'), | ||
| 86 | - url('/fonts/roboto-italic-webfont.woff2') format('woff2'), | ||
| 87 | - url('/fonts/roboto-italic-webfont.woff') format('woff'), | ||
| 88 | - url('/fonts/roboto-italic-webfont.ttf') format('truetype'), | ||
| 89 | - url('/fonts/roboto-italic-webfont.svg#robotoitalic') format('svg'); | ||
| 90 | - font-weight: normal; | ||
| 91 | - font-style: italic; | ||
| 92 | -} | ||
| 93 | - | ||
| 94 | -@font-face { | ||
| 95 | - font-family: 'Roboto'; | ||
| 96 | - src: url('/fonts/roboto-light-webfont.eot'); | ||
| 97 | - src: url('/fonts/roboto-light-webfont.eot?#iefix') format('embedded-opentype'), | ||
| 98 | - url('/fonts/roboto-light-webfont.woff2') format('woff2'), | ||
| 99 | - url('/fonts/roboto-light-webfont.woff') format('woff'), | ||
| 100 | - url('/fonts/roboto-light-webfont.ttf') format('truetype'), | ||
| 101 | - url('/fonts/roboto-light-webfont.svg#robotolight') format('svg'); | ||
| 102 | - font-weight: 300; | ||
| 103 | - font-style: normal; | ||
| 104 | -} | ||
| 105 | - | ||
| 106 | -@font-face { | ||
| 107 | - font-family: 'Roboto'; | ||
| 108 | - src: url('/fonts/roboto-lightitalic-webfont.eot'); | ||
| 109 | - src: url('/fonts/roboto-lightitalic-webfont.eot?#iefix') format('embedded-opentype'), | ||
| 110 | - url('/fonts/roboto-lightitalic-webfont.woff2') format('woff2'), | ||
| 111 | - url('/fonts/roboto-lightitalic-webfont.woff') format('woff'), | ||
| 112 | - url('/fonts/roboto-lightitalic-webfont.ttf') format('truetype'), | ||
| 113 | - url('/fonts/roboto-lightitalic-webfont.svg#robotolight_italic') format('svg'); | ||
| 114 | - font-weight: 300; | ||
| 115 | - font-style: italic; | ||
| 116 | -} | ||
| 117 | - | ||
| 118 | -@font-face { | ||
| 119 | - font-family: 'Roboto'; | ||
| 120 | - src: url('/fonts/roboto-medium-webfont.eot'); | ||
| 121 | - src: url('/fonts/roboto-medium-webfont.eot?#iefix') format('embedded-opentype'), | ||
| 122 | - url('/fonts/roboto-medium-webfont.woff2') format('woff2'), | ||
| 123 | - url('/fonts/roboto-medium-webfont.woff') format('woff'), | ||
| 124 | - url('/fonts/roboto-medium-webfont.ttf') format('truetype'), | ||
| 125 | - url('/fonts/roboto-medium-webfont.svg#robotomedium') format('svg'); | ||
| 126 | - font-weight: 500; | ||
| 127 | - font-style: normal; | ||
| 128 | -} | ||
| 129 | - | ||
| 130 | -@font-face { | ||
| 131 | - font-family: 'Roboto'; | ||
| 132 | - src: url('/fonts/roboto-mediumitalic-webfont.eot'); | ||
| 133 | - src: url('/fonts/roboto-mediumitalic-webfont.eot?#iefix') format('embedded-opentype'), | ||
| 134 | - url('/fonts/roboto-mediumitalic-webfont.woff2') format('woff2'), | ||
| 135 | - url('/fonts/roboto-mediumitalic-webfont.woff') format('woff'), | ||
| 136 | - url('/fonts/roboto-mediumitalic-webfont.ttf') format('truetype'), | ||
| 137 | - url('/fonts/roboto-mediumitalic-webfont.svg#robotomedium_italic') format('svg'); | ||
| 138 | - font-weight: 500; | ||
| 139 | - font-style: italic; | ||
| 140 | -} | ||
| 141 | - | ||
| 142 | -@font-face { | ||
| 143 | - font-family: 'Roboto'; | ||
| 144 | - src: url('/fonts/roboto-regular-webfont.eot'); | ||
| 145 | - src: url('/fonts/roboto-regular-webfont.eot?#iefix') format('embedded-opentype'), | ||
| 146 | - url('/fonts/roboto-regular-webfont.woff2') format('woff2'), | ||
| 147 | - url('/fonts/roboto-regular-webfont.woff') format('woff'), | ||
| 148 | - url('/fonts/roboto-regular-webfont.ttf') format('truetype'), | ||
| 149 | - url('/fonts/roboto-regular-webfont.svg#robotoregular') format('svg'); | ||
| 150 | - font-weight: normal; | ||
| 151 | - font-style: normal; | ||
| 152 | -} | ... | ... |
resources/assets/sass/export-styles.scss
0 → 100644
| 1 | +@import "reset"; | ||
| 2 | +@import "variables"; | ||
| 3 | +@import "mixins"; | ||
| 4 | +@import "html"; | ||
| 5 | +@import "text"; | ||
| 6 | +@import "grid"; | ||
| 7 | +@import "blocks"; | ||
| 8 | +@import "forms"; | ||
| 9 | +@import "tables"; | ||
| 10 | +@import "header"; | ||
| 11 | +@import "lists"; | ||
| 12 | +@import "pages"; | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
resources/views/pages/pdf.blade.php
0 → 100644
| 1 | +<!doctype html> | ||
| 2 | +<html lang="en"> | ||
| 3 | +<head> | ||
| 4 | + <meta charset="UTF-8"> | ||
| 5 | + <title>{{ $page->name }}</title> | ||
| 6 | + | ||
| 7 | + <style> | ||
| 8 | + {!! $css !!} | ||
| 9 | + </style> | ||
| 10 | +</head> | ||
| 11 | +<body> | ||
| 12 | +<div class="container" id="page-show" ng-non-bindable> | ||
| 13 | + <div class="row"> | ||
| 14 | + <div class="col-md-8 col-md-offset-2"> | ||
| 15 | + <div class="page-content"> | ||
| 16 | + | ||
| 17 | + @include('pages/page-display') | ||
| 18 | + | ||
| 19 | + <hr> | ||
| 20 | + | ||
| 21 | + <p class="text-muted small"> | ||
| 22 | + Created {{$page->created_at->diffForHumans()}} @if($page->createdBy) by {{$page->createdBy->name}} @endif | ||
| 23 | + <br> | ||
| 24 | + Last Updated {{$page->updated_at->diffForHumans()}} @if($page->updatedBy) by {{$page->updatedBy->name}} @endif | ||
| 25 | + </p> | ||
| 26 | + | ||
| 27 | + </div> | ||
| 28 | + </div> | ||
| 29 | + </div> | ||
| 30 | +</div> | ||
| 31 | +</body> | ||
| 32 | +</html> |
| ... | @@ -19,6 +19,12 @@ | ... | @@ -19,6 +19,12 @@ |
| 19 | </div> | 19 | </div> |
| 20 | <div class="col-sm-6 faded"> | 20 | <div class="col-sm-6 faded"> |
| 21 | <div class="action-buttons"> | 21 | <div class="action-buttons"> |
| 22 | + <span dropdown class="dropdown-container"> | ||
| 23 | + <div dropdown-toggle class="text-button text-primary"><i class="zmdi zmdi-open-in-new"></i>Export Page</div> | ||
| 24 | + <ul> | ||
| 25 | + <li><a href="{{$page->getUrl() . '/export/html'}}" target="_blank">Contained HTML File</a></li> | ||
| 26 | + </ul> | ||
| 27 | + </span> | ||
| 22 | @if($currentUser->can('page-update')) | 28 | @if($currentUser->can('page-update')) |
| 23 | <a href="{{$page->getUrl() . '/revisions'}}" class="text-primary text-button"><i class="zmdi zmdi-replay"></i>Revisions</a> | 29 | <a href="{{$page->getUrl() . '/revisions'}}" class="text-primary text-button"><i class="zmdi zmdi-replay"></i>Revisions</a> |
| 24 | <a href="{{$page->getUrl() . '/edit'}}" class="text-primary text-button" ><i class="zmdi zmdi-edit"></i>Edit</a> | 30 | <a href="{{$page->getUrl() . '/edit'}}" class="text-primary text-button" ><i class="zmdi zmdi-edit"></i>Edit</a> | ... | ... |
-
Please register or sign in to post a comment