$recentFactor = count($draftPages) > 0 ? 0.5 : 1;
$recents = $this->signedIn ? Views::getUserRecentlyViewed(12*$recentFactor, 0) : $this->entityRepo->getRecentlyCreated('book', 12*$recentFactor);
$recentlyUpdatedPages = $this->entityRepo->getRecentlyUpdated('page', 12);
- return view('home', [
+
+ // Custom homepage
+ $customHomepage = false;
+ $homepageSetting = setting('app-homepage');
+ if ($homepageSetting) {
+ $id = intval(explode(':', $homepageSetting)[0]);
+ $customHomepage = $this->entityRepo->getById('page', $id);
+ $this->entityRepo->renderPage($customHomepage);
+ }
+
+ $view = $customHomepage ? 'home-custom' : 'home';
+ return view($view, [
'activity' => $activity,
'recents' => $recents,
'recentlyUpdatedPages' => $recentlyUpdatedPages,
- 'draftPages' => $draftPages
+ 'draftPages' => $draftPages,
+ 'customHomepage' => $customHomepage
]);
}
return view('pages/show', [
'page' => $page,'book' => $page->book,
'current' => $page, 'sidebarTree' => $sidebarTree,
- 'pageNav' => $pageNav, 'pageContent' => $pageContent]);
+ 'pageNav' => $pageNav]);
}
/**
$content = str_replace($matches[0][$index], trim($innerContent), $content);
}
+ $page->renderedHTML = $content;
return $content;
}
*/
public function pageToContainedHtml(Page $page)
{
+ $this->entityRepo->renderPage($page);
$pageHtml = view('pages/export', [
- 'page' => $page,
- 'pageContent' => $this->entityRepo->renderPage($page)
+ 'page' => $page
])->render();
return $this->containHtml($pageHtml);
}
*/
public function pageToPdf(Page $page)
{
+ $this->entityRepo->renderPage($page);
$html = view('pages/pdf', [
- 'page' => $page,
- 'pageContent' => $this->entityRepo->renderPage($page)
+ 'page' => $page
])->render();
return $this->htmlToPdf($html);
}
$query->whereIn('viewable_type', $filterModel);
} else if ($filterModel) {
$query->where('viewable_type', '=', get_class($filterModel));
- };
+ }
return $query->with('viewable')->skip($skipCount)->take($count)->get()->pluck('viewable');
}
onClick(event) {
let t = event.target;
+ console.log('click', t);
- if (t.matches('.entity-list a')) {
+ if (t.matches('.entity-list-item *')) {
event.preventDefault();
event.stopPropagation();
let item = t.closest('[data-entity-type]');
let isDblClick = this.isDoubleClick();
let type = item.getAttribute('data-entity-type');
let id = item.getAttribute('data-entity-id');
- let isSelected = item.classList.contains('selected') || isDblClick;
+ let isSelected = !item.classList.contains('selected') || isDblClick;
this.unselectAll();
this.input.value = isSelected ? `${type}:${id}` : '';
if (!isSelected) window.$events.emit('entity-select-change', null);
+ if (isSelected) {
+ item.classList.add('selected');
+ item.classList.add('primary-background');
+ }
if (!isDblClick && !isSelected) return;
let link = item.querySelector('.entity-list-item-link').getAttribute('href');
'entity-selector-popup': require('./entity-selector-popup'),
'entity-selector': require('./entity-selector'),
'sidebar': require('./sidebar'),
+ 'page-picker': require('./page-picker'),
};
window.components = {};
--- /dev/null
+
+class PagePicker {
+
+ constructor(elem) {
+ this.elem = elem;
+ this.input = elem.querySelector('input');
+ this.resetButton = elem.querySelector('[page-picker-reset]');
+ this.selectButton = elem.querySelector('[page-picker-select]');
+ this.display = elem.querySelector('[page-picker-display]');
+ this.defaultDisplay = elem.querySelector('[page-picker-default]');
+ this.buttonSep = elem.querySelector('span.sep');
+
+ this.value = this.input.value;
+ this.setupListeners();
+ }
+
+ setupListeners() {
+ // Select click
+ this.selectButton.addEventListener('click', event => {
+ window.EntitySelectorPopup.show(entity => {
+ this.setValue(entity.id, entity.name);
+ });
+ });
+
+ this.resetButton.addEventListener('click', event => {
+ this.setValue('', '');
+ });
+ }
+
+ setValue(value, name) {
+ this.value = value;
+ this.input.value = value;
+ this.controlView(name);
+ }
+
+ controlView(name) {
+ let hasValue = this.value && this.value !== 0;
+ toggleElem(this.resetButton, hasValue);
+ toggleElem(this.buttonSep, hasValue);
+ toggleElem(this.defaultDisplay, !hasValue);
+ toggleElem(this.display, hasValue);
+ if (hasValue) {
+ let id = this.getAssetIdFromVal();
+ this.display.textContent = `#${id}, ${name}`;
+ this.display.href = window.baseUrl(`/link/${id}`);
+ }
+ }
+
+ getAssetIdFromVal() {
+ return Number(this.value);
+ }
+
+}
+
+function toggleElem(elem, show) {
+ let display = (elem.tagName === 'BUTTON' || elem.tagName === 'SPAN') ? 'inline-block' : 'block';
+ elem.style.display = show ? display : 'none';
+}
+
+module.exports = PagePicker;
\ No newline at end of file
}
}
+.fake-input {
+ @extend .input-base;
+ overflow: auto;
+}
+
#html-editor {
display: none;
}
'app_logo_desc' => 'This image should be 43px in height. <br>Large images will be scaled down.',
'app_primary_color' => 'Application primary color',
'app_primary_color_desc' => 'This should be a hex value. <br>Leave empty to reset to the default color.',
+ 'app_homepage' => 'Application Homepage',
+ 'app_homepage_desc' => 'Select a page to show on the homepage instead of the default view. Page permissions are ignored for selected pages.',
+ 'app_homepage_default' => 'Default homepage view chosen',
/**
* Registration settings
--- /dev/null
+
+{{--Depends on entity selector popup--}}
+<div page-picker>
+ <div class="input-base">
+ <span @if($value) style="display: none" @endif page-picker-default class="text-muted italic">{{ $placeholder }}</span>
+ <a @if(!$value) style="display: none" @endif href="{{ baseUrl('/link/' . $value) }}" target="_blank" class="text-page" page-picker-display>#{{$value}}, {{$value ? \BookStack\Page::find($value)->name : '' }}</a>
+ </div>
+ <br>
+ <input type="hidden" value="{{$value}}" name="{{$name}}" id="{{$name}}">
+ <button @if(!$value) style="display: none" @endif type="button" page-picker-reset class="text-button">{{ trans('common.reset') }}</button>
+ <span @if(!$value) style="display: none" @endif class="sep">|</span>
+ <button type="button" page-picker-select class="text-button">{{ trans('common.select') }}</button>
+</div>
\ No newline at end of file
--- /dev/null
+@extends('sidebar-layout')
+
+@section('toolbar')
+ <div class="col-sm-6 faded">
+ <div class="action-buttons text-left">
+ <a expand-toggle=".entity-list.compact .entity-item-snippet" class="text-primary text-button"><i class="zmdi zmdi-wrap-text"></i>{{ trans('common.toggle_details') }}</a>
+ </div>
+ </div>
+@stop
+
+@section('sidebar')
+ @if(count($draftPages) > 0)
+ <div id="recent-drafts" class="card">
+ <h3><i class="zmdi zmdi-edit"></i> {{ trans('entities.my_recent_drafts') }}</h3>
+ @include('partials/entity-list', ['entities' => $draftPages, 'style' => 'compact'])
+ </div>
+ @endif
+
+ <div class="card">
+ <h3><i class="zmdi zmdi-{{ $signedIn ? 'eye' : 'star-circle' }}"></i> {{ trans('entities.' . ($signedIn ? 'my_recently_viewed' : 'books_recent')) }}</h3>
+ @include('partials/entity-list', [
+ 'entities' => $recents,
+ 'style' => 'compact',
+ 'emptyText' => $signedIn ? trans('entities.no_pages_viewed') : trans('entities.books_empty')
+ ])
+ </div>
+
+ <div class="card">
+ <h3><i class="zmdi zmdi-file"></i> <a class="no-color" href="{{ baseUrl("/pages/recently-updated") }}">{{ trans('entities.recently_updated_pages') }}</a></h3>
+ <div id="recently-updated-pages">
+ @include('partials/entity-list', [
+ 'entities' => $recentlyUpdatedPages,
+ 'style' => 'compact',
+ 'emptyText' => trans('entities.no_pages_recently_updated')
+ ])
+ </div>
+ </div>
+
+ <div id="recent-activity" class="card">
+ <h3><i class="zmdi zmdi-time"></i> {{ trans('entities.recent_activity') }}</h3>
+ @include('partials/activity-list', ['activity' => $activity])
+ </div>
+@stop
+
+@section('body')
+ <div class="page-content" ng-non-bindable>
+ @include('pages/page-display', ['page' => $customHomepage])
+ </div>
+@stop
+
+@section('scripts')
+ <script>
+ setupPageShow({{$customHomepage->id}});
+ </script>
+@stop
+
@if (isset($diff) && $diff)
{!! $diff !!}
@else
- {!! isset($pageContent) ? $pageContent : $page->html !!}
+ {!! isset($page->renderedHTML) ? $page->renderedHTML : $page->html !!}
@endif
</div>
\ No newline at end of file
<input type="text" value="{{ setting('app-color') }}" name="setting-app-color" id="setting-app-color" placeholder="#0288D1">
<input type="hidden" value="{{ setting('app-color-light') }}" name="setting-app-color-light" id="setting-app-color-light">
</div>
+ <div class="form-group" id="homepage-control">
+ <label for="setting-app-homepage">{{ trans('settings.app_homepage') }}</label>
+ <p class="small">{{ trans('settings.app_homepage_desc') }}</p>
+ @include('components.page-picker', ['name' => 'setting-app-homepage', 'placeholder' => trans('settings.app_homepage_default'), 'value' => setting('app-homepage')])
+ </div>
</div>
</div>
</div>
@include('components.image-manager', ['imageType' => 'system'])
+@include('components.entity-selector-popup', ['entityTypes' => 'page'])
@stop