Skip to content

Instantly share code, notes, and snippets.

@putzflorian
Last active December 19, 2015 14:59
Show Gist options
  • Save putzflorian/5972934 to your computer and use it in GitHub Desktop.
Save putzflorian/5972934 to your computer and use it in GitHub Desktop.
SEO Meta Helper
<?php
class Website_View_Helper_ElementsHeadMeta extends Zend_View_Helper_Placeholder_Container_Standalone
{
private $built;
public function elementsHeadMeta()
{
return $this;
}
public function resetMeta()
{
$this->built = false;
}
/**
* set's property "built" to true,
* use this method if metaDescription is set in headMeta before
* (e.g. deskline)
*/
public function setMetaDescriptionIsSet()
{
$this->built = true;
}
private function getStringAsOneLine($string)
{
$string = str_replace("\r\n", " ", $string);
$string = str_replace("\n", " ", $string);
$string = str_replace("\r", " ", $string);
$string = str_replace("\t", "", $string);
$string = preg_replace('#[ ]+#', ' ', $string);
return $string;
}
private function getMetaDescription($string, $length)
{
$string = $this->getStringAsOneLine(strip_tags($string));
if ($length < strlen($string)) {
$text = substr($string, 0, $length);
if (false !== ($length = strrpos($text, ' '))) {
$text = substr($text, 0, $length);
}
$string = $text;
}
return $string;
}
public function toString()
{
if (!$this->built) {
$this->setHeadMeta();
}
return (string)$this->view->headMeta();
}
public function setFirstContent($content)
{
if (!$this->metaDescriptionFromContent && $content) {
$this->metaDescriptionFromContent = $content;
}
}
private function setHeadMeta()
{
$this->view->set_metadescription = true;
if ($this->view->getProperty('seo_description_characters_length')) {
$desclength = $this->view->getProperty('seo_description_characters_length');
}
elseif ($this->view->document->getDescription()) {
$desclength = 10000;
}
else {
$desclength = 155;
}
if ($this->view->document->getDescription() and $this->view->set_metadescription) {
$metadescription = $this->getMetaDescription($this->view->document->getDescription(), $desclength);
$this->view->set_metadescription = false;
}
if ($this->view->placeholder('object_seodescription') != "") {
$metadescription = $this->view->placeholder('object_seodescription');
$this->view->set_metadescription = false;
}
if ($this->view->set_metadescription) {
foreach ($this->view->document->getElements() as $e) {
if ($e instanceof Document_Tag_Wysiwyg) {
$metadescription = $e->getValue();
if($e->getValue() != ''){
break;
}
}
}
}
$this->view->headMeta()->appendName('description', $this->getMetaDescription($metadescription, $desclength));
$this->built = true;
}
}
<?php
class Website_View_Helper_ElementsHeadTitle extends Zend_View_Helper_Placeholder_Container_Standalone
{
public function elementsHeadTitle()
{
$crop = false;
$this->view->set_metatitle = true;
// add title (Docuemnt Title)
if ($this->view->document instanceof Document) {
if ($this->view->document->getTitle()) {
$this->view->headTitle($this->view->document->getTitle());
$this->view->set_metatitle = false;
}
}
$headline = "";
if($this->view->document) {
$headlineElement = $this->view->document->getElement("headline");
if($headlineElement instanceof Document_Tag_Textarea || $headlineElement instanceof Document_Tag_Input) {
$headline = $headlineElement->getData();
}
}
if ($this->view->getProperty('seo_suffix')) {
$l = strlen($headline) + strlen($this->view->getProperty("seo_suffix"));
if ($l > 59) {
$crop = 60;
}
}
else {
$l = strlen($headline) + strlen($this->view->translate("seo_title"));
if ($l > 59) {
$crop = 60;
}
}
// for default content-pages
if ($this->view->set_metatitle) {
if ($headline) {
if ($crop) {
$this->view->headTitle($this->getSmartTitle($headline . ' ' . $this->view->getProperty('seo_separator') . ' ' . $this->view->getProperty('seo_suffix')
, $crop));
}
else {
$this->view->headTitle($headline);
}
if (!$this->view->getProperty('seo_title_suffix_disable')) {
$this->view->headTitle()->setSeparator(' ' . $this->view->getProperty('seo_separator') . ' ');
if ($this->view->getProperty('seo_suffix')) {
if (!$crop) {
$this->view->headTitle($this->view->getProperty('seo_suffix'));
}
}
else {
if (!$crop) {
$this->view->headTitle($this->view->translate("seo_title"));
}
}
}
}
}
if (!$this->view->metaTitleSet) {
if($this->view->getProperty('seo_title_characters_length') != ""){
$crop = $this->view->getProperty('seo_title_characters_length');
} else {
$crop = 60;
}
// override title in object detail view
if ($this->view->placeholder('object_seotitle') != "") {
if ($this->view->getProperty('seo_suffix')) {
$tempt = $this->getSmartTitle($this->view->placeholder('object_seotitle') . ' ' . $this->view->getProperty('seo_separator') . ' ' . $this->view->getProperty('seo_suffix'), $crop);
$this->view->headTitle($tempt, 'SET');
} else {
$this->view->headTitle($this->view->placeholder('object_seotitle'), 'SET');
}
}
if ($this->view->getProperty('seo_title_characters_length')) {
$this->view->headTitle($this->getSmartTitle($this->view->headTitle(), $this->view->getProperty('seo_title_characters_length')), 'SET');
}
$this->view->metaTitleSet = true; //set to true to avoid duplicate meta titles in case elementsHeadMeta() is called twice
}
return $this;
}
private function getSmartTitle($headTitle, $length)
{
$smarttitle = strip_tags(htmlspecialchars_decode($headTitle));
return $this->cutStringRespectingWhitespace($smarttitle, $length);
}
private function cutStringRespectingWhitespace($string, $length)
{
if ($length < strlen($string)) {
$text = substr($string, 0, $length);
if (false !== ($length = strrpos($text, ' '))) {
$text = substr($text, 0, $length);
}
$string = $text;
}
return $string;
}
public function toString()
{
return (string)$this->view->headTitle();
}
}
@Gerhard-Kanzler
Copy link

Readme

Vordefinierte Eigenschaften

  • seo_suffix (Hier kann der Standard SEO Title überschrieben werden)
  • seo_title_suffix_disable (Entfernt den Suffix)
  • seo_title_characters_length (Zeichenbeschränkung im Title)
  • seo_description_characters_length (Zeichenbeschränkung in der Beschreibung)
  • seo_separator SEO Trennzeichen

Translation Key
seo_title (Standard SEO Title)

Einbindung

Falls noch nicht im Website_Controller_Action in der init() folgende Zeile einfügen.

$this->view->addHelperPath(PIMCORE_WEBSITE_PATH . "/lib/Website/View/Helper","Website_View_Helper_");

Die beiden Dateien werden nach /website/lib/Website/View/Helper kopiert
Im Head wird das ganze aufgerufen

<?php
    if( ! $this->editmode && $this->document instanceof Document_Page ){ 
        echo $this->elementsHeadTitle();
        echo $this->elementsHeadMeta();
    } 
?>

Logik zur Generierung der Metadescription

  • ist die Description im headMeta()-View-Helper schon anderweitig gesetzt worden (kann dem elementsHeadMeta()-Helper per setMetaDescriptionIsSet() mitgeteilt werden) ? Ja => gib headMeta() aus, nein => weiter zu punkt 2
  • am Dokument Description gesetzt? ja => verwende diesen, nein => weiter zu 2.
    placeholder "object_seodescription" gesetzt? ja => verwende diesen, nein => weiter zu 3.
  • metaDescriptionFromContent (per setFirstContent($text) ) gesetzt? ja => verwende diesen, nein => weiter zu 4.
  • Content erster WYSIWYG-Block

Integration in Textblöcken

Per default wird, wenn sonst keine Bedingungen zu treffen (siehe oben), der Content des ersten WYSIWYG-Content-Block des Dokuments als meta-Description verwendet. "Erster" bezieht sich jedoch hier auf die Erstellung des Textblocks, nicht auf die Reihenfolge in der Ausgabe! Der MetaDescription-Helper kann gar nicht wissen, welcher Block als erster bzw. überhaupt ausgegeben wird, da das ja erst in der view beim rendern passiert. Um konkret einen content zu setzen, kann daher die Methode setFirstContent() aufgerufen werden - wenn der metaDescription-Helper noch keinen Text aus dem Content gesetzt
z.B. in der View der WYSIWYG-.Area:

$this->elementsHeadMeta()->setFirstContent($this->wysiwyg("content")->getValue());

Wichtig
Die H1 bitte mit $this->input("headline") einbinden.
Dieses Input wird für die Titelbefüllung verwendet.
Placeholder für Objekte

$this->placeholder('object_seotitle')->set( $object->getHeadline() );
$this->placeholder('object_seodescription')->set( $object->getDescription() );

Eigenen Meta Title oder Meta Description verwenden

$this->view->metaTitleSet = true;
$this->view->metaDescriptionSet = true;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment