mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-11-24 03:21:33 +08:00
Merge pull request #3698 from BookStackApp/include_theme_event
Added "page_include_parse" theme event
This commit is contained in:
commit
b9941e8e61
|
@ -5,6 +5,8 @@ namespace BookStack\Entities\Tools;
|
|||
use BookStack\Entities\Models\Page;
|
||||
use BookStack\Entities\Tools\Markdown\MarkdownToHtml;
|
||||
use BookStack\Exceptions\ImageUploadException;
|
||||
use BookStack\Facades\Theme;
|
||||
use BookStack\Theming\ThemeEvents;
|
||||
use BookStack\Uploads\ImageRepo;
|
||||
use BookStack\Uploads\ImageService;
|
||||
use BookStack\Util\HtmlContentFilter;
|
||||
|
@ -372,23 +374,30 @@ class PageContent
|
|||
continue;
|
||||
}
|
||||
|
||||
// Find page and skip this if page not found
|
||||
// Find page to use, and default replacement to empty string for non-matches.
|
||||
/** @var ?Page $matchedPage */
|
||||
$matchedPage = Page::visible()->find($pageId);
|
||||
if ($matchedPage === null) {
|
||||
$html = str_replace($fullMatch, '', $html);
|
||||
continue;
|
||||
$replacement = '';
|
||||
|
||||
if ($matchedPage && count($splitInclude) === 1) {
|
||||
// If we only have page id, just insert all page html and continue.
|
||||
$replacement = $matchedPage->html;
|
||||
} else if ($matchedPage && count($splitInclude) > 1) {
|
||||
// Otherwise, if our include tag defines a section, load that specific content
|
||||
$innerContent = $this->fetchSectionOfPage($matchedPage, $splitInclude[1]);
|
||||
$replacement = trim($innerContent);
|
||||
}
|
||||
|
||||
// If we only have page id, just insert all page html and continue.
|
||||
if (count($splitInclude) === 1) {
|
||||
$html = str_replace($fullMatch, $matchedPage->html, $html);
|
||||
continue;
|
||||
}
|
||||
$themeReplacement = Theme::dispatch(
|
||||
ThemeEvents::PAGE_INCLUDE_PARSE,
|
||||
$includeId,
|
||||
$replacement,
|
||||
clone $this->page,
|
||||
$matchedPage ? (clone $matchedPage) : null,
|
||||
);
|
||||
|
||||
// Create and load HTML into a document
|
||||
$innerContent = $this->fetchSectionOfPage($matchedPage, $splitInclude[1]);
|
||||
$html = str_replace($fullMatch, trim($innerContent), $html);
|
||||
// Perform the content replacement
|
||||
$html = str_replace($fullMatch, $themeReplacement ?? $replacement, $html);
|
||||
}
|
||||
|
||||
return $html;
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace BookStack\Theming;
|
||||
|
||||
use BookStack\Entities\Models\Page;
|
||||
|
||||
/**
|
||||
* The ThemeEvents used within BookStack.
|
||||
*
|
||||
|
@ -60,8 +62,7 @@ class ThemeEvents
|
|||
|
||||
/**
|
||||
* Commonmark environment configure.
|
||||
* Provides the commonmark library environment for customization
|
||||
* before it's used to render markdown content.
|
||||
* Provides the commonmark library environment for customization before it's used to render markdown content.
|
||||
* If the listener returns a non-null value, that will be used as an environment instead.
|
||||
*
|
||||
* @param \League\CommonMark\ConfigurableEnvironmentInterface $environment
|
||||
|
@ -69,6 +70,21 @@ class ThemeEvents
|
|||
*/
|
||||
const COMMONMARK_ENVIRONMENT_CONFIGURE = 'commonmark_environment_configure';
|
||||
|
||||
/**
|
||||
* Page include parse event.
|
||||
* Runs when a page include tag is being parsed, typically when page content is being processed for viewing.
|
||||
* Provides the "include tag" reference string, the default BookStack replacement content for the tag,
|
||||
* the current page being processed, and the page that's being referenced by the include tag.
|
||||
* The referenced page may be null where the page does not exist or where permissions prevent visibility.
|
||||
* If the listener returns a non-null value, that will be used as the replacement HTML content instead.
|
||||
*
|
||||
* @param string $tagReference
|
||||
* @param string $replacementHTML
|
||||
* @param Page $currentPage
|
||||
* @param ?Page $referencedPage
|
||||
*/
|
||||
const PAGE_INCLUDE_PARSE = 'page_include_parse';
|
||||
|
||||
/**
|
||||
* Web before middleware action.
|
||||
* Runs before the request is handled but after all other middleware apart from those
|
||||
|
|
|
@ -214,6 +214,36 @@ class ThemeTest extends TestCase
|
|||
$this->assertEquals($book->id, $args[1]->id);
|
||||
}
|
||||
|
||||
public function test_event_page_include_parse()
|
||||
{
|
||||
/** @var Page $page */
|
||||
/** @var Page $otherPage */
|
||||
$page = Page::query()->first();
|
||||
$otherPage = Page::query()->where('id', '!=', $page->id)->first();
|
||||
$otherPage->html = '<p id="bkmrk-cool">This is a really cool section</p>';
|
||||
$page->html = "<p>{{@{$otherPage->id}#bkmrk-cool}}</p>";
|
||||
$page->save();
|
||||
$otherPage->save();
|
||||
|
||||
$args = [];
|
||||
$callback = function (...$eventArgs) use (&$args) {
|
||||
$args = $eventArgs;
|
||||
return '<strong>Big & content replace surprise!</strong>';
|
||||
};
|
||||
|
||||
Theme::listen(ThemeEvents::PAGE_INCLUDE_PARSE, $callback);
|
||||
$resp = $this->asEditor()->get($page->getUrl());
|
||||
$this->withHtml($resp)->assertElementContains('.page-content strong', 'Big & content replace surprise!');
|
||||
|
||||
$this->assertCount(4, $args);
|
||||
$this->assertEquals($otherPage->id . '#bkmrk-cool', $args[0]);
|
||||
$this->assertEquals('This is a really cool section', $args[1]);
|
||||
$this->assertTrue($args[2] instanceof Page);
|
||||
$this->assertTrue($args[3] instanceof Page);
|
||||
$this->assertEquals($page->id, $args[2]->id);
|
||||
$this->assertEquals($otherPage->id, $args[3]->id);
|
||||
}
|
||||
|
||||
public function test_add_social_driver()
|
||||
{
|
||||
Theme::addSocialDriver('catnet', [
|
||||
|
|
Loading…
Reference in New Issue
Block a user