Zum Inhalt springen

BrowseLinks Hooks

Erstellt am 12. Februar 2013 · 4 Antworten · letzte Antwort am 30. Juni 2014

Tags: Frage

MajPay ·

Hi,

Ich muss den Link Browser (der sich unter anderem aus dem RTE öffnet) so erweitern, dass ich einnen eigenen Datentypen verlinken kann.

Ich weiß, dass es da eine Erweiterung gibt, die möchte ich aber nicht benutzen, sondern einen Hook für BrowseLinks einbinden.

Ich finde aber keine konkreten How-Tos oder irgendwas, das mir dabei hilft. Die Klasse ans ich ist auch nicht sehr aufschlussreich dokumentiert.

Das ganze sollte nach TYPO3-6.0 Konventionen laufen inkl. Namespaces.

Gibts irgendwo ein brauchbares Tutorial dazu?

MajPay ·

War ein brutales Stück Arbeit, habe absolut nichts brauchbars im Netz gefunden, schlussendlich hat mir das durchforsten der linkhandler extension und das Sourcecode studieren geholfen. Damit nicht jeder Stundenlang durch 1000e Zeilen Code durch muss ein paar Dinge dazu:

Hooks hinzufügen:

//register hook for adding regional_object tab to Link Browser in RTE
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/rtehtmlarea/mod3/class.tx_rtehtmlarea_browse_links.php']['browseLinksHook'][] = 'Vendor\\RegionalObject\\Hook\\BrowseLinksHook';
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/class.browse_links.php']['browseLinksHook'][] = 'Vendor\\RegionalObject\\Hook\\BrowseLinksHook';

//register hook for parsing regional_object link in the frontend
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content.php']['typolinkLinkHandler']['typo3/regional_object'] = 'Vendor\\RegionalObject\\Hook\\LinkHandler';

Hooks im Autoloader registrieren.

Der Browselinkshook leitet sich vom Interface \TYPO3\CMS\Core\ElementBrowser\ElementBrowserHookInterface ab, die nötigen Methoden anlegen...

init Methode: Hier muss nichts passieren, es hilft euch aber, wenn ihr dem Hook eine Eigenschaft parentObject gibt und dieses dort referenziert

In addAllowedItems pushed ihr in das Array, das per Parameter kommt euren Key und returned es.

In modifyMenuDefinition bekommt ihr ein array, dem ihr eure neue Definition anhängt. Sieht in etwa so aus:

if (in_array('regional_object',$this->parentObject->allowedItems)) {
			$menuDefinition['regional_object']['isActive'] = $this->parentObject->act == 'regional_object';
			$menuDefinition['regional_object']['label'] = $GLOBALS['LANG']->sL('LLL:EXT:regional_object/Resources/Private/Language/locallang_ttc.xml:browseLinks.regional_object',1);
			$menuDefinition['regional_object']['url'] = '#';
			$menuDefinition['regional_object']['addParams'] = 'onclick="jumpToUrl(\'' . htmlspecialchars(('?act=regional_object&mode=' . $this->parentObject->mode . '&bparams=' . $this->parentObject->bparams)) . '\');return false;"';
		}
		return $menuDefinition;

in getTab returned ihr euren neuen Inhalt.

Pagetree und Records könnt ihr so laden:

$pageTree = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TBE_PageTree');
$tree = $pageTree->printTree($pageTree->getBrowsableTree());
$cElements = $this->getRegionalObjects();

die getRegionalObjects methode von mir beinhaltet folgendes:

$tablename = 'tx_regionalobject_domain_model_regionalobject';
		$out = '';
		// Set page id (if any) to expand
		$expPageId = $this->parentObject->expandPage;
		// If there is an anchor value (content element reference) in the element reference, then force an ID to expand:
		if (!$this->parentObject->expandPage && $this->parentObject->curUrlInfo['cElement']) {
			// Set to the current link page id.
			$expPageId = $this->parentObject->curUrlInfo['pageid'];
		}
		// Draw the record list IF there is a page id to expand:
		if ($expPageId && \TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($expPageId) && $GLOBALS['BE_USER']->isInWebMount($expPageId)) {
			// Set header:
			$out .= $this->parentObject->barheader($GLOBALS['LANG']->sL('LLL:EXT:regional_object/Resources/Private/Language/locallang_db.xml:tx_regionalobject_domain_model_regionalobject',1));
			// Create header for listing, showing the page title/icon:
			$titleLen = intval($GLOBALS['BE_USER']->uc['titleLen']);
			$mainPageRec = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecordWSOL('pages', $expPageId);
			$picon = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIconForRecord('pages', $mainPageRec);
			$picon .= \TYPO3\CMS\Backend\Utility\BackendUtility::getRecordTitle('pages', $mainPageRec, TRUE);
			$out .= $picon . '<br />';
			// Look up tt_content elements from the expanded page:
			$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
				'uid,type,hidden,starttime,endtime,title',
				$tablename,
				'pid=' . intval($expPageId) .
				\TYPO3\CMS\Backend\Utility\BackendUtility::deleteClause($tablename) .
				\TYPO3\CMS\Backend\Utility\BackendUtility::versioningPlaceholderClause($tablename), '', 'sorting,title,uid');
			
			$cc = $GLOBALS['TYPO3_DB']->sql_num_rows($res);
			
			// Traverse list of records:
			$c = 0;
			while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
				$c++;
				$icon = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIconForRecord($tablename, $row);
				if ($this->parentObject->curUrlInfo['act'] == 'page' && $this->parentObject->curUrlInfo['cElement'] == $row['uid']) {
					$arrCol = '<img' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/blinkarrow_left.gif', 'width="5" height="9"') . ' class="c-blinkArrowL" alt="" />';
				} else {
					$arrCol = '';
				}
				// Putting list element HTML together:
				// 
				// onclick="return link_typo3Page(\'' . $expPageId . '\',\'#' . $row['uid'] . '\');"
				$onclick = 'onclick="return link_spec(\'regional_object:' . $row['uid'] . '\');"';
				$out .=
				'<img' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($GLOBALS['BACK_PATH'], ('gfx/ol/join' . ($c == $cc ? 'bottom' : '') . '.gif'), 'width="18" height="16"') . ' alt="" />'. $arrCol .
				'<a href="#" '.$onclick.'>' . $icon . \TYPO3\CMS\Backend\Utility\BackendUtility::getRecordTitle($tablename, $row, TRUE) . '</a><br />';
			}
		}
		return $out;

in parseCurrentUrl returne ich einfach das info Array.

####

LinkHandler: Ich kopiere das gesamte File hier rein:

<?php

namespace Vendor\RegionalObject\Hook;

/**
 * LinkHandler Class
 * Generates a link for the frontend for linked regional object elements
 * 
 * @author Philipp Wrann
 * @vendor ******
 */

class LinkHandler {
	
	/**
	 * Process the typolink
	 * 
	 * todo: think of rewriting the link
	 * 
	 * @param string $linktxt The linktext
	 * @param array $conf Configuraion
	 * @param string $linkHandlerKeyword should be regional_object
	 * @param string $linkHandlerValue The uid of the record
	 * @param string $linkParams Full link params
	 * @param \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $contentObjectRenderer
	 * 
	 * @return string the rendered link
	 */
	function main($linktxt, $conf, $linkHandlerKeyword, $linkHandlerValue, $linkParams, &$contentObjectRenderer) {
		
		$regionalObject = $GLOBALS['TSFE']->sys_page->checkRecord('tx_regionalobject_domain_model_regionalobject',$linkHandlerValue);
		
		if ($regionalObject && !empty($regionalObject)) {
			$typesConfig = $GLOBALS['TSFE']->tmpl->setup['plugin.']['regional_object.']['types.'];
			$link = '';
			$localContentObjectRenderer = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer');
			$localContentObjectRenderer->start($regionalObject);
			$type = $localContentObjectRenderer->data['type'];
			
			//get types detail page based on the according typoscript setting
			if (isset($typesConfig[$type.'.']['detailPageUid']) && \TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($typesConfig[$type.'.']['detailPageUid']))
				$detailPageUid = $typesConfig[$type.'.']['detailPageUid'];
			else
				$detailPageUid = $typesConfig['default.']['detailPageUid'];
			
			$link = $localContentObjectRenderer->typoLink($linktxt,array(
					'parameter' => $detailPageUid,
					'additionalParams' => '&regional_object='.$linkHandlerValue
				)
			);
			
			return $link;
		}
		
		return $linktxt;
	}
	
	
	
}

?>
MajPay ·

Ein Problem gibts noch:

$pageTree = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TBE_PageTree');
$tree = $pageTree->printTree($pageTree->getBrowsableTree());
$cElements = $this->getRegionalObjects();

Hier wird mir nur der letzte Mount des Users ausgegeben, wenn er mehrere Mounts hat habe ich das Problem, dass ich nicht alle DB Mounts sehe. Ich habe das nun fürs erste so umgangen:

$pageTree->MOUNTS = array('0'=>'0');

Damit wird nur ein Mount (der der Root Page) angezeigt, es wird alle mal ALLES angezeigt. Jedoch wäre es logischerweise sinnvoller die jeweils zutreffenden Mounts zu benutzen. Woher bekomme ich die, damit die Sichtbarkeitseinstellungen die selben sind wie beim Pagetree im Backend?

MajPay ·

Immer wieder toll, wenn man ewig rumprobiert, dann nachfragt und es kurz danach hinbekommt.

So funktioniert es:

$pageTree = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TBE_PageTree');
			$pageTree->ext_showNavTitle = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showNavTitle');
			$pageTree->ext_showPageId = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showPageIdWithTitle');
			$pageTree->addField('nav_title');
			
			$tree = $pageTree->getBrowsableTree();
mischa ·

Hallo,

super Anleitung. Vielen Dank dafür.

Eine kleine Ergänzung:

Ich frage in der getTab() ab, ob ich im RTE bin oder nicht und binde dann den ganzen Klassenauswahl udn title-Felder ein.

	if($this->isRTE()) {
		$rte = GeneralUtility::makeInstance('TYPO3\\CMS\\Rtehtmlarea\\BrowseLinks');
		$rte->anchorTypes[] = $linkSelectorAction;
		$rte->init();
		$out .= $rte->addAttributesForm();
	}

So kann man im TSConfig eigene Klassen und Title-Attribute für den RTE definieren. (Nach API)

Meine isRTE() schaut so aus (aus der EXT linkhandler geklaut)

	protected function isRTE() {
		if ($this->pObj->mode=='rte') {
			return true;
		}
		else {
			return false;
		}
	}