mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-10-01 01:36:00 -04:00
Added page HTML export
This commit is contained in:
parent
7bcd967fd9
commit
ea2e16cabb
@ -3,6 +3,7 @@
|
|||||||
namespace BookStack\Http\Controllers;
|
namespace BookStack\Http\Controllers;
|
||||||
|
|
||||||
use Activity;
|
use Activity;
|
||||||
|
use BookStack\Services\ExportService;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
@ -18,18 +19,21 @@ class PageController extends Controller
|
|||||||
protected $pageRepo;
|
protected $pageRepo;
|
||||||
protected $bookRepo;
|
protected $bookRepo;
|
||||||
protected $chapterRepo;
|
protected $chapterRepo;
|
||||||
|
protected $exportService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PageController constructor.
|
* PageController constructor.
|
||||||
* @param PageRepo $pageRepo
|
* @param PageRepo $pageRepo
|
||||||
* @param BookRepo $bookRepo
|
* @param BookRepo $bookRepo
|
||||||
* @param ChapterRepo $chapterRepo
|
* @param ChapterRepo $chapterRepo
|
||||||
|
* @param ExportService $exportService
|
||||||
*/
|
*/
|
||||||
public function __construct(PageRepo $pageRepo, BookRepo $bookRepo, ChapterRepo $chapterRepo)
|
public function __construct(PageRepo $pageRepo, BookRepo $bookRepo, ChapterRepo $chapterRepo, ExportService $exportService)
|
||||||
{
|
{
|
||||||
$this->pageRepo = $pageRepo;
|
$this->pageRepo = $pageRepo;
|
||||||
$this->bookRepo = $bookRepo;
|
$this->bookRepo = $bookRepo;
|
||||||
$this->chapterRepo = $chapterRepo;
|
$this->chapterRepo = $chapterRepo;
|
||||||
|
$this->exportService = $exportService;
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,4 +225,30 @@ class PageController extends Controller
|
|||||||
Activity::add($page, 'page_restore', $book->id);
|
Activity::add($page, 'page_restore', $book->id);
|
||||||
return redirect($page->getUrl());
|
return redirect($page->getUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function exportPdf($bookSlug, $pageSlug)
|
||||||
|
{
|
||||||
|
$book = $this->bookRepo->getBySlug($bookSlug);
|
||||||
|
$page = $this->pageRepo->getBySlug($pageSlug, $book->id);
|
||||||
|
$cssContent = file_get_contents(public_path('/css/styles.css'));
|
||||||
|
|
||||||
|
return $pdf->download($pageSlug . '.pdf');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export a page to a self-contained HTML file.
|
||||||
|
* @param $bookSlug
|
||||||
|
* @param $pageSlug
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function exportHtml($bookSlug, $pageSlug)
|
||||||
|
{
|
||||||
|
$book = $this->bookRepo->getBySlug($bookSlug);
|
||||||
|
$page = $this->pageRepo->getBySlug($pageSlug, $book->id);
|
||||||
|
$containedHtml = $this->exportService->pageToContainedHtml($page);
|
||||||
|
return response()->make($containedHtml, 200, [
|
||||||
|
'Content-Type' => 'application/octet-stream',
|
||||||
|
'Content-Disposition' => 'attachment; filename="'.$pageSlug.'.html'
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,11 +18,12 @@ Route::group(['middleware' => 'auth'], function () {
|
|||||||
Route::get('/{bookSlug}/sort', 'BookController@sort');
|
Route::get('/{bookSlug}/sort', 'BookController@sort');
|
||||||
Route::put('/{bookSlug}/sort', 'BookController@saveSort');
|
Route::put('/{bookSlug}/sort', 'BookController@saveSort');
|
||||||
|
|
||||||
|
|
||||||
// Pages
|
// Pages
|
||||||
Route::get('/{bookSlug}/page/create', 'PageController@create');
|
Route::get('/{bookSlug}/page/create', 'PageController@create');
|
||||||
Route::post('/{bookSlug}/page', 'PageController@store');
|
Route::post('/{bookSlug}/page', 'PageController@store');
|
||||||
Route::get('/{bookSlug}/page/{pageSlug}', 'PageController@show');
|
Route::get('/{bookSlug}/page/{pageSlug}', 'PageController@show');
|
||||||
|
Route::get('/{bookSlug}/page/{pageSlug}/export/pdf', 'PageController@exportPdf');
|
||||||
|
Route::get('/{bookSlug}/page/{pageSlug}/export/html', 'PageController@exportHtml');
|
||||||
Route::get('/{bookSlug}/page/{pageSlug}/edit', 'PageController@edit');
|
Route::get('/{bookSlug}/page/{pageSlug}/edit', 'PageController@edit');
|
||||||
Route::get('/{bookSlug}/page/{pageSlug}/delete', 'PageController@showDelete');
|
Route::get('/{bookSlug}/page/{pageSlug}/delete', 'PageController@showDelete');
|
||||||
Route::put('/{bookSlug}/page/{pageSlug}', 'PageController@update');
|
Route::put('/{bookSlug}/page/{pageSlug}', 'PageController@update');
|
||||||
|
61
app/Services/ExportService.php
Normal file
61
app/Services/ExportService.php
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<?php namespace BookStack\Services;
|
||||||
|
|
||||||
|
|
||||||
|
use BookStack\Page;
|
||||||
|
|
||||||
|
class ExportService
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a page to a self-contained HTML file.
|
||||||
|
* Includes required CSS & image content. Images are base64 encoded into the HTML.
|
||||||
|
* @param Page $page
|
||||||
|
* @return mixed|string
|
||||||
|
*/
|
||||||
|
public function pageToContainedHtml(Page $page)
|
||||||
|
{
|
||||||
|
$cssContent = file_get_contents(public_path('/css/export-styles.css'));
|
||||||
|
$pageHtml = view('pages/pdf', ['page' => $page, 'css' => $cssContent])->render();
|
||||||
|
|
||||||
|
$imageTagsOutput = [];
|
||||||
|
preg_match_all("/\<img.*src\=(\'|\")(.*?)(\'|\").*?\>/i", $pageHtml, $imageTagsOutput);
|
||||||
|
|
||||||
|
// Replace image src with base64 encoded image strings
|
||||||
|
if (isset($imageTagsOutput[0]) && count($imageTagsOutput[0]) > 0) {
|
||||||
|
foreach ($imageTagsOutput[0] as $index => $imgMatch) {
|
||||||
|
$oldImgString = $imgMatch;
|
||||||
|
$srcString = $imageTagsOutput[2][$index];
|
||||||
|
if (strpos(trim($srcString), 'http') !== 0) {
|
||||||
|
$pathString = public_path($srcString);
|
||||||
|
} else {
|
||||||
|
$pathString = $srcString;
|
||||||
|
}
|
||||||
|
$imageContent = file_get_contents($pathString);
|
||||||
|
$imageEncoded = 'data:image/' . pathinfo($pathString, PATHINFO_EXTENSION) . ';base64,' . base64_encode($imageContent);
|
||||||
|
$newImageString = str_replace($srcString, $imageEncoded, $oldImgString);
|
||||||
|
$pageHtml = str_replace($oldImgString, $newImageString, $pageHtml);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$linksOutput = [];
|
||||||
|
preg_match_all("/\<a.*href\=(\'|\")(.*?)(\'|\").*?\>/i", $pageHtml, $linksOutput);
|
||||||
|
|
||||||
|
// Replace image src with base64 encoded image strings
|
||||||
|
if (isset($linksOutput[0]) && count($linksOutput[0]) > 0) {
|
||||||
|
foreach ($linksOutput[0] as $index => $linkMatch) {
|
||||||
|
$oldLinkString = $linkMatch;
|
||||||
|
$srcString = $linksOutput[2][$index];
|
||||||
|
if (strpos(trim($srcString), 'http') !== 0) {
|
||||||
|
$newSrcString = url($srcString);
|
||||||
|
$newLinkString = str_replace($srcString, $newSrcString, $oldLinkString);
|
||||||
|
$pageHtml = str_replace($oldLinkString, $newLinkString, $pageHtml);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace any relative links with system domain
|
||||||
|
return $pageHtml;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
32
composer.lock
generated
32
composer.lock
generated
@ -9,16 +9,16 @@
|
|||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "aws/aws-sdk-php",
|
"name": "aws/aws-sdk-php",
|
||||||
"version": "3.12.1",
|
"version": "3.13.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/aws/aws-sdk-php.git",
|
"url": "https://github.com/aws/aws-sdk-php.git",
|
||||||
"reference": "5ee0f33fafe47740c03ff38ddb73ae4f52b4da5b"
|
"reference": "cc1796d1c21146cdcbfb7628aee816acb7b85e09"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/5ee0f33fafe47740c03ff38ddb73ae4f52b4da5b",
|
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/cc1796d1c21146cdcbfb7628aee816acb7b85e09",
|
||||||
"reference": "5ee0f33fafe47740c03ff38ddb73ae4f52b4da5b",
|
"reference": "cc1796d1c21146cdcbfb7628aee816acb7b85e09",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -40,7 +40,7 @@
|
|||||||
"ext-simplexml": "*",
|
"ext-simplexml": "*",
|
||||||
"ext-spl": "*",
|
"ext-spl": "*",
|
||||||
"nette/neon": "^2.3",
|
"nette/neon": "^2.3",
|
||||||
"phpunit/phpunit": "~4.0"
|
"phpunit/phpunit": "~4.0|~5.0"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"aws/aws-php-sns-message-validator": "To validate incoming SNS notifications",
|
"aws/aws-php-sns-message-validator": "To validate incoming SNS notifications",
|
||||||
@ -84,7 +84,7 @@
|
|||||||
"s3",
|
"s3",
|
||||||
"sdk"
|
"sdk"
|
||||||
],
|
],
|
||||||
"time": "2016-01-06 22:50:48"
|
"time": "2016-01-19 22:46:22"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "barryvdh/laravel-debugbar",
|
"name": "barryvdh/laravel-debugbar",
|
||||||
@ -829,16 +829,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "laravel/framework",
|
"name": "laravel/framework",
|
||||||
"version": "v5.2.7",
|
"version": "v5.2.10",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/laravel/framework.git",
|
"url": "https://github.com/laravel/framework.git",
|
||||||
"reference": "26cd65eaa4bcc0fb0be381cfb7cfdcda06a3c2b4"
|
"reference": "93dc5b0089eef468157fd7200e575c3861ec59a5"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/laravel/framework/zipball/26cd65eaa4bcc0fb0be381cfb7cfdcda06a3c2b4",
|
"url": "https://api.github.com/repos/laravel/framework/zipball/93dc5b0089eef468157fd7200e575c3861ec59a5",
|
||||||
"reference": "26cd65eaa4bcc0fb0be381cfb7cfdcda06a3c2b4",
|
"reference": "93dc5b0089eef468157fd7200e575c3861ec59a5",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -953,7 +953,7 @@
|
|||||||
"framework",
|
"framework",
|
||||||
"laravel"
|
"laravel"
|
||||||
],
|
],
|
||||||
"time": "2016-01-07 13:54:34"
|
"time": "2016-01-13 20:29:10"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "laravel/socialite",
|
"name": "laravel/socialite",
|
||||||
@ -1849,16 +1849,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/class-loader",
|
"name": "symfony/class-loader",
|
||||||
"version": "v2.8.1",
|
"version": "v2.8.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/class-loader.git",
|
"url": "https://github.com/symfony/class-loader.git",
|
||||||
"reference": "ec74b0a279cf3a9bd36172b3e3061591d380ce6c"
|
"reference": "98e9089a428ed0e39423b67352c57ef5910a3269"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/class-loader/zipball/ec74b0a279cf3a9bd36172b3e3061591d380ce6c",
|
"url": "https://api.github.com/repos/symfony/class-loader/zipball/98e9089a428ed0e39423b67352c57ef5910a3269",
|
||||||
"reference": "ec74b0a279cf3a9bd36172b3e3061591d380ce6c",
|
"reference": "98e9089a428ed0e39423b67352c57ef5910a3269",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -1897,7 +1897,7 @@
|
|||||||
],
|
],
|
||||||
"description": "Symfony ClassLoader Component",
|
"description": "Symfony ClassLoader Component",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"time": "2015-12-05 17:37:59"
|
"time": "2016-01-03 15:33:41"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/console",
|
"name": "symfony/console",
|
||||||
|
@ -21,6 +21,7 @@ elixir.extend('queryVersion', function(inputFiles) {
|
|||||||
elixir(function(mix) {
|
elixir(function(mix) {
|
||||||
mix.sass('styles.scss')
|
mix.sass('styles.scss')
|
||||||
.sass('print-styles.scss')
|
.sass('print-styles.scss')
|
||||||
|
.sass('export-styles.scss')
|
||||||
.browserify('global.js', 'public/js/common.js')
|
.browserify('global.js', 'public/js/common.js')
|
||||||
.queryVersion(['css/styles.css', 'css/print-styles.css', 'js/common.js']);
|
.queryVersion(['css/styles.css', 'css/print-styles.css', 'js/common.js']);
|
||||||
});
|
});
|
||||||
|
96
resources/assets/sass/_fonts.scss
Normal file
96
resources/assets/sass/_fonts.scss
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/* Generated by Font Squirrel (http://www.fontsquirrel.com) on December 30, 2015 */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
src: url('/fonts/roboto-bold-webfont.eot');
|
||||||
|
src: url('/fonts/roboto-bold-webfont.eot?#iefix') format('embedded-opentype'),
|
||||||
|
url('/fonts/roboto-bold-webfont.woff2') format('woff2'),
|
||||||
|
url('/fonts/roboto-bold-webfont.woff') format('woff'),
|
||||||
|
url('/fonts/roboto-bold-webfont.ttf') format('truetype'),
|
||||||
|
url('/fonts/roboto-bold-webfont.svg#robotobold') format('svg');
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
src: url('/fonts/roboto-bolditalic-webfont.eot');
|
||||||
|
src: url('/fonts/roboto-bolditalic-webfont.eot?#iefix') format('embedded-opentype'),
|
||||||
|
url('/fonts/roboto-bolditalic-webfont.woff2') format('woff2'),
|
||||||
|
url('/fonts/roboto-bolditalic-webfont.woff') format('woff'),
|
||||||
|
url('/fonts/roboto-bolditalic-webfont.ttf') format('truetype'),
|
||||||
|
url('/fonts/roboto-bolditalic-webfont.svg#robotobold_italic') format('svg');
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
src: url('/fonts/roboto-italic-webfont.eot');
|
||||||
|
src: url('/fonts/roboto-italic-webfont.eot?#iefix') format('embedded-opentype'),
|
||||||
|
url('/fonts/roboto-italic-webfont.woff2') format('woff2'),
|
||||||
|
url('/fonts/roboto-italic-webfont.woff') format('woff'),
|
||||||
|
url('/fonts/roboto-italic-webfont.ttf') format('truetype'),
|
||||||
|
url('/fonts/roboto-italic-webfont.svg#robotoitalic') format('svg');
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
src: url('/fonts/roboto-light-webfont.eot');
|
||||||
|
src: url('/fonts/roboto-light-webfont.eot?#iefix') format('embedded-opentype'),
|
||||||
|
url('/fonts/roboto-light-webfont.woff2') format('woff2'),
|
||||||
|
url('/fonts/roboto-light-webfont.woff') format('woff'),
|
||||||
|
url('/fonts/roboto-light-webfont.ttf') format('truetype'),
|
||||||
|
url('/fonts/roboto-light-webfont.svg#robotolight') format('svg');
|
||||||
|
font-weight: 300;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
src: url('/fonts/roboto-lightitalic-webfont.eot');
|
||||||
|
src: url('/fonts/roboto-lightitalic-webfont.eot?#iefix') format('embedded-opentype'),
|
||||||
|
url('/fonts/roboto-lightitalic-webfont.woff2') format('woff2'),
|
||||||
|
url('/fonts/roboto-lightitalic-webfont.woff') format('woff'),
|
||||||
|
url('/fonts/roboto-lightitalic-webfont.ttf') format('truetype'),
|
||||||
|
url('/fonts/roboto-lightitalic-webfont.svg#robotolight_italic') format('svg');
|
||||||
|
font-weight: 300;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
src: url('/fonts/roboto-medium-webfont.eot');
|
||||||
|
src: url('/fonts/roboto-medium-webfont.eot?#iefix') format('embedded-opentype'),
|
||||||
|
url('/fonts/roboto-medium-webfont.woff2') format('woff2'),
|
||||||
|
url('/fonts/roboto-medium-webfont.woff') format('woff'),
|
||||||
|
url('/fonts/roboto-medium-webfont.ttf') format('truetype'),
|
||||||
|
url('/fonts/roboto-medium-webfont.svg#robotomedium') format('svg');
|
||||||
|
font-weight: 500;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
src: url('/fonts/roboto-mediumitalic-webfont.eot');
|
||||||
|
src: url('/fonts/roboto-mediumitalic-webfont.eot?#iefix') format('embedded-opentype'),
|
||||||
|
url('/fonts/roboto-mediumitalic-webfont.woff2') format('woff2'),
|
||||||
|
url('/fonts/roboto-mediumitalic-webfont.woff') format('woff'),
|
||||||
|
url('/fonts/roboto-mediumitalic-webfont.ttf') format('truetype'),
|
||||||
|
url('/fonts/roboto-mediumitalic-webfont.svg#robotomedium_italic') format('svg');
|
||||||
|
font-weight: 500;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
src: url('/fonts/roboto-regular-webfont.eot');
|
||||||
|
src: url('/fonts/roboto-regular-webfont.eot?#iefix') format('embedded-opentype'),
|
||||||
|
url('/fonts/roboto-regular-webfont.woff2') format('woff2'),
|
||||||
|
url('/fonts/roboto-regular-webfont.woff') format('woff'),
|
||||||
|
url('/fonts/roboto-regular-webfont.ttf') format('truetype'),
|
||||||
|
url('/fonts/roboto-regular-webfont.svg#robotoregular') format('svg');
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
@ -187,7 +187,7 @@ form.search-box {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.faded {
|
.faded {
|
||||||
a, button, span {
|
a, button, span, span > div {
|
||||||
color: #666;
|
color: #666;
|
||||||
}
|
}
|
||||||
.text-button {
|
.text-button {
|
||||||
|
@ -52,101 +52,3 @@ $text-light: #EEE;
|
|||||||
$bs-light: 0 0 4px 1px #CCC;
|
$bs-light: 0 0 4px 1px #CCC;
|
||||||
$bs-med: 0 1px 3px 1px rgba(76, 76, 76, 0.26);
|
$bs-med: 0 1px 3px 1px rgba(76, 76, 76, 0.26);
|
||||||
$bs-hover: 0 2px 2px 1px rgba(0,0,0,.13);
|
$bs-hover: 0 2px 2px 1px rgba(0,0,0,.13);
|
||||||
|
|
||||||
|
|
||||||
/* Generated by Font Squirrel (http://www.fontsquirrel.com) on December 30, 2015 */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
src: url('/fonts/roboto-bold-webfont.eot');
|
|
||||||
src: url('/fonts/roboto-bold-webfont.eot?#iefix') format('embedded-opentype'),
|
|
||||||
url('/fonts/roboto-bold-webfont.woff2') format('woff2'),
|
|
||||||
url('/fonts/roboto-bold-webfont.woff') format('woff'),
|
|
||||||
url('/fonts/roboto-bold-webfont.ttf') format('truetype'),
|
|
||||||
url('/fonts/roboto-bold-webfont.svg#robotobold') format('svg');
|
|
||||||
font-weight: bold;
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
src: url('/fonts/roboto-bolditalic-webfont.eot');
|
|
||||||
src: url('/fonts/roboto-bolditalic-webfont.eot?#iefix') format('embedded-opentype'),
|
|
||||||
url('/fonts/roboto-bolditalic-webfont.woff2') format('woff2'),
|
|
||||||
url('/fonts/roboto-bolditalic-webfont.woff') format('woff'),
|
|
||||||
url('/fonts/roboto-bolditalic-webfont.ttf') format('truetype'),
|
|
||||||
url('/fonts/roboto-bolditalic-webfont.svg#robotobold_italic') format('svg');
|
|
||||||
font-weight: bold;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
src: url('/fonts/roboto-italic-webfont.eot');
|
|
||||||
src: url('/fonts/roboto-italic-webfont.eot?#iefix') format('embedded-opentype'),
|
|
||||||
url('/fonts/roboto-italic-webfont.woff2') format('woff2'),
|
|
||||||
url('/fonts/roboto-italic-webfont.woff') format('woff'),
|
|
||||||
url('/fonts/roboto-italic-webfont.ttf') format('truetype'),
|
|
||||||
url('/fonts/roboto-italic-webfont.svg#robotoitalic') format('svg');
|
|
||||||
font-weight: normal;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
src: url('/fonts/roboto-light-webfont.eot');
|
|
||||||
src: url('/fonts/roboto-light-webfont.eot?#iefix') format('embedded-opentype'),
|
|
||||||
url('/fonts/roboto-light-webfont.woff2') format('woff2'),
|
|
||||||
url('/fonts/roboto-light-webfont.woff') format('woff'),
|
|
||||||
url('/fonts/roboto-light-webfont.ttf') format('truetype'),
|
|
||||||
url('/fonts/roboto-light-webfont.svg#robotolight') format('svg');
|
|
||||||
font-weight: 300;
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
src: url('/fonts/roboto-lightitalic-webfont.eot');
|
|
||||||
src: url('/fonts/roboto-lightitalic-webfont.eot?#iefix') format('embedded-opentype'),
|
|
||||||
url('/fonts/roboto-lightitalic-webfont.woff2') format('woff2'),
|
|
||||||
url('/fonts/roboto-lightitalic-webfont.woff') format('woff'),
|
|
||||||
url('/fonts/roboto-lightitalic-webfont.ttf') format('truetype'),
|
|
||||||
url('/fonts/roboto-lightitalic-webfont.svg#robotolight_italic') format('svg');
|
|
||||||
font-weight: 300;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
src: url('/fonts/roboto-medium-webfont.eot');
|
|
||||||
src: url('/fonts/roboto-medium-webfont.eot?#iefix') format('embedded-opentype'),
|
|
||||||
url('/fonts/roboto-medium-webfont.woff2') format('woff2'),
|
|
||||||
url('/fonts/roboto-medium-webfont.woff') format('woff'),
|
|
||||||
url('/fonts/roboto-medium-webfont.ttf') format('truetype'),
|
|
||||||
url('/fonts/roboto-medium-webfont.svg#robotomedium') format('svg');
|
|
||||||
font-weight: 500;
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
src: url('/fonts/roboto-mediumitalic-webfont.eot');
|
|
||||||
src: url('/fonts/roboto-mediumitalic-webfont.eot?#iefix') format('embedded-opentype'),
|
|
||||||
url('/fonts/roboto-mediumitalic-webfont.woff2') format('woff2'),
|
|
||||||
url('/fonts/roboto-mediumitalic-webfont.woff') format('woff'),
|
|
||||||
url('/fonts/roboto-mediumitalic-webfont.ttf') format('truetype'),
|
|
||||||
url('/fonts/roboto-mediumitalic-webfont.svg#robotomedium_italic') format('svg');
|
|
||||||
font-weight: 500;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
src: url('/fonts/roboto-regular-webfont.eot');
|
|
||||||
src: url('/fonts/roboto-regular-webfont.eot?#iefix') format('embedded-opentype'),
|
|
||||||
url('/fonts/roboto-regular-webfont.woff2') format('woff2'),
|
|
||||||
url('/fonts/roboto-regular-webfont.woff') format('woff'),
|
|
||||||
url('/fonts/roboto-regular-webfont.ttf') format('truetype'),
|
|
||||||
url('/fonts/roboto-regular-webfont.svg#robotoregular') format('svg');
|
|
||||||
font-weight: normal;
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
|
12
resources/assets/sass/export-styles.scss
Normal file
12
resources/assets/sass/export-styles.scss
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
@import "reset";
|
||||||
|
@import "variables";
|
||||||
|
@import "mixins";
|
||||||
|
@import "html";
|
||||||
|
@import "text";
|
||||||
|
@import "grid";
|
||||||
|
@import "blocks";
|
||||||
|
@import "forms";
|
||||||
|
@import "tables";
|
||||||
|
@import "header";
|
||||||
|
@import "lists";
|
||||||
|
@import "pages";
|
@ -1,5 +1,6 @@
|
|||||||
@import "reset";
|
@import "reset";
|
||||||
@import "variables";
|
@import "variables";
|
||||||
|
@import "fonts";
|
||||||
@import "mixins";
|
@import "mixins";
|
||||||
@import "html";
|
@import "html";
|
||||||
@import "text";
|
@import "text";
|
||||||
|
32
resources/views/pages/pdf.blade.php
Normal file
32
resources/views/pages/pdf.blade.php
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>{{ $page->name }}</title>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
{!! $css !!}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container" id="page-show" ng-non-bindable>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-8 col-md-offset-2">
|
||||||
|
<div class="page-content">
|
||||||
|
|
||||||
|
@include('pages/page-display')
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<p class="text-muted small">
|
||||||
|
Created {{$page->created_at->diffForHumans()}} @if($page->createdBy) by {{$page->createdBy->name}} @endif
|
||||||
|
<br>
|
||||||
|
Last Updated {{$page->updated_at->diffForHumans()}} @if($page->updatedBy) by {{$page->updatedBy->name}} @endif
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -19,6 +19,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6 faded">
|
<div class="col-sm-6 faded">
|
||||||
<div class="action-buttons">
|
<div class="action-buttons">
|
||||||
|
<span dropdown class="dropdown-container">
|
||||||
|
<div dropdown-toggle class="text-button text-primary"><i class="zmdi zmdi-open-in-new"></i>Export Page</div>
|
||||||
|
<ul>
|
||||||
|
<li><a href="{{$page->getUrl() . '/export/html'}}" target="_blank">Contained HTML File</a></li>
|
||||||
|
</ul>
|
||||||
|
</span>
|
||||||
@if($currentUser->can('page-update'))
|
@if($currentUser->can('page-update'))
|
||||||
<a href="{{$page->getUrl() . '/revisions'}}" class="text-primary text-button"><i class="zmdi zmdi-replay"></i>Revisions</a>
|
<a href="{{$page->getUrl() . '/revisions'}}" class="text-primary text-button"><i class="zmdi zmdi-replay"></i>Revisions</a>
|
||||||
<a href="{{$page->getUrl() . '/edit'}}" class="text-primary text-button" ><i class="zmdi zmdi-edit"></i>Edit</a>
|
<a href="{{$page->getUrl() . '/edit'}}" class="text-primary text-button" ><i class="zmdi zmdi-edit"></i>Edit</a>
|
||||||
|
Loading…
Reference in New Issue
Block a user