Skip to content

Commit

Permalink
NEW Get anchor links from elemental pages
Browse files Browse the repository at this point in the history
Co-Authored-By: Steve Boyd <[email protected]>
  • Loading branch information
GuySartorelli and emteknetnz committed May 25, 2022
1 parent 38bd12b commit bd813b9
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 17 deletions.
57 changes: 42 additions & 15 deletions src/Extensions/ElementalPageExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

namespace DNADesign\Elemental\Extensions;

use DNADesign\Elemental\Models\BaseElement;
use DNADesign\Elemental\Models\ElementalArea;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\Control\Controller;
use SilverStripe\View\Parsers\HTML4Value;
use SilverStripe\View\SSViewer;
Expand Down Expand Up @@ -47,23 +49,14 @@ public function getElementsForSearch()
SSViewer::set_themes(SSViewer::config()->get('themes'));
try {
$output = [];
foreach ($this->owner->hasOne() as $key => $class) {
if ($class !== ElementalArea::class) {
continue;
}
/** @var ElementalArea $area */
$area = $this->owner->$key();
if ($area) {
foreach ($area->Elements() as $element) {
if ($element->getSearchIndexable()) {
$content = $element->getContentForSearchIndex();
if ($content) {
$output[] = $content;
}
}
$this->loopThroughElements(function(BaseElement $element) use (&$output) {
if ($element->getSearchIndexable()) {
$content = $element->getContentForSearchIndex();
if ($content) {
$output[] = $content;
}
}
}
});
} finally {
// Reset theme if an exception occurs, if you don't have a
// try / finally around code that might throw an Exception,
Expand All @@ -73,6 +66,21 @@ public function getElementsForSearch()
return implode($this->owner->config()->get('search_index_element_delimiter') ?? '', $output);
}

/**
* @param array $anchors
*
* @see SiteTree::getAnchorsOnPage()
*/
public function updateAnchorsOnPage(array &$anchors): void
{
if (!($this->owner instanceof SiteTree)) {
return;
}
$this->loopThroughElements(function(BaseElement $element) use (&$anchors) {
$anchors = array_merge($anchors, $element->getAnchorsInContent());
});
}

public function MetaTags(&$tags)
{
if (!Controller::has_curr()) {
Expand All @@ -91,4 +99,23 @@ public function MetaTags(&$tags)
$tags = $html->getContent();
}
}

/**
* Call some function over all elements belonging to this page
*/
private function loopThroughElements(callable $callback): void
{
foreach ($this->owner->hasOne() as $key => $class) {
if ($class !== ElementalArea::class) {
continue;
}
/** @var ElementalArea $area */
$area = $this->owner->$key();
if ($area) {
foreach ($area->Elements() as $element) {
$callback($element);
}
}
}
}
}
35 changes: 33 additions & 2 deletions src/Models/BaseElement.php
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ public function canEdit($member = null)
public function canDelete($member = null)
{
$extended = $this->extendedCan(__FUNCTION__, $member);

if ($extended !== null) {
return $extended;
}
Expand Down Expand Up @@ -679,6 +679,37 @@ public function getAnchor()
return $this->anchor = $result;
}

/**
* Get anchors in this block's content.
* Used to populate the "anchor on a page" link in the WYSIWYG
*
* By default, this finds anchors in any HTMLText field on the block, but
* this method should be overridden if anchors are provided in other ways
* for this block or if not all HTMLText fields for this block are
* displayed on the front-end.
*/
public function getAnchorsInContent(): array
{
$anchors = [$this->getAnchor()];
$anchorRegex = "/\\s+(name|id)\\s*=\\s*([\"'])([^\\2\\s>]*?)\\2|\\s+(name|id)\\s*=\\s*([^\"']+)[\\s +>]/im";
$allFields = DataObject::getSchema()->fieldSpecs($this);
foreach ($allFields as $field => $fieldSpec) {
$fieldObj = $this->owner->dbObject($field);
if ($fieldObj instanceof DBHTMLText) {
$parseSuccess = preg_match_all($anchorRegex, $fieldObj->getValue() ?? '', $matches);
if ($parseSuccess >= 1) {
$fieldAnchors = array_values(array_filter(
array_merge($matches[3], $matches[5])
));
$anchors = array_unique(array_merge($anchors, $fieldAnchors));
}
}
}

$this->extend('updateAnchorsInContent', $anchors);
return $anchors;
}

/**
* @param string|null $action
* @return string|null
Expand All @@ -688,7 +719,7 @@ public function getAnchor()
public function AbsoluteLink($action = null)
{
$page = $this->getPage();

if ($page && ClassInfo::hasMethod($page, 'AbsoluteLink')) {
$link = $page->AbsoluteLink($action) . '#' . $this->getAnchor();
$this->extend('updateAbsoluteLink', $link);
Expand Down

0 comments on commit bd813b9

Please sign in to comment.