Skip to content

Commit

Permalink
FEATURE focus keyword highlighting
Browse files Browse the repository at this point in the history
  • Loading branch information
zanderwar committed Apr 17, 2018
1 parent d5fb93c commit 97e3b1b
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 10 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
An all-in-one SEO module for SilverStripe

## Features
* SEO Health Analysis in the Page Editor ![SEO Health Analysis](https://i.imgur.com/axlmK1j.png)
* SEO Health Analysis in the Page Editor ![SEO Health Analysis](https://i.imgur.com/L2MTFDd.png)
* Automatic Facebook OpenGraph meta-tag generation (can override) ![Facebook SEO Control](https://i.imgur.com/FcK0ExJ.png)
* Automatic Twitter meta-tag generation (can override) ![Twitter SEO Control](https://i.imgur.com/7I4rnXw.png)
* Also adds a `TwitterAccountName` field to `SilverStripe\Security\Member` which is used for the creator tag. The creator is recorded when a new page is created and their Twitter account name will be used for the meta tag
Expand Down
83 changes: 77 additions & 6 deletions src/Forms/GoogleSearchPreview.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@

namespace Vulcan\Seo\Forms;

use SilverStripe\Control\Controller;
use SilverStripe\Control\Director;
use SilverStripe\Forms\LiteralField;
use SilverStripe\View\ArrayData;
use SilverStripe\View\Parsers\URLSegmentFilter;
use SilverStripe\View\Requirements;
use simplehtmldom_1_5\simple_html_dom;
use Vulcan\Seo\Extensions\PageHealthExtension;
use Vulcan\Seo\Extensions\PageSeoExtension;

/**
* Class GoogleSearchPreview
Expand All @@ -25,20 +30,32 @@ class GoogleSearchPreview extends LiteralField
/**
* HealthAnalysisField constructor.
*
* @param string $name
* @param \SilverStripe\Forms\FormField|string $title
* @param \Page $page
* @param simple_html_dom $domParser
* @param string $name
* @param \SilverStripe\Forms\FormField|string $title
* @param \Page|PageHealthExtension|PageSeoExtension $page
* @param simple_html_dom $domParser
*/
public function __construct($name, $title, \Page $page, simple_html_dom $domParser)
public function __construct($name, $title, $page, simple_html_dom $domParser)
{
$renderedTitle = $domParser->find('title', 0);
$firstParagraph = $domParser->find('p', 0);

Requirements::javascript('vulcandigital/silverstripe-seo:dist/javascript/main.min.js');
Requirements::css('vulcandigital/silverstripe-seo:dist/css/styles.min.css');

parent::__construct($name, ArrayData::create(['Title' => $title, 'Page' => $page, 'FirstParagraph' => $firstParagraph ? $firstParagraph->innertext() : null, 'RenderedTitle' => $renderedTitle ? $renderedTitle->innertext() : null])->renderWith(self::class));
parent::__construct($name, ArrayData::create([
'Title' => $title,
'Page' => $page,
'AbsoluteLink' => Controller::join_links(Director::absoluteBaseURL(),
str_replace($page->URLSegment, '', $page->Link()),
$this->urlSegmentHighlight($page->URLSegment, $page->FocusKeyword)),
'MetaDescription' => $page->MetaDescription ? $this->highlight($page->MetaDescription,
$page->FocusKeyword) : null,
'FirstParagraph' => $firstParagraph ? $this->highlight($firstParagraph->innertext(),
$page->FocusKeyword) : null,
'RenderedTitle' => $renderedTitle ? $this->highlight($renderedTitle->innertext(),
$page->FocusKeyword) : null
])->renderWith(self::class));
}

/**
Expand All @@ -52,4 +69,58 @@ public function setResult($int)

return $this;
}

/**
* Highlights parts of the $haystack that match the focus keyword as a whole, case insensitive
*
* @param $haystack
* @param $needle
*
* @return mixed
*/
public function highlight($haystack, $needle)
{
if (!$needle) {
return $haystack;
}

return preg_replace('/\b(' . $needle . ')\b/i', '<strong>$0</strong>', $haystack);
}

/**
* Highlights parts of the URLSegment that match the focus keyword as a whole, does not highlight hyphens in that
* same match.
*
* @param $urlSegment
* @param $needle
*
* @return mixed|string
*/
public function urlSegmentHighlight($urlSegment, $needle)
{
if ($urlSegment === 'home') {
return '/';
}

if (!$needle) {
return $urlSegment;
}

$needle = URLSegmentFilter::create()->filter($needle);

preg_match('/(' . $needle . ')/i', $needle, $matches);

if (!isset($matches[1])) {
return $urlSegment;
}

$needles = explode('-', $needle);
$output = $urlSegment;

foreach ($needles as $needle) {
$output = preg_replace('/(' . $needle . ')/i', '<strong>$0</strong>', $output);
}

return $output;
}
}
6 changes: 3 additions & 3 deletions templates/Vulcan/Seo/Forms/GoogleSearchPreview.ss
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

<div class="form__field-holder" style="padding: 7px 1.5385rem; position: relative;">
<div class="google-search-preview">
<h3><a href="$Page.Link" target="_blank"><% if $RenderedTitle %>$RenderedTitle<% else %>$Page.Title<% end_if %></a></h3>
<div class="google-url-preview">$Page.AbsoluteLink</div>
<div class="snippet"><% if $Page.MetaDescription %>$Page.MetaDescription.LimitCharacters(320).RAW<% else_if $FirstParagraph %>$FirstParagraph.LimitCharacters(320).RAW<% else %><em>No description found for this page</em><% end_if %></div>
<h3><a href="$Page.Link" target="_blank"><% if $RenderedTitle %>$RenderedTitle.RAW<% else %>$Page.Title<% end_if %></a></h3>
<div class="google-url-preview">$AbsoluteLink.RAW</div>
<div class="snippet"><% if $MetaDescription %>$MetaDescription.LimitCharacters(320).RAW<% else_if $FirstParagraph %>$FirstParagraph.LimitCharacters(320).RAW<% else %><em>No description found for this page</em><% end_if %></div>
</div>
</div>
</div>

0 comments on commit 97e3b1b

Please sign in to comment.