-
- /**
- * Remove any page include tags within the given HTML.
- */
- protected function blankPageIncludes(string $html): string
- {
- return preg_replace("/{{@\s?([0-9].*?)}}/", '', $html);
- }
-
- /**
- * Parse any include tags "{{@<page_id>#section}}" to be part of the page.
- */
- protected function parsePageIncludes(string $html): string
- {
- $matches = [];
- preg_match_all("/{{@\s?([0-9].*?)}}/", $html, $matches);
-
- foreach ($matches[1] as $index => $includeId) {
- $fullMatch = $matches[0][$index];
- $splitInclude = explode('#', $includeId, 2);
-
- // Get page id from reference
- $pageId = intval($splitInclude[0]);
- if (is_nan($pageId)) {
- continue;
- }
-
- // Find page to use, and default replacement to empty string for non-matches.
- /** @var ?Page $matchedPage */
- $matchedPage = Page::visible()->find($pageId);
- $replacement = '';
-
- if ($matchedPage && count($splitInclude) === 1) {
- // If we only have page id, just insert all page html and continue.
- $replacement = $matchedPage->html;
- } elseif ($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);
- }
-
- $themeReplacement = Theme::dispatch(
- ThemeEvents::PAGE_INCLUDE_PARSE,
- $includeId,
- $replacement,
- clone $this->page,
- $matchedPage ? (clone $matchedPage) : null,
- );
-
- // Perform the content replacement
- $html = str_replace($fullMatch, $themeReplacement ?? $replacement, $html);
- }
-
- return $html;
- }
-
- /**
- * Fetch the content from a specific section of the given page.
- */
- protected function fetchSectionOfPage(Page $page, string $sectionId): string
- {
- $topLevelTags = ['table', 'ul', 'ol', 'pre'];
- $doc = new HtmlDocument($page->html);
-
- // Search included content for the id given and blank out if not exists.
- $matchingElem = $doc->getElementById($sectionId);
- if ($matchingElem === null) {
- return '';
- }
-
- // Otherwise replace the content with the found content
- // Checks if the top-level wrapper should be included by matching on tag types
- $isTopLevel = in_array(strtolower($matchingElem->nodeName), $topLevelTags);
- if ($isTopLevel) {
- return $doc->getNodeOuterHtml($matchingElem);
- }
-
- return $doc->getNodeInnerHtml($matchingElem);
- }